diff options
117 files changed, 10806 insertions, 8829 deletions
diff --git a/source/Makefile.in b/source/Makefile.in index eb5cea522fa..5abb7ebbf48 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -386,6 +386,7 @@ OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o NOTIFY_OBJ = smbd/notify.o smbd/notify_hash.o smbd/notify_kernel.o smbd/notify_fam.o +VFS_DEFAULT_OBJ = modules/vfs_default.o VFS_AUDIT_OBJ = modules/vfs_audit.o VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o VFS_FULL_AUDIT_OBJ = modules/vfs_full_audit.o @@ -406,6 +407,9 @@ VFS_HPUXACL_OBJ = modules/vfs_hpuxacl.o VFS_IRIXACL_OBJ = modules/vfs_irixacl.o VFS_TRU64ACL_OBJ = modules/vfs_tru64acl.o VFS_CATIA_OBJ = modules/vfs_catia.o +VFS_CACHEPRIME_OBJ = modules/vfs_cacheprime.o +VFS_PREALLOC_OBJ = modules/vfs_prealloc.o +VFS_COMMIT_OBJ = modules/vfs_commit.o VFS_GPFS_OBJ = modules/vfs_gpfs.o modules/gpfs.o PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o @@ -441,7 +445,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/reply.o smbd/sesssetup.o smbd/trans2.o smbd/uid.o \ smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \ smbd/blocking.o smbd/sec_ctx.o smbd/srvstr.o \ - smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \ + smbd/vfs.o smbd/statcache.o \ smbd/posix_acls.o lib/sysacls.o $(SERVER_MUTEX_OBJ) \ smbd/process.o smbd/service.o smbd/error.o \ printing/printfsp.o lib/sysquotas.o lib/sysquotas_linux.o \ @@ -464,7 +468,7 @@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \ printing/print_cups.o printing/print_generic.o \ printing/lpq_parse.o printing/load.o \ - printing/print_iprint.o + printing/print_iprint.o printing/print_test.o PRINTBASE_OBJ = printing/notify.o printing/printing_db.o PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o $(PRINTBASE_OBJ) diff --git a/source/auth/auth_server.c b/source/auth/auth_server.c index 7bec1b4128d..7ffea1ca11b 100644 --- a/source/auth/auth_server.c +++ b/source/auth/auth_server.c @@ -39,7 +39,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx) char *pserver; BOOL connected_ok = False; - if (!(cli = cli_initialise(cli))) + if (!(cli = cli_initialise())) return NULL; /* security = server just can't function with spnego */ @@ -49,7 +49,8 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx) p = pserver; while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) { - standard_sub_basic(current_user_info.smb_name, desthost, sizeof(desthost)); + standard_sub_basic(current_user_info.smb_name, current_user_info.domain, + desthost, sizeof(desthost)); strupper_m(desthost); if(!resolve_name( desthost, &dest_ip, 0x20)) { @@ -85,7 +86,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx) return NULL; } - if (!attempt_netbios_session_request(cli, global_myname(), + if (!attempt_netbios_session_request(&cli, global_myname(), desthost, &dest_ip)) { release_server_mutex(); DEBUG(1,("password server fails session request\n")); @@ -119,8 +120,8 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx) this one... */ - if (!cli_session_setup(cli, "", "", 0, "", 0, - "")) { + if (!NT_STATUS_IS_OK(cli_session_setup(cli, "", "", 0, "", 0, + ""))) { DEBUG(0,("%s rejected the initial session setup (%s)\n", desthost, cli_errstr(cli))); release_server_mutex(); @@ -129,7 +130,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx) } release_server_mutex(); - + DEBUG(3,("password server OK\n")); return cli; @@ -240,7 +241,7 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context return nt_status; } - cli = my_private_data; + cli = (struct cli_state *)my_private_data; if (cli) { } else { @@ -295,8 +296,12 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context */ if ((!tested_password_server) && (lp_paranoid_server_security())) { - if (cli_session_setup(cli, baduser, (char *)badpass, sizeof(badpass), - (char *)badpass, sizeof(badpass), user_info->domain)) { + if (NT_STATUS_IS_OK(cli_session_setup(cli, baduser, + (char *)badpass, + sizeof(badpass), + (char *)badpass, + sizeof(badpass), + user_info->domain))) { /* * We connected to the password server so we @@ -342,30 +347,25 @@ use this machine as the password server.\n")); if (!user_info->encrypted) { /* Plaintext available */ - if (!cli_session_setup(cli, user_info->smb_name, - (char *)user_info->plaintext_password.data, - user_info->plaintext_password.length, - NULL, 0, - user_info->domain)) { - DEBUG(1,("password server %s rejected the password\n", cli->desthost)); - /* Make this cli_nt_error() when the conversion is in */ - nt_status = cli_nt_error(cli); - } else { - nt_status = NT_STATUS_OK; - } + nt_status = cli_session_setup( + cli, user_info->smb_name, + (char *)user_info->plaintext_password.data, + user_info->plaintext_password.length, + NULL, 0, user_info->domain); + } else { - if (!cli_session_setup(cli, user_info->smb_name, - (char *)user_info->lm_resp.data, - user_info->lm_resp.length, - (char *)user_info->nt_resp.data, - user_info->nt_resp.length, - user_info->domain)) { - DEBUG(1,("password server %s rejected the password\n", cli->desthost)); - /* Make this cli_nt_error() when the conversion is in */ - nt_status = cli_nt_error(cli); - } else { - nt_status = NT_STATUS_OK; - } + nt_status = cli_session_setup( + cli, user_info->smb_name, + (char *)user_info->lm_resp.data, + user_info->lm_resp.length, + (char *)user_info->nt_resp.data, + user_info->nt_resp.length, + user_info->domain); + } + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(1,("password server %s rejected the password: %s\n", + cli->desthost, nt_errstr(nt_status))); } /* if logged in as guest then reject */ diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c index 0fbf672026f..82a13fd9e78 100644 --- a/source/auth/auth_util.c +++ b/source/auth/auth_util.c @@ -513,15 +513,9 @@ NT_USER_TOKEN *get_root_nt_token( void ) return token; } -static int server_info_dtor(void *p) +static int server_info_dtor(auth_serversupplied_info *server_info) { - auth_serversupplied_info *server_info = - talloc_get_type_abort(p, auth_serversupplied_info); - - if (server_info->sam_account != NULL) { - TALLOC_FREE(server_info->sam_account); - } - + TALLOC_FREE(server_info->sam_account); ZERO_STRUCTP(server_info); return 0; } @@ -633,12 +627,17 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, * Add alias SIDs from memberships within the partially created token SID list */ -static NTSTATUS add_aliases(TALLOC_CTX *tmp_ctx, const DOM_SID *domain_sid, +static NTSTATUS add_aliases(const DOM_SID *domain_sid, struct nt_user_token *token) { uint32 *aliases; size_t i, num_aliases; NTSTATUS status; + TALLOC_CTX *tmp_ctx; + + if (!(tmp_ctx = talloc_init("add_aliases"))) { + return NT_STATUS_NO_MEMORY; + } aliases = NULL; num_aliases = 0; @@ -651,6 +650,7 @@ static NTSTATUS add_aliases(TALLOC_CTX *tmp_ctx, const DOM_SID *domain_sid, if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n", nt_errstr(status))); + TALLOC_FREE(tmp_ctx); return status; } @@ -662,10 +662,12 @@ static NTSTATUS add_aliases(TALLOC_CTX *tmp_ctx, const DOM_SID *domain_sid, &token->num_sids); if (token->user_sids == NULL) { DEBUG(0, ("add_sid_to_array failed\n")); + TALLOC_FREE(tmp_ctx); return NT_STATUS_NO_MEMORY; } } + TALLOC_FREE(tmp_ctx); return NT_STATUS_OK; } @@ -708,7 +710,7 @@ static NTSTATUS log_nt_token(TALLOC_CTX *tmp_ctx, NT_USER_TOKEN *token) /******************************************************************* *******************************************************************/ -static NTSTATUS add_builtin_administrators( TALLOC_CTX *ctx, struct nt_user_token *token ) +static NTSTATUS add_builtin_administrators( struct nt_user_token *token ) { DOM_SID domadm; @@ -829,22 +831,14 @@ static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, int num_groupsids, const DOM_SID *groupsids) { - TALLOC_CTX *tmp_ctx; struct nt_user_token *result = NULL; int i; NTSTATUS status; gid_t gid; - tmp_ctx = talloc_new(mem_ctx); - if (tmp_ctx == NULL) { - DEBUG(0, ("talloc_new failed\n")); - return NULL; - } - - result = TALLOC_ZERO_P(tmp_ctx, NT_USER_TOKEN); - if (result == NULL) { + if (!(result = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN))) { DEBUG(0, ("talloc failed\n")); - goto done; + return NULL; } /* Add the user and primary group sid */ @@ -902,7 +896,7 @@ static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, unbecome_root(); } else { - status = add_builtin_administrators( tmp_ctx, result ); + status = add_builtin_administrators( result ); if ( !NT_STATUS_IS_OK(status) ) { /* just log a complaint but do not fail */ DEBUG(3,("create_local_nt_token: failed to check for local Administrators" @@ -936,31 +930,26 @@ static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, /* Now add the aliases. First the one from our local SAM */ - status = add_aliases(tmp_ctx, get_global_sam_sid(), result); + status = add_aliases(get_global_sam_sid(), result); if (!NT_STATUS_IS_OK(status)) { - result = NULL; - goto done; + TALLOC_FREE(result); + return NULL; } /* Finally the builtin ones */ - status = add_aliases(tmp_ctx, &global_sid_Builtin, result); + status = add_aliases(&global_sid_Builtin, result); if (!NT_STATUS_IS_OK(status)) { - result = NULL; - goto done; + TALLOC_FREE(result); + return NULL; } } get_privileges_for_sids(&result->privileges, result->user_sids, result->num_sids); - - talloc_steal(mem_ctx, result); - - done: - TALLOC_FREE(tmp_ctx); return result; } @@ -982,6 +971,12 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info) return NT_STATUS_NO_MEMORY; } + /* + * If winbind is not around, we can not make much use of the SIDs the + * domain controller provided us with. Likewise if the user name was + * mapped to some local unix user. + */ + if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) || (server_info->was_mapped)) { status = create_token_from_username(server_info, @@ -1377,7 +1372,7 @@ static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_inf struct samu *sampass = NULL; DOM_SID guest_sid; BOOL ret; - static const char zeros[16]; + static const char zeros[16] = { 0, }; if ( !(sampass = samu_new( NULL )) ) { return NT_STATUS_NO_MEMORY; @@ -1432,8 +1427,8 @@ static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src) dst->gid = src->gid; dst->n_groups = src->n_groups; if (src->n_groups != 0) { - dst->groups = talloc_memdup(dst, src->groups, - sizeof(gid_t)*dst->n_groups); + dst->groups = (gid_t *)talloc_memdup( + dst, src->groups, sizeof(gid_t)*dst->n_groups); } else { dst->groups = NULL; } @@ -1489,6 +1484,66 @@ NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info) return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; } +BOOL copy_current_user(struct current_user *dst, struct current_user *src) +{ + gid_t *groups; + NT_USER_TOKEN *nt_token; + + groups = (gid_t *)memdup(src->ut.groups, + sizeof(gid_t) * src->ut.ngroups); + if ((src->ut.ngroups != 0) && (groups == NULL)) { + return False; + } + + nt_token = dup_nt_token(NULL, src->nt_user_token); + if (nt_token == NULL) { + SAFE_FREE(groups); + return False; + } + + dst->conn = src->conn; + dst->vuid = src->vuid; + dst->ut.uid = src->ut.uid; + dst->ut.gid = src->ut.gid; + dst->ut.ngroups = src->ut.ngroups; + dst->ut.groups = groups; + dst->nt_user_token = nt_token; + return True; +} + +BOOL set_current_user_guest(struct current_user *dst) +{ + gid_t *groups; + NT_USER_TOKEN *nt_token; + + groups = (gid_t *)memdup(guest_info->groups, + sizeof(gid_t) * guest_info->n_groups); + if (groups == NULL) { + return False; + } + + nt_token = dup_nt_token(NULL, guest_info->ptok); + if (nt_token == NULL) { + SAFE_FREE(groups); + return False; + } + + TALLOC_FREE(dst->nt_user_token); + SAFE_FREE(dst->ut.groups); + + /* dst->conn is never really dereferenced, it's only tested for + * equality in uid.c */ + dst->conn = NULL; + + dst->vuid = UID_FIELD_INVALID; + dst->ut.uid = guest_info->uid; + dst->ut.gid = guest_info->gid; + dst->ut.ngroups = guest_info->n_groups; + dst->ut.groups = groups; + dst->nt_user_token = nt_token; + return True; +} + /*************************************************************************** Purely internal function for make_server_info_info3 Fill the sam account from getpwnam @@ -1634,7 +1689,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, auth_serversupplied_info **server_info, NET_USER_INFO_3 *info3) { - static const char zeros[16]; + static const char zeros[16] = { 0, }; NTSTATUS nt_status = NT_STATUS_OK; char *found_username; @@ -1931,8 +1986,8 @@ NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, NT_USER_TOKEN *ptoken) ZERO_STRUCTP(token); if (ptoken->user_sids && ptoken->num_sids) { - token->user_sids = talloc_memdup(token, ptoken->user_sids, - sizeof(DOM_SID) * ptoken->num_sids ); + token->user_sids = (DOM_SID *)talloc_memdup( + token, ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids ); if (token->user_sids == NULL) { DEBUG(0, ("talloc_memdup failed\n")); @@ -1941,7 +1996,7 @@ NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, NT_USER_TOKEN *ptoken) } token->num_sids = ptoken->num_sids; } - + /* copy the privileges; don't consider failure to be critical here */ if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) { diff --git a/source/client/client.c b/source/client/client.c index a578608bfff..3b153a7e04c 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -23,6 +23,7 @@ #include "includes.h" #include "client/client_proto.h" +#include "include/rpc_client.h" #ifndef REGISTER #define REGISTER 0 #endif @@ -102,7 +103,8 @@ static double dir_total; struct cli_state *cli; - +static char CLI_DIRSEP_CHAR = '\\'; +static char CLI_DIRSEP_STR[] = { '\\', '\0' }; /**************************************************************************** Write to a local file with CR/LF->LF translation if appropriate. Return the @@ -269,18 +271,18 @@ static int do_cd(char *newdir) pstrcpy(saved_dir, cur_dir); - if (*p == '\\') + if (*p == CLI_DIRSEP_CHAR) pstrcpy(cur_dir,p); else pstrcat(cur_dir,p); - if ((cur_dir[0] != '\0') && (*(cur_dir+strlen(cur_dir)-1) != '\\')) { - pstrcat(cur_dir, "\\"); + if ((cur_dir[0] != '\0') && (*(cur_dir+strlen(cur_dir)-1) != CLI_DIRSEP_CHAR)) { + pstrcat(cur_dir, CLI_DIRSEP_STR); } dos_clean_name(cur_dir); pstrcpy( dname, cur_dir ); - pstrcat(cur_dir,"\\"); + pstrcat(cur_dir,CLI_DIRSEP_STR); dos_clean_name(cur_dir); if ( !cli_resolve_path( "", cli, dname, &targetcli, targetpath ) ) { @@ -290,7 +292,7 @@ static int do_cd(char *newdir) } - if ( strequal(targetpath,"\\" ) ) + if ( strequal(targetpath,CLI_DIRSEP_STR ) ) return 0; /* Use a trans2_qpathinfo to test directories for modern servers. @@ -309,7 +311,7 @@ static int do_cd(char *newdir) goto out; } } else { - pstrcat( targetpath, "\\" ); + pstrcat( targetpath, CLI_DIRSEP_STR ); dos_clean_name( targetpath ); if ( !cli_chkpath(targetcli, targetpath) ) { @@ -384,11 +386,11 @@ static void display_finfo(file_info *finfo) d_printf(" %-30s%7.7s %8.0f %s", finfo->name, attrib_string(finfo->mode), - (double)finfo->size, - time_to_asc(&t)); + (double)finfo->size, + time_to_asc(&t)); dir_total += finfo->size; - } else { /* showacls */ - static pstring afname; + } else { + pstring afname; int fnum; /* skip if this is . or .. */ @@ -406,8 +408,8 @@ static void display_finfo(file_info *finfo) fnum = cli_nt_create(cli, afname, CREATE_ACCESS_READ); if (fnum == -1) { DEBUG( 0, ("display_finfo() Failed to open %s: %s\n", - afname, - cli_errstr( cli))); + afname, + cli_errstr( cli))); } else { SEC_DESC *sd = NULL; sd = cli_query_secdesc(cli, fnum, ctx); @@ -470,7 +472,7 @@ static void init_do_list_queue(void) { reset_do_list_queue(); do_list_queue_size = 1024; - do_list_queue = SMB_MALLOC(do_list_queue_size); + do_list_queue = (char *)SMB_MALLOC(do_list_queue_size); if (do_list_queue == 0) { d_printf("malloc fail for size %d\n", (int)do_list_queue_size); @@ -514,7 +516,7 @@ static void add_to_do_list_queue(const char* entry) do_list_queue_size *= 2; DEBUG(4,("enlarging do_list_queue to %d\n", (int)do_list_queue_size)); - do_list_queue = SMB_REALLOC(do_list_queue, do_list_queue_size); + do_list_queue = (char *)SMB_REALLOC(do_list_queue, do_list_queue_size); if (! do_list_queue) { d_printf("failure enlarging do_list_queue to %d bytes\n", (int)do_list_queue_size); @@ -563,7 +565,7 @@ static void do_list_helper(const char *mntpoint, file_info *f, const char *mask, /* save the directory */ pstrcpy( f->dir, mask ); - if ( (dir_end = strrchr( f->dir, '\\' )) != NULL ) { + if ( (dir_end = strrchr( f->dir, CLI_DIRSEP_CHAR )) != NULL ) { *dir_end = '\0'; } @@ -584,7 +586,7 @@ static void do_list_helper(const char *mntpoint, file_info *f, const char *mask, pstrcpy(mask2, mntpoint); pstrcat(mask2, mask); - p = strrchr_m(mask2,'\\'); + p = strrchr_m(mask2,CLI_DIRSEP_CHAR); if (!p) return; p[1] = 0; @@ -651,7 +653,7 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, char* save_ch = 0; if ((strlen(next_file) >= 2) && (next_file[strlen(next_file) - 1] == '*') && - (next_file[strlen(next_file) - 2] == '\\')) { + (next_file[strlen(next_file) - 2] == CLI_DIRSEP_CHAR)) { save_ch = next_file + strlen(next_file) - 2; *save_ch = '\0'; @@ -661,7 +663,7 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, if (!showacls) /* don't disturbe the showacls output */ d_printf("\n%s\n",next_file); if (save_ch) { - *save_ch = '\\'; + *save_ch = CLI_DIRSEP_CHAR; } } } @@ -694,17 +696,17 @@ static int cmd_dir(void) int rc; dir_total = 0; - if (strcmp(cur_dir, "\\") != 0) { + if (strcmp(cur_dir, CLI_DIRSEP_STR) != 0) { pstrcpy(mask,cur_dir); - if ((mask[0] != '\0') && (mask[strlen(mask)-1]!='\\')) - pstrcat(mask,"\\"); + if ((mask[0] != '\0') && (mask[strlen(mask)-1]!=CLI_DIRSEP_CHAR)) + pstrcat(mask,CLI_DIRSEP_STR); } else { - pstrcpy(mask, "\\"); + pstrcpy(mask, CLI_DIRSEP_STR); } if (next_token_nr(NULL,buf,NULL,sizeof(buf))) { dos_format(p); - if (*p == '\\') + if (*p == CLI_DIRSEP_CHAR) pstrcpy(mask,p + 1); else pstrcat(mask,p); @@ -735,12 +737,12 @@ static int cmd_du(void) dir_total = 0; pstrcpy(mask,cur_dir); - if ((mask[0] != '\0') && (mask[strlen(mask)-1]!='\\')) - pstrcat(mask,"\\"); + if ((mask[0] != '\0') && (mask[strlen(mask)-1]!=CLI_DIRSEP_CHAR)) + pstrcat(mask,CLI_DIRSEP_STR); if (next_token_nr(NULL,buf,NULL,sizeof(buf))) { dos_format(p); - if (*p == '\\') + if (*p == CLI_DIRSEP_CHAR) pstrcpy(mask,p); else pstrcat(mask,p); @@ -913,7 +915,7 @@ static int cmd_get(void) char *p; pstrcpy(rname,cur_dir); - pstrcat(rname,"\\"); + pstrcat(rname,CLI_DIRSEP_STR); p = rname + strlen(rname); @@ -969,7 +971,7 @@ static void do_mget(file_info *finfo) pstrcpy(saved_curdir,cur_dir); pstrcat(cur_dir,finfo->name); - pstrcat(cur_dir,"\\"); + pstrcat(cur_dir,CLI_DIRSEP_STR); unix_format(finfo->name); if (lowercase) @@ -1008,7 +1010,7 @@ static int cmd_more(void) int rc = 0; pstrcpy(rname,cur_dir); - pstrcat(rname,"\\"); + pstrcat(rname,CLI_DIRSEP_STR); slprintf(lname,sizeof(lname)-1, "%s/smbmore.XXXXXX",tmpdir()); fd = smb_mkstemp(lname); @@ -1057,10 +1059,10 @@ static int cmd_mget(void) while (next_token_nr(NULL,p,NULL,sizeof(buf))) { pstrcpy(mget_mask,cur_dir); - if ((mget_mask[0] != '\0') && (mget_mask[strlen(mget_mask)-1]!='\\')) - pstrcat(mget_mask,"\\"); + if ((mget_mask[0] != '\0') && (mget_mask[strlen(mget_mask)-1]!=CLI_DIRSEP_CHAR)) + pstrcat(mget_mask,CLI_DIRSEP_STR); - if (*p == '\\') + if (*p == CLI_DIRSEP_CHAR) pstrcpy(mget_mask,p); else pstrcat(mget_mask,p); @@ -1069,8 +1071,8 @@ static int cmd_mget(void) if (!*mget_mask) { pstrcpy(mget_mask,cur_dir); - if(mget_mask[strlen(mget_mask)-1]!='\\') - pstrcat(mget_mask,"\\"); + if(mget_mask[strlen(mget_mask)-1]!=CLI_DIRSEP_CHAR) + pstrcat(mget_mask,CLI_DIRSEP_STR); pstrcat(mget_mask,"*"); do_list(mget_mask, attribute,do_mget,False,True); } @@ -1163,7 +1165,7 @@ static int cmd_mkdir(void) if (!cli_chkpath(cli, ddir2)) { do_mkdir(ddir2); } - pstrcat(ddir2,"\\"); + pstrcat(ddir2,CLI_DIRSEP_STR); p = strtok(NULL,"/\\"); } } else { @@ -1343,7 +1345,7 @@ static int cmd_put(void) char *p=buf; pstrcpy(rname,cur_dir); - pstrcat(rname,"\\"); + pstrcat(rname,CLI_DIRSEP_STR); if (!next_token_nr(NULL,p,NULL,sizeof(buf))) { d_printf("put <filename>\n"); @@ -1715,7 +1717,8 @@ static int cmd_open(void) pstring buf; struct cli_state *targetcli; pstring targetname; - + int fnum; + pstrcpy(mask,cur_dir); if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { @@ -1729,7 +1732,169 @@ static int cmd_open(void) return 1; } - cli_nt_create(targetcli, targetname, FILE_READ_DATA); + fnum = cli_nt_create(targetcli, targetname, FILE_READ_DATA|FILE_WRITE_DATA); + if (fnum == -1) { + fnum = cli_nt_create(targetcli, targetname, FILE_READ_DATA); + if (fnum != -1) { + d_printf("open file %s: for read/write fnum %d\n", targetname, fnum); + } else { + d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli)); + } + } else { + d_printf("open file %s: for read/write fnum %d\n", targetname, fnum); + } + + return 0; +} + +static int cmd_close(void) +{ + fstring buf; + int fnum; + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("close <fnum>\n"); + return 1; + } + + fnum = atoi(buf); + /* We really should use the targetcli here.... */ + if (!cli_close(cli, fnum)) { + d_printf("close %d: %s\n", fnum, cli_errstr(cli)); + return 1; + } + return 0; +} + +static int cmd_posix(void) +{ + uint16 major, minor; + uint32 caplow, caphigh; + pstring caps; + + if (!SERVER_HAS_UNIX_CIFS(cli)) { + d_printf("Server doesn't support UNIX CIFS extensions.\n"); + return 1; + } + + if (!cli_unix_extensions_version(cli, &major, &minor, &caplow, &caphigh)) { + d_printf("Can't get UNIX CIFS extensions version from server.\n"); + return 1; + } + + d_printf("Server supports CIFS extensions %u.%u\n", (unsigned int)major, (unsigned int)minor); + + *caps = '\0'; + if (caplow & CIFS_UNIX_FCNTL_LOCKS_CAP) { + pstrcat(caps, "locks "); + } + if (caplow & CIFS_UNIX_POSIX_ACLS_CAP) { + pstrcat(caps, "acls "); + } + if (caplow & CIFS_UNIX_XATTTR_CAP) { + pstrcat(caps, "eas "); + } + if (caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP) { + pstrcat(caps, "pathnames "); + } + + if (strlen(caps) > 0 && caps[strlen(caps)-1] == ' ') { + caps[strlen(caps)-1] = '\0'; + } + + if (!cli_set_unix_extensions_capabilities(cli, major, minor, caplow, caphigh)) { + d_printf("Can't set UNIX CIFS extensions capabilities. %s.\n", cli_errstr(cli)); + return 1; + } + + d_printf("Selecting server supported CIFS capabilities %s\n", caps); + + if (caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP) { + CLI_DIRSEP_CHAR = '/'; + *CLI_DIRSEP_STR = '/'; + pstrcpy(cur_dir, CLI_DIRSEP_STR); + } + + return 0; +} + +static int cmd_lock(void) +{ + fstring buf; + SMB_BIG_UINT start, len; + enum brl_type lock_type; + int fnum; + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n"); + return 1; + } + fnum = atoi(buf); + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n"); + return 1; + } + + if (*buf == 'r' || *buf == 'R') { + lock_type = READ_LOCK; + } else if (*buf == 'w' || *buf == 'W') { + lock_type = WRITE_LOCK; + } else { + d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n"); + return 1; + } + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n"); + return 1; + } + + start = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16); + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n"); + return 1; + } + + len = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16); + + if (!cli_posix_lock(cli, fnum, start, len, True, lock_type)) { + d_printf("lock failed %d: %s\n", fnum, cli_errstr(cli)); + } + + return 0; +} + +static int cmd_unlock(void) +{ + fstring buf; + SMB_BIG_UINT start, len; + int fnum; + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("unlock <fnum> <hex-start> <hex-len>\n"); + return 1; + } + fnum = atoi(buf); + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("unlock <fnum> <hex-start> <hex-len>\n"); + return 1; + } + + start = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16); + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("unlock <fnum> <hex-start> <hex-len>\n"); + return 1; + } + + len = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16); + + if (!cli_posix_unlock(cli, fnum, start, len)) { + d_printf("unlock failed %d: %s\n", fnum, cli_errstr(cli)); + } return 0; } @@ -2532,7 +2697,7 @@ static int cmd_reget(void) char *p; pstrcpy(remote_name, cur_dir); - pstrcat(remote_name, "\\"); + pstrcat(remote_name, CLI_DIRSEP_STR); p = remote_name + strlen(remote_name); @@ -2561,7 +2726,7 @@ static int cmd_reput(void) SMB_STRUCT_STAT st; pstrcpy(remote_name, cur_dir); - pstrcat(remote_name, "\\"); + pstrcat(remote_name, CLI_DIRSEP_STR); if (!next_token_nr(NULL, p, NULL, sizeof(buf))) { d_printf("reput <filename>\n"); @@ -2622,10 +2787,13 @@ static BOOL browse_host_rpc(BOOL sort) NTSTATUS status; struct rpc_pipe_client *pipe_hnd; TALLOC_CTX *mem_ctx; - ENUM_HND enum_hnd; - WERROR werr; - SRV_SHARE_INFO_CTR ctr; + uint32 enum_hnd = 0; + uint32 *penum_hnd = &enum_hnd; + struct srvsvc_NetShareCtr1 ctr1; + union srvsvc_NetShareCtr ctr; int i; + uint32 level; + uint32 numentries; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { @@ -2633,8 +2801,6 @@ static BOOL browse_host_rpc(BOOL sort) return False; } - init_enum_hnd(&enum_hnd, 0); - pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &status); if (pipe_hnd == NULL) { @@ -2644,23 +2810,23 @@ static BOOL browse_host_rpc(BOOL sort) return False; } - werr = rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, 1, &ctr, - 0xffffffff, &enum_hnd); + ZERO_STRUCT(ctr1); + level = 1; + ctr.ctr1 = &ctr1; + + status = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, "", &level, + &ctr, 0xffffffff, &numentries, + &penum_hnd); - if (!W_ERROR_IS_OK(werr)) { + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(mem_ctx); cli_rpc_pipe_close(pipe_hnd); return False; } - for (i=0; i<ctr.num_entries; i++) { - SRV_SHARE_INFO_1 *info = &ctr.share.info1[i]; - char *name, *comment; - name = rpcstr_pull_unistr2_talloc( - mem_ctx, &info->info_1_str.uni_netname); - comment = rpcstr_pull_unistr2_talloc( - mem_ctx, &info->info_1_str.uni_remark); - browse_fn(name, info->info_1.type, comment, NULL); + for (i=0; i<numentries; i++) { + struct srvsvc_NetShareInfo1 *info = &ctr.ctr1->array[i]; + browse_fn(info->name, info->type, info->comment, NULL); } TALLOC_FREE(mem_ctx); @@ -2777,10 +2943,10 @@ static int cmd_logon(void) else pstrcpy(l_password, buf2); - if (!cli_session_setup(cli, l_username, - l_password, strlen(l_password), - l_password, strlen(l_password), - lp_workgroup())) { + if (!NT_STATUS_IS_OK(cli_session_setup(cli, l_username, + l_password, strlen(l_password), + l_password, strlen(l_password), + lp_workgroup()))) { d_printf("session setup failed: %s\n", cli_errstr(cli)); return -1; } @@ -2846,6 +3012,7 @@ static struct {"cd",cmd_cd,"[directory] change/report the remote directory",{COMPL_REMOTE,COMPL_NONE}}, {"chmod",cmd_chmod,"<src> <mode> chmod a file using UNIX permission",{COMPL_REMOTE,COMPL_REMOTE}}, {"chown",cmd_chown,"<src> <uid> <gid> chown a file using UNIX uids and gids",{COMPL_REMOTE,COMPL_REMOTE}}, + {"close",cmd_close,"<fid> close a file given a fid",{COMPL_REMOTE,COMPL_REMOTE}}, {"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}}, {"dir",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}}, {"du",cmd_du,"<mask> computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}}, @@ -2857,6 +3024,7 @@ static struct {"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}}, {"lcd",cmd_lcd,"[directory] change/report the local current working directory",{COMPL_LOCAL,COMPL_NONE}}, {"link",cmd_link,"<oldname> <newname> create a UNIX hard link",{COMPL_REMOTE,COMPL_REMOTE}}, + {"lock",cmd_lock,"lock <fnum> [r|w] <hex-start> <hex-len> : set a POSIX lock",{COMPL_REMOTE,COMPL_REMOTE}}, {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get",{COMPL_NONE,COMPL_NONE}}, {"ls",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}}, {"mask",cmd_select,"<mask> mask all filenames against this",{COMPL_REMOTE,COMPL_NONE}}, @@ -2867,6 +3035,7 @@ static struct {"mput",cmd_mput,"<mask> put all matching files",{COMPL_REMOTE,COMPL_NONE}}, {"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}}, {"open",cmd_open,"<mask> open a file",{COMPL_REMOTE,COMPL_NONE}}, + {"posix", cmd_posix, "turn on all POSIX capabilities", {COMPL_REMOTE,COMPL_NONE}}, {"print",cmd_print,"<file name> print a file",{COMPL_NONE,COMPL_NONE}}, {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput",{COMPL_NONE,COMPL_NONE}}, {"put",cmd_put,"<local name> [remote name] put a file",{COMPL_LOCAL,COMPL_REMOTE}}, @@ -2888,6 +3057,7 @@ static struct {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}}, {"tarmode",cmd_tarmode,"<full|inc|reset|noreset> tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}}, {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}}, + {"unlock",cmd_unlock,"unlock <fnum> <hex-start> <hex-len> : remove a POSIX lock",{COMPL_REMOTE,COMPL_REMOTE}}, {"volume",cmd_volume,"print the volume name",{COMPL_NONE,COMPL_NONE}}, {"vuid",cmd_vuid,"change current vuid",{COMPL_NONE,COMPL_NONE}}, {"logon",cmd_logon,"establish new logon",{COMPL_NONE,COMPL_NONE}}, @@ -3068,10 +3238,17 @@ static char **remote_completion(const char *text, int len) if (!info.matches) { return NULL; } + + /* + * We're leaving matches[0] free to fill it later with the text to + * display: Either the one single match or the longest common subset + * of the matches. + */ info.matches[0] = NULL; + info.count = 1; for (i = len-1; i >= 0; i--) { - if ((text[i] == '/') || (text[i] == '\\')) { + if ((text[i] == '/') || (text[i] == CLI_DIRSEP_CHAR)) { break; } } @@ -3090,15 +3267,36 @@ static char **remote_completion(const char *text, int len) if (cli_list(cli, dirmask, aDIR | aSYSTEM | aHIDDEN, completion_remote_filter, &info) < 0) goto cleanup; - if (info.count == 2) - info.matches[0] = SMB_STRDUP(info.matches[1]); - else { - info.matches[0] = SMB_MALLOC(info.samelen+1); - if (!info.matches[0]) - goto cleanup; - strncpy(info.matches[0], info.matches[1], info.samelen); - info.matches[0][info.samelen] = 0; + if (info.count == 1) { + + /* + * No matches at all, NULL indicates there is nothing + */ + + SAFE_FREE(info.matches[0]); + SAFE_FREE(info.matches); + return NULL; + } + + if (info.count == 2) { + + /* + * Exactly one match in matches[1], indicate this is the one + * in matches[0]. + */ + + info.matches[0] = info.matches[1]; + info.matches[1] = NULL; + info.count -= 1; + return info.matches; } + + /* + * We got more than one possible match, set the result to the maximum + * common subset + */ + + info.matches[0] = SMB_STRNDUP(info.matches[1], info.samelen); info.matches[info.count] = NULL; return info.matches; @@ -3125,10 +3323,13 @@ static char **completion_fn(const char *text, int start, int end) sp = strchr(buf, ' '); if (sp == NULL) return NULL; - - for (i = 0; commands[i].name; i++) - if ((strncmp(commands[i].name, text, sp - buf) == 0) && (commands[i].name[sp - buf] == 0)) + + for (i = 0; commands[i].name; i++) { + if ((strncmp(commands[i].name, buf, sp - buf) == 0) && + (commands[i].name[sp - buf] == 0)) { break; + } + } if (commands[i].name == NULL) return NULL; @@ -3177,7 +3378,7 @@ static char **completion_fn(const char *text, int start, int end) matches[0] = SMB_STRDUP(matches[1]); break; default: - matches[0] = SMB_MALLOC(samelen+1); + matches[0] = (char *)SMB_MALLOC(samelen+1); if (!matches[0]) goto cleanup; strncpy(matches[0], matches[1], samelen); @@ -3415,7 +3616,7 @@ static int do_message_op(void) msg_port = port ? port : 139; - if (!(cli=cli_initialise(NULL)) || (cli_set_port(cli, msg_port) != msg_port) || + if (!(cli=cli_initialise()) || (cli_set_port(cli, msg_port) != msg_port) || !cli_connect(cli, server_name, &ip)) { d_printf("Connection to %s failed\n", desthost); return 1; diff --git a/source/client/smbctool.c b/source/client/smbctool.c index fd385ee6817..b7042f99cb2 100644 --- a/source/client/smbctool.c +++ b/source/client/smbctool.c @@ -3494,7 +3494,7 @@ static int do_message_op(void) msg_port = port ? port : 139; - if (!(cli=cli_initialise(NULL)) || (cli_set_port(cli, msg_port) != msg_port) || + if (!(cli=cli_initialise()) || (cli_set_port(cli, msg_port) != msg_port) || !cli_connect(cli, server_name, &ip)) { d_printf("Connection to %s failed\n", desthost); return 1; diff --git a/source/client/smbmount.c b/source/client/smbmount.c index 7a3ccb7630d..56b7e9e6234 100644 --- a/source/client/smbmount.c +++ b/source/client/smbmount.c @@ -149,7 +149,7 @@ static struct cli_state *do_connection(char *the_service) if (have_ip) ip = dest_ip; /* have to open a new connection */ - if (!(c=cli_initialise(NULL)) || (cli_set_port(c, smb_port) != smb_port) || + if (!(c=cli_initialise()) || (cli_set_port(c, smb_port) != smb_port) || !cli_connect(c, server_n, &ip)) { DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n)); if (c) { @@ -211,14 +211,14 @@ static struct cli_state *do_connection(char *the_service) c->force_dos_errors = True; } - if (!cli_session_setup(c, username, - password, strlen(password), - password, strlen(password), - workgroup)) { + if (!NT_STATUS_IS_OK(cli_session_setup(c, username, + password, strlen(password), + password, strlen(password), + workgroup))) { /* if a password was not supplied then try again with a null username */ if (password[0] || !username[0] || - !cli_session_setup(c, "", "", 0, "", 0, workgroup)) { + !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0, workgroup))) { DEBUG(0,("%d: session setup failed: %s\n", sys_getpid(), cli_errstr(c))); cli_shutdown(c); diff --git a/source/client/smbspool.c b/source/client/smbspool.c index c9a7fbe10ef..5783cbe1381 100644 --- a/source/client/smbspool.c +++ b/source/client/smbspool.c @@ -429,9 +429,10 @@ static struct cli_state } - if (!cli_session_setup(cli, username, password, strlen(password)+1, - password, strlen(password)+1, - workgroup)) + if (!NT_STATUS_IS_OK(cli_session_setup(cli, username, + password, strlen(password)+1, + password, strlen(password)+1, + workgroup))) { fprintf(stderr,"ERROR: Session setup failed: %s\n", cli_errstr(cli)); if (NT_STATUS_V(cli_nt_error(cli)) == diff --git a/source/include/includes.h b/source/include/includes.h index ea639d28a9b..1591b1b7d14 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -640,6 +640,7 @@ typedef int BOOL; #include "debugparse.h" #include "version.h" #include "privileges.h" +#include "locking.h" #include "smb.h" #include "ads_cldap.h" #include "nameserv.h" diff --git a/source/include/libsmb_internal.h b/source/include/libsmb_internal.h index 86e98617558..41f72d5fb3d 100644 --- a/source/include/libsmb_internal.h +++ b/source/include/libsmb_internal.h @@ -10,7 +10,7 @@ struct _SMBCSRV { - struct cli_state cli; + struct cli_state *cli; dev_t dev; BOOL no_pathinfo; BOOL no_pathinfo2; diff --git a/source/include/locking.h b/source/include/locking.h new file mode 100644 index 00000000000..4b3b10d7367 --- /dev/null +++ b/source/include/locking.h @@ -0,0 +1,89 @@ +/* + Unix SMB/CIFS implementation. + SMB parameters and setup, plus a whole lot more. + + Copyright (C) Jeremy Allison 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _LOCKING_H +#define _LOCKING_H + +/* passed to br lock code - the UNLOCK_LOCK should never be stored into the tdb + and is used in calculating POSIX unlock ranges only. We differentiate between + PENDING read and write locks to allow posix lock downgrades to trigger a lock + re-evaluation. */ + +enum brl_type {READ_LOCK, WRITE_LOCK, PENDING_READ_LOCK, PENDING_WRITE_LOCK, UNLOCK_LOCK}; +enum brl_flavour {WINDOWS_LOCK = 0, POSIX_LOCK = 1}; + +#define IS_PENDING_LOCK(type) ((type) == PENDING_READ_LOCK || (type) == PENDING_WRITE_LOCK) + +/* This contains elements that differentiate locks. The smbpid is a + client supplied pid, and is essentially the locking context for + this client */ + +struct lock_context { + uint32 smbpid; + uint16 tid; + struct process_id pid; +}; + +/* The key used in the brlock database. */ + +struct lock_key { + SMB_DEV_T device; + SMB_INO_T inode; +}; + +struct files_struct; + +struct byte_range_lock { + struct files_struct *fsp; + unsigned int num_locks; + BOOL modified; + BOOL read_only; + struct lock_key key; + void *lock_data; +}; + +#define BRLOCK_FN_CAST() \ + void (*)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \ + enum brl_type lock_type, \ + enum brl_flavour lock_flav, \ + br_off start, br_off size) + +#define BRLOCK_FN(fn) \ + void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \ + enum brl_type lock_type, \ + enum brl_flavour lock_flav, \ + br_off start, br_off size) + +/* Internal structure in brlock.tdb. + The data in brlock records is an unsorted linear array of these + records. It is unnecessary to store the count as tdb provides the + size of the record */ + +struct lock_struct { + struct lock_context context; + br_off start; + br_off size; + uint16 fnum; + enum brl_type lock_type; + enum brl_flavour lock_flav; +}; + +#endif /* _LOCKING_H_ */ diff --git a/source/include/nt_status.h b/source/include/nt_status.h index f57ddf6b3dc..968657ca44f 100644 --- a/source/include/nt_status.h +++ b/source/include/nt_status.h @@ -56,7 +56,6 @@ typedef uint32 WERROR; #define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0) #define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000) -#define NT_STATUS_IS_INVALID(x) (NT_STATUS_V(x) == 0xFFFFFFFF) #define NT_STATUS_EQUAL(x,y) (NT_STATUS_V(x) == NT_STATUS_V(y)) #define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0) #define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y)) diff --git a/source/include/nterr.h b/source/include/nterr.h index 417719625e7..b6db14817d4 100644 --- a/source/include/nterr.h +++ b/source/include/nterr.h @@ -37,9 +37,6 @@ #define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c) #define ERROR_INVALID_DATATYPE NT_STATUS(0x070c) -/* Special "invalid" NT status code. */ -#define NT_STATUS_INVALID NT_STATUS(0xFFFFFFFF) - /* Win32 Error codes extracted using a loop in smbclient then printing a netmon sniff to a file. */ @@ -564,5 +561,6 @@ #define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267) #define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275) #define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */ +#define NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x20004) #endif /* _NTERR_H */ diff --git a/source/include/printing.h b/source/include/printing.h index 54f32d5954c..21caff0a832 100644 --- a/source/include/printing.h +++ b/source/include/printing.h @@ -73,6 +73,10 @@ extern struct printif cups_printif; extern struct printif iprint_printif; #endif /* HAVE_IPRINT */ +#if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS) +extern struct printif test_printif; +#endif /* DEVELOPER||ENABLE_BUILD_FARM_HACKS */ + /* PRINT_MAX_JOBID is now defined in local.h */ #define UNIX_JOB_START PRINT_MAX_JOBID #define NEXT_JOBID(j) ((j+1) % PRINT_MAX_JOBID > 0 ? (j+1) % PRINT_MAX_JOBID : 1) diff --git a/source/include/reg_objects.h b/source/include/reg_objects.h index fff6fa16f79..1f819df999b 100644 --- a/source/include/reg_objects.h +++ b/source/include/reg_objects.h @@ -1,7 +1,8 @@ /* - Unix SMB/CIFS implementation. + Samba's Internal Registry objects + SMB parameters and setup - Copyright (C) Gerald Carter 2002-2005. + Copyright (C) Gerald Carter 2002-2006. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source/include/rpc_misc.h b/source/include/rpc_misc.h index 0ee63ae7e18..7404f5669d2 100644 --- a/source/include/rpc_misc.h +++ b/source/include/rpc_misc.h @@ -339,10 +339,5 @@ typedef struct owf_info { uint8 data[16]; } OWF_INFO; -typedef struct uint64_s -{ - uint32 low; - uint32 high; -} UINT64_S; #endif /* _RPC_MISC_H */ diff --git a/source/include/smb.h b/source/include/smb.h index 4dd6028509c..15006c239f3 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -406,6 +406,15 @@ struct fd_handle { struct timed_event; struct idle_event; struct share_mode_entry; +struct uuid; + +struct vfs_fsp_data { + struct vfs_fsp_data *next; + struct vfs_handle_struct *owner; + /* NOTE: This structure contains two pointers so that we can guarantee + * that the end of the structure is always both 4-byte and 8-byte aligned. + */ +}; typedef struct files_struct { struct files_struct *next, *prev; @@ -431,6 +440,7 @@ typedef struct files_struct { int oplock_type; int sent_oplock_break; struct timed_event *oplock_timeout; + struct lock_struct last_lock_failure; struct share_mode_entry *pending_break_messages; int num_pending_break_messages; @@ -445,6 +455,8 @@ typedef struct files_struct { BOOL aio_write_behind; BOOL lockdb_clean; char *fsp_name; + + struct vfs_fsp_data *vfs_extension; FAKE_FILE_HANDLE *fake_file_handle; } files_struct; @@ -516,6 +528,8 @@ struct trans_state { /* Include VFS stuff */ +struct security_descriptor_info; + #include "smb_acls.h" #include "vfs.h" @@ -850,54 +864,11 @@ struct parm_struct { #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */ #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */ -/* passed to br lock code - the UNLOCK_LOCK should never be stored into the tdb - and is used in calculating POSIX unlock ranges only. */ - -enum brl_type {READ_LOCK, WRITE_LOCK, PENDING_LOCK, UNLOCK_LOCK}; -enum brl_flavour {WINDOWS_LOCK = 0, POSIX_LOCK = 1}; - -/* The key used in the brlock database. */ - -struct lock_key { - SMB_DEV_T device; - SMB_INO_T inode; -}; - -struct byte_range_lock { - files_struct *fsp; - unsigned int num_locks; - BOOL modified; - struct lock_key key; - void *lock_data; -}; - -#define BRLOCK_FN_CAST() \ - void (*)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \ - enum brl_type lock_type, \ - enum brl_flavour lock_flav, \ - br_off start, br_off size) - -#define BRLOCK_FN(fn) \ - void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \ - enum brl_type lock_type, \ - enum brl_flavour lock_flav, \ - br_off start, br_off size) - -#define LOCKING_FN_CAST() \ - void (*)(struct share_mode_entry *, const char *, const char *) - -#define LOCKING_FN(fn) \ - void (*fn)(struct share_mode_entry *, const char *, const char *) - struct bitmap { uint32 *b; unsigned int n; }; -#ifndef LOCKING_VERSION -#define LOCKING_VERSION 4 -#endif /* LOCKING_VERSION */ - /* the basic packet size, assuming no words or bytes */ #define smb_size 39 @@ -1497,7 +1468,7 @@ enum server_types { enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX, PRINT_QNX,PRINT_PLP,PRINT_LPRNG,PRINT_SOFTQ, PRINT_CUPS,PRINT_LPRNT,PRINT_LPROS2,PRINT_IPRINT -#ifdef DEVELOPER +#if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS) ,PRINT_TEST,PRINT_VLP #endif /* DEVELOPER */ }; diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h index b9c51002fa5..44f15734d9a 100644 --- a/source/include/smb_macros.h +++ b/source/include/smb_macros.h @@ -83,8 +83,6 @@ #define SMB_ASSERT_ARRAY(a,n) SMB_ASSERT((sizeof(a)/sizeof((a)[0])) >= (n)) /* these are useful macros for checking validity of handles */ -#define OPEN_FSP(fsp) ((fsp) && !(fsp)->is_directory) -#define OPEN_CONN(conn) ((conn) && (conn)->open) #define IS_IPC(conn) ((conn) && (conn)->ipc) #define IS_PRINT(conn) ((conn) && (conn)->printer) /* you must add the following extern declaration to files using this macro @@ -93,20 +91,24 @@ #define FSP_BELONGS_CONN(fsp,conn) do {\ extern struct current_user current_user;\ if (!((fsp) && (conn) && ((conn)==(fsp)->conn) && (current_user.vuid==(fsp)->vuid))) \ - return(ERROR_DOS(ERRDOS,ERRbadfid));\ + return ERROR_NT(NT_STATUS_INVALID_HANDLE); \ } while(0) -#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn && current_user.vuid==(fsp)->vuid) +#define FNUM_OK(fsp,c) ((fsp) && !(fsp)->is_directory && (c)==(fsp)->conn && current_user.vuid==(fsp)->vuid) /* you must add the following extern declaration to files using this macro * extern struct current_user current_user; */ #define CHECK_FSP(fsp,conn) do {\ extern struct current_user current_user;\ - if (!FNUM_OK(fsp,conn)) \ - return(ERROR_DOS(ERRDOS,ERRbadfid)); \ - else if((fsp)->fh->fd == -1) \ - return(ERROR_DOS(ERRDOS,ERRbadaccess));\ + if (!(fsp) || !(conn)) \ + return ERROR_NT(NT_STATUS_INVALID_HANDLE); \ + else if (((conn) != (fsp)->conn) || current_user.vuid != (fsp)->vuid) \ + return ERROR_NT(NT_STATUS_INVALID_HANDLE); \ + else if ((fsp)->is_directory) \ + return ERROR_NT(NT_STATUS_INVALID_DEVICE_REQUEST); \ + else if ((fsp)->fh->fd == -1) \ + return ERROR_NT(NT_STATUS_ACCESS_DENIED); \ (fsp)->num_smb_operations++;\ } while(0) @@ -182,7 +184,6 @@ #define CACHED_ERROR(fsp) cached_error_packet(outbuf,fsp,__LINE__,__FILE__) #define ERROR_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_OK,__LINE__,__FILE__) -#define ERROR_FORCE_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_INVALID,__LINE__,__FILE__) #define ERROR_NT(status) error_packet(outbuf,0,0,status,__LINE__,__FILE__) #define ERROR_FORCE_NT(status) error_packet(outbuf,-1,-1,status,__LINE__,__FILE__) #define ERROR_BOTH(status,class,code) error_packet(outbuf,class,code,status,__LINE__,__FILE__) @@ -284,7 +285,7 @@ copy an IP address from one buffer to another #define SMB_XMALLOC_ARRAY(type,count) (type *)smb_xmalloc_array(sizeof(type),(count)) /* limiting size of ipc replies */ -#define SMB_REALLOC_LIMIT(ptr,size) SMB_REALLOC(ptr,MAX((size),4*1024)) +#define SMB_REALLOC_LIMIT(ptr,size) (char *)SMB_REALLOC(ptr,MAX((size),4*1024)) /* The new talloc is paranoid malloc checker safe. */ @@ -377,6 +378,6 @@ do { \ } while (0) #define ADD_TO_LARGE_ARRAY(mem_ctx, type, elem, array, num, size) \ - add_to_large_array((mem_ctx), sizeof(type), &(elem), (void **)(array), (num), (size)); + add_to_large_array((mem_ctx), sizeof(type), &(elem), (void *)(array), (num), (size)); #endif /* _SMB_MACROS_H */ diff --git a/source/include/vfs.h b/source/include/vfs.h index 16d1428779d..fe4886567ff 100644 --- a/source/include/vfs.h +++ b/source/include/vfs.h @@ -62,8 +62,10 @@ /* Changed to version 14 as we had to change DIR to SMB_STRUCT_DIR. JRA */ /* Changed to version 15 as we added the statvfs call. JRA */ /* Changed to version 16 as we added the getlock call. JRA */ -/* Changed to version 17 to add kernel_flock call. Note in 3.0 dev branch it's different - jmcd */ -#define SMB_VFS_INTERFACE_VERSION 17 +/* Changed to version 17 as we removed redundant connection_struct parameters. --jpeach */ +/* Changed to version 18 to add fsp parameter to the open call -- jpeach + Also include kernel_flock call - jmcd */ +#define SMB_VFS_INTERFACE_VERSION 18 /* to bug old modules which are trying to compile with the old functions */ @@ -84,7 +86,7 @@ struct vfs_handle_struct; struct connection_struct; struct files_struct; -struct security_descriptor_info; +struct security_descriptor; struct vfs_statvfs_struct; /* @@ -221,29 +223,29 @@ struct vfs_ops { struct vfs_fn_pointers { /* Disk operations */ - int (*connect_fn)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *service, const char *user); - void (*disconnect)(struct vfs_handle_struct *handle, struct connection_struct *conn); - SMB_BIG_UINT (*disk_free)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, + int (*connect_fn)(struct vfs_handle_struct *handle, const char *service, const char *user); + void (*disconnect)(struct vfs_handle_struct *handle); + SMB_BIG_UINT (*disk_free)(struct vfs_handle_struct *handle, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize); - int (*get_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); - int (*set_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); + int (*get_quota)(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); + int (*set_quota)(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); int (*get_shadow_copy_data)(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels); - int (*statvfs)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, struct vfs_statvfs_struct *statbuf); + int (*statvfs)(struct vfs_handle_struct *handle, const char *path, struct vfs_statvfs_struct *statbuf); /* Directory operations */ - SMB_STRUCT_DIR *(*opendir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, const char *mask, uint32 attributes); - SMB_STRUCT_DIRENT *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *dirp); - void (*seekdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *dirp, long offset); - long (*telldir)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *dirp); - void (*rewind_dir)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *dirp); - int (*mkdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode); - int (*rmdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path); - int (*closedir)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *dir); + SMB_STRUCT_DIR *(*opendir)(struct vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attributes); + SMB_STRUCT_DIRENT *(*readdir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp); + void (*seekdir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset); + long (*telldir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp); + void (*rewind_dir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp); + int (*mkdir)(struct vfs_handle_struct *handle, const char *path, mode_t mode); + int (*rmdir)(struct vfs_handle_struct *handle, const char *path); + int (*closedir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dir); /* File operations */ - int (*open)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, int flags, mode_t mode); + int (*open)(struct vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode); int (*close_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd); ssize_t (*read)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n); ssize_t (*pread)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset); @@ -251,28 +253,28 @@ struct vfs_ops { ssize_t (*pwrite)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset); SMB_OFF_T (*lseek)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset, int whence); ssize_t (*sendfile)(struct vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count); - int (*rename)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldname, const char *newname); + int (*rename)(struct vfs_handle_struct *handle, const char *oldname, const char *newname); int (*fsync)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd); - int (*stat)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf); + int (*stat)(struct vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf); int (*fstat)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf); - int (*lstat)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf); - int (*unlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path); - int (*chmod)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode); + int (*lstat)(struct vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf); + int (*unlink)(struct vfs_handle_struct *handle, const char *path); + int (*chmod)(struct vfs_handle_struct *handle, const char *path, mode_t mode); int (*fchmod)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, mode_t mode); - int (*chown)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, uid_t uid, gid_t gid); + int (*chown)(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid); int (*fchown)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uid_t uid, gid_t gid); - int (*chdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path); - char *(*getwd)(struct vfs_handle_struct *handle, struct connection_struct *conn, char *buf); - int (*utime)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, struct utimbuf *times); + int (*chdir)(struct vfs_handle_struct *handle, const char *path); + char *(*getwd)(struct vfs_handle_struct *handle, char *buf); + int (*utime)(struct vfs_handle_struct *handle, const char *path, struct utimbuf *times); int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset); BOOL (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); int (*kernel_flock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 share_mode); BOOL (*getlock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid); - int (*symlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldpath, const char *newpath); - int (*readlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, char *buf, size_t bufsiz); - int (*link)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldpath, const char *newpath); - int (*mknod)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev); - char *(*realpath)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, char *resolved_path); + int (*symlink)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath); + int (*readlink)(struct vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz); + int (*link)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath); + int (*mknod)(struct vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev); + char *(*realpath)(struct vfs_handle_struct *handle, const char *path, char *resolved_path); /* NT ACL operations. */ @@ -283,44 +285,44 @@ struct vfs_ops { /* POSIX ACL operations. */ - int (*chmod_acl)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *name, mode_t mode); + int (*chmod_acl)(struct vfs_handle_struct *handle, const char *name, mode_t mode); int (*fchmod_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, mode_t mode); - int (*sys_acl_get_entry)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p); - int (*sys_acl_get_tag_type)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); - int (*sys_acl_get_permset)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); - void * (*sys_acl_get_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d); - SMB_ACL_T (*sys_acl_get_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type); + int (*sys_acl_get_entry)(struct vfs_handle_struct *handle, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p); + int (*sys_acl_get_tag_type)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); + int (*sys_acl_get_permset)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); + void * (*sys_acl_get_qualifier)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d); + SMB_ACL_T (*sys_acl_get_file)(struct vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type); SMB_ACL_T (*sys_acl_get_fd)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd); - int (*sys_acl_clear_perms)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset); - int (*sys_acl_add_perm)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); - char * (*sys_acl_to_text)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen); - SMB_ACL_T (*sys_acl_init)(struct vfs_handle_struct *handle, struct connection_struct *conn, int count); - int (*sys_acl_create_entry)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry); - int (*sys_acl_set_tag_type)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype); - int (*sys_acl_set_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual); - int (*sys_acl_set_permset)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset); - int (*sys_acl_valid)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl ); - int (*sys_acl_set_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); + int (*sys_acl_clear_perms)(struct vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset); + int (*sys_acl_add_perm)(struct vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); + char * (*sys_acl_to_text)(struct vfs_handle_struct *handle, SMB_ACL_T theacl, ssize_t *plen); + SMB_ACL_T (*sys_acl_init)(struct vfs_handle_struct *handle, int count); + int (*sys_acl_create_entry)(struct vfs_handle_struct *handle, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry); + int (*sys_acl_set_tag_type)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype); + int (*sys_acl_set_qualifier)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, void *qual); + int (*sys_acl_set_permset)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset); + int (*sys_acl_valid)(struct vfs_handle_struct *handle, SMB_ACL_T theacl ); + int (*sys_acl_set_file)(struct vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); int (*sys_acl_set_fd)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_ACL_T theacl); - int (*sys_acl_delete_def_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path); - int (*sys_acl_get_perm)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); - int (*sys_acl_free_text)(struct vfs_handle_struct *handle, struct connection_struct *conn, char *text); - int (*sys_acl_free_acl)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T posix_acl); - int (*sys_acl_free_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype); + int (*sys_acl_delete_def_file)(struct vfs_handle_struct *handle, const char *path); + int (*sys_acl_get_perm)(struct vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); + int (*sys_acl_free_text)(struct vfs_handle_struct *handle, char *text); + int (*sys_acl_free_acl)(struct vfs_handle_struct *handle, SMB_ACL_T posix_acl); + int (*sys_acl_free_qualifier)(struct vfs_handle_struct *handle, void *qualifier, SMB_ACL_TAG_T tagtype); /* EA operations. */ - ssize_t (*getxattr)(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size); - ssize_t (*lgetxattr)(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size); + ssize_t (*getxattr)(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size); + ssize_t (*lgetxattr)(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size); ssize_t (*fgetxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size); - ssize_t (*listxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size); - ssize_t (*llistxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size); + ssize_t (*listxattr)(struct vfs_handle_struct *handle, const char *path, char *list, size_t size); + ssize_t (*llistxattr)(struct vfs_handle_struct *handle, const char *path, char *list, size_t size); ssize_t (*flistxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size); - int (*removexattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name); - int (*lremovexattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name); + int (*removexattr)(struct vfs_handle_struct *handle, const char *path, const char *name); + int (*lremovexattr)(struct vfs_handle_struct *handle, const char *path, const char *name); int (*fremovexattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int filedes, const char *name); - int (*setxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags); - int (*lsetxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags); + int (*setxattr)(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags); + int (*lsetxattr)(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags); int (*fsetxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int filedes, const char *name, const void *value, size_t size, int flags); /* aio operations */ @@ -534,6 +536,14 @@ typedef struct vfs_statvfs_struct { /* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */ } vfs_statvfs_struct; +#define VFS_ADD_FSP_EXTENSION(handle, fsp, type) \ + vfs_add_fsp_extension_notype(handle, (fsp), sizeof(type)) + +#define VFS_FETCH_FSP_EXTENSION(handle, fsp) \ + vfs_fetch_fsp_extension(handle, (fsp)) + +#define VFS_REMOVE_FSP_EXTENSION(handle, fsp) \ + vfs_remove_fsp_extension((handle), (fsp)) #define SMB_VFS_HANDLE_GET_DATA(handle, datap, type, ret) { \ if (!(handle)||((datap=(type *)(handle)->data)==NULL)) { \ @@ -566,6 +576,7 @@ typedef struct vfs_statvfs_struct { #define SMB_VFS_OP(x) ((void *) x) +#define DEFAULT_VFS_MODULE_NAME "/[Default VFS]/" #include "vfs_macros.h" diff --git a/source/include/vfs_macros.h b/source/include/vfs_macros.h index 843dd89ce7a..119b616e72e 100644 --- a/source/include/vfs_macros.h +++ b/source/include/vfs_macros.h @@ -28,26 +28,26 @@ ********************************************************************/ /* Disk operations */ -#define SMB_VFS_CONNECT(conn, service, user) ((conn)->vfs.ops.connect_fn((conn)->vfs.handles.connect_hnd, (conn), (service), (user))) -#define SMB_VFS_DISCONNECT(conn) ((conn)->vfs.ops.disconnect((conn)->vfs.handles.disconnect, (conn))) -#define SMB_VFS_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs.ops.disk_free((conn)->vfs.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize))) -#define SMB_VFS_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.get_quota((conn)->vfs.handles.get_quota, (conn), (qtype), (id), (qt))) -#define SMB_VFS_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.set_quota((conn)->vfs.handles.set_quota, (conn), (qtype), (id), (qt))) +#define SMB_VFS_CONNECT(conn, service, user) ((conn)->vfs.ops.connect_fn((conn)->vfs.handles.connect_hnd, (service), (user))) +#define SMB_VFS_DISCONNECT(conn) ((conn)->vfs.ops.disconnect((conn)->vfs.handles.disconnect)) +#define SMB_VFS_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs.ops.disk_free((conn)->vfs.handles.disk_free, (path), (small_query), (bsize), (dfree), (dsize))) +#define SMB_VFS_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.get_quota((conn)->vfs.handles.get_quota, (qtype), (id), (qt))) +#define SMB_VFS_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.set_quota((conn)->vfs.handles.set_quota, (qtype), (id), (qt))) #define SMB_VFS_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs.ops.get_shadow_copy_data((fsp)->conn->vfs.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels))) -#define SMB_VFS_STATVFS(conn, path, statbuf) ((conn)->vfs.ops.statvfs((conn)->vfs.handles.statvfs, (conn), (path), (statbuf))) +#define SMB_VFS_STATVFS(conn, path, statbuf) ((conn)->vfs.ops.statvfs((conn)->vfs.handles.statvfs, (path), (statbuf))) /* Directory operations */ -#define SMB_VFS_OPENDIR(conn, fname, mask, attr) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (conn), (fname), (mask), (attr))) -#define SMB_VFS_READDIR(conn, dirp) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (conn), (dirp))) -#define SMB_VFS_SEEKDIR(conn, dirp, offset) ((conn)->vfs.ops.seekdir((conn)->vfs.handles.seekdir, (conn), (dirp), (offset))) -#define SMB_VFS_TELLDIR(conn, dirp) ((conn)->vfs.ops.telldir((conn)->vfs.handles.telldir, (conn), (dirp))) -#define SMB_VFS_REWINDDIR(conn, dirp) ((conn)->vfs.ops.rewind_dir((conn)->vfs.handles.rewind_dir, (conn), (dirp))) -#define SMB_VFS_MKDIR(conn, path, mode) ((conn)->vfs.ops.mkdir((conn)->vfs.handles.mkdir,(conn), (path), (mode))) -#define SMB_VFS_RMDIR(conn, path) ((conn)->vfs.ops.rmdir((conn)->vfs.handles.rmdir, (conn), (path))) -#define SMB_VFS_CLOSEDIR(conn, dir) ((conn)->vfs.ops.closedir((conn)->vfs.handles.closedir, (conn), dir)) +#define SMB_VFS_OPENDIR(conn, fname, mask, attr) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (fname), (mask), (attr))) +#define SMB_VFS_READDIR(conn, dirp) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (dirp))) +#define SMB_VFS_SEEKDIR(conn, dirp, offset) ((conn)->vfs.ops.seekdir((conn)->vfs.handles.seekdir, (dirp), (offset))) +#define SMB_VFS_TELLDIR(conn, dirp) ((conn)->vfs.ops.telldir((conn)->vfs.handles.telldir, (dirp))) +#define SMB_VFS_REWINDDIR(conn, dirp) ((conn)->vfs.ops.rewind_dir((conn)->vfs.handles.rewind_dir, (dirp))) +#define SMB_VFS_MKDIR(conn, path, mode) ((conn)->vfs.ops.mkdir((conn)->vfs.handles.mkdir,(path), (mode))) +#define SMB_VFS_RMDIR(conn, path) ((conn)->vfs.ops.rmdir((conn)->vfs.handles.rmdir, (path))) +#define SMB_VFS_CLOSEDIR(conn, dir) ((conn)->vfs.ops.closedir((conn)->vfs.handles.closedir, dir)) /* File operations */ -#define SMB_VFS_OPEN(conn, fname, flags, mode) ((conn)->vfs.ops.open((conn)->vfs.handles.open, (conn), (fname), (flags), (mode))) +#define SMB_VFS_OPEN(conn, fname, fsp, flags, mode) ((conn)->vfs.ops.open((conn)->vfs.handles.open, (fname), (fsp), (flags), (mode))) #define SMB_VFS_CLOSE(fsp, fd) ((fsp)->conn->vfs.ops.close_fn((fsp)->conn->vfs.handles.close_hnd, (fsp), (fd))) #define SMB_VFS_READ(fsp, fd, data, n) ((fsp)->conn->vfs.ops.read((fsp)->conn->vfs.handles.read, (fsp), (fd), (data), (n))) #define SMB_VFS_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs.ops.pread((fsp)->conn->vfs.handles.pread, (fsp), (fd), (data), (n), (off))) @@ -55,28 +55,28 @@ #define SMB_VFS_PWRITE(fsp, fd, data, n, off) ((fsp)->conn->vfs.ops.pwrite((fsp)->conn->vfs.handles.pwrite, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_LSEEK(fsp, fd, offset, whence) ((fsp)->conn->vfs.ops.lseek((fsp)->conn->vfs.handles.lseek, (fsp), (fd), (offset), (whence))) #define SMB_VFS_SENDFILE(tofd, fsp, fromfd, header, offset, count) ((fsp)->conn->vfs.ops.sendfile((fsp)->conn->vfs.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count))) -#define SMB_VFS_RENAME(conn, old, new) ((conn)->vfs.ops.rename((conn)->vfs.handles.rename, (conn), (old), (new))) +#define SMB_VFS_RENAME(conn, old, new) ((conn)->vfs.ops.rename((conn)->vfs.handles.rename, (old), (new))) #define SMB_VFS_FSYNC(fsp, fd) ((fsp)->conn->vfs.ops.fsync((fsp)->conn->vfs.handles.fsync, (fsp), (fd))) -#define SMB_VFS_STAT(conn, fname, sbuf) ((conn)->vfs.ops.stat((conn)->vfs.handles.stat, (conn), (fname), (sbuf))) +#define SMB_VFS_STAT(conn, fname, sbuf) ((conn)->vfs.ops.stat((conn)->vfs.handles.stat, (fname), (sbuf))) #define SMB_VFS_FSTAT(fsp, fd, sbuf) ((fsp)->conn->vfs.ops.fstat((fsp)->conn->vfs.handles.fstat, (fsp) ,(fd) ,(sbuf))) -#define SMB_VFS_LSTAT(conn, path, sbuf) ((conn)->vfs.ops.lstat((conn)->vfs.handles.lstat, (conn), (path), (sbuf))) -#define SMB_VFS_UNLINK(conn, path) ((conn)->vfs.ops.unlink((conn)->vfs.handles.unlink, (conn), (path))) -#define SMB_VFS_CHMOD(conn, path, mode) ((conn)->vfs.ops.chmod((conn)->vfs.handles.chmod, (conn), (path), (mode))) +#define SMB_VFS_LSTAT(conn, path, sbuf) ((conn)->vfs.ops.lstat((conn)->vfs.handles.lstat, (path), (sbuf))) +#define SMB_VFS_UNLINK(conn, path) ((conn)->vfs.ops.unlink((conn)->vfs.handles.unlink, (path))) +#define SMB_VFS_CHMOD(conn, path, mode) ((conn)->vfs.ops.chmod((conn)->vfs.handles.chmod, (path), (mode))) #define SMB_VFS_FCHMOD(fsp, fd, mode) ((fsp)->conn->vfs.ops.fchmod((fsp)->conn->vfs.handles.fchmod, (fsp), (fd), (mode))) -#define SMB_VFS_CHOWN(conn, path, uid, gid) ((conn)->vfs.ops.chown((conn)->vfs.handles.chown, (conn), (path), (uid), (gid))) +#define SMB_VFS_CHOWN(conn, path, uid, gid) ((conn)->vfs.ops.chown((conn)->vfs.handles.chown, (path), (uid), (gid))) #define SMB_VFS_FCHOWN(fsp, fd, uid, gid) ((fsp)->conn->vfs.ops.fchown((fsp)->conn->vfs.handles.fchown, (fsp), (fd), (uid), (gid))) -#define SMB_VFS_CHDIR(conn, path) ((conn)->vfs.ops.chdir((conn)->vfs.handles.chdir, (conn), (path))) -#define SMB_VFS_GETWD(conn, buf) ((conn)->vfs.ops.getwd((conn)->vfs.handles.getwd, (conn), (buf))) -#define SMB_VFS_UTIME(conn, path, times) ((conn)->vfs.ops.utime((conn)->vfs.handles.utime, (conn), (path), (times))) +#define SMB_VFS_CHDIR(conn, path) ((conn)->vfs.ops.chdir((conn)->vfs.handles.chdir, (path))) +#define SMB_VFS_GETWD(conn, buf) ((conn)->vfs.ops.getwd((conn)->vfs.handles.getwd, (buf))) +#define SMB_VFS_UTIME(conn, path, times) ((conn)->vfs.ops.utime((conn)->vfs.handles.utime, (path), (times))) #define SMB_VFS_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs.ops.ftruncate((fsp)->conn->vfs.handles.ftruncate, (fsp), (fd), (offset))) #define SMB_VFS_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs.ops.lock((fsp)->conn->vfs.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type))) #define SMB_VFS_KERNEL_FLOCK(fsp, fd, share_mode) ((fsp)->conn->vfs.ops.kernel_flock((fsp)->conn->vfs.handles.kernel_flock, (fsp), (fd), (share_mode))) #define SMB_VFS_GETLOCK(fsp, fd, poffset, pcount, ptype, ppid) ((fsp)->conn->vfs.ops.getlock((fsp)->conn->vfs.handles.getlock, (fsp), (fd) ,(poffset), (pcount), (ptype), (ppid))) -#define SMB_VFS_SYMLINK(conn, oldpath, newpath) ((conn)->vfs.ops.symlink((conn)->vfs.handles.symlink, (conn), (oldpath), (newpath))) -#define SMB_VFS_READLINK(conn, path, buf, bufsiz) ((conn)->vfs.ops.readlink((conn)->vfs.handles.readlink, (conn), (path), (buf), (bufsiz))) -#define SMB_VFS_LINK(conn, oldpath, newpath) ((conn)->vfs.ops.link((conn)->vfs.handles.link, (conn), (oldpath), (newpath))) -#define SMB_VFS_MKNOD(conn, path, mode, dev) ((conn)->vfs.ops.mknod((conn)->vfs.handles.mknod, (conn), (path), (mode), (dev))) -#define SMB_VFS_REALPATH(conn, path, resolved_path) ((conn)->vfs.ops.realpath((conn)->vfs.handles.realpath, (conn), (path), (resolved_path))) +#define SMB_VFS_SYMLINK(conn, oldpath, newpath) ((conn)->vfs.ops.symlink((conn)->vfs.handles.symlink, (oldpath), (newpath))) +#define SMB_VFS_READLINK(conn, path, buf, bufsiz) ((conn)->vfs.ops.readlink((conn)->vfs.handles.readlink, (path), (buf), (bufsiz))) +#define SMB_VFS_LINK(conn, oldpath, newpath) ((conn)->vfs.ops.link((conn)->vfs.handles.link, (oldpath), (newpath))) +#define SMB_VFS_MKNOD(conn, path, mode, dev) ((conn)->vfs.ops.mknod((conn)->vfs.handles.mknod, (path), (mode), (dev))) +#define SMB_VFS_REALPATH(conn, path, resolved_path) ((conn)->vfs.ops.realpath((conn)->vfs.handles.realpath, (path), (resolved_path))) /* NT ACL operations. */ #define SMB_VFS_FGET_NT_ACL(fsp, fd, security_info, ppdesc) ((fsp)->conn->vfs.ops.fget_nt_acl((fsp)->conn->vfs.handles.fget_nt_acl, (fsp), (fd), (security_info), (ppdesc))) @@ -85,44 +85,44 @@ #define SMB_VFS_SET_NT_ACL(fsp, name, security_info_sent, psd) ((fsp)->conn->vfs.ops.set_nt_acl((fsp)->conn->vfs.handles.set_nt_acl, (fsp), (name), (security_info_sent), (psd))) /* POSIX ACL operations. */ -#define SMB_VFS_CHMOD_ACL(conn, name, mode) ((conn)->vfs.ops.chmod_acl((conn)->vfs.handles.chmod_acl, (conn), (name), (mode))) +#define SMB_VFS_CHMOD_ACL(conn, name, mode) ((conn)->vfs.ops.chmod_acl((conn)->vfs.handles.chmod_acl, (name), (mode))) #define SMB_VFS_FCHMOD_ACL(fsp, fd, mode) ((fsp)->conn->vfs.ops.fchmod_acl((fsp)->conn->vfs.handles.chmod_acl, (fsp), (fd), (mode))) -#define SMB_VFS_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs.ops.sys_acl_get_entry((conn)->vfs.handles.sys_acl_get_entry, (conn), (theacl), (entry_id), (entry_p))) -#define SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs.ops.sys_acl_get_tag_type((conn)->vfs.handles.sys_acl_get_tag_type, (conn), (entry_d), (tag_type_p))) -#define SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry_d, permset_p) ((conn)->vfs.ops.sys_acl_get_permset((conn)->vfs.handles.sys_acl_get_permset, (conn), (entry_d), (permset_p))) -#define SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry_d) ((conn)->vfs.ops.sys_acl_get_qualifier((conn)->vfs.handles.sys_acl_get_qualifier, (conn), (entry_d))) -#define SMB_VFS_SYS_ACL_GET_FILE(conn, path_p, type) ((conn)->vfs.ops.sys_acl_get_file((conn)->vfs.handles.sys_acl_get_file, (conn), (path_p), (type))) +#define SMB_VFS_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs.ops.sys_acl_get_entry((conn)->vfs.handles.sys_acl_get_entry, (theacl), (entry_id), (entry_p))) +#define SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs.ops.sys_acl_get_tag_type((conn)->vfs.handles.sys_acl_get_tag_type, (entry_d), (tag_type_p))) +#define SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry_d, permset_p) ((conn)->vfs.ops.sys_acl_get_permset((conn)->vfs.handles.sys_acl_get_permset, (entry_d), (permset_p))) +#define SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry_d) ((conn)->vfs.ops.sys_acl_get_qualifier((conn)->vfs.handles.sys_acl_get_qualifier, (entry_d))) +#define SMB_VFS_SYS_ACL_GET_FILE(conn, path_p, type) ((conn)->vfs.ops.sys_acl_get_file((conn)->vfs.handles.sys_acl_get_file, (path_p), (type))) #define SMB_VFS_SYS_ACL_GET_FD(fsp, fd) ((fsp)->conn->vfs.ops.sys_acl_get_fd((fsp)->conn->vfs.handles.sys_acl_get_fd, (fsp), (fd))) -#define SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, permset) ((conn)->vfs.ops.sys_acl_clear_perms((conn)->vfs.handles.sys_acl_clear_perms, (conn), (permset))) -#define SMB_VFS_SYS_ACL_ADD_PERM(conn, permset, perm) ((conn)->vfs.ops.sys_acl_add_perm((conn)->vfs.handles.sys_acl_add_perm, (conn), (permset), (perm))) -#define SMB_VFS_SYS_ACL_TO_TEXT(conn, theacl, plen) ((conn)->vfs.ops.sys_acl_to_text((conn)->vfs.handles.sys_acl_to_text, (conn), (theacl), (plen))) -#define SMB_VFS_SYS_ACL_INIT(conn, count) ((conn)->vfs.ops.sys_acl_init((conn)->vfs.handles.sys_acl_init, (conn), (count))) -#define SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, pacl, pentry) ((conn)->vfs.ops.sys_acl_create_entry((conn)->vfs.handles.sys_acl_create_entry, (conn), (pacl), (pentry))) -#define SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, entry, tagtype) ((conn)->vfs.ops.sys_acl_set_tag_type((conn)->vfs.handles.sys_acl_set_tag_type, (conn), (entry), (tagtype))) -#define SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, entry, qual) ((conn)->vfs.ops.sys_acl_set_qualifier((conn)->vfs.handles.sys_acl_set_qualifier, (conn), (entry), (qual))) -#define SMB_VFS_SYS_ACL_SET_PERMSET(conn, entry, permset) ((conn)->vfs.ops.sys_acl_set_permset((conn)->vfs.handles.sys_acl_set_permset, (conn), (entry), (permset))) -#define SMB_VFS_SYS_ACL_VALID(conn, theacl) ((conn)->vfs.ops.sys_acl_valid((conn)->vfs.handles.sys_acl_valid, (conn), (theacl))) -#define SMB_VFS_SYS_ACL_SET_FILE(conn, name, acltype, theacl) ((conn)->vfs.ops.sys_acl_set_file((conn)->vfs.handles.sys_acl_set_file, (conn), (name), (acltype), (theacl))) +#define SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, permset) ((conn)->vfs.ops.sys_acl_clear_perms((conn)->vfs.handles.sys_acl_clear_perms, (permset))) +#define SMB_VFS_SYS_ACL_ADD_PERM(conn, permset, perm) ((conn)->vfs.ops.sys_acl_add_perm((conn)->vfs.handles.sys_acl_add_perm, (permset), (perm))) +#define SMB_VFS_SYS_ACL_TO_TEXT(conn, theacl, plen) ((conn)->vfs.ops.sys_acl_to_text((conn)->vfs.handles.sys_acl_to_text, (theacl), (plen))) +#define SMB_VFS_SYS_ACL_INIT(conn, count) ((conn)->vfs.ops.sys_acl_init((conn)->vfs.handles.sys_acl_init, (count))) +#define SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, pacl, pentry) ((conn)->vfs.ops.sys_acl_create_entry((conn)->vfs.handles.sys_acl_create_entry, (pacl), (pentry))) +#define SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, entry, tagtype) ((conn)->vfs.ops.sys_acl_set_tag_type((conn)->vfs.handles.sys_acl_set_tag_type, (entry), (tagtype))) +#define SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, entry, qual) ((conn)->vfs.ops.sys_acl_set_qualifier((conn)->vfs.handles.sys_acl_set_qualifier, (entry), (qual))) +#define SMB_VFS_SYS_ACL_SET_PERMSET(conn, entry, permset) ((conn)->vfs.ops.sys_acl_set_permset((conn)->vfs.handles.sys_acl_set_permset, (entry), (permset))) +#define SMB_VFS_SYS_ACL_VALID(conn, theacl) ((conn)->vfs.ops.sys_acl_valid((conn)->vfs.handles.sys_acl_valid, (theacl))) +#define SMB_VFS_SYS_ACL_SET_FILE(conn, name, acltype, theacl) ((conn)->vfs.ops.sys_acl_set_file((conn)->vfs.handles.sys_acl_set_file, (name), (acltype), (theacl))) #define SMB_VFS_SYS_ACL_SET_FD(fsp, fd, theacl) ((fsp)->conn->vfs.ops.sys_acl_set_fd((fsp)->conn->vfs.handles.sys_acl_set_fd, (fsp), (fd), (theacl))) -#define SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, path) ((conn)->vfs.ops.sys_acl_delete_def_file((conn)->vfs.handles.sys_acl_delete_def_file, (conn), (path))) -#define SMB_VFS_SYS_ACL_GET_PERM(conn, permset, perm) ((conn)->vfs.ops.sys_acl_get_perm((conn)->vfs.handles.sys_acl_get_perm, (conn), (permset), (perm))) -#define SMB_VFS_SYS_ACL_FREE_TEXT(conn, text) ((conn)->vfs.ops.sys_acl_free_text((conn)->vfs.handles.sys_acl_free_text, (conn), (text))) -#define SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl) ((conn)->vfs.ops.sys_acl_free_acl((conn)->vfs.handles.sys_acl_free_acl, (conn), (posix_acl))) -#define SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, qualifier, tagtype) ((conn)->vfs.ops.sys_acl_free_qualifier((conn)->vfs.handles.sys_acl_free_qualifier, (conn), (qualifier), (tagtype))) +#define SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, path) ((conn)->vfs.ops.sys_acl_delete_def_file((conn)->vfs.handles.sys_acl_delete_def_file, (path))) +#define SMB_VFS_SYS_ACL_GET_PERM(conn, permset, perm) ((conn)->vfs.ops.sys_acl_get_perm((conn)->vfs.handles.sys_acl_get_perm, (permset), (perm))) +#define SMB_VFS_SYS_ACL_FREE_TEXT(conn, text) ((conn)->vfs.ops.sys_acl_free_text((conn)->vfs.handles.sys_acl_free_text, (text))) +#define SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl) ((conn)->vfs.ops.sys_acl_free_acl((conn)->vfs.handles.sys_acl_free_acl, (posix_acl))) +#define SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, qualifier, tagtype) ((conn)->vfs.ops.sys_acl_free_qualifier((conn)->vfs.handles.sys_acl_free_qualifier, (qualifier), (tagtype))) /* EA operations. */ -#define SMB_VFS_GETXATTR(conn,path,name,value,size) ((conn)->vfs.ops.getxattr((conn)->vfs.handles.getxattr,(conn),(path),(name),(value),(size))) -#define SMB_VFS_LGETXATTR(conn,path,name,value,size) ((conn)->vfs.ops.lgetxattr((conn)->vfs.handles.lgetxattr,(conn),(path),(name),(value),(size))) +#define SMB_VFS_GETXATTR(conn,path,name,value,size) ((conn)->vfs.ops.getxattr((conn)->vfs.handles.getxattr,(path),(name),(value),(size))) +#define SMB_VFS_LGETXATTR(conn,path,name,value,size) ((conn)->vfs.ops.lgetxattr((conn)->vfs.handles.lgetxattr,(path),(name),(value),(size))) #define SMB_VFS_FGETXATTR(fsp,fd,name,value,size) ((fsp)->conn->vfs.ops.fgetxattr((fsp)->conn->vfs.handles.fgetxattr,(fsp),(fd),(name),(value),(size))) -#define SMB_VFS_LISTXATTR(conn,path,list,size) ((conn)->vfs.ops.listxattr((conn)->vfs.handles.listxattr,(conn),(path),(list),(size))) -#define SMB_VFS_LLISTXATTR(conn,path,list,size) ((conn)->vfs.ops.llistxattr((conn)->vfs.handles.llistxattr,(conn),(path),(list),(size))) +#define SMB_VFS_LISTXATTR(conn,path,list,size) ((conn)->vfs.ops.listxattr((conn)->vfs.handles.listxattr,(path),(list),(size))) +#define SMB_VFS_LLISTXATTR(conn,path,list,size) ((conn)->vfs.ops.llistxattr((conn)->vfs.handles.llistxattr,(path),(list),(size))) #define SMB_VFS_FLISTXATTR(fsp,fd,list,size) ((fsp)->conn->vfs.ops.flistxattr((fsp)->conn->vfs.handles.flistxattr,(fsp),(fd),(list),(size))) -#define SMB_VFS_REMOVEXATTR(conn,path,name) ((conn)->vfs.ops.removexattr((conn)->vfs.handles.removexattr,(conn),(path),(name))) -#define SMB_VFS_LREMOVEXATTR(conn,path,name) ((conn)->vfs.ops.lremovexattr((conn)->vfs.handles.lremovexattr,(conn),(path),(name))) +#define SMB_VFS_REMOVEXATTR(conn,path,name) ((conn)->vfs.ops.removexattr((conn)->vfs.handles.removexattr,(path),(name))) +#define SMB_VFS_LREMOVEXATTR(conn,path,name) ((conn)->vfs.ops.lremovexattr((conn)->vfs.handles.lremovexattr,(path),(name))) #define SMB_VFS_FREMOVEXATTR(fsp,fd,name) ((fsp)->conn->vfs.ops.fremovexattr((fsp)->conn->vfs.handles.fremovexattr,(fsp),(fd),(name))) -#define SMB_VFS_SETXATTR(conn,path,name,value,size,flags) ((conn)->vfs.ops.setxattr((conn)->vfs.handles.setxattr,(conn),(path),(name),(value),(size),(flags))) -#define SMB_VFS_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs.ops.lsetxattr((conn)->vfs.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags))) +#define SMB_VFS_SETXATTR(conn,path,name,value,size,flags) ((conn)->vfs.ops.setxattr((conn)->vfs.handles.setxattr,(path),(name),(value),(size),(flags))) +#define SMB_VFS_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs.ops.lsetxattr((conn)->vfs.handles.lsetxattr,(path),(name),(value),(size),(flags))) #define SMB_VFS_FSETXATTR(fsp,fd,name,value,size,flags) ((fsp)->conn->vfs.ops.fsetxattr((fsp)->conn->vfs.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags))) /* AIO operations. */ @@ -141,26 +141,26 @@ ********************************************************************/ /* Disk operations */ -#define SMB_VFS_OPAQUE_CONNECT(conn, service, user) ((conn)->vfs_opaque.ops.connect_fn((conn)->vfs_opaque.handles.connect_hnd, (conn), (service), (user))) -#define SMB_VFS_OPAQUE_DISCONNECT(conn) ((conn)->vfs_opaque.ops.disconnect((conn)->vfs_opaque.handles.disconnect, (conn))) -#define SMB_VFS_OPAQUE_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs_opaque.ops.disk_free((conn)->vfs_opaque.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize))) -#define SMB_VFS_OPAQUE_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.get_quota((conn)->vfs_opaque.handles.get_quota, (conn), (qtype), (id), (qt))) -#define SMB_VFS_OPAQUE_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.set_quota((conn)->vfs_opaque.handles.set_quota, (conn), (qtype), (id), (qt))) +#define SMB_VFS_OPAQUE_CONNECT(conn, service, user) ((conn)->vfs_opaque.ops.connect_fn((conn)->vfs_opaque.handles.connect_hnd, (service), (user))) +#define SMB_VFS_OPAQUE_DISCONNECT(conn) ((conn)->vfs_opaque.ops.disconnect((conn)->vfs_opaque.handles.disconnect)) +#define SMB_VFS_OPAQUE_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs_opaque.ops.disk_free((conn)->vfs_opaque.handles.disk_free, (path), (small_query), (bsize), (dfree), (dsize))) +#define SMB_VFS_OPAQUE_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.get_quota((conn)->vfs_opaque.handles.get_quota, (qtype), (id), (qt))) +#define SMB_VFS_OPAQUE_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.set_quota((conn)->vfs_opaque.handles.set_quota, (qtype), (id), (qt))) #define SMB_VFS_OPAQUE_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs_opaque.ops.get_shadow_copy_data((fsp)->conn->vfs_opaque.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels))) -#define SMB_VFS_OPAQUE_STATVFS(conn, path, statbuf) ((conn)->vfs_opaque.ops.statvfs((conn)->vfs_opaque.handles.statvfs, (conn), (path), (statbuf))) +#define SMB_VFS_OPAQUE_STATVFS(conn, path, statbuf) ((conn)->vfs_opaque.ops.statvfs((conn)->vfs_opaque.handles.statvfs, (path), (statbuf))) /* Directory operations */ -#define SMB_VFS_OPAQUE_OPENDIR(conn, fname, mask, attr) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (conn), (fname), (mask), (attr))) -#define SMB_VFS_OPAQUE_READDIR(conn, dirp) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (conn), (dirp))) -#define SMB_VFS_OPAQUE_SEEKDIR(conn, dirp, offset) ((conn)->vfs_opaque.ops.seekdir((conn)->vfs_opaque.handles.seekdir, (conn), (dirp), (offset))) -#define SMB_VFS_OPAQUE_TELLDIR(conn, dirp) ((conn)->vfs_opaque.ops.telldir((conn)->vfs_opaque.handles.telldir, (conn), (dirp))) -#define SMB_VFS_OPAQUE_REWINDDIR(conn, dirp) ((conn)->vfs_opaque.ops.rewind_dir((conn)->vfs_opaque.handles.rewind_dir, (conn), (dirp))) -#define SMB_VFS_OPAQUE_MKDIR(conn, path, mode) ((conn)->vfs_opaque.ops.mkdir((conn)->vfs_opaque.handles.mkdir,(conn), (path), (mode))) -#define SMB_VFS_OPAQUE_RMDIR(conn, path) ((conn)->vfs_opaque.ops.rmdir((conn)->vfs_opaque.handles.rmdir, (conn), (path))) -#define SMB_VFS_OPAQUE_CLOSEDIR(conn, dir) ((conn)->vfs_opaque.ops.closedir((conn)->vfs_opaque.handles.closedir, (conn), dir)) +#define SMB_VFS_OPAQUE_OPENDIR(conn, fname, mask, attr) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (fname), (mask), (attr))) +#define SMB_VFS_OPAQUE_READDIR(conn, dirp) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (dirp))) +#define SMB_VFS_OPAQUE_SEEKDIR(conn, dirp, offset) ((conn)->vfs_opaque.ops.seekdir((conn)->vfs_opaque.handles.seekdir, (dirp), (offset))) +#define SMB_VFS_OPAQUE_TELLDIR(conn, dirp) ((conn)->vfs_opaque.ops.telldir((conn)->vfs_opaque.handles.telldir, (dirp))) +#define SMB_VFS_OPAQUE_REWINDDIR(conn, dirp) ((conn)->vfs_opaque.ops.rewind_dir((conn)->vfs_opaque.handles.rewind_dir, (dirp))) +#define SMB_VFS_OPAQUE_MKDIR(conn, path, mode) ((conn)->vfs_opaque.ops.mkdir((conn)->vfs_opaque.handles.mkdir,(path), (mode))) +#define SMB_VFS_OPAQUE_RMDIR(conn, path) ((conn)->vfs_opaque.ops.rmdir((conn)->vfs_opaque.handles.rmdir, (path))) +#define SMB_VFS_OPAQUE_CLOSEDIR(conn, dir) ((conn)->vfs_opaque.ops.closedir((conn)->vfs_opaque.handles.closedir, dir)) /* File operations */ -#define SMB_VFS_OPAQUE_OPEN(conn, fname, flags, mode) ((conn)->vfs_opaque.ops.open((conn)->vfs_opaque.handles.open, (conn), (fname), (flags), (mode))) +#define SMB_VFS_OPAQUE_OPEN(conn, fname, fsp, flags, mode) ((conn)->vfs_opaque.ops.open((conn)->vfs_opaque.handles.open, (fname), (fsp), (flags), (mode))) #define SMB_VFS_OPAQUE_CLOSE(fsp, fd) ((fsp)->conn->vfs_opaque.ops.close_fn((fsp)->conn->vfs_opaque.handles.close_hnd, (fsp), (fd))) #define SMB_VFS_OPAQUE_READ(fsp, fd, data, n) ((fsp)->conn->vfs_opaque.ops.read((fsp)->conn->vfs_opaque.handles.read, (fsp), (fd), (data), (n))) #define SMB_VFS_OPAQUE_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs_opaque.ops.pread((fsp)->conn->vfs_opaque.handles.pread, (fsp), (fd), (data), (n), (off))) @@ -168,28 +168,28 @@ #define SMB_VFS_OPAQUE_PWRITE(fsp, fd, data, n, off) ((fsp)->conn->vfs_opaque.ops.pwrite((fsp)->conn->vfs_opaque.handles.pwrite, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_OPAQUE_LSEEK(fsp, fd, offset, whence) ((fsp)->conn->vfs_opaque.ops.lseek((fsp)->conn->vfs_opaque.handles.lseek, (fsp), (fd), (offset), (whence))) #define SMB_VFS_OPAQUE_SENDFILE(tofd, fsp, fromfd, header, offset, count) ((fsp)->conn->vfs_opaque.ops.sendfile((fsp)->conn->vfs_opaque.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count))) -#define SMB_VFS_OPAQUE_RENAME(conn, old, new) ((conn)->vfs_opaque.ops.rename((conn)->vfs_opaque.handles.rename, (conn), (old), (new))) +#define SMB_VFS_OPAQUE_RENAME(conn, old, new) ((conn)->vfs_opaque.ops.rename((conn)->vfs_opaque.handles.rename, (old), (new))) #define SMB_VFS_OPAQUE_FSYNC(fsp, fd) ((fsp)->conn->vfs_opaque.ops.fsync((fsp)->conn->vfs_opaque.handles.fsync, (fsp), (fd))) -#define SMB_VFS_OPAQUE_STAT(conn, fname, sbuf) ((conn)->vfs_opaque.ops.stat((conn)->vfs_opaque.handles.stat, (conn), (fname), (sbuf))) +#define SMB_VFS_OPAQUE_STAT(conn, fname, sbuf) ((conn)->vfs_opaque.ops.stat((conn)->vfs_opaque.handles.stat, (fname), (sbuf))) #define SMB_VFS_OPAQUE_FSTAT(fsp, fd, sbuf) ((fsp)->conn->vfs_opaque.ops.fstat((fsp)->conn->vfs_opaque.handles.fstat, (fsp) ,(fd) ,(sbuf))) -#define SMB_VFS_OPAQUE_LSTAT(conn, path, sbuf) ((conn)->vfs_opaque.ops.lstat((conn)->vfs_opaque.handles.lstat, (conn), (path), (sbuf))) -#define SMB_VFS_OPAQUE_UNLINK(conn, path) ((conn)->vfs_opaque.ops.unlink((conn)->vfs_opaque.handles.unlink, (conn), (path))) -#define SMB_VFS_OPAQUE_CHMOD(conn, path, mode) ((conn)->vfs_opaque.ops.chmod((conn)->vfs_opaque.handles.chmod, (conn), (path), (mode))) +#define SMB_VFS_OPAQUE_LSTAT(conn, path, sbuf) ((conn)->vfs_opaque.ops.lstat((conn)->vfs_opaque.handles.lstat, (path), (sbuf))) +#define SMB_VFS_OPAQUE_UNLINK(conn, path) ((conn)->vfs_opaque.ops.unlink((conn)->vfs_opaque.handles.unlink, (path))) +#define SMB_VFS_OPAQUE_CHMOD(conn, path, mode) ((conn)->vfs_opaque.ops.chmod((conn)->vfs_opaque.handles.chmod, (path), (mode))) #define SMB_VFS_OPAQUE_FCHMOD(fsp, fd, mode) ((fsp)->conn->vfs_opaque.ops.fchmod((fsp)->conn->vfs_opaque.handles.fchmod, (fsp), (fd), (mode))) -#define SMB_VFS_OPAQUE_CHOWN(conn, path, uid, gid) ((conn)->vfs_opaque.ops.chown((conn)->vfs_opaque.handles.chown, (conn), (path), (uid), (gid))) +#define SMB_VFS_OPAQUE_CHOWN(conn, path, uid, gid) ((conn)->vfs_opaque.ops.chown((conn)->vfs_opaque.handles.chown, (path), (uid), (gid))) #define SMB_VFS_OPAQUE_FCHOWN(fsp, fd, uid, gid) ((fsp)->conn->vfs_opaque.ops.fchown((fsp)->conn->vfs_opaque.handles.fchown, (fsp), (fd), (uid), (gid))) -#define SMB_VFS_OPAQUE_CHDIR(conn, path) ((conn)->vfs_opaque.ops.chdir((conn)->vfs_opaque.handles.chdir, (conn), (path))) -#define SMB_VFS_OPAQUE_GETWD(conn, buf) ((conn)->vfs_opaque.ops.getwd((conn)->vfs_opaque.handles.getwd, (conn), (buf))) -#define SMB_VFS_OPAQUE_UTIME(conn, path, times) ((conn)->vfs_opaque.ops.utime((conn)->vfs_opaque.handles.utime, (conn), (path), (times))) +#define SMB_VFS_OPAQUE_CHDIR(conn, path) ((conn)->vfs_opaque.ops.chdir((conn)->vfs_opaque.handles.chdir, (path))) +#define SMB_VFS_OPAQUE_GETWD(conn, buf) ((conn)->vfs_opaque.ops.getwd((conn)->vfs_opaque.handles.getwd, (buf))) +#define SMB_VFS_OPAQUE_UTIME(conn, path, times) ((conn)->vfs_opaque.ops.utime((conn)->vfs_opaque.handles.utime, (path), (times))) #define SMB_VFS_OPAQUE_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs_opaque.ops.ftruncate((fsp)->conn->vfs_opaque.handles.ftruncate, (fsp), (fd), (offset))) #define SMB_VFS_OPAQUE_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs_opaque.ops.lock((fsp)->conn->vfs_opaque.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type))) #define SMB_VFS_OPAQUE_FLOCK(fsp, fd, share_mode) ((fsp)->conn->vfs_opaque.ops.lock((fsp)->conn->vfs_opaque.handles.kernel_flock, (fsp), (fd), (share_mode))) #define SMB_VFS_OPAQUE_GETLOCK(fsp, fd, poffset, pcount, ptype, ppid) ((fsp)->conn->vfs_opaque.ops.getlock((fsp)->conn->vfs_opaque.handles.getlock, (fsp), (fd), (poffset), (pcount), (ptype), (ppid))) -#define SMB_VFS_OPAQUE_SYMLINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.symlink((conn)->vfs_opaque.handles.symlink, (conn), (oldpath), (newpath))) -#define SMB_VFS_OPAQUE_READLINK(conn, path, buf, bufsiz) ((conn)->vfs_opaque.ops.readlink((conn)->vfs_opaque.handles.readlink, (conn), (path), (buf), (bufsiz))) -#define SMB_VFS_OPAQUE_LINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.link((conn)->vfs_opaque.handles.link, (conn), (oldpath), (newpath))) -#define SMB_VFS_OPAQUE_MKNOD(conn, path, mode, dev) ((conn)->vfs_opaque.ops.mknod((conn)->vfs_opaque.handles.mknod, (conn), (path), (mode), (dev))) -#define SMB_VFS_OPAQUE_REALPATH(conn, path, resolved_path) ((conn)->vfs_opaque.ops.realpath((conn)->vfs_opaque.handles.realpath, (conn), (path), (resolved_path))) +#define SMB_VFS_OPAQUE_SYMLINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.symlink((conn)->vfs_opaque.handles.symlink, (oldpath), (newpath))) +#define SMB_VFS_OPAQUE_READLINK(conn, path, buf, bufsiz) ((conn)->vfs_opaque.ops.readlink((conn)->vfs_opaque.handles.readlink, (path), (buf), (bufsiz))) +#define SMB_VFS_OPAQUE_LINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.link((conn)->vfs_opaque.handles.link, (oldpath), (newpath))) +#define SMB_VFS_OPAQUE_MKNOD(conn, path, mode, dev) ((conn)->vfs_opaque.ops.mknod((conn)->vfs_opaque.handles.mknod, (path), (mode), (dev))) +#define SMB_VFS_OPAQUE_REALPATH(conn, path, resolved_path) ((conn)->vfs_opaque.ops.realpath((conn)->vfs_opaque.handles.realpath, (path), (resolved_path))) /* NT ACL operations. */ #define SMB_VFS_OPAQUE_FGET_NT_ACL(fsp, fd, security_info, ppdesc) ((fsp)->conn->vfs_opaque.ops.fget_nt_acl((fsp)->conn->vfs_opaque.handles.fget_nt_acl, (fsp), (fd), (security_info), (ppdesc))) @@ -198,44 +198,44 @@ #define SMB_VFS_OPAQUE_SET_NT_ACL(fsp, name, security_info_sent, psd) ((fsp)->conn->vfs_opaque.ops.set_nt_acl((fsp)->conn->vfs_opaque.handles.set_nt_acl, (fsp), (name), (security_info_sent), (psd))) /* POSIX ACL operations. */ -#define SMB_VFS_OPAQUE_CHMOD_ACL(conn, name, mode) ((conn)->vfs_opaque.ops.chmod_acl((conn)->vfs_opaque.handles.chmod_acl, (conn), (name), (mode))) +#define SMB_VFS_OPAQUE_CHMOD_ACL(conn, name, mode) ((conn)->vfs_opaque.ops.chmod_acl((conn)->vfs_opaque.handles.chmod_acl, (name), (mode))) #define SMB_VFS_OPAQUE_FCHMOD_ACL(fsp, fd, mode) ((fsp)->conn->vfs_opaque.ops.fchmod_acl((fsp)->conn->vfs_opaque.handles.chmod_acl, (fsp), (fd), (mode))) -#define SMB_VFS_OPAQUE_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs_opaque.ops.sys_acl_get_entry((conn)->vfs_opaque.handles.sys_acl_get_entry, (conn), (theacl), (entry_id), (entry_p))) -#define SMB_VFS_OPAQUE_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs_opaque.ops.sys_acl_get_tag_type((conn)->vfs_opaque.handles.sys_acl_get_tag_type, (conn), (entry_d), (tag_type_p))) -#define SMB_VFS_OPAQUE_SYS_ACL_GET_PERMSET(conn, entry_d, permset_p) ((conn)->vfs_opaque.ops.sys_acl_get_permset((conn)->vfs_opaque.handles.sys_acl_get_permset, (conn), (entry_d), (permset_p))) -#define SMB_VFS_OPAQUE_SYS_ACL_GET_QUALIFIER(conn, entry_d) ((conn)->vfs_opaque.ops.sys_acl_get_qualifier((conn)->vfs_opaque.handles.sys_acl_get_qualifier, (conn), (entry_d))) -#define SMB_VFS_OPAQUE_SYS_ACL_GET_FILE(conn, path_p, type) ((conn)->vfs_opaque.ops.sys_acl_get_file((conn)->vfs_opaque.handles.sys_acl_get_file, (conn), (path_p), (type))) +#define SMB_VFS_OPAQUE_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs_opaque.ops.sys_acl_get_entry((conn)->vfs_opaque.handles.sys_acl_get_entry, (theacl), (entry_id), (entry_p))) +#define SMB_VFS_OPAQUE_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs_opaque.ops.sys_acl_get_tag_type((conn)->vfs_opaque.handles.sys_acl_get_tag_type, (entry_d), (tag_type_p))) +#define SMB_VFS_OPAQUE_SYS_ACL_GET_PERMSET(conn, entry_d, permset_p) ((conn)->vfs_opaque.ops.sys_acl_get_permset((conn)->vfs_opaque.handles.sys_acl_get_permset, (entry_d), (permset_p))) +#define SMB_VFS_OPAQUE_SYS_ACL_GET_QUALIFIER(conn, entry_d) ((conn)->vfs_opaque.ops.sys_acl_get_qualifier((conn)->vfs_opaque.handles.sys_acl_get_qualifier, (entry_d))) +#define SMB_VFS_OPAQUE_SYS_ACL_GET_FILE(conn, path_p, type) ((conn)->vfs_opaque.ops.sys_acl_get_file((conn)->vfs_opaque.handles.sys_acl_get_file, (path_p), (type))) #define SMB_VFS_OPAQUE_SYS_ACL_GET_FD(fsp, fd) ((fsp)->conn->vfs_opaque.ops.sys_acl_get_fd((fsp)->conn->vfs_opaque.handles.sys_acl_get_fd, (fsp), (fd))) -#define SMB_VFS_OPAQUE_SYS_ACL_CLEAR_PERMS(conn, permset) ((conn)->vfs_opaque.ops.sys_acl_clear_perms((conn)->vfs_opaque.handles.sys_acl_clear_perms, (conn), (permset))) -#define SMB_VFS_OPAQUE_SYS_ACL_ADD_PERM(conn, permset, perm) ((conn)->vfs_opaque.ops.sys_acl_add_perm((conn)->vfs_opaque.handles.sys_acl_add_perm, (conn), (permset), (perm))) -#define SMB_VFS_OPAQUE_SYS_ACL_TO_TEXT(conn, theacl, plen) ((conn)->vfs_opaque.ops.sys_acl_to_text((conn)->vfs_opaque.handles.sys_acl_to_text, (conn), (theacl), (plen))) -#define SMB_VFS_OPAQUE_SYS_ACL_INIT(conn, count) ((conn)->vfs_opaque.ops.sys_acl_init((conn)->vfs_opaque.handles.sys_acl_init, (conn), (count))) -#define SMB_VFS_OPAQUE_SYS_ACL_CREATE_ENTRY(conn, pacl, pentry) ((conn)->vfs_opaque.ops.sys_acl_create_entry((conn)->vfs_opaque.handles.sys_acl_create_entry, (conn), (pacl), (pentry))) -#define SMB_VFS_OPAQUE_SYS_ACL_SET_TAG_TYPE(conn, entry, tagtype) ((conn)->vfs_opaque.ops.sys_acl_set_tag_type((conn)->vfs_opaque.handles.sys_acl_set_tag_type, (conn), (entry), (tagtype))) -#define SMB_VFS_OPAQUE_SYS_ACL_SET_QUALIFIER(conn, entry, qual) ((conn)->vfs_opaque.ops.sys_acl_set_qualifier((conn)->vfs_opaque.handles.sys_acl_set_qualifier, (conn), (entry), (qual))) -#define SMB_VFS_OPAQUE_SYS_ACL_SET_PERMSET(conn, entry, permset) ((conn)->vfs_opaque.ops.sys_acl_set_permset((conn)->vfs_opaque.handles.sys_acl_set_permset, (conn), (entry), (permset))) -#define SMB_VFS_OPAQUE_SYS_ACL_VALID(conn, theacl) ((conn)->vfs_opaque.ops.sys_acl_valid((conn)->vfs_opaque.handles.sys_acl_valid, (conn), (theacl))) -#define SMB_VFS_OPAQUE_SYS_ACL_SET_FILE(conn, name, acltype, theacl) ((conn)->vfs_opaque.ops.sys_acl_set_file((conn)->vfs_opaque.handles.sys_acl_set_file, (conn), (name), (acltype), (theacl))) +#define SMB_VFS_OPAQUE_SYS_ACL_CLEAR_PERMS(conn, permset) ((conn)->vfs_opaque.ops.sys_acl_clear_perms((conn)->vfs_opaque.handles.sys_acl_clear_perms, (permset))) +#define SMB_VFS_OPAQUE_SYS_ACL_ADD_PERM(conn, permset, perm) ((conn)->vfs_opaque.ops.sys_acl_add_perm((conn)->vfs_opaque.handles.sys_acl_add_perm, (permset), (perm))) +#define SMB_VFS_OPAQUE_SYS_ACL_TO_TEXT(conn, theacl, plen) ((conn)->vfs_opaque.ops.sys_acl_to_text((conn)->vfs_opaque.handles.sys_acl_to_text, (theacl), (plen))) +#define SMB_VFS_OPAQUE_SYS_ACL_INIT(conn, count) ((conn)->vfs_opaque.ops.sys_acl_init((conn)->vfs_opaque.handles.sys_acl_init, (count))) +#define SMB_VFS_OPAQUE_SYS_ACL_CREATE_ENTRY(conn, pacl, pentry) ((conn)->vfs_opaque.ops.sys_acl_create_entry((conn)->vfs_opaque.handles.sys_acl_create_entry, (pacl), (pentry))) +#define SMB_VFS_OPAQUE_SYS_ACL_SET_TAG_TYPE(conn, entry, tagtype) ((conn)->vfs_opaque.ops.sys_acl_set_tag_type((conn)->vfs_opaque.handles.sys_acl_set_tag_type, (entry), (tagtype))) +#define SMB_VFS_OPAQUE_SYS_ACL_SET_QUALIFIER(conn, entry, qual) ((conn)->vfs_opaque.ops.sys_acl_set_qualifier((conn)->vfs_opaque.handles.sys_acl_set_qualifier, (entry), (qual))) +#define SMB_VFS_OPAQUE_SYS_ACL_SET_PERMSET(conn, entry, permset) ((conn)->vfs_opaque.ops.sys_acl_set_permset((conn)->vfs_opaque.handles.sys_acl_set_permset, (entry), (permset))) +#define SMB_VFS_OPAQUE_SYS_ACL_VALID(conn, theacl) ((conn)->vfs_opaque.ops.sys_acl_valid((conn)->vfs_opaque.handles.sys_acl_valid, (theacl))) +#define SMB_VFS_OPAQUE_SYS_ACL_SET_FILE(conn, name, acltype, theacl) ((conn)->vfs_opaque.ops.sys_acl_set_file((conn)->vfs_opaque.handles.sys_acl_set_file, (name), (acltype), (theacl))) #define SMB_VFS_OPAQUE_SYS_ACL_SET_FD(fsp, fd, theacl) ((fsp)->conn->vfs_opaque.ops.sys_acl_set_fd((fsp)->conn->vfs_opaque.handles.sys_acl_set_fd, (fsp), (fd), (theacl))) -#define SMB_VFS_OPAQUE_SYS_ACL_DELETE_DEF_FILE(conn, path) ((conn)->vfs_opaque.ops.sys_acl_delete_def_file((conn)->vfs_opaque.handles.sys_acl_delete_def_file, (conn), (path))) -#define SMB_VFS_OPAQUE_SYS_ACL_GET_PERM(conn, permset, perm) ((conn)->vfs_opaque.ops.sys_acl_get_perm((conn)->vfs_opaque.handles.sys_acl_get_perm, (conn), (permset), (perm))) -#define SMB_VFS_OPAQUE_SYS_ACL_FREE_TEXT(conn, text) ((conn)->vfs_opaque.ops.sys_acl_free_text((conn)->vfs_opaque.handles.sys_acl_free_text, (conn), (text))) -#define SMB_VFS_OPAQUE_SYS_ACL_FREE_ACL(conn, posix_acl) ((conn)->vfs_opaque.ops.sys_acl_free_acl((conn)->vfs_opaque.handles.sys_acl_free_acl, (conn), (posix_acl))) -#define SMB_VFS_OPAQUE_SYS_ACL_FREE_QUALIFIER(conn, qualifier, tagtype) ((conn)->vfs_opaque.ops.sys_acl_free_qualifier((conn)->vfs_opaque.handles.sys_acl_free_qualifier, (conn), (qualifier), (tagtype))) +#define SMB_VFS_OPAQUE_SYS_ACL_DELETE_DEF_FILE(conn, path) ((conn)->vfs_opaque.ops.sys_acl_delete_def_file((conn)->vfs_opaque.handles.sys_acl_delete_def_file, (path))) +#define SMB_VFS_OPAQUE_SYS_ACL_GET_PERM(conn, permset, perm) ((conn)->vfs_opaque.ops.sys_acl_get_perm((conn)->vfs_opaque.handles.sys_acl_get_perm, (permset), (perm))) +#define SMB_VFS_OPAQUE_SYS_ACL_FREE_TEXT(conn, text) ((conn)->vfs_opaque.ops.sys_acl_free_text((conn)->vfs_opaque.handles.sys_acl_free_text, (text))) +#define SMB_VFS_OPAQUE_SYS_ACL_FREE_ACL(conn, posix_acl) ((conn)->vfs_opaque.ops.sys_acl_free_acl((conn)->vfs_opaque.handles.sys_acl_free_acl, (posix_acl))) +#define SMB_VFS_OPAQUE_SYS_ACL_FREE_QUALIFIER(conn, qualifier, tagtype) ((conn)->vfs_opaque.ops.sys_acl_free_qualifier((conn)->vfs_opaque.handles.sys_acl_free_qualifier, (qualifier), (tagtype))) /* EA operations. */ -#define SMB_VFS_OPAQUE_GETXATTR(conn,path,name,value,size) ((conn)->vfs_opaque.ops.getxattr((conn)->vfs_opaque.handles.getxattr,(conn),(path),(name),(value),(size))) -#define SMB_VFS_OPAQUE_LGETXATTR(conn,path,name,value,size) ((conn)->vfs_opaque.ops.lgetxattr((conn)->vfs_opaque.handles.lgetxattr,(conn),(path),(name),(value),(size))) +#define SMB_VFS_OPAQUE_GETXATTR(conn,path,name,value,size) ((conn)->vfs_opaque.ops.getxattr((conn)->vfs_opaque.handles.getxattr,(path),(name),(value),(size))) +#define SMB_VFS_OPAQUE_LGETXATTR(conn,path,name,value,size) ((conn)->vfs_opaque.ops.lgetxattr((conn)->vfs_opaque.handles.lgetxattr,(path),(name),(value),(size))) #define SMB_VFS_OPAQUE_FGETXATTR(fsp,fd,name,value,size) ((fsp)->conn->vfs_opaque.ops.fgetxattr((fsp)->conn->vfs_opaque.handles.fgetxattr,(fsp),(fd),(name),(value),(size))) -#define SMB_VFS_OPAQUE_LISTXATTR(conn,path,list,size) ((conn)->vfs_opaque.ops.listxattr((conn)->vfs_opaque.handles.listxattr,(conn),(path),(list),(size))) -#define SMB_VFS_OPAQUE_LLISTXATTR(conn,path,list,size) ((conn)->vfs_opaque.ops.llistxattr((conn)->vfs_opaque.handles.llistxattr,(conn),(path),(list),(size))) +#define SMB_VFS_OPAQUE_LISTXATTR(conn,path,list,size) ((conn)->vfs_opaque.ops.listxattr((conn)->vfs_opaque.handles.listxattr,(path),(list),(size))) +#define SMB_VFS_OPAQUE_LLISTXATTR(conn,path,list,size) ((conn)->vfs_opaque.ops.llistxattr((conn)->vfs_opaque.handles.llistxattr,(path),(list),(size))) #define SMB_VFS_OPAQUE_FLISTXATTR(fsp,fd,list,size) ((fsp)->conn->vfs_opaque.ops.flistxattr((fsp)->conn->vfs_opaque.handles.flistxattr,(fsp),(fd),(list),(size))) -#define SMB_VFS_OPAQUE_REMOVEXATTR(conn,path,name) ((conn)->vfs_opaque.ops.removexattr((conn)->vfs_opaque.handles.removexattr,(conn),(path),(name))) -#define SMB_VFS_OPAQUE_LREMOVEXATTR(conn,path,name) ((conn)->vfs_opaque.ops.lremovexattr((conn)->vfs_opaque.handles.lremovexattr,(conn),(path),(name))) +#define SMB_VFS_OPAQUE_REMOVEXATTR(conn,path,name) ((conn)->vfs_opaque.ops.removexattr((conn)->vfs_opaque.handles.removexattr,(path),(name))) +#define SMB_VFS_OPAQUE_LREMOVEXATTR(conn,path,name) ((conn)->vfs_opaque.ops.lremovexattr((conn)->vfs_opaque.handles.lremovexattr,(path),(name))) #define SMB_VFS_OPAQUE_FREMOVEXATTR(fsp,fd,name) ((fsp)->conn->vfs_opaque.ops.fremovexattr((fsp)->conn->vfs_opaque.handles.fremovexattr,(fsp),(fd),(name))) -#define SMB_VFS_OPAQUE_SETXATTR(conn,path,name,value,size,flags) ((conn)->vfs_opaque.ops.setxattr((conn)->vfs_opaque.handles.setxattr,(conn),(path),(name),(value),(size),(flags))) -#define SMB_VFS_OPAQUE_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs_opaque.ops.lsetxattr((conn)->vfs_opaque.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags))) +#define SMB_VFS_OPAQUE_SETXATTR(conn,path,name,value,size,flags) ((conn)->vfs_opaque.ops.setxattr((conn)->vfs_opaque.handles.setxattr,(path),(name),(value),(size),(flags))) +#define SMB_VFS_OPAQUE_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs_opaque.ops.lsetxattr((conn)->vfs_opaque.handles.lsetxattr,(path),(name),(value),(size),(flags))) #define SMB_VFS_OPAQUE_FSETXATTR(fsp,fd,name,value,size,flags) ((fsp)->conn->vfs_opaque.ops.fsetxattr((fsp)->conn->vfs_opaque.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags))) /* AIO operations. */ @@ -254,27 +254,27 @@ ********************************************************************/ /* Disk operations */ -#define SMB_VFS_NEXT_CONNECT(handle, conn, service, user) ((handle)->vfs_next.ops.connect_fn((handle)->vfs_next.handles.connect_hnd, (conn), (service), (user))) -#define SMB_VFS_NEXT_DISCONNECT(handle, conn) ((handle)->vfs_next.ops.disconnect((handle)->vfs_next.handles.disconnect, (conn))) -#define SMB_VFS_NEXT_DISK_FREE(handle, conn, path, small_query, bsize, dfree ,dsize) ((handle)->vfs_next.ops.disk_free((handle)->vfs_next.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize))) -#define SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.get_quota((handle)->vfs_next.handles.get_quota, (conn), (qtype), (id), (qt))) -#define SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.set_quota((handle)->vfs_next.handles.set_quota, (conn), (qtype), (id), (qt))) +#define SMB_VFS_NEXT_CONNECT(handle, service, user) ((handle)->vfs_next.ops.connect_fn((handle)->vfs_next.handles.connect_hnd, (service), (user))) +#define SMB_VFS_NEXT_DISCONNECT(handle) ((handle)->vfs_next.ops.disconnect((handle)->vfs_next.handles.disconnect)) +#define SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, bsize, dfree ,dsize) ((handle)->vfs_next.ops.disk_free((handle)->vfs_next.handles.disk_free, (path), (small_query), (bsize), (dfree), (dsize))) +#define SMB_VFS_NEXT_GET_QUOTA(handle, qtype, id, qt) ((handle)->vfs_next.ops.get_quota((handle)->vfs_next.handles.get_quota, (qtype), (id), (qt))) +#define SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, qt) ((handle)->vfs_next.ops.set_quota((handle)->vfs_next.handles.set_quota, (qtype), (id), (qt))) #define SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data ,labels) ((handle)->vfs_next.ops.get_shadow_copy_data((handle)->vfs_next.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels))) -#define SMB_VFS_NEXT_STATVFS(handle, conn, path, statbuf) ((handle)->vfs_next.ops.statvfs((handle)->vfs_next.handles.statvfs, (conn), (path), (statbuf))) +#define SMB_VFS_NEXT_STATVFS(handle, path, statbuf) ((handle)->vfs_next.ops.statvfs((handle)->vfs_next.handles.statvfs, (path), (statbuf))) /* Directory operations */ -#define SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (conn), (fname), (mask), (attr))) -#define SMB_VFS_NEXT_READDIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp))) -#define SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp, offset) ((handle)->vfs_next.ops.seekdir((handle)->vfs_next.handles.seekdir, (conn), (dirp), (offset))) -#define SMB_VFS_NEXT_TELLDIR(handle, conn, dirp) ((handle)->vfs_next.ops.telldir((handle)->vfs_next.handles.telldir, (conn), (dirp))) -#define SMB_VFS_NEXT_REWINDDIR(handle, conn, dirp) ((handle)->vfs_next.ops.rewind_dir((handle)->vfs_next.handles.rewind_dir, (conn), (dirp))) -#define SMB_VFS_NEXT_DIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp))) -#define SMB_VFS_NEXT_MKDIR(handle, conn, path, mode) ((handle)->vfs_next.ops.mkdir((handle)->vfs_next.handles.mkdir,(conn), (path), (mode))) -#define SMB_VFS_NEXT_RMDIR(handle, conn, path) ((handle)->vfs_next.ops.rmdir((handle)->vfs_next.handles.rmdir, (conn), (path))) -#define SMB_VFS_NEXT_CLOSEDIR(handle, conn, dir) ((handle)->vfs_next.ops.closedir((handle)->vfs_next.handles.closedir, (conn), dir)) +#define SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (fname), (mask), (attr))) +#define SMB_VFS_NEXT_READDIR(handle, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (dirp))) +#define SMB_VFS_NEXT_SEEKDIR(handle, dirp, offset) ((handle)->vfs_next.ops.seekdir((handle)->vfs_next.handles.seekdir, (dirp), (offset))) +#define SMB_VFS_NEXT_TELLDIR(handle, dirp) ((handle)->vfs_next.ops.telldir((handle)->vfs_next.handles.telldir, (dirp))) +#define SMB_VFS_NEXT_REWINDDIR(handle, dirp) ((handle)->vfs_next.ops.rewind_dir((handle)->vfs_next.handles.rewind_dir, (dirp))) +#define SMB_VFS_NEXT_DIR(handle, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (dirp))) +#define SMB_VFS_NEXT_MKDIR(handle, path, mode) ((handle)->vfs_next.ops.mkdir((handle)->vfs_next.handles.mkdir,(path), (mode))) +#define SMB_VFS_NEXT_RMDIR(handle, path) ((handle)->vfs_next.ops.rmdir((handle)->vfs_next.handles.rmdir, (path))) +#define SMB_VFS_NEXT_CLOSEDIR(handle, dir) ((handle)->vfs_next.ops.closedir((handle)->vfs_next.handles.closedir, dir)) /* File operations */ -#define SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode) ((handle)->vfs_next.ops.open((handle)->vfs_next.handles.open, (conn), (fname), (flags), (mode))) +#define SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode) ((handle)->vfs_next.ops.open((handle)->vfs_next.handles.open, (fname), (fsp), (flags), (mode))) #define SMB_VFS_NEXT_CLOSE(handle, fsp, fd) ((handle)->vfs_next.ops.close_fn((handle)->vfs_next.handles.close_hnd, (fsp), (fd))) #define SMB_VFS_NEXT_READ(handle, fsp, fd, data, n) ((handle)->vfs_next.ops.read((handle)->vfs_next.handles.read, (fsp), (fd), (data), (n))) #define SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, n, off) ((handle)->vfs_next.ops.pread((handle)->vfs_next.handles.pread, (fsp), (fd), (data), (n), (off))) @@ -282,28 +282,28 @@ #define SMB_VFS_NEXT_PWRITE(handle, fsp, fd, data, n, off) ((handle)->vfs_next.ops.pwrite((handle)->vfs_next.handles.pwrite, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_NEXT_LSEEK(handle, fsp, fd, offset, whence) ((handle)->vfs_next.ops.lseek((handle)->vfs_next.handles.lseek, (fsp), (fd), (offset), (whence))) #define SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, fromfd, header, offset, count) ((handle)->vfs_next.ops.sendfile((handle)->vfs_next.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count))) -#define SMB_VFS_NEXT_RENAME(handle, conn, old, new) ((handle)->vfs_next.ops.rename((handle)->vfs_next.handles.rename, (conn), (old), (new))) +#define SMB_VFS_NEXT_RENAME(handle, old, new) ((handle)->vfs_next.ops.rename((handle)->vfs_next.handles.rename, (old), (new))) #define SMB_VFS_NEXT_FSYNC(handle, fsp, fd) ((handle)->vfs_next.ops.fsync((handle)->vfs_next.handles.fsync, (fsp), (fd))) -#define SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf) ((handle)->vfs_next.ops.stat((handle)->vfs_next.handles.stat, (conn), (fname), (sbuf))) +#define SMB_VFS_NEXT_STAT(handle, fname, sbuf) ((handle)->vfs_next.ops.stat((handle)->vfs_next.handles.stat, (fname), (sbuf))) #define SMB_VFS_NEXT_FSTAT(handle, fsp, fd, sbuf) ((handle)->vfs_next.ops.fstat((handle)->vfs_next.handles.fstat, (fsp) ,(fd) ,(sbuf))) -#define SMB_VFS_NEXT_LSTAT(handle, conn, path, sbuf) ((handle)->vfs_next.ops.lstat((handle)->vfs_next.handles.lstat, (conn), (path), (sbuf))) -#define SMB_VFS_NEXT_UNLINK(handle, conn, path) ((handle)->vfs_next.ops.unlink((handle)->vfs_next.handles.unlink, (conn), (path))) -#define SMB_VFS_NEXT_CHMOD(handle, conn, path, mode) ((handle)->vfs_next.ops.chmod((handle)->vfs_next.handles.chmod, (conn), (path), (mode))) +#define SMB_VFS_NEXT_LSTAT(handle, path, sbuf) ((handle)->vfs_next.ops.lstat((handle)->vfs_next.handles.lstat, (path), (sbuf))) +#define SMB_VFS_NEXT_UNLINK(handle, path) ((handle)->vfs_next.ops.unlink((handle)->vfs_next.handles.unlink, (path))) +#define SMB_VFS_NEXT_CHMOD(handle, path, mode) ((handle)->vfs_next.ops.chmod((handle)->vfs_next.handles.chmod, (path), (mode))) #define SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode) ((handle)->vfs_next.ops.fchmod((handle)->vfs_next.handles.fchmod, (fsp), (fd), (mode))) -#define SMB_VFS_NEXT_CHOWN(handle, conn, path, uid, gid) ((handle)->vfs_next.ops.chown((handle)->vfs_next.handles.chown, (conn), (path), (uid), (gid))) +#define SMB_VFS_NEXT_CHOWN(handle, path, uid, gid) ((handle)->vfs_next.ops.chown((handle)->vfs_next.handles.chown, (path), (uid), (gid))) #define SMB_VFS_NEXT_FCHOWN(handle, fsp, fd, uid, gid) ((handle)->vfs_next.ops.fchown((handle)->vfs_next.handles.fchown, (fsp), (fd), (uid), (gid))) -#define SMB_VFS_NEXT_CHDIR(handle, conn, path) ((handle)->vfs_next.ops.chdir((handle)->vfs_next.handles.chdir, (conn), (path))) -#define SMB_VFS_NEXT_GETWD(handle, conn, buf) ((handle)->vfs_next.ops.getwd((handle)->vfs_next.handles.getwd, (conn), (buf))) -#define SMB_VFS_NEXT_UTIME(handle, conn, path, times) ((handle)->vfs_next.ops.utime((handle)->vfs_next.handles.utime, (conn), (path), (times))) +#define SMB_VFS_NEXT_CHDIR(handle, path) ((handle)->vfs_next.ops.chdir((handle)->vfs_next.handles.chdir, (path))) +#define SMB_VFS_NEXT_GETWD(handle, buf) ((handle)->vfs_next.ops.getwd((handle)->vfs_next.handles.getwd, (buf))) +#define SMB_VFS_NEXT_UTIME(handle, path, times) ((handle)->vfs_next.ops.utime((handle)->vfs_next.handles.utime, (path), (times))) #define SMB_VFS_NEXT_FTRUNCATE(handle, fsp, fd, offset) ((handle)->vfs_next.ops.ftruncate((handle)->vfs_next.handles.ftruncate, (fsp), (fd), (offset))) #define SMB_VFS_NEXT_LOCK(handle, fsp, fd, op, offset, count, type) ((handle)->vfs_next.ops.lock((handle)->vfs_next.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type))) #define SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, fd, share_mode)((handle)->vfs_next.ops.lock((handle)->vfs_next.handles.kernel_flock, (fsp), (fd), (share_mode))) #define SMB_VFS_NEXT_GETLOCK(handle, fsp, fd, poffset, pcount, ptype, ppid) ((handle)->vfs_next.ops.getlock((handle)->vfs_next.handles.getlock, (fsp), (fd), (poffset), (pcount), (ptype), (ppid))) -#define SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath) ((handle)->vfs_next.ops.symlink((handle)->vfs_next.handles.symlink, (conn), (oldpath), (newpath))) -#define SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz) ((handle)->vfs_next.ops.readlink((handle)->vfs_next.handles.readlink, (conn), (path), (buf), (bufsiz))) -#define SMB_VFS_NEXT_LINK(handle, conn, oldpath, newpath) ((handle)->vfs_next.ops.link((handle)->vfs_next.handles.link, (conn), (oldpath), (newpath))) -#define SMB_VFS_NEXT_MKNOD(handle, conn, path, mode, dev) ((handle)->vfs_next.ops.mknod((handle)->vfs_next.handles.mknod, (conn), (path), (mode), (dev))) -#define SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path) ((handle)->vfs_next.ops.realpath((handle)->vfs_next.handles.realpath, (conn), (path), (resolved_path))) +#define SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath) ((handle)->vfs_next.ops.symlink((handle)->vfs_next.handles.symlink, (oldpath), (newpath))) +#define SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz) ((handle)->vfs_next.ops.readlink((handle)->vfs_next.handles.readlink, (path), (buf), (bufsiz))) +#define SMB_VFS_NEXT_LINK(handle, oldpath, newpath) ((handle)->vfs_next.ops.link((handle)->vfs_next.handles.link, (oldpath), (newpath))) +#define SMB_VFS_NEXT_MKNOD(handle, path, mode, dev) ((handle)->vfs_next.ops.mknod((handle)->vfs_next.handles.mknod, (path), (mode), (dev))) +#define SMB_VFS_NEXT_REALPATH(handle, path, resolved_path) ((handle)->vfs_next.ops.realpath((handle)->vfs_next.handles.realpath, (path), (resolved_path))) /* NT ACL operations. */ #define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, fd, security_info, ppdesc) ((handle)->vfs_next.ops.fget_nt_acl((handle)->vfs_next.handles.fget_nt_acl, (fsp), (fd), (security_info), (ppdesc))) @@ -312,44 +312,44 @@ #define SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent, psd) ((handle)->vfs_next.ops.set_nt_acl((handle)->vfs_next.handles.set_nt_acl, (fsp), (name), (security_info_sent), (psd))) /* POSIX ACL operations. */ -#define SMB_VFS_NEXT_CHMOD_ACL(handle, conn, name, mode) ((handle)->vfs_next.ops.chmod_acl((handle)->vfs_next.handles.chmod_acl, (conn), (name), (mode))) +#define SMB_VFS_NEXT_CHMOD_ACL(handle, name, mode) ((handle)->vfs_next.ops.chmod_acl((handle)->vfs_next.handles.chmod_acl, (name), (mode))) #define SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode) ((handle)->vfs_next.ops.fchmod_acl((handle)->vfs_next.handles.chmod_acl, (fsp), (fd), (mode))) -#define SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, conn, theacl, entry_id, entry_p) ((handle)->vfs_next.ops.sys_acl_get_entry((handle)->vfs_next.handles.sys_acl_get_entry, (conn), (theacl), (entry_id), (entry_p))) -#define SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, conn, entry_d, tag_type_p) ((handle)->vfs_next.ops.sys_acl_get_tag_type((handle)->vfs_next.handles.sys_acl_get_tag_type, (conn), (entry_d), (tag_type_p))) -#define SMB_VFS_NEXT_SYS_ACL_GET_PERMSET(handle, conn, entry_d, permset_p) ((handle)->vfs_next.ops.sys_acl_get_permset((handle)->vfs_next.handles.sys_acl_get_permset, (conn), (entry_d), (permset_p))) -#define SMB_VFS_NEXT_SYS_ACL_GET_QUALIFIER(handle, conn, entry_d) ((handle)->vfs_next.ops.sys_acl_get_qualifier((handle)->vfs_next.handles.sys_acl_get_qualifier, (conn), (entry_d))) -#define SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, conn, path_p, type) ((handle)->vfs_next.ops.sys_acl_get_file((handle)->vfs_next.handles.sys_acl_get_file, (conn), (path_p), (type))) +#define SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, theacl, entry_id, entry_p) ((handle)->vfs_next.ops.sys_acl_get_entry((handle)->vfs_next.handles.sys_acl_get_entry, (theacl), (entry_id), (entry_p))) +#define SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, entry_d, tag_type_p) ((handle)->vfs_next.ops.sys_acl_get_tag_type((handle)->vfs_next.handles.sys_acl_get_tag_type, (entry_d), (tag_type_p))) +#define SMB_VFS_NEXT_SYS_ACL_GET_PERMSET(handle, entry_d, permset_p) ((handle)->vfs_next.ops.sys_acl_get_permset((handle)->vfs_next.handles.sys_acl_get_permset, (entry_d), (permset_p))) +#define SMB_VFS_NEXT_SYS_ACL_GET_QUALIFIER(handle, entry_d) ((handle)->vfs_next.ops.sys_acl_get_qualifier((handle)->vfs_next.handles.sys_acl_get_qualifier, (entry_d))) +#define SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type) ((handle)->vfs_next.ops.sys_acl_get_file((handle)->vfs_next.handles.sys_acl_get_file, (path_p), (type))) #define SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, fd) ((handle)->vfs_next.ops.sys_acl_get_fd((handle)->vfs_next.handles.sys_acl_get_fd, (fsp), (fd))) -#define SMB_VFS_NEXT_SYS_ACL_CLEAR_PERMS(handle, conn, permset) ((handle)->vfs_next.ops.sys_acl_clear_perms((handle)->vfs_next.handles.sys_acl_clear_perms, (conn), (permset))) -#define SMB_VFS_NEXT_SYS_ACL_ADD_PERM(handle, conn, permset, perm) ((handle)->vfs_next.ops.sys_acl_add_perm((handle)->vfs_next.handles.sys_acl_add_perm, (conn), (permset), (perm))) -#define SMB_VFS_NEXT_SYS_ACL_TO_TEXT(handle, conn, theacl, plen) ((handle)->vfs_next.ops.sys_acl_to_text((handle)->vfs_next.handles.sys_acl_to_text, (conn), (theacl), (plen))) -#define SMB_VFS_NEXT_SYS_ACL_INIT(handle, conn, count) ((handle)->vfs_next.ops.sys_acl_init((handle)->vfs_next.handles.sys_acl_init, (conn), (count))) -#define SMB_VFS_NEXT_SYS_ACL_CREATE_ENTRY(handle, conn, pacl, pentry) ((handle)->vfs_next.ops.sys_acl_create_entry((handle)->vfs_next.handles.sys_acl_create_entry, (conn), (pacl), (pentry))) -#define SMB_VFS_NEXT_SYS_ACL_SET_TAG_TYPE(handle, conn, entry, tagtype) ((handle)->vfs_next.ops.sys_acl_set_tag_type((handle)->vfs_next.handles.sys_acl_set_tag_type, (conn), (entry), (tagtype))) -#define SMB_VFS_NEXT_SYS_ACL_SET_QUALIFIER(handle, conn, entry, qual) ((handle)->vfs_next.ops.sys_acl_set_qualifier((handle)->vfs_next.handles.sys_acl_set_qualifier, (conn), (entry), (qual))) -#define SMB_VFS_NEXT_SYS_ACL_SET_PERMSET(handle, conn, entry, permset) ((handle)->vfs_next.ops.sys_acl_set_permset((handle)->vfs_next.handles.sys_acl_set_permset, (conn), (entry), (permset))) -#define SMB_VFS_NEXT_SYS_ACL_VALID(handle, conn, theacl) ((handle)->vfs_next.ops.sys_acl_valid((handle)->vfs_next.handles.sys_acl_valid, (conn), (theacl))) -#define SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, conn, name, acltype, theacl) ((handle)->vfs_next.ops.sys_acl_set_file((handle)->vfs_next.handles.sys_acl_set_file, (conn), (name), (acltype), (theacl))) +#define SMB_VFS_NEXT_SYS_ACL_CLEAR_PERMS(handle, permset) ((handle)->vfs_next.ops.sys_acl_clear_perms((handle)->vfs_next.handles.sys_acl_clear_perms, (permset))) +#define SMB_VFS_NEXT_SYS_ACL_ADD_PERM(handle, permset, perm) ((handle)->vfs_next.ops.sys_acl_add_perm((handle)->vfs_next.handles.sys_acl_add_perm, (permset), (perm))) +#define SMB_VFS_NEXT_SYS_ACL_TO_TEXT(handle, theacl, plen) ((handle)->vfs_next.ops.sys_acl_to_text((handle)->vfs_next.handles.sys_acl_to_text, (theacl), (plen))) +#define SMB_VFS_NEXT_SYS_ACL_INIT(handle, count) ((handle)->vfs_next.ops.sys_acl_init((handle)->vfs_next.handles.sys_acl_init, (count))) +#define SMB_VFS_NEXT_SYS_ACL_CREATE_ENTRY(handle, pacl, pentry) ((handle)->vfs_next.ops.sys_acl_create_entry((handle)->vfs_next.handles.sys_acl_create_entry, (pacl), (pentry))) +#define SMB_VFS_NEXT_SYS_ACL_SET_TAG_TYPE(handle, entry, tagtype) ((handle)->vfs_next.ops.sys_acl_set_tag_type((handle)->vfs_next.handles.sys_acl_set_tag_type, (entry), (tagtype))) +#define SMB_VFS_NEXT_SYS_ACL_SET_QUALIFIER(handle, entry, qual) ((handle)->vfs_next.ops.sys_acl_set_qualifier((handle)->vfs_next.handles.sys_acl_set_qualifier, (entry), (qual))) +#define SMB_VFS_NEXT_SYS_ACL_SET_PERMSET(handle, entry, permset) ((handle)->vfs_next.ops.sys_acl_set_permset((handle)->vfs_next.handles.sys_acl_set_permset, (entry), (permset))) +#define SMB_VFS_NEXT_SYS_ACL_VALID(handle, theacl) ((handle)->vfs_next.ops.sys_acl_valid((handle)->vfs_next.handles.sys_acl_valid, (theacl))) +#define SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype, theacl) ((handle)->vfs_next.ops.sys_acl_set_file((handle)->vfs_next.handles.sys_acl_set_file, (name), (acltype), (theacl))) #define SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, fd, theacl) ((handle)->vfs_next.ops.sys_acl_set_fd((handle)->vfs_next.handles.sys_acl_set_fd, (fsp), (fd), (theacl))) -#define SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, conn, path) ((handle)->vfs_next.ops.sys_acl_delete_def_file((handle)->vfs_next.handles.sys_acl_delete_def_file, (conn), (path))) -#define SMB_VFS_NEXT_SYS_ACL_GET_PERM(handle, conn, permset, perm) ((handle)->vfs_next.ops.sys_acl_get_perm((handle)->vfs_next.handles.sys_acl_get_perm, (conn), (permset), (perm))) -#define SMB_VFS_NEXT_SYS_ACL_FREE_TEXT(handle, conn, text) ((handle)->vfs_next.ops.sys_acl_free_text((handle)->vfs_next.handles.sys_acl_free_text, (conn), (text))) -#define SMB_VFS_NEXT_SYS_ACL_FREE_ACL(handle, conn, posix_acl) ((handle)->vfs_next.ops.sys_acl_free_acl((handle)->vfs_next.handles.sys_acl_free_acl, (conn), (posix_acl))) -#define SMB_VFS_NEXT_SYS_ACL_FREE_QUALIFIER(handle, conn, qualifier, tagtype) ((handle)->vfs_next.ops.sys_acl_free_qualifier((handle)->vfs_next.handles.sys_acl_free_qualifier, (conn), (qualifier), (tagtype))) +#define SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path) ((handle)->vfs_next.ops.sys_acl_delete_def_file((handle)->vfs_next.handles.sys_acl_delete_def_file, (path))) +#define SMB_VFS_NEXT_SYS_ACL_GET_PERM(handle, permset, perm) ((handle)->vfs_next.ops.sys_acl_get_perm((handle)->vfs_next.handles.sys_acl_get_perm, (permset), (perm))) +#define SMB_VFS_NEXT_SYS_ACL_FREE_TEXT(handle, text) ((handle)->vfs_next.ops.sys_acl_free_text((handle)->vfs_next.handles.sys_acl_free_text, (text))) +#define SMB_VFS_NEXT_SYS_ACL_FREE_ACL(handle, posix_acl) ((handle)->vfs_next.ops.sys_acl_free_acl((handle)->vfs_next.handles.sys_acl_free_acl, (posix_acl))) +#define SMB_VFS_NEXT_SYS_ACL_FREE_QUALIFIER(handle, qualifier, tagtype) ((handle)->vfs_next.ops.sys_acl_free_qualifier((handle)->vfs_next.handles.sys_acl_free_qualifier, (qualifier), (tagtype))) /* EA operations. */ -#define SMB_VFS_NEXT_GETXATTR(handle,conn,path,name,value,size) ((handle)->vfs_next.ops.getxattr((handle)->vfs_next.handles.getxattr,(conn),(path),(name),(value),(size))) -#define SMB_VFS_NEXT_LGETXATTR(handle,conn,path,name,value,size) ((handle)->vfs_next.ops.lgetxattr((handle)->vfs_next.handles.lgetxattr,(conn),(path),(name),(value),(size))) +#define SMB_VFS_NEXT_GETXATTR(handle,path,name,value,size) ((handle)->vfs_next.ops.getxattr((handle)->vfs_next.handles.getxattr,(path),(name),(value),(size))) +#define SMB_VFS_NEXT_LGETXATTR(handle,path,name,value,size) ((handle)->vfs_next.ops.lgetxattr((handle)->vfs_next.handles.lgetxattr,(path),(name),(value),(size))) #define SMB_VFS_NEXT_FGETXATTR(handle,fsp,fd,name,value,size) ((handle)->vfs_next.ops.fgetxattr((handle)->vfs_next.handles.fgetxattr,(fsp),(fd),(name),(value),(size))) -#define SMB_VFS_NEXT_LISTXATTR(handle,conn,path,list,size) ((handle)->vfs_next.ops.listxattr((handle)->vfs_next.handles.listxattr,(conn),(path),(list),(size))) -#define SMB_VFS_NEXT_LLISTXATTR(handle,conn,path,list,size) ((handle)->vfs_next.ops.llistxattr((handle)->vfs_next.handles.llistxattr,(conn),(path),(list),(size))) +#define SMB_VFS_NEXT_LISTXATTR(handle,path,list,size) ((handle)->vfs_next.ops.listxattr((handle)->vfs_next.handles.listxattr,(path),(list),(size))) +#define SMB_VFS_NEXT_LLISTXATTR(handle,path,list,size) ((handle)->vfs_next.ops.llistxattr((handle)->vfs_next.handles.llistxattr,(path),(list),(size))) #define SMB_VFS_NEXT_FLISTXATTR(handle,fsp,fd,list,size) ((handle)->vfs_next.ops.flistxattr((handle)->vfs_next.handles.flistxattr,(fsp),(fd),(list),(size))) -#define SMB_VFS_NEXT_REMOVEXATTR(handle,conn,path,name) ((handle)->vfs_next.ops.removexattr((handle)->vfs_next.handles.removexattr,(conn),(path),(name))) -#define SMB_VFS_NEXT_LREMOVEXATTR(handle,conn,path,name) ((handle)->vfs_next.ops.lremovexattr((handle)->vfs_next.handles.lremovexattr,(conn),(path),(name))) +#define SMB_VFS_NEXT_REMOVEXATTR(handle,path,name) ((handle)->vfs_next.ops.removexattr((handle)->vfs_next.handles.removexattr,(path),(name))) +#define SMB_VFS_NEXT_LREMOVEXATTR(handle,path,name) ((handle)->vfs_next.ops.lremovexattr((handle)->vfs_next.handles.lremovexattr,(path),(name))) #define SMB_VFS_NEXT_FREMOVEXATTR(handle,fsp,fd,name) ((handle)->vfs_next.ops.fremovexattr((handle)->vfs_next.handles.fremovexattr,(fsp),(fd),(name))) -#define SMB_VFS_NEXT_SETXATTR(handle,conn,path,name,value,size,flags) ((handle)->vfs_next.ops.setxattr((handle)->vfs_next.handles.setxattr,(conn),(path),(name),(value),(size),(flags))) -#define SMB_VFS_NEXT_LSETXATTR(handle,conn,path,name,value,size,flags) ((handle)->vfs_next.ops.lsetxattr((handle)->vfs_next.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags))) +#define SMB_VFS_NEXT_SETXATTR(handle,path,name,value,size,flags) ((handle)->vfs_next.ops.setxattr((handle)->vfs_next.handles.setxattr,(path),(name),(value),(size),(flags))) +#define SMB_VFS_NEXT_LSETXATTR(handle,path,name,value,size,flags) ((handle)->vfs_next.ops.lsetxattr((handle)->vfs_next.handles.lsetxattr,(path),(name),(value),(size),(flags))) #define SMB_VFS_NEXT_FSETXATTR(handle,fsp,fd,name,value,size,flags) ((handle)->vfs_next.ops.fsetxattr((handle)->vfs_next.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags))) /* AIO operations. */ diff --git a/source/lib/afs.c b/source/lib/afs.c index 8a304adcf0c..ea83fdebc25 100644 --- a/source/lib/afs.c +++ b/source/lib/afs.c @@ -211,6 +211,7 @@ char *afs_createtoken_str(const char *username, const char *cell) BOOL afs_login(connection_struct *conn) { + extern userdom_struct current_user_info; extern struct current_user current_user; DATA_BLOB ticket; pstring afs_username; @@ -222,7 +223,11 @@ BOOL afs_login(connection_struct *conn) struct ClearToken ct; pstrcpy(afs_username, lp_afs_username_map()); - standard_sub_conn(conn, afs_username, sizeof(afs_username)); + standard_sub_advanced(SNUM(conn), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + afs_username, sizeof(afs_username)); user_sid = ¤t_user.nt_user_token->user_sids[0]; pstring_sub(afs_username, "%s", sid_string_static(user_sid)); diff --git a/source/lib/data_blob.c b/source/lib/data_blob.c index 73e5357df86..c7eadc1acfb 100644 --- a/source/lib/data_blob.c +++ b/source/lib/data_blob.c @@ -102,7 +102,7 @@ void data_blob_free(DATA_BLOB *d) Clear a DATA_BLOB's contents *******************************************************************/ -static void data_blob_clear(DATA_BLOB *d) +void data_blob_clear(DATA_BLOB *d) { if (d->data) { memset(d->data, 0, d->length); diff --git a/source/lib/sharesec.c b/source/lib/sharesec.c index 8105d5c37a6..e3216aa4594 100644 --- a/source/lib/sharesec.c +++ b/source/lib/sharesec.c @@ -108,7 +108,8 @@ SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, size_t *psize, uint32 def Pull a security descriptor from the share tdb. ********************************************************************/ -SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize) +SEC_DESC *get_share_security( TALLOC_CTX *ctx, const char *servicename, + size_t *psize) { prs_struct ps; fstring key; @@ -122,12 +123,13 @@ SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize) /* Fetch security descriptor from tdb */ - slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum)); + slprintf(key, sizeof(key)-1, "SECDESC/%s", servicename); if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 || !sec_io_desc("get_share_security", &psd, &ps, 1)) { - DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) )); + DEBUG(4, ("get_share_security: using default secdesc for %s\n", + servicename)); return get_share_security_default(ctx, psize, GENERIC_ALL_ACCESS); } @@ -143,7 +145,7 @@ SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize) Store a security descriptor in the share db. ********************************************************************/ -BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd) +BOOL set_share_security(const char *share_name, SEC_DESC *psd) { prs_struct ps; TALLOC_CTX *mem_ctx = NULL; @@ -186,24 +188,56 @@ out: Delete a security descriptor. ********************************************************************/ -BOOL delete_share_security(int snum) +BOOL delete_share_security(const struct share_params *params) { TDB_DATA kbuf; fstring key; - slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum)); + slprintf(key, sizeof(key)-1, "SECDESC/%s", + lp_servicename(params->service)); kbuf.dptr = key; kbuf.dsize = strlen(key)+1; - if (tdb_delete(share_tdb, kbuf) != 0) { + if (tdb_trans_delete(share_tdb, kbuf) != 0) { DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n", - lp_servicename(snum) )); + lp_servicename(params->service) )); return False; } return True; } +/******************************************************************* + Can this user access with share with the required permissions ? +********************************************************************/ + +BOOL share_access_check(const NT_USER_TOKEN *token, const char *sharename, + uint32 desired_access) +{ + uint32 granted; + NTSTATUS status; + TALLOC_CTX *mem_ctx = NULL; + SEC_DESC *psd = NULL; + size_t sd_size; + BOOL ret = True; + + if (!(mem_ctx = talloc_init("share_access_check"))) { + return False; + } + + psd = get_share_security(mem_ctx, sharename, &sd_size); + + if (!psd) { + TALLOC_FREE(mem_ctx); + return True; + } + + ret = se_access_check(psd, token, desired_access, &granted, &status); + + talloc_destroy(mem_ctx); + return ret; +} + /*************************************************************************** Parse the contents of an acl string from a usershare file. ***************************************************************************/ diff --git a/source/lib/substitute.c b/source/lib/substitute.c index 3e556cebd1e..25a6a2c4c82 100644 --- a/source/lib/substitute.c +++ b/source/lib/substitute.c @@ -415,11 +415,12 @@ static const char *automount_server(const char *user_name) don't allow expansions. ****************************************************************************/ -void standard_sub_basic(const char *smb_name, char *str, size_t len) +void standard_sub_basic(const char *smb_name, const char *domain_name, + char *str, size_t len) { char *s; - if ( (s = alloc_sub_basic( smb_name, str )) != NULL ) { + if ( (s = alloc_sub_basic( smb_name, domain_name, str )) != NULL ) { strncpy( str, s, len ); } @@ -432,11 +433,12 @@ void standard_sub_basic(const char *smb_name, char *str, size_t len) This function will return an allocated string that have to be freed. ****************************************************************************/ -char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *str) +char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, + const char *domain_name, const char *str) { char *a, *t; - if ( (a = alloc_sub_basic(smb_name, str)) == NULL ) { + if ( (a = alloc_sub_basic(smb_name, domain_name, str)) == NULL ) { return NULL; } t = talloc_strdup(mem_ctx, a); @@ -447,7 +449,8 @@ char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *st /**************************************************************************** ****************************************************************************/ -char *alloc_sub_basic(const char *smb_name, const char *str) +char *alloc_sub_basic(const char *smb_name, const char *domain_name, + const char *str) { char *b, *p, *s, *r, *a_string; fstring pidstr; @@ -463,7 +466,7 @@ char *alloc_sub_basic(const char *smb_name, const char *str) a_string = SMB_STRDUP(str); if (a_string == NULL) { - DEBUG(0, ("alloc_sub_specified: Out of memory!\n")); + DEBUG(0, ("alloc_sub_basic: Out of memory!\n")); return NULL; } @@ -490,7 +493,7 @@ char *alloc_sub_basic(const char *smb_name, const char *str) } break; case 'D' : - r = strdup_upper(current_user_info.domain); + r = strdup_upper(domain_name); if (r == NULL) { goto error; } @@ -580,32 +583,20 @@ char *talloc_sub_specified(TALLOC_CTX *mem_ctx, uid_t uid, gid_t gid) { - char *a, *t; - a = alloc_sub_specified(input_string, username, domain, uid, gid); - if (!a) { + char *a_string; + char *ret_string = NULL; + char *b, *p, *s; + TALLOC_CTX *tmp_ctx; + + if (!(tmp_ctx = talloc_new(mem_ctx))) { + DEBUG(0, ("talloc_new failed\n")); return NULL; } - t = talloc_strdup(mem_ctx, a); - SAFE_FREE(a); - return t; -} -/**************************************************************************** -****************************************************************************/ - -char *alloc_sub_specified(const char *input_string, - const char *username, - const char *domain, - uid_t uid, - gid_t gid) -{ - char *a_string, *ret_string; - char *b, *p, *s; - - a_string = SMB_STRDUP(input_string); + a_string = talloc_strdup(tmp_ctx, input_string); if (a_string == NULL) { - DEBUG(0, ("alloc_sub_specified: Out of memory!\n")); - return NULL; + DEBUG(0, ("talloc_sub_specified: Out of memory!\n")); + goto done; } for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) { @@ -614,30 +605,42 @@ char *alloc_sub_specified(const char *input_string, switch (*(p+1)) { case 'U' : - a_string = realloc_string_sub(a_string, "%U", username); + a_string = talloc_string_sub( + tmp_ctx, a_string, "%U", username); break; case 'u' : - a_string = realloc_string_sub(a_string, "%u", username); + a_string = talloc_string_sub( + tmp_ctx, a_string, "%u", username); break; case 'G' : if (gid != -1) { - a_string = realloc_string_sub(a_string, "%G", gidtoname(gid)); + a_string = talloc_string_sub( + tmp_ctx, a_string, "%G", + gidtoname(gid)); } else { - a_string = realloc_string_sub(a_string, "%G", "NO_GROUP"); + a_string = talloc_string_sub( + tmp_ctx, a_string, + "%G", "NO_GROUP"); } break; case 'g' : if (gid != -1) { - a_string = realloc_string_sub(a_string, "%g", gidtoname(gid)); + a_string = talloc_string_sub( + tmp_ctx, a_string, "%g", + gidtoname(gid)); } else { - a_string = realloc_string_sub(a_string, "%g", "NO_GROUP"); + a_string = talloc_string_sub( + tmp_ctx, a_string, "%g", "NO_GROUP"); } break; case 'D' : - a_string = realloc_string_sub(a_string, "%D", domain); + a_string = talloc_string_sub(tmp_ctx, a_string, + "%D", domain); break; case 'N' : - a_string = realloc_string_sub(a_string, "%N", automount_server(username)); + a_string = talloc_string_sub( + tmp_ctx, a_string, "%N", + automount_server(username)); break; default: break; @@ -645,42 +648,27 @@ char *alloc_sub_specified(const char *input_string, p++; if (a_string == NULL) { - return NULL; + goto done; } } - ret_string = alloc_sub_basic(username, a_string); - SAFE_FREE(a_string); - return ret_string; -} + /* Watch out, using "mem_ctx" here, so all intermediate stuff goes + * away with the TALLOC_FREE(tmp_ctx) further down. */ -/**************************************************************************** -****************************************************************************/ + ret_string = talloc_sub_basic(mem_ctx, username, domain, a_string); -char *talloc_sub_advanced(TALLOC_CTX *mem_ctx, - int snum, - const char *user, - const char *connectpath, - gid_t gid, - const char *smb_name, - const char *str) -{ - char *a, *t; - a = alloc_sub_advanced(snum, user, connectpath, gid, smb_name, str); - if (!a) { - return NULL; - } - t = talloc_strdup(mem_ctx, a); - SAFE_FREE(a); - return t; + done: + TALLOC_FREE(tmp_ctx); + return ret_string; } /**************************************************************************** ****************************************************************************/ -char *alloc_sub_advanced(int snum, const char *user, - const char *connectpath, gid_t gid, - const char *smb_name, const char *str) +static char *alloc_sub_advanced(const char *servicename, const char *user, + const char *connectpath, gid_t gid, + const char *smb_name, const char *domain_name, + const char *str) { char *a_string, *ret_string; char *b, *p, *s, *h; @@ -707,7 +695,7 @@ char *alloc_sub_advanced(int snum, const char *user, a_string = realloc_string_sub(a_string, "%P", connectpath); break; case 'S': - a_string = realloc_string_sub(a_string, "%S", lp_servicename(snum)); + a_string = realloc_string_sub(a_string, "%S", servicename); break; case 'g': a_string = realloc_string_sub(a_string, "%g", gidtoname(gid)); @@ -724,7 +712,8 @@ char *alloc_sub_advanced(int snum, const char *user, * "path =" string in [homes] and so needs the * service name, not the username. */ case 'p': - a_string = realloc_string_sub(a_string, "%p", automount_path(lp_servicename(snum))); + a_string = realloc_string_sub(a_string, "%p", + automount_path(servicename)); break; default: @@ -737,67 +726,43 @@ char *alloc_sub_advanced(int snum, const char *user, } } - ret_string = alloc_sub_basic(smb_name, a_string); + ret_string = alloc_sub_basic(smb_name, domain_name, a_string); SAFE_FREE(a_string); return ret_string; } -/**************************************************************************** - Do some standard substitutions in a string. -****************************************************************************/ +/* + * This obviously is inefficient and needs to be merged into + * alloc_sub_advanced... + */ -void standard_sub_conn(connection_struct *conn, char *str, size_t len) +char *talloc_sub_advanced(TALLOC_CTX *mem_ctx, + const char *servicename, const char *user, + const char *connectpath, gid_t gid, + const char *smb_name, const char *domain_name, + const char *str) { - char *s; - - s = alloc_sub_advanced(SNUM(conn), conn->user, conn->connectpath, - conn->gid, smb_user_name, str); + char *a, *t; - if ( s ) { - strncpy( str, s, len ); - SAFE_FREE( s ); + if (!(a = alloc_sub_advanced(servicename, user, connectpath, gid, + smb_name, domain_name, str))) { + return NULL; } + t = talloc_strdup(mem_ctx, a); + SAFE_FREE(a); + return t; } -/**************************************************************************** -****************************************************************************/ - -char *talloc_sub_conn(TALLOC_CTX *mem_ctx, connection_struct *conn, const char *str) -{ - return talloc_sub_advanced(mem_ctx, SNUM(conn), conn->user, - conn->connectpath, conn->gid, - smb_user_name, str); -} - -/**************************************************************************** -****************************************************************************/ - -char *alloc_sub_conn(connection_struct *conn, const char *str) -{ - return alloc_sub_advanced(SNUM(conn), conn->user, conn->connectpath, - conn->gid, smb_user_name, str); -} - -/**************************************************************************** - Like standard_sub but by snum. -****************************************************************************/ -void standard_sub_snum(int snum, char *str, size_t len) +void standard_sub_advanced(const char *servicename, const char *user, + const char *connectpath, gid_t gid, + const char *smb_name, const char *domain_name, + char *str, size_t len) { - static uid_t cached_uid = -1; - static fstring cached_user; char *s; - /* calling uidtoname() on every substitute would be too expensive, so - we cache the result here as nearly every call is for the same uid */ - - if (cached_uid != current_user.ut.uid) { - fstrcpy(cached_user, uidtoname(current_user.ut.uid)); - cached_uid = current_user.ut.uid; - } - - s = alloc_sub_advanced(snum, cached_user, "", current_user.ut.gid, - smb_user_name, str); + s = alloc_sub_advanced(servicename, user, connectpath, + gid, smb_name, domain_name, str); if ( s ) { strncpy( str, s, len ); diff --git a/source/lib/util.c b/source/lib/util.c index dde637cf703..19c6cab5b28 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -1059,9 +1059,11 @@ void *realloc_array(void *p, size_t el_size, unsigned int count, BOOL free_old_o ****************************************************************************/ void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size, - void *element, void **array, uint32 *num_elements, + void *element, void *_array, uint32 *num_elements, ssize_t *array_size) { + void **array = (void **)_array; + if (*array_size < 0) { return; } diff --git a/source/lib/util_str.c b/source/lib/util_str.c index 08be2cd2a11..fc13b75cc57 100644 --- a/source/lib/util_str.c +++ b/source/lib/util_str.c @@ -33,7 +33,7 @@ * Internal function to get the next token from a string, return False if none * found. Handles double-quotes. This is the work horse function called by * next_token() and next_token_no_ltrim(). - * + * * Based on a routine by GJC@VILLAGE.COM. * Extensively modified by Andrew.Tridgell@anu.edu.au */ @@ -59,8 +59,8 @@ static BOOL next_token_internal(const char **ptr, /* find the first non sep char, if left-trimming is requested */ if (ltrim) { - while (*s && strchr_m(sep,*s)) - s++; + while (*s && strchr_m(sep,*s)) + s++; } /* nothing left? */ @@ -1943,13 +1943,14 @@ int str_list_count( const char **list ) for the work *****************************************************************************/ -BOOL str_list_sub_basic( char **list, const char *smb_name ) +BOOL str_list_sub_basic( char **list, const char *smb_name, + const char *domain_name ) { char *s, *tmpstr; while ( *list ) { s = *list; - tmpstr = alloc_sub_basic(smb_name, s); + tmpstr = alloc_sub_basic(smb_name, domain_name, s); if ( !tmpstr ) { DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n")); return False; diff --git a/source/libmsrpc/cac_lsarpc.c b/source/libmsrpc/cac_lsarpc.c index eb1a9613734..2e3eb276d5a 100644 --- a/source/libmsrpc/cac_lsarpc.c +++ b/source/libmsrpc/cac_lsarpc.c @@ -1,3 +1,4 @@ + /* * Unix SMB/CIFS implementation. * MS-RPC client library implementation (LSA pipe) @@ -21,1061 +22,1212 @@ #include "libmsrpc.h" #include "libsmb_internal.h" -int cac_LsaOpenPolicy(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaOpenPolicy *op) { - SMBCSRV *srv = NULL; - POLICY_HND *policy = NULL; - struct rpc_pipe_client *pipe_hnd = NULL; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!mem_ctx || !op) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - op->out.pol = NULL; - - srv = cac_GetServer(hnd); - if(!srv) { - hnd->status = NT_STATUS_INVALID_CONNECTION; - return CAC_FAILURE; - } - - /*see if there is already an active session on this pipe, if not then open one*/ - if(!hnd->_internal.pipes[PI_LSARPC]) { - pipe_hnd = cli_rpc_pipe_open_noauth(&(srv->cli), PI_LSARPC, &(hnd->status)); - - if(!pipe_hnd) { - hnd->status = NT_STATUS_UNSUCCESSFUL; - return CAC_FAILURE; - } - - hnd->_internal.pipes[PI_LSARPC] = True; - } - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - policy = TALLOC_P(mem_ctx, POLICY_HND); - if(!policy) { - errno = ENOMEM; - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - /*need to make sure that our nt status is good otherwise check might fail below*/ - hnd->status = NT_STATUS_OK; - - if(hnd->_internal.srv_level >= SRV_WIN_2K) { - - /*try using open_policy2, if this fails try again in next block using open_policy, if that works then adjust hnd->_internal.srv_level*/ - - /*we shouldn't need to modify the access mask to make it work here*/ - hnd->status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, op->in.security_qos, op->in.access, policy); - - } - - if(hnd->_internal.srv_level < SRV_WIN_2K || !NT_STATUS_IS_OK(hnd->status)) { - hnd->status = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, op->in.security_qos, op->in.access, policy); - - if(hnd->_internal.srv_level > SRV_WIN_NT4 && NT_STATUS_IS_OK(hnd->status)) { - /*change the server level to 1*/ - hnd->_internal.srv_level = SRV_WIN_NT4; - } - - } - - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } - - op->out.pol = policy; - - return CAC_SUCCESS; +int cac_LsaOpenPolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaOpenPolicy *op ) +{ + SMBCSRV *srv = NULL; + POLICY_HND *policy = NULL; + struct rpc_pipe_client *pipe_hnd = NULL; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !mem_ctx || !op ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + op->out.pol = NULL; + + srv = cac_GetServer( hnd ); + if ( !srv ) { + hnd->status = NT_STATUS_INVALID_CONNECTION; + return CAC_FAILURE; + } + + /*see if there is already an active session on this pipe, if not then open one */ + if ( !hnd->_internal.pipes[PI_LSARPC] ) { + pipe_hnd = + cli_rpc_pipe_open_noauth( srv->cli, PI_LSARPC, + &hnd->status ); + + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_UNSUCCESSFUL; + return CAC_FAILURE; + } + + hnd->_internal.pipes[PI_LSARPC] = True; + } + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + policy = TALLOC_P( mem_ctx, POLICY_HND ); + if ( !policy ) { + errno = ENOMEM; + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + /*need to make sure that our nt status is good otherwise check might fail below */ + hnd->status = NT_STATUS_OK; + + if ( hnd->_internal.srv_level >= SRV_WIN_2K ) { + + /*try using open_policy2, if this fails try again in next block using open_policy, if that works then adjust hnd->_internal.srv_level */ + + /*we shouldn't need to modify the access mask to make it work here */ + hnd->status = + rpccli_lsa_open_policy2( pipe_hnd, mem_ctx, + op->in.security_qos, + op->in.access, policy ); + + } + + if ( hnd->_internal.srv_level < SRV_WIN_2K + || !NT_STATUS_IS_OK( hnd->status ) ) { + hnd->status = + rpccli_lsa_open_policy( pipe_hnd, mem_ctx, + op->in.security_qos, + op->in.access, policy ); + + if ( hnd->_internal.srv_level > SRV_WIN_NT4 + && NT_STATUS_IS_OK( hnd->status ) ) { + /*change the server level to 1 */ + hnd->_internal.srv_level = SRV_WIN_NT4; + } + + } + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } + + op->out.pol = policy; + + return CAC_SUCCESS; } -int cac_LsaClosePolicy(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *pol) { +int cac_LsaClosePolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + POLICY_HND * pol ) +{ + + struct rpc_pipe_client *pipe_hnd = NULL; - struct rpc_pipe_client *pipe_hnd = NULL; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd) - return CAC_FAILURE; - - if(!pol) - return CAC_SUCCESS; /*if the policy handle doesnt exist then it's already closed*/ + if ( !pol ) + return CAC_SUCCESS; /*if the policy handle doesnt exist then it's already closed */ - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_lsa_close(pipe_hnd, mem_ctx, pol); + hnd->status = rpccli_lsa_Close( pipe_hnd, mem_ctx, pol ); - TALLOC_FREE(pol); + TALLOC_FREE( pol ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_LsaGetNamesFromSids(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaGetNamesFromSids *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - int result = -1; - - int i; - - /*buffers for outputs*/ - char **domains = NULL; - char **names = NULL; - uint32 *types = NULL; - - CacSidInfo *sids_out = NULL; - DOM_SID *unknown_out = NULL; - int num_unknown = 0; - - int num_sids; - - int found_idx; - int unknown_idx; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!mem_ctx || !op || !op->in.pol || !op->in.sids) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - num_sids = op->in.num_sids; - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - - - /*now actually lookup the names*/ - hnd->status = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, op->in.pol, op->in.num_sids, - op->in.sids, &domains, &names, &types); - - if(NT_STATUS_IS_OK(hnd->status)) { - /*this is the easy part, just make the out.sids array*/ - sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, num_sids); - if(!sids_out) { - errno = ENOMEM; - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - for(i = 0; i < num_sids; i++) { - sids_out[i].sid = op->in.sids[i]; - sids_out[i].name = names[i]; - sids_out[i].domain = domains[i]; - } - - result = CAC_SUCCESS; - } - else if(NT_STATUS_V(hnd->status) == NT_STATUS_V(STATUS_SOME_UNMAPPED)) { - /*first find out how many couldn't be looked up*/ - - for(i = 0; i < num_sids; i++) { - if(names[i] == NULL) { - num_unknown++; - } - } - - if( num_unknown >= num_sids) { - hnd->status = NT_STATUS_UNSUCCESSFUL; - return CAC_FAILURE; - } - - sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, (num_sids - num_unknown)); - if(!sids_out) { - errno = ENOMEM; - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - unknown_out = TALLOC_ARRAY(mem_ctx, DOM_SID, num_unknown); - if(!unknown_out) { - errno = ENOMEM; - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - found_idx = unknown_idx = 0; - - /*now we can actually do the real work*/ - for(i = 0; i < num_sids; i++) { - if(names[i] != NULL) { - sids_out[found_idx].sid = op->in.sids[i]; - sids_out[found_idx].name = names[i]; - sids_out[found_idx].domain = domains[i]; - - found_idx++; - } - else { /*then this one didnt work out*/ - unknown_out[unknown_idx] = op->in.sids[i]; - - unknown_idx++; - } - } - - result = CAC_PARTIAL_SUCCESS; - } - else { /*then it failed for some reason*/ - return CAC_FAILURE; - } - - op->out.num_found = num_sids - num_unknown; - op->out.sids = sids_out; - op->out.unknown = unknown_out; - - return result; - +int cac_LsaGetNamesFromSids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaGetNamesFromSids *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + int result = -1; + + int i; + + /*buffers for outputs */ + char **domains = NULL; + char **names = NULL; + enum lsa_SidType *types = NULL; + + CacSidInfo *sids_out = NULL; + DOM_SID *unknown_out = NULL; + int num_unknown = 0; + + int num_sids; + + int found_idx; + int unknown_idx; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !mem_ctx || !op || !op->in.pol || !op->in.sids ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + num_sids = op->in.num_sids; + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + + + /*now actually lookup the names */ + hnd->status = + rpccli_lsa_lookup_sids( pipe_hnd, mem_ctx, op->in.pol, + op->in.num_sids, op->in.sids, + &domains, &names, &types ); + + if ( NT_STATUS_IS_OK( hnd->status ) ) { + /*this is the easy part, just make the out.sids array */ + sids_out = TALLOC_ARRAY( mem_ctx, CacSidInfo, num_sids ); + if ( !sids_out ) { + errno = ENOMEM; + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + for ( i = 0; i < num_sids; i++ ) { + sids_out[i].sid = op->in.sids[i]; + sids_out[i].name = names[i]; + sids_out[i].domain = domains[i]; + } + + result = CAC_SUCCESS; + } else if ( NT_STATUS_V( hnd->status ) == + NT_STATUS_V( STATUS_SOME_UNMAPPED ) ) { + /*first find out how many couldn't be looked up */ + + for ( i = 0; i < num_sids; i++ ) { + if ( names[i] == NULL ) { + num_unknown++; + } + } + + if ( num_unknown >= num_sids ) { + hnd->status = NT_STATUS_UNSUCCESSFUL; + return CAC_FAILURE; + } + + sids_out = + TALLOC_ARRAY( mem_ctx, CacSidInfo, + ( num_sids - num_unknown ) ); + if ( !sids_out ) { + errno = ENOMEM; + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + unknown_out = TALLOC_ARRAY( mem_ctx, DOM_SID, num_unknown ); + if ( !unknown_out ) { + errno = ENOMEM; + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + found_idx = unknown_idx = 0; + + /*now we can actually do the real work */ + for ( i = 0; i < num_sids; i++ ) { + if ( names[i] != NULL ) { + sids_out[found_idx].sid = op->in.sids[i]; + sids_out[found_idx].name = names[i]; + sids_out[found_idx].domain = domains[i]; + + found_idx++; + } else { /*then this one didnt work out */ + unknown_out[unknown_idx] = op->in.sids[i]; + + unknown_idx++; + } + } + + result = CAC_PARTIAL_SUCCESS; + } else { /*then it failed for some reason */ + return CAC_FAILURE; + } + + op->out.num_found = num_sids - num_unknown; + op->out.sids = sids_out; + op->out.unknown = unknown_out; + + return result; + } -int cac_LsaGetSidsFromNames(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaGetSidsFromNames *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - int result = -1; - - int i; - - /*buffers for outputs*/ - DOM_SID *sids = NULL; - uint32 *types = NULL; - - CacSidInfo *sids_out = NULL; - char **unknown_out = NULL; - int num_unknown = 0; - - int num_names; - - int found_idx = 0; - int unknown_idx = 0; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!mem_ctx || !op || !op->in.pol || !op->in.names) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - num_names = op->in.num_names; - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - - /*now actually lookup the names*/ - hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, num_names, - (const char **)op->in.names, NULL, &sids, &types); - - if(NT_STATUS_IS_OK(hnd->status)) { - /*this is the easy part, just make the out.sids array*/ - sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, num_names); - if(!sids_out) { - errno = ENOMEM; - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - for(i = 0; i < num_names; i++) { - sids_out[i].sid = sids[i]; - sids_out[i].name = talloc_strdup(mem_ctx, op->in.names[i]); - sids_out[i].domain = NULL; - } - - result = CAC_SUCCESS; - } - else if(NT_STATUS_V(hnd->status) == NT_STATUS_V(STATUS_SOME_UNMAPPED)) { - /*first find out how many couldn't be looked up*/ - - for(i = 0; i < num_names; i++) { - if(types[i] == SID_NAME_UNKNOWN) { - num_unknown++; - } - } - - if( num_unknown >= num_names) { - hnd->status = NT_STATUS_UNSUCCESSFUL; - return CAC_FAILURE; - } - - sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, (num_names - num_unknown)); - if(!sids_out) { - errno = ENOMEM; - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - unknown_out = TALLOC_ARRAY(mem_ctx, char *, num_unknown); - if(!unknown_out) { - errno = ENOMEM; - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - unknown_idx = found_idx = 0; - - /*now we can actually do the real work*/ - for(i = 0; i < num_names; i++) { - if(types[i] != SID_NAME_UNKNOWN) { - sids_out[found_idx].sid = sids[i]; - sids_out[found_idx].name = talloc_strdup(mem_ctx, op->in.names[i]); - sids_out[found_idx].domain = NULL; - - found_idx++; - } - else { /*then this one didnt work out*/ - unknown_out[unknown_idx] = talloc_strdup(mem_ctx, op->in.names[i]); - - unknown_idx++; - } - } - - result = CAC_PARTIAL_SUCCESS; - } - else { /*then it failed for some reason*/ - return CAC_FAILURE; - } - - op->out.num_found = num_names - num_unknown; - op->out.sids = sids_out; - op->out.unknown = unknown_out; - - return result; - +int cac_LsaGetSidsFromNames( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaGetSidsFromNames *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + int result = -1; + + int i; + + /*buffers for outputs */ + DOM_SID *sids = NULL; + enum lsa_SidType *types = NULL; + + CacSidInfo *sids_out = NULL; + char **unknown_out = NULL; + int num_unknown = 0; + + int num_names; + + int found_idx = 0; + int unknown_idx = 0; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !mem_ctx || !op || !op->in.pol || !op->in.names ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + num_names = op->in.num_names; + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + + /*now actually lookup the names */ + hnd->status = + rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, + num_names, + ( const char ** ) op->in.names, NULL, + &sids, &types ); + + if ( NT_STATUS_IS_OK( hnd->status ) ) { + /*this is the easy part, just make the out.sids array */ + sids_out = TALLOC_ARRAY( mem_ctx, CacSidInfo, num_names ); + if ( !sids_out ) { + errno = ENOMEM; + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + for ( i = 0; i < num_names; i++ ) { + sids_out[i].sid = sids[i]; + sids_out[i].name = + talloc_strdup( mem_ctx, op->in.names[i] ); + sids_out[i].domain = NULL; + } + + result = CAC_SUCCESS; + } else if ( NT_STATUS_V( hnd->status ) == + NT_STATUS_V( STATUS_SOME_UNMAPPED ) ) { + /*first find out how many couldn't be looked up */ + + for ( i = 0; i < num_names; i++ ) { + if ( types[i] == SID_NAME_UNKNOWN ) { + num_unknown++; + } + } + + if ( num_unknown >= num_names ) { + hnd->status = NT_STATUS_UNSUCCESSFUL; + return CAC_FAILURE; + } + + sids_out = + TALLOC_ARRAY( mem_ctx, CacSidInfo, + ( num_names - num_unknown ) ); + if ( !sids_out ) { + errno = ENOMEM; + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + unknown_out = TALLOC_ARRAY( mem_ctx, char *, num_unknown ); + if ( !unknown_out ) { + errno = ENOMEM; + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + unknown_idx = found_idx = 0; + + /*now we can actually do the real work */ + for ( i = 0; i < num_names; i++ ) { + if ( types[i] != SID_NAME_UNKNOWN ) { + sids_out[found_idx].sid = sids[i]; + sids_out[found_idx].name = + talloc_strdup( mem_ctx, + op->in.names[i] ); + sids_out[found_idx].domain = NULL; + + found_idx++; + } else { /*then this one didnt work out */ + unknown_out[unknown_idx] = + talloc_strdup( mem_ctx, + op->in.names[i] ); + + unknown_idx++; + } + } + + result = CAC_PARTIAL_SUCCESS; + } else { /*then it failed for some reason */ + return CAC_FAILURE; + } + + op->out.num_found = num_names - num_unknown; + op->out.sids = sids_out; + op->out.unknown = unknown_out; + + return result; + } -int cac_LsaFetchSid(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaFetchSid *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - int result = -1; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!mem_ctx || !op || !op->in.pol) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - op->out.local_sid = NULL; - op->out.domain_sid = NULL; - - if( (op->in.info_class & CAC_LOCAL_INFO) == CAC_LOCAL_INFO) { - DOM_SID *local_sid = NULL; - char *dom_name = NULL; - - hnd->status = rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx, op->in.pol, CAC_LOCAL_INFO, &dom_name, &local_sid); - - if(!NT_STATUS_IS_OK(hnd->status)) { - result = CAC_FAILURE; - goto domain; - } - - op->out.local_sid = talloc(mem_ctx, CacSidInfo); - if(!op->out.local_sid) { - hnd->status = NT_STATUS_NO_MEMORY; - result = CAC_FAILURE; - goto domain; - } - - op->out.local_sid->domain = dom_name; - - sid_copy(&op->out.local_sid->sid, local_sid); - TALLOC_FREE(local_sid); - } - -domain: - - if( (op->in.info_class & CAC_DOMAIN_INFO) == CAC_DOMAIN_INFO) { - DOM_SID *domain_sid; - char *dom_name; - - hnd->status = rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx, op->in.pol, CAC_DOMAIN_INFO, &dom_name, &domain_sid); - if(!NT_STATUS_IS_OK(hnd->status)) { - /*if we succeeded above, report partial success*/ - result = CAC_FAILURE; - goto done; - } - else if(result == CAC_FAILURE) { - /*if we failed above but succeded here then report partial success*/ - result = CAC_PARTIAL_SUCCESS; - } - - op->out.domain_sid = talloc(mem_ctx, CacSidInfo); - if(!op->out.domain_sid) { - hnd->status = NT_STATUS_NO_MEMORY; - result = CAC_FAILURE; - goto done; - } - - op->out.domain_sid->domain = dom_name; - sid_copy(&op->out.domain_sid->sid, domain_sid); - TALLOC_FREE(domain_sid); - } - -done: - return result; +int cac_LsaFetchSid( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaFetchSid *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + int result = -1; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !mem_ctx || !op || !op->in.pol ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + op->out.local_sid = NULL; + op->out.domain_sid = NULL; + + if ( ( op->in.info_class & CAC_LOCAL_INFO ) == CAC_LOCAL_INFO ) { + DOM_SID *local_sid = NULL; + char *dom_name = NULL; + + hnd->status = + rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx, + op->in.pol, + CAC_LOCAL_INFO, + &dom_name, &local_sid ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + result = CAC_FAILURE; + goto domain; + } + + op->out.local_sid = talloc( mem_ctx, CacSidInfo ); + if ( !op->out.local_sid ) { + hnd->status = NT_STATUS_NO_MEMORY; + result = CAC_FAILURE; + goto domain; + } + + op->out.local_sid->domain = dom_name; + + sid_copy( &op->out.local_sid->sid, local_sid ); + TALLOC_FREE( local_sid ); + } + + domain: + + if ( ( op->in.info_class & CAC_DOMAIN_INFO ) == CAC_DOMAIN_INFO ) { + DOM_SID *domain_sid; + char *dom_name; + + hnd->status = + rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx, + op->in.pol, + CAC_DOMAIN_INFO, + &dom_name, + &domain_sid ); + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + /*if we succeeded above, report partial success */ + result = CAC_FAILURE; + goto done; + } else if ( result == CAC_FAILURE ) { + /*if we failed above but succeded here then report partial success */ + result = CAC_PARTIAL_SUCCESS; + } + + op->out.domain_sid = talloc( mem_ctx, CacSidInfo ); + if ( !op->out.domain_sid ) { + hnd->status = NT_STATUS_NO_MEMORY; + result = CAC_FAILURE; + goto done; + } + + op->out.domain_sid->domain = dom_name; + sid_copy( &op->out.domain_sid->sid, domain_sid ); + TALLOC_FREE( domain_sid ); + } + + done: + return result; } -int cac_LsaQueryInfoPolicy(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaQueryInfoPolicy *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - char *domain_name = NULL; - char *dns_name = NULL; - char *forest_name = NULL; - struct GUID *domain_guid = NULL; - DOM_SID *domain_sid = NULL; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.pol) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - /*only works if info_class parm is 12*/ - hnd->status = rpccli_lsa_query_info_policy2(pipe_hnd, mem_ctx, op->in.pol, 12, - &domain_name, &dns_name, &forest_name, &domain_guid, &domain_sid); - - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } - - op->out.domain_name = domain_name; - op->out.dns_name = dns_name; - op->out.forest_name = forest_name; - op->out.domain_guid = domain_guid; - op->out.domain_sid = domain_sid; - - return CAC_SUCCESS; +int cac_LsaQueryInfoPolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaQueryInfoPolicy *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + char *domain_name = NULL; + char *dns_name = NULL; + char *forest_name = NULL; + struct GUID *domain_guid = NULL; + DOM_SID *domain_sid = NULL; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.pol ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + /*only works if info_class parm is 12 */ + hnd->status = + rpccli_lsa_query_info_policy2( pipe_hnd, mem_ctx, op->in.pol, + 12, &domain_name, &dns_name, + &forest_name, &domain_guid, + &domain_sid ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } + + op->out.domain_name = domain_name; + op->out.dns_name = dns_name; + op->out.forest_name = forest_name; + op->out.domain_guid = domain_guid; + op->out.domain_sid = domain_sid; + + return CAC_SUCCESS; } -int cac_LsaEnumSids(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumSids *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_LsaEnumSids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaEnumSids *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - uint32 num_sids; - DOM_SID *sids; + uint32 num_sids; + DOM_SID *sids; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.pol) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.pol ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_lsa_enum_sids(pipe_hnd, mem_ctx, op->in.pol, &(op->out.resume_idx), op->in.pref_max_sids, &num_sids, &sids); + hnd->status = + rpccli_lsa_enum_sids( pipe_hnd, mem_ctx, op->in.pol, + &( op->out.resume_idx ), + op->in.pref_max_sids, &num_sids, + &sids ); - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } - op->out.num_sids = num_sids; - op->out.sids = sids; + op->out.num_sids = num_sids; + op->out.sids = sids; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_LsaEnumAccountRights(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumAccountRights *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_LsaEnumAccountRights( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaEnumAccountRights *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - uint32 count = 0; - char **privs = NULL; + uint32 count = 0; + char **privs = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op->in.pol) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op->in.pol ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(!op->in.name && !op->in.sid) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op->in.name && !op->in.sid ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(op->in.name && !op->in.sid) { - DOM_SID *user_sid = NULL; - uint32 *type; + if ( op->in.name && !op->in.sid ) { + DOM_SID *user_sid = NULL; + enum lsa_SidType *type; - /*lookup the SID*/ - hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type); + /*lookup the SID */ + hnd->status = + rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, + op->in.pol, 1, + ( const char ** ) &( op->in. + name ), + NULL, &user_sid, &type ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->in.sid = user_sid; - } - - hnd->status = rpccli_lsa_enum_account_rights( pipe_hnd, mem_ctx, op->in.pol, op->in.sid, - &count, &privs); + op->in.sid = user_sid; + } - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } + hnd->status = + rpccli_lsa_enum_account_rights( pipe_hnd, mem_ctx, op->in.pol, + op->in.sid, &count, &privs ); - op->out.num_privs = count; - op->out.priv_names = privs; + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } - return CAC_SUCCESS; -} + op->out.num_privs = count; + op->out.priv_names = privs; -int cac_LsaEnumTrustedDomains(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumTrustedDomains *op) { - struct rpc_pipe_client *pipe_hnd; - - uint32 num_domains; - char **domain_names; - DOM_SID *domain_sids; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op->in.pol) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - hnd->status = rpccli_lsa_enum_trust_dom( pipe_hnd, mem_ctx, op->in.pol, &(op->out.resume_idx), &num_domains, &domain_names, &domain_sids); - - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } - - op->out.num_domains = num_domains; - op->out.domain_names = domain_names; - op->out.domain_sids = domain_sids; - - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_LsaOpenTrustedDomain(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaOpenTrustedDomain *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - POLICY_HND *dom_pol = NULL; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op->in.pol || !op->in.access || !op->in.domain_sid) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - dom_pol = talloc(mem_ctx, POLICY_HND); - if(!dom_pol) { - hnd->status = NT_STATUS_NO_MEMORY; - errno = ENOMEM; - return CAC_FAILURE; - } - - hnd->status = rpccli_lsa_open_trusted_domain( pipe_hnd, mem_ctx, op->in.pol, op->in.domain_sid, op->in.access, dom_pol); - - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } - - op->out.domain_pol = dom_pol; - - return CAC_SUCCESS; +int cac_LsaEnumTrustedDomains( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaEnumTrustedDomains *op ) +{ + struct rpc_pipe_client *pipe_hnd; + + uint32 num_domains; + char **domain_names; + DOM_SID *domain_sids; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op->in.pol ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + hnd->status = + rpccli_lsa_enum_trust_dom( pipe_hnd, mem_ctx, op->in.pol, + &( op->out.resume_idx ), + &num_domains, &domain_names, + &domain_sids ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } + + op->out.num_domains = num_domains; + op->out.domain_names = domain_names; + op->out.domain_sids = domain_sids; + + return CAC_SUCCESS; } -int cac_LsaQueryTrustedDomainInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaQueryTrustedDomainInfo *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_LsaOpenTrustedDomain( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaOpenTrustedDomain *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - LSA_TRUSTED_DOMAIN_INFO *dom_info; + POLICY_HND *dom_pol = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op->in.pol || !op->in.info_class) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op->in.pol || !op->in.access || !op->in.domain_sid ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(!op->in.domain_sid && !op->in.domain_name) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + dom_pol = talloc( mem_ctx, POLICY_HND ); + if ( !dom_pol ) { + hnd->status = NT_STATUS_NO_MEMORY; + errno = ENOMEM; + return CAC_FAILURE; + } - if(op->in.domain_sid) { - hnd->status = rpccli_lsa_query_trusted_domain_info_by_sid( pipe_hnd, mem_ctx, op->in.pol, op->in.info_class, op->in.domain_sid, &dom_info); - } - else if(op->in.domain_name) { - hnd->status = rpccli_lsa_query_trusted_domain_info_by_name( pipe_hnd, mem_ctx, op->in.pol, op->in.info_class, op->in.domain_name, &dom_info); - } + hnd->status = + rpccli_lsa_open_trusted_domain( pipe_hnd, mem_ctx, op->in.pol, + op->in.domain_sid, + op->in.access, dom_pol ); - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } - op->out.info = dom_info; - - return CAC_SUCCESS; + op->out.domain_pol = dom_pol; + return CAC_SUCCESS; } -int cac_LsaEnumPrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumPrivileges *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - uint32 num_privs; - char **priv_names; - uint32 *high_bits; - uint32 *low_bits; - - if(!hnd) { - return CAC_FAILURE; - } - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.pol) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - hnd->status = rpccli_lsa_enum_privilege(pipe_hnd, mem_ctx, op->in.pol, &(op->out.resume_idx), op->in.pref_max_privs, - &num_privs, &priv_names, &high_bits, &low_bits); - - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } +int cac_LsaQueryTrustedDomainInfo( CacServerHandle * hnd, + TALLOC_CTX * mem_ctx, + struct LsaQueryTrustedDomainInfo *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + LSA_TRUSTED_DOMAIN_INFO *dom_info; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op->in.pol || !op->in.info_class ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( !op->in.domain_sid && !op->in.domain_name ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( op->in.domain_sid ) { + hnd->status = + rpccli_lsa_query_trusted_domain_info_by_sid( pipe_hnd, + mem_ctx, + op->in. + pol, + op->in. + info_class, + op->in. + domain_sid, + &dom_info ); + } else if ( op->in.domain_name ) { + hnd->status = + rpccli_lsa_query_trusted_domain_info_by_name + ( pipe_hnd, mem_ctx, op->in.pol, op->in.info_class, + op->in.domain_name, &dom_info ); + } + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } + + op->out.info = dom_info; + + return CAC_SUCCESS; - op->out.num_privs = num_privs; - op->out.priv_names = priv_names; - op->out.high_bits = high_bits; - op->out.low_bits = low_bits; - - return CAC_SUCCESS; } -int cac_LsaOpenAccount(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaOpenAccount *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - POLICY_HND *user_pol = NULL; - - if(!hnd) { - return CAC_FAILURE; - } - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.pol) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - if(!op->in.sid && !op->in.name) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - /*look up the user's SID if we have to*/ - if(op->in.name && !op->in.sid) { - DOM_SID *user_sid = NULL; - uint32 *type; - - /*lookup the SID*/ - hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - op->in.sid = user_sid; - } - - user_pol = talloc(mem_ctx, POLICY_HND); - if(!user_pol) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - hnd->status = rpccli_lsa_open_account(pipe_hnd, mem_ctx, op->in.pol, op->in.sid, op->in.access, user_pol); - - if(!NT_STATUS_IS_OK(hnd->status)) { - TALLOC_FREE(user_pol); - return CAC_FAILURE; - } - - op->out.user = user_pol; - - return CAC_SUCCESS; +int cac_LsaEnumPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaEnumPrivileges *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + uint32 num_privs; + char **priv_names; + uint32 *high_bits; + uint32 *low_bits; + + if ( !hnd ) { + return CAC_FAILURE; + } + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.pol ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + hnd->status = + rpccli_lsa_enum_privilege( pipe_hnd, mem_ctx, op->in.pol, + &( op->out.resume_idx ), + op->in.pref_max_privs, &num_privs, + &priv_names, &high_bits, + &low_bits ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } + + op->out.num_privs = num_privs; + op->out.priv_names = priv_names; + op->out.high_bits = high_bits; + op->out.low_bits = low_bits; + + return CAC_SUCCESS; } - -int cac_LsaAddPrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaAddPrivileges *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - DOM_SID *user_sid = NULL; - uint32 *type = NULL; - - if(!hnd) { - return CAC_FAILURE; - } - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.pol || !op->in.priv_names) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - if(!op->in.sid && !op->in.name) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(op->in.name && !op->in.sid) { - /*lookup the SID*/ - hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - op->in.sid = user_sid; - } - - hnd->status = rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol, *(op->in.sid), op->in.num_privs, (const char **)op->in.priv_names); - - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } - - return CAC_SUCCESS; +int cac_LsaOpenAccount( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaOpenAccount *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + POLICY_HND *user_pol = NULL; + + if ( !hnd ) { + return CAC_FAILURE; + } + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.pol ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( !op->in.sid && !op->in.name ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + /*look up the user's SID if we have to */ + if ( op->in.name && !op->in.sid ) { + DOM_SID *user_sid = NULL; + enum lsa_SidType *type; + + /*lookup the SID */ + hnd->status = + rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, + op->in.pol, 1, + ( const char ** ) &( op->in. + name ), + NULL, &user_sid, &type ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + op->in.sid = user_sid; + } + + user_pol = talloc( mem_ctx, POLICY_HND ); + if ( !user_pol ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + hnd->status = + rpccli_lsa_open_account( pipe_hnd, mem_ctx, op->in.pol, + op->in.sid, op->in.access, + user_pol ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + TALLOC_FREE( user_pol ); + return CAC_FAILURE; + } + + op->out.user = user_pol; + + return CAC_SUCCESS; } -int cac_LsaRemovePrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaRemovePrivileges *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - DOM_SID *user_sid = NULL; - uint32 *type = NULL; - - if(!hnd) { - return CAC_FAILURE; - } - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.pol || !op->in.priv_names) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - if(!op->in.sid && !op->in.name) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(op->in.name && !op->in.sid) { - /*lookup the SID*/ - hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - op->in.sid = user_sid; - } - - hnd->status = rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx, op->in.pol, *(op->in.sid), False, op->in.num_privs, (const char **)op->in.priv_names); - - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } - - return CAC_SUCCESS; +int cac_LsaAddPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaAddPrivileges *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + DOM_SID *user_sid = NULL; + enum lsa_SidType *type = NULL; + + if ( !hnd ) { + return CAC_FAILURE; + } + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.pol || !op->in.priv_names ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( !op->in.sid && !op->in.name ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( op->in.name && !op->in.sid ) { + /*lookup the SID */ + hnd->status = + rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, + op->in.pol, 1, + ( const char ** ) &( op->in. + name ), + NULL, &user_sid, &type ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + op->in.sid = user_sid; + } + + hnd->status = + rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol, + *( op->in.sid ), + op->in.num_privs, + ( const char ** ) op->in. + priv_names ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } + + return CAC_SUCCESS; } -int cac_LsaClearPrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaClearPrivileges *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - DOM_SID *user_sid = NULL; - uint32 *type = NULL; - - if(!hnd) { - return CAC_FAILURE; - } - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.pol) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - if(!op->in.sid && !op->in.name) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(op->in.name && !op->in.sid) { - /*lookup the SID*/ - hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - op->in.sid = user_sid; - } - - hnd->status = rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx, op->in.pol, *(op->in.sid), True, 0, NULL); - - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } - - return CAC_SUCCESS; +int cac_LsaRemovePrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaRemovePrivileges *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + DOM_SID *user_sid = NULL; + enum lsa_SidType *type = NULL; + + if ( !hnd ) { + return CAC_FAILURE; + } + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.pol || !op->in.priv_names ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( !op->in.sid && !op->in.name ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( op->in.name && !op->in.sid ) { + /*lookup the SID */ + hnd->status = + rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, + op->in.pol, 1, + ( const char ** ) &( op->in. + name ), + NULL, &user_sid, &type ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + op->in.sid = user_sid; + } + + hnd->status = + rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx, + op->in.pol, *( op->in.sid ), + False, op->in.num_privs, + ( const char ** ) op->in. + priv_names ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } + + return CAC_SUCCESS; } -int cac_LsaSetPrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaAddPrivileges *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - DOM_SID *user_sid = NULL; - uint32 *type = NULL; - - if(!hnd) { - return CAC_FAILURE; - } - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.pol || !op->in.priv_names) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - if(!op->in.sid && !op->in.name) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - return CAC_FAILURE; - } - - if(op->in.name && !op->in.sid) { - /*lookup the SID*/ - hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - op->in.sid = user_sid; - } - - /*first remove all privileges*/ - hnd->status = rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx, op->in.pol, *(op->in.sid), True, 0, NULL); - - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } - - hnd->status = rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol, *(op->in.sid), op->in.num_privs, (const char **)op->in.priv_names); - - if(!NT_STATUS_IS_OK(hnd->status)) { - return CAC_FAILURE; - } +int cac_LsaClearPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaClearPrivileges *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + DOM_SID *user_sid = NULL; + enum lsa_SidType *type = NULL; + + if ( !hnd ) { + return CAC_FAILURE; + } + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.pol ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( !op->in.sid && !op->in.name ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( op->in.name && !op->in.sid ) { + /*lookup the SID */ + hnd->status = + rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, + op->in.pol, 1, + ( const char ** ) &( op->in. + name ), + NULL, &user_sid, &type ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + op->in.sid = user_sid; + } + + hnd->status = + rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx, + op->in.pol, *( op->in.sid ), + True, 0, NULL ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } + + return CAC_SUCCESS; +} - return CAC_SUCCESS; +int cac_LsaSetPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaAddPrivileges *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + DOM_SID *user_sid = NULL; + enum lsa_SidType *type = NULL; + + if ( !hnd ) { + return CAC_FAILURE; + } + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.pol || !op->in.priv_names ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( !op->in.sid && !op->in.name ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + return CAC_FAILURE; + } + + if ( op->in.name && !op->in.sid ) { + /*lookup the SID */ + hnd->status = + rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, + op->in.pol, 1, + ( const char ** ) &( op->in. + name ), + NULL, &user_sid, &type ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + op->in.sid = user_sid; + } + + /*first remove all privileges */ + hnd->status = + rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx, + op->in.pol, *( op->in.sid ), + True, 0, NULL ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } + + hnd->status = + rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol, + *( op->in.sid ), + op->in.num_privs, + ( const char ** ) op->in. + priv_names ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + return CAC_FAILURE; + } + + return CAC_SUCCESS; } -int cac_LsaGetSecurityObject(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaGetSecurityObject *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_LsaGetSecurityObject( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct LsaGetSecurityObject *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - /*this is taken from rpcclient/cmd_lsarpc.c*/ - uint16 info_level = 4; + /*this is taken from rpcclient/cmd_lsarpc.c */ + uint16 info_level = 4; - SEC_DESC_BUF *sec_out = NULL; + SEC_DESC_BUF *sec_out = NULL; - if(!hnd) { - return CAC_FAILURE; - } + if ( !hnd ) { + return CAC_FAILURE; + } - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.pol) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.pol ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_LSARPC); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_LSARPC ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_lsa_query_secobj( pipe_hnd, mem_ctx, op->in.pol, info_level, &sec_out); + hnd->status = + rpccli_lsa_query_secobj( pipe_hnd, mem_ctx, op->in.pol, + info_level, &sec_out ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.sec = sec_out; + op->out.sec = sec_out; - return CAC_FAILURE; + return CAC_FAILURE; } diff --git a/source/libmsrpc/cac_samr.c b/source/libmsrpc/cac_samr.c index 60c6562988e..aee60804372 100644 --- a/source/libmsrpc/cac_samr.c +++ b/source/libmsrpc/cac_samr.c @@ -1,3 +1,4 @@ + /* * Unix SMB/CIFS implementation. * MS-RPC client library implementation (SAMR pipe) @@ -29,2383 +30,2651 @@ /*not sure what this is.. taken from rpcclient/cmd_samr.c*/ #define SAMR_LOOKUP_FLAGS 0x000003e8 -int cac_SamConnect(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamConnect *op) { - SMBCSRV *srv = NULL; - struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND *sam_out = NULL; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || op->in.access == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - srv = cac_GetServer(hnd); - if(!srv) { - hnd->status = NT_STATUS_INVALID_CONNECTION; - return CAC_FAILURE; - } - - /*initialize for samr pipe if we have to*/ - if(!hnd->_internal.pipes[PI_SAMR]) { - if(!(pipe_hnd = cli_rpc_pipe_open_noauth(&srv->cli, PI_SAMR, &(hnd->status)))) { - return CAC_FAILURE; - } - - hnd->_internal.pipes[PI_SAMR] = True; - } - - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - sam_out = talloc(mem_ctx, POLICY_HND); - if(!sam_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } +int cac_SamConnect( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamConnect *op ) +{ + SMBCSRV *srv = NULL; + struct rpc_pipe_client *pipe_hnd = NULL; + POLICY_HND *sam_out = NULL; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || op->in.access == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + srv = cac_GetServer( hnd ); + if ( !srv ) { + hnd->status = NT_STATUS_INVALID_CONNECTION; + return CAC_FAILURE; + } + + /*initialize for samr pipe if we have to */ + if ( !hnd->_internal.pipes[PI_SAMR] ) { + if ( ! + ( pipe_hnd = + cli_rpc_pipe_open_noauth( srv->cli, PI_SAMR, + &hnd->status ) ) ) { + return CAC_FAILURE; + } + + hnd->_internal.pipes[PI_SAMR] = True; + } + + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + sam_out = talloc( mem_ctx, POLICY_HND ); + if ( !sam_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + if ( hnd->_internal.srv_level >= SRV_WIN_2K_SP3 ) { + hnd->status = + rpccli_samr_connect4( pipe_hnd, mem_ctx, + op->in.access, sam_out ); + } + + if ( hnd->_internal.srv_level < SRV_WIN_2K_SP3 + || !NT_STATUS_IS_OK( hnd->status ) ) { + /*if sam_connect4 failed, the use sam_connect and lower srv_level */ + + hnd->status = + rpccli_samr_connect( pipe_hnd, mem_ctx, op->in.access, + sam_out ); + + if ( NT_STATUS_IS_OK( hnd->status ) + && hnd->_internal.srv_level > SRV_WIN_2K ) { + hnd->_internal.srv_level = SRV_WIN_2K; + } + } + + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + op->out.sam = sam_out; + + return CAC_SUCCESS; +} - if(hnd->_internal.srv_level >= SRV_WIN_2K_SP3) { - hnd->status = rpccli_samr_connect4( pipe_hnd, mem_ctx, op->in.access, sam_out); - } +int cac_SamClose( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + POLICY_HND * sam ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - if(hnd->_internal.srv_level < SRV_WIN_2K_SP3 || !NT_STATUS_IS_OK(hnd->status)) { - /*if sam_connect4 failed, the use sam_connect and lower srv_level*/ + if ( !hnd ) + return CAC_FAILURE; - hnd->status = rpccli_samr_connect( pipe_hnd, mem_ctx, op->in.access, sam_out); + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(NT_STATUS_IS_OK(hnd->status) && hnd->_internal.srv_level > SRV_WIN_2K) { - hnd->_internal.srv_level = SRV_WIN_2K; - } - } + if ( !sam || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - op->out.sam = sam_out; + hnd->status = rpccli_samr_close( pipe_hnd, mem_ctx, sam ); - return CAC_SUCCESS; -} + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; -int cac_SamClose(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *sam) { - struct rpc_pipe_client *pipe_hnd = NULL; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!sam || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - hnd->status = rpccli_samr_close( pipe_hnd, mem_ctx, sam); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - return CAC_SUCCESS; + return CAC_SUCCESS; } /*this is an internal function. Due to a circular dependency, it must be prototyped in libmsrpc.h (which I don't want to do) * cac_SamOpenDomain() is the only function that calls it, so I just put the definition here */ + /*attempts to find the sid of the domain we are connected to*/ -DOM_SID *cac_get_domain_sid(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, uint32 des_access) { - struct LsaOpenPolicy lop; - struct LsaFetchSid fs; +DOM_SID *cac_get_domain_sid( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + uint32 des_access ) +{ + struct LsaOpenPolicy lop; + struct LsaFetchSid fs; + + DOM_SID *sid; + + ZERO_STRUCT( lop ); + ZERO_STRUCT( fs ); - DOM_SID *sid; - - ZERO_STRUCT(lop); - ZERO_STRUCT(fs); + lop.in.access = des_access; + lop.in.security_qos = True; - lop.in.access = des_access; - lop.in.security_qos = True; + if ( !cac_LsaOpenPolicy( hnd, mem_ctx, &lop ) ) + return NULL; - if(!cac_LsaOpenPolicy(hnd, mem_ctx, &lop)) - return NULL; + fs.in.pol = lop.out.pol; + fs.in.info_class = CAC_DOMAIN_INFO; - fs.in.pol = lop.out.pol; - fs.in.info_class = CAC_DOMAIN_INFO; + if ( !cac_LsaFetchSid( hnd, mem_ctx, &fs ) ) + return NULL; - if(!cac_LsaFetchSid(hnd, mem_ctx, &fs)) - return NULL; - - cac_LsaClosePolicy(hnd, mem_ctx, lop.out.pol); + cac_LsaClosePolicy( hnd, mem_ctx, lop.out.pol ); - if(!fs.out.domain_sid) - return NULL; + if ( !fs.out.domain_sid ) + return NULL; - sid = talloc_memdup(mem_ctx, &(fs.out.domain_sid->sid), sizeof(DOM_SID)); + sid = ( DOM_SID * ) talloc_memdup( mem_ctx, + &( fs.out.domain_sid->sid ), + sizeof( DOM_SID ) ); - if(!sid) { - hnd->status = NT_STATUS_NO_MEMORY; - } + if ( !sid ) { + hnd->status = NT_STATUS_NO_MEMORY; + } - return sid; + return sid; } -int cac_SamOpenDomain(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamOpenDomain *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - DOM_SID *sid_buf; - POLICY_HND *sam_out; - POLICY_HND *pol_out; - - struct SamLookupDomain sld; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || op->in.access == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - if(!op->in.sam) { - /*use cac_SamConnect() since it does the session setup*/ - struct SamConnect sc; - ZERO_STRUCT(sc); - - sc.in.access = op->in.access; - - if(!cac_SamConnect(hnd, mem_ctx, &sc)) { - return CAC_FAILURE; - } - - sam_out = sc.out.sam; - } - else { - sam_out = op->in.sam; - } - - if(!op->in.sid) { - /*find the sid for the SAM's domain*/ - - /*try using cac_SamLookupDomain() first*/ - ZERO_STRUCT(sld); - - sld.in.sam = sam_out; - sld.in.name = hnd->domain; - - if(cac_SamLookupDomain(hnd, mem_ctx, &sld)) { - /*then we got the sid*/ - sid_buf = sld.out.sid; - } - else { - /*try to get it from the LSA*/ - sid_buf = cac_get_domain_sid(hnd, mem_ctx, op->in.access); - } - } - else { - /*we already have the sid for the domain we want*/ - sid_buf = op->in.sid; - } - - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - pol_out = talloc(mem_ctx, POLICY_HND); - if(!pol_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - /*now open the domain*/ - hnd->status = rpccli_samr_open_domain( pipe_hnd, mem_ctx, sam_out, op->in.access, sid_buf, pol_out); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - op->out.sam = sam_out; - op->out.dom_hnd = pol_out; - - return CAC_SUCCESS; +int cac_SamOpenDomain( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamOpenDomain *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + DOM_SID *sid_buf; + POLICY_HND *sam_out; + POLICY_HND *pol_out; + + struct SamLookupDomain sld; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || op->in.access == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( !op->in.sam ) { + /*use cac_SamConnect() since it does the session setup */ + struct SamConnect sc; + + ZERO_STRUCT( sc ); + + sc.in.access = op->in.access; + + if ( !cac_SamConnect( hnd, mem_ctx, &sc ) ) { + return CAC_FAILURE; + } + + sam_out = sc.out.sam; + } else { + sam_out = op->in.sam; + } + + if ( !op->in.sid ) { + /*find the sid for the SAM's domain */ + + /*try using cac_SamLookupDomain() first */ + ZERO_STRUCT( sld ); + + sld.in.sam = sam_out; + sld.in.name = hnd->domain; + + if ( cac_SamLookupDomain( hnd, mem_ctx, &sld ) ) { + /*then we got the sid */ + sid_buf = sld.out.sid; + } else { + /*try to get it from the LSA */ + sid_buf = + cac_get_domain_sid( hnd, mem_ctx, + op->in.access ); + } + } else { + /*we already have the sid for the domain we want */ + sid_buf = op->in.sid; + } + + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + pol_out = talloc( mem_ctx, POLICY_HND ); + if ( !pol_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + /*now open the domain */ + hnd->status = + rpccli_samr_open_domain( pipe_hnd, mem_ctx, sam_out, + op->in.access, sid_buf, pol_out ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + op->out.sam = sam_out; + op->out.dom_hnd = pol_out; + + return CAC_SUCCESS; } -int cac_SamOpenUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamOpenUser *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamOpenUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamOpenUser *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - uint32 *rid_buf = NULL; + uint32 *rid_buf = NULL; - uint32 num_rids = 0; - uint32 *rid_types = NULL; + uint32 num_rids = 0; + uint32 *rid_types = NULL; - POLICY_HND *user_out = NULL; + POLICY_HND *user_out = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.dom_hnd || op->in.access == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.dom_hnd || op->in.access == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(op->in.rid == 0 && op->in.name == NULL) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( op->in.rid == 0 && op->in.name == NULL ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(op->in.rid == 0 && op->in.name) { - /*lookup the name and then set rid_buf*/ + if ( op->in.rid == 0 && op->in.name ) { + /*lookup the name and then set rid_buf */ - hnd->status = rpccli_samr_lookup_names( pipe_hnd, mem_ctx, op->in.dom_hnd, SAMR_LOOKUP_FLAGS, 1, (const char **)&op->in.name, - &num_rids, &rid_buf, &rid_types); + hnd->status = + rpccli_samr_lookup_names( pipe_hnd, mem_ctx, + op->in.dom_hnd, + SAMR_LOOKUP_FLAGS, 1, + ( const char ** ) &op->in. + name, &num_rids, &rid_buf, + &rid_types ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - if(num_rids == 0 || rid_buf == NULL || rid_types[0] == SAMR_RID_UNKNOWN) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( num_rids == 0 || rid_buf == NULL + || rid_types[0] == SAMR_RID_UNKNOWN ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - TALLOC_FREE(rid_types); + TALLOC_FREE( rid_types ); - } - else { - rid_buf = &op->in.rid; - } + } else { + rid_buf = &op->in.rid; + } - user_out = talloc(mem_ctx, POLICY_HND); - if(!user_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + user_out = talloc( mem_ctx, POLICY_HND ); + if ( !user_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_open_user(pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.access, *rid_buf, user_out); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + hnd->status = + rpccli_samr_open_user( pipe_hnd, mem_ctx, op->in.dom_hnd, + op->in.access, *rid_buf, user_out ); - op->out.user_hnd = user_out; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + op->out.user_hnd = user_out; + + return CAC_SUCCESS; } -int cac_SamCreateUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamCreateUser *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamCreateUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamCreateUser *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND *user_out = NULL; - uint32 rid_out; + POLICY_HND *user_out = NULL; + uint32 rid_out; /**found in rpcclient/cmd_samr.c*/ - uint32 unknown = 0xe005000b; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.dom_hnd || !op->in.name || op->in.acb_mask == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - user_out = talloc(mem_ctx, POLICY_HND); - if(!user_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - hnd->status = rpccli_samr_create_dom_user( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.name, op->in.acb_mask, unknown, user_out, &rid_out); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - op->out.user_hnd = user_out; - op->out.rid = rid_out; - - return CAC_SUCCESS; + uint32 unknown = 0xe005000b; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.dom_hnd || !op->in.name || op->in.acb_mask == 0 + || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + user_out = talloc( mem_ctx, POLICY_HND ); + if ( !user_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + hnd->status = + rpccli_samr_create_dom_user( pipe_hnd, mem_ctx, + op->in.dom_hnd, op->in.name, + op->in.acb_mask, unknown, + user_out, &rid_out ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + op->out.user_hnd = user_out; + op->out.rid = rid_out; + + return CAC_SUCCESS; } -int cac_SamDeleteUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *user_hnd) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamDeleteUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + POLICY_HND * user_hnd ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!user_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !user_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_delete_dom_user( pipe_hnd, mem_ctx, user_hnd); + hnd->status = + rpccli_samr_delete_dom_user( pipe_hnd, mem_ctx, user_hnd ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamEnumUsers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamEnumUsers *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamEnumUsers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamEnumUsers *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - uint32 resume_idx_out = 0; - char **names_out = NULL; - uint32 *rids_out = NULL; - uint32 num_users_out = 0; + uint32 resume_idx_out = 0; + char **names_out = NULL; + uint32 *rids_out = NULL; + uint32 num_users_out = 0; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.dom_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.dom_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - /*this is a hack.. but is the only reliable way to know if everything has been enumerated*/ - if(op->out.done == True) - return CAC_FAILURE; + /*this is a hack.. but is the only reliable way to know if everything has been enumerated */ + if ( op->out.done == True ) + return CAC_FAILURE; - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - resume_idx_out = op->out.resume_idx; + resume_idx_out = op->out.resume_idx; - hnd->status = rpccli_samr_enum_dom_users( pipe_hnd, mem_ctx, op->in.dom_hnd, &resume_idx_out, op->in.acb_mask, SAMR_ENUM_MAX_SIZE, - &names_out, &rids_out, &num_users_out); + hnd->status = + rpccli_samr_enum_dom_users( pipe_hnd, mem_ctx, op->in.dom_hnd, + &resume_idx_out, op->in.acb_mask, + SAMR_ENUM_MAX_SIZE, &names_out, + &rids_out, &num_users_out ); - if(NT_STATUS_IS_OK(hnd->status)) - op->out.done = True; + if ( NT_STATUS_IS_OK( hnd->status ) ) + op->out.done = True; - /*if there are no more entries, the operation will return NT_STATUS_OK. - * We want to return failure if no results were returned*/ - if(!NT_STATUS_IS_OK(hnd->status) && NT_STATUS_V(hnd->status) != NT_STATUS_V(STATUS_MORE_ENTRIES)) - return CAC_FAILURE; + /*if there are no more entries, the operation will return NT_STATUS_OK. + * We want to return failure if no results were returned*/ + if ( !NT_STATUS_IS_OK( hnd->status ) + && NT_STATUS_V( hnd->status ) != + NT_STATUS_V( STATUS_MORE_ENTRIES ) ) + return CAC_FAILURE; - op->out.resume_idx= resume_idx_out; - op->out.num_users = num_users_out; - op->out.rids = rids_out; - op->out.names = names_out; + op->out.resume_idx = resume_idx_out; + op->out.num_users = num_users_out; + op->out.rids = rids_out; + op->out.names = names_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamGetNamesFromRids(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetNamesFromRids *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - uint32 num_names_out; - char **names_out; - uint32 *name_types_out; - - - uint32 i = 0; - - CacLookupRidsRecord *map_out; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.dom_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - if(!op->in.rids && op->in.num_rids != 0) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - if(op->in.num_rids == 0) { - /*nothing to do*/ - op->out.num_names = 0; - return CAC_SUCCESS; - } - - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - hnd->status = rpccli_samr_lookup_rids( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.num_rids, op->in.rids, &num_names_out, &names_out, &name_types_out); - - if(!NT_STATUS_IS_OK(hnd->status) && !NT_STATUS_EQUAL(hnd->status, STATUS_SOME_UNMAPPED)) - return CAC_FAILURE; - - map_out = TALLOC_ARRAY(mem_ctx, CacLookupRidsRecord, num_names_out); - if(!map_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - for(i = 0; i < num_names_out; i++) { - if(name_types_out[i] == SAMR_RID_UNKNOWN) { - map_out[i].found = False; - map_out[i].name = NULL; - map_out[i].type = 0; - } - else { - map_out[i].found = True; - map_out[i].name = talloc_strdup(mem_ctx, names_out[i]); - map_out[i].type = name_types_out[i]; - } - map_out[i].rid = op->in.rids[i]; - } - - TALLOC_FREE(names_out); - TALLOC_FREE(name_types_out); - - op->out.num_names = num_names_out; - op->out.map = map_out; - - if(NT_STATUS_EQUAL(hnd->status, STATUS_SOME_UNMAPPED)) - return CAC_PARTIAL_SUCCESS; - - return CAC_SUCCESS; +int cac_SamGetNamesFromRids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetNamesFromRids *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + uint32 num_names_out; + char **names_out; + uint32 *name_types_out; + + + uint32 i = 0; + + CacLookupRidsRecord *map_out; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.dom_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( !op->in.rids && op->in.num_rids != 0 ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( op->in.num_rids == 0 ) { + /*nothing to do */ + op->out.num_names = 0; + return CAC_SUCCESS; + } + + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + hnd->status = + rpccli_samr_lookup_rids( pipe_hnd, mem_ctx, op->in.dom_hnd, + op->in.num_rids, op->in.rids, + &num_names_out, &names_out, + &name_types_out ); + + if ( !NT_STATUS_IS_OK( hnd->status ) + && !NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) ) + return CAC_FAILURE; + + map_out = TALLOC_ARRAY( mem_ctx, CacLookupRidsRecord, num_names_out ); + if ( !map_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + for ( i = 0; i < num_names_out; i++ ) { + if ( name_types_out[i] == SAMR_RID_UNKNOWN ) { + map_out[i].found = False; + map_out[i].name = NULL; + map_out[i].type = 0; + } else { + map_out[i].found = True; + map_out[i].name = + talloc_strdup( mem_ctx, names_out[i] ); + map_out[i].type = name_types_out[i]; + } + map_out[i].rid = op->in.rids[i]; + } + + TALLOC_FREE( names_out ); + TALLOC_FREE( name_types_out ); + + op->out.num_names = num_names_out; + op->out.map = map_out; + + if ( NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) ) + return CAC_PARTIAL_SUCCESS; + + return CAC_SUCCESS; } -int cac_SamGetRidsFromNames(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetRidsFromNames *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - uint32 num_rids_out; - uint32 *rids_out; - uint32 *rid_types_out; - - uint32 i = 0; - - CacLookupRidsRecord *map_out; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.dom_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - if(!op->in.names && op->in.num_names != 0) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - if(op->in.num_names == 0) { - /*then we don't have to do anything*/ - op->out.num_rids = 0; - return CAC_SUCCESS; - } - - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - hnd->status = rpccli_samr_lookup_names( pipe_hnd, mem_ctx, op->in.dom_hnd, SAMR_LOOKUP_FLAGS, op->in.num_names, (const char **)op->in.names, - &num_rids_out, &rids_out, &rid_types_out); - - if(!NT_STATUS_IS_OK(hnd->status) && !NT_STATUS_EQUAL(hnd->status, STATUS_SOME_UNMAPPED)) - return CAC_FAILURE; - - map_out = TALLOC_ARRAY(mem_ctx, CacLookupRidsRecord, num_rids_out); - if(!map_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - for(i = 0; i < num_rids_out; i++) { - - if(rid_types_out[i] == SAMR_RID_UNKNOWN) { - map_out[i].found = False; - map_out[i].rid = 0; - map_out[i].type = 0; - } - else { - map_out[i].found = True; - map_out[i].rid = rids_out[i]; - map_out[i].type = rid_types_out[i]; - } - - map_out[i].name = talloc_strdup(mem_ctx, op->in.names[i]); - } - - op->out.num_rids = num_rids_out; - op->out.map = map_out; - - TALLOC_FREE(rids_out); - TALLOC_FREE(rid_types_out); - - if(NT_STATUS_EQUAL(hnd->status, STATUS_SOME_UNMAPPED)) - return CAC_PARTIAL_SUCCESS; - - return CAC_SUCCESS; +int cac_SamGetRidsFromNames( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetRidsFromNames *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + uint32 num_rids_out; + uint32 *rids_out; + uint32 *rid_types_out; + + uint32 i = 0; + + CacLookupRidsRecord *map_out; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.dom_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( !op->in.names && op->in.num_names != 0 ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( op->in.num_names == 0 ) { + /*then we don't have to do anything */ + op->out.num_rids = 0; + return CAC_SUCCESS; + } + + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + hnd->status = + rpccli_samr_lookup_names( pipe_hnd, mem_ctx, op->in.dom_hnd, + SAMR_LOOKUP_FLAGS, op->in.num_names, + ( const char ** ) op->in.names, + &num_rids_out, &rids_out, + &rid_types_out ); + + if ( !NT_STATUS_IS_OK( hnd->status ) + && !NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) ) + return CAC_FAILURE; + + map_out = TALLOC_ARRAY( mem_ctx, CacLookupRidsRecord, num_rids_out ); + if ( !map_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + for ( i = 0; i < num_rids_out; i++ ) { + + if ( rid_types_out[i] == SAMR_RID_UNKNOWN ) { + map_out[i].found = False; + map_out[i].rid = 0; + map_out[i].type = 0; + } else { + map_out[i].found = True; + map_out[i].rid = rids_out[i]; + map_out[i].type = rid_types_out[i]; + } + + map_out[i].name = talloc_strdup( mem_ctx, op->in.names[i] ); + } + + op->out.num_rids = num_rids_out; + op->out.map = map_out; + + TALLOC_FREE( rids_out ); + TALLOC_FREE( rid_types_out ); + + if ( NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) ) + return CAC_PARTIAL_SUCCESS; + + return CAC_SUCCESS; } -int cac_SamGetGroupsForUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetGroupsForUser *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamGetGroupsForUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetGroupsForUser *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + DOM_GID *groups = NULL; + uint32 num_groups_out = 0; - DOM_GID *groups = NULL; - uint32 num_groups_out = 0; + uint32 *rids_out = NULL; + uint32 *attr_out = NULL; - uint32 *rids_out = NULL; - uint32 *attr_out = NULL; + uint32 i; - uint32 i; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd) - return CAC_FAILURE; + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !op || !op->in.user_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(!op || !op->in.user_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + hnd->status = + rpccli_samr_query_usergroups( pipe_hnd, mem_ctx, + op->in.user_hnd, + &num_groups_out, &groups ); - hnd->status = rpccli_samr_query_usergroups(pipe_hnd, mem_ctx, op->in.user_hnd, &num_groups_out, &groups); + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + rids_out = talloc_array( mem_ctx, uint32, num_groups_out ); + if ( !rids_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - rids_out = talloc_array(mem_ctx, uint32, num_groups_out); - if(!rids_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + attr_out = talloc_array( mem_ctx, uint32, num_groups_out ); + if ( !attr_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - attr_out = talloc_array(mem_ctx, uint32, num_groups_out); - if(!attr_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - for(i = 0; i < num_groups_out; i++) { - rids_out[i] = groups[i].g_rid; - attr_out[i] = groups[i].attr; - } + for ( i = 0; i < num_groups_out; i++ ) { + rids_out[i] = groups[i].g_rid; + attr_out[i] = groups[i].attr; + } - TALLOC_FREE(groups); + TALLOC_FREE( groups ); - op->out.num_groups = num_groups_out; - op->out.rids = rids_out; - op->out.attributes = attr_out; + op->out.num_groups = num_groups_out; + op->out.rids = rids_out; + op->out.attributes = attr_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamOpenGroup(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamOpenGroup *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamOpenGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamOpenGroup *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND *group_hnd_out = NULL; + POLICY_HND *group_hnd_out = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || op->in.access == 0 || op->in.rid == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || op->in.access == 0 || op->in.rid == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - group_hnd_out = talloc(mem_ctx, POLICY_HND); - if(!group_hnd_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + group_hnd_out = talloc( mem_ctx, POLICY_HND ); + if ( !group_hnd_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_open_group( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.access, op->in.rid, group_hnd_out); + hnd->status = + rpccli_samr_open_group( pipe_hnd, mem_ctx, op->in.dom_hnd, + op->in.access, op->in.rid, + group_hnd_out ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.group_hnd = group_hnd_out; + op->out.group_hnd = group_hnd_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamCreateGroup(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamCreateGroup *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamCreateGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamCreateGroup *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND *group_hnd_out = NULL; + POLICY_HND *group_hnd_out = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.name || op->in.name[0] == '\0' || op->in.access == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.name || op->in.name[0] == '\0' + || op->in.access == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - group_hnd_out = talloc(mem_ctx, POLICY_HND); - if(!group_hnd_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + group_hnd_out = talloc( mem_ctx, POLICY_HND ); + if ( !group_hnd_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_create_dom_group( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.name, op->in.access, group_hnd_out); + hnd->status = + rpccli_samr_create_dom_group( pipe_hnd, mem_ctx, + op->in.dom_hnd, op->in.name, + op->in.access, group_hnd_out ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.group_hnd = group_hnd_out; + op->out.group_hnd = group_hnd_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamDeleteGroup(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *group_hnd) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamDeleteGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + POLICY_HND * group_hnd ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!group_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !group_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_delete_dom_group( pipe_hnd, mem_ctx, group_hnd); + hnd->status = + rpccli_samr_delete_dom_group( pipe_hnd, mem_ctx, group_hnd ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamGetGroupMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetGroupMembers *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamGetGroupMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetGroupMembers *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - uint32 num_mem_out; - uint32 *rids_out; - uint32 *attr_out; + uint32 num_mem_out; + uint32 *rids_out; + uint32 *attr_out; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.group_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.group_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_query_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd, &num_mem_out, &rids_out, &attr_out); + hnd->status = + rpccli_samr_query_groupmem( pipe_hnd, mem_ctx, + op->in.group_hnd, &num_mem_out, + &rids_out, &attr_out ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.num_members = num_mem_out; - op->out.rids = rids_out; - op->out.attributes = attr_out; + op->out.num_members = num_mem_out; + op->out.rids = rids_out; + op->out.attributes = attr_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamAddGroupMember(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamAddGroupMember *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamAddGroupMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamAddGroupMember *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.group_hnd || op->in.rid == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.group_hnd || op->in.rid == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_add_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd, op->in.rid); + hnd->status = + rpccli_samr_add_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd, + op->in.rid ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamRemoveGroupMember(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamRemoveGroupMember *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamRemoveGroupMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamRemoveGroupMember *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.group_hnd || op->in.rid == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.group_hnd || op->in.rid == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_del_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd, op->in.rid); + hnd->status = + rpccli_samr_del_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd, + op->in.rid ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamClearGroupMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *group_hnd) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamClearGroupMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + POLICY_HND * group_hnd ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - int result = CAC_SUCCESS; + int result = CAC_SUCCESS; - int i = 0; + int i = 0; - uint32 num_mem = 0; - uint32 *rid = NULL; - uint32 *attr = NULL; + uint32 num_mem = 0; + uint32 *rid = NULL; + uint32 *attr = NULL; - NTSTATUS status; + NTSTATUS status; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!group_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !group_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, group_hnd, &num_mem, &rid, &attr); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + hnd->status = + rpccli_samr_query_groupmem( pipe_hnd, mem_ctx, group_hnd, + &num_mem, &rid, &attr ); - /*try to delete the users one by one*/ - for(i = 0; i < num_mem && NT_STATUS_IS_OK(hnd->status); i++) { - hnd->status = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, group_hnd, rid[i]); - } + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - /*if not all members could be removed, then try to re-add the members that were already deleted*/ - if(!NT_STATUS_IS_OK(hnd->status)) { - status = NT_STATUS_OK; + /*try to delete the users one by one */ + for ( i = 0; i < num_mem && NT_STATUS_IS_OK( hnd->status ); i++ ) { + hnd->status = + rpccli_samr_del_groupmem( pipe_hnd, mem_ctx, + group_hnd, rid[i] ); + } - for(i -= 1; i >= 0 && NT_STATUS_IS_OK(status); i--) { - status = rpccli_samr_add_groupmem( pipe_hnd, mem_ctx, group_hnd, rid[i]); - } + /*if not all members could be removed, then try to re-add the members that were already deleted */ + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + status = NT_STATUS_OK; - /*we return with the NTSTATUS error that we got when trying to delete users*/ - if(!NT_STATUS_IS_OK(status)) - result = CAC_FAILURE; - } + for ( i -= 1; i >= 0 && NT_STATUS_IS_OK( status ); i-- ) { + status = rpccli_samr_add_groupmem( pipe_hnd, mem_ctx, + group_hnd, + rid[i] ); + } - TALLOC_FREE(attr); + /*we return with the NTSTATUS error that we got when trying to delete users */ + if ( !NT_STATUS_IS_OK( status ) ) + result = CAC_FAILURE; + } - return result; + TALLOC_FREE( attr ); + + return result; } -int cac_SamSetGroupMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetGroupMembers *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamSetGroupMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamSetGroupMembers *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + uint32 i = 0; - uint32 i = 0; - - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.group_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.group_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - /*use cac_SamClearGroupMembers() to clear them*/ - if(!cac_SamClearGroupMembers(hnd, mem_ctx, op->in.group_hnd)) - return CAC_FAILURE; /*hnd->status is already set*/ + /*use cac_SamClearGroupMembers() to clear them */ + if ( !cac_SamClearGroupMembers( hnd, mem_ctx, op->in.group_hnd ) ) + return CAC_FAILURE; /*hnd->status is already set */ - for(i = 0; i < op->in.num_members && NT_STATUS_IS_OK(hnd->status); i++) { - hnd->status = rpccli_samr_add_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd, op->in.rids[i]); - } + for ( i = 0; i < op->in.num_members && NT_STATUS_IS_OK( hnd->status ); + i++ ) { + hnd->status = + rpccli_samr_add_groupmem( pipe_hnd, mem_ctx, + op->in.group_hnd, + op->in.rids[i] ); + } - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamEnumGroups(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamEnumGroups *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - uint32 i = 0; - - uint32 resume_idx_out = 0; - char **names_out = NULL; - char **desc_out = NULL; - uint32 *rids_out = NULL; - uint32 num_groups_out = 0; - - struct acct_info *acct_buf = NULL; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.dom_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - /*using this BOOL is the only reliable way to know that we are done*/ - if(op->out.done == True) /*we return failure so the call will break out of a loop*/ - return CAC_FAILURE; - - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - resume_idx_out = op->out.resume_idx; - - hnd->status = rpccli_samr_enum_dom_groups( pipe_hnd, mem_ctx, op->in.dom_hnd, &resume_idx_out, SAMR_ENUM_MAX_SIZE, - &acct_buf, &num_groups_out); - - - if(NT_STATUS_IS_OK(hnd->status)) { - op->out.done = True; - } - else if(NT_STATUS_V(hnd->status) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { - /*if there are no more entries, the operation will return NT_STATUS_OK. - * We want to return failure if no results were returned*/ - return CAC_FAILURE; - } - - names_out = talloc_array(mem_ctx, char *, num_groups_out); - if(!names_out) { - hnd->status = NT_STATUS_NO_MEMORY; - TALLOC_FREE(acct_buf); - return CAC_FAILURE; - } - - desc_out = talloc_array(mem_ctx, char *, num_groups_out); - if(!desc_out) { - hnd->status = NT_STATUS_NO_MEMORY; - TALLOC_FREE(acct_buf); - TALLOC_FREE(names_out); - return CAC_FAILURE; - } - - rids_out = talloc_array(mem_ctx, uint32, num_groups_out); - if(!rids_out) { - hnd->status = NT_STATUS_NO_MEMORY; - TALLOC_FREE(acct_buf); - TALLOC_FREE(names_out); - TALLOC_FREE(desc_out); - return CAC_FAILURE; - } - - for(i = 0; i < num_groups_out; i++) { - names_out[i] = talloc_strdup(mem_ctx, acct_buf[i].acct_name); - desc_out[i] = talloc_strdup(mem_ctx, acct_buf[i].acct_desc); - rids_out[i] = acct_buf[i].rid; - - if(!names_out[i] || !desc_out[i]) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - } - - op->out.resume_idx = resume_idx_out; - op->out.num_groups = num_groups_out; - op->out.rids = rids_out; - op->out.names = names_out; - op->out.descriptions = desc_out; - - return CAC_SUCCESS; +int cac_SamEnumGroups( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamEnumGroups *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + uint32 i = 0; + + uint32 resume_idx_out = 0; + char **names_out = NULL; + char **desc_out = NULL; + uint32 *rids_out = NULL; + uint32 num_groups_out = 0; + + struct acct_info *acct_buf = NULL; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.dom_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + /*using this BOOL is the only reliable way to know that we are done */ + if ( op->out.done == True ) /*we return failure so the call will break out of a loop */ + return CAC_FAILURE; + + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + resume_idx_out = op->out.resume_idx; + + hnd->status = + rpccli_samr_enum_dom_groups( pipe_hnd, mem_ctx, + op->in.dom_hnd, &resume_idx_out, + SAMR_ENUM_MAX_SIZE, &acct_buf, + &num_groups_out ); + + + if ( NT_STATUS_IS_OK( hnd->status ) ) { + op->out.done = True; + } else if ( NT_STATUS_V( hnd->status ) != + NT_STATUS_V( STATUS_MORE_ENTRIES ) ) { + /*if there are no more entries, the operation will return NT_STATUS_OK. + * We want to return failure if no results were returned*/ + return CAC_FAILURE; + } + + names_out = talloc_array( mem_ctx, char *, num_groups_out ); + if ( !names_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + TALLOC_FREE( acct_buf ); + return CAC_FAILURE; + } + + desc_out = talloc_array( mem_ctx, char *, num_groups_out ); + if ( !desc_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + TALLOC_FREE( acct_buf ); + TALLOC_FREE( names_out ); + return CAC_FAILURE; + } + + rids_out = talloc_array( mem_ctx, uint32, num_groups_out ); + if ( !rids_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + TALLOC_FREE( acct_buf ); + TALLOC_FREE( names_out ); + TALLOC_FREE( desc_out ); + return CAC_FAILURE; + } + + for ( i = 0; i < num_groups_out; i++ ) { + names_out[i] = + talloc_strdup( mem_ctx, acct_buf[i].acct_name ); + desc_out[i] = talloc_strdup( mem_ctx, acct_buf[i].acct_desc ); + rids_out[i] = acct_buf[i].rid; + + if ( !names_out[i] || !desc_out[i] ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + } + + op->out.resume_idx = resume_idx_out; + op->out.num_groups = num_groups_out; + op->out.rids = rids_out; + op->out.names = names_out; + op->out.descriptions = desc_out; + + return CAC_SUCCESS; } -int cac_SamEnumAliases(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamEnumAliases *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - uint32 i = 0; - - uint32 resume_idx_out = 0; - char **names_out = NULL; - char **desc_out = NULL; - uint32 *rids_out = NULL; - uint32 num_als_out = 0; - - struct acct_info *acct_buf = NULL; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || !op->in.dom_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - /*this is a hack.. but is the only reliable way to know if everything has been enumerated*/ - if(op->out.done == True) { - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - resume_idx_out = op->out.resume_idx; - - hnd->status = rpccli_samr_enum_als_groups( pipe_hnd, mem_ctx, op->in.dom_hnd, &resume_idx_out, SAMR_ENUM_MAX_SIZE, - &acct_buf, &num_als_out); - - - if(NT_STATUS_IS_OK(hnd->status)) - op->out.done = True; - - /*if there are no more entries, the operation will return NT_STATUS_OK. - * We want to return failure if no results were returned*/ - if(!NT_STATUS_IS_OK(hnd->status) && NT_STATUS_V(hnd->status) != NT_STATUS_V(STATUS_MORE_ENTRIES)) - return CAC_FAILURE; - - names_out = talloc_array(mem_ctx, char *, num_als_out); - if(!names_out) { - hnd->status = NT_STATUS_NO_MEMORY; - TALLOC_FREE(acct_buf); - return CAC_FAILURE; - } - - desc_out = talloc_array(mem_ctx, char *, num_als_out); - if(!desc_out) { - hnd->status = NT_STATUS_NO_MEMORY; - TALLOC_FREE(acct_buf); - TALLOC_FREE(names_out); - return CAC_FAILURE; - } - - rids_out = talloc_array(mem_ctx, uint32, num_als_out); - if(!rids_out) { - hnd->status = NT_STATUS_NO_MEMORY; - TALLOC_FREE(acct_buf); - TALLOC_FREE(names_out); - TALLOC_FREE(desc_out); - return CAC_FAILURE; - } - - for(i = 0; i < num_als_out; i++) { - names_out[i] = talloc_strdup(mem_ctx, acct_buf[i].acct_name); - desc_out[i] = talloc_strdup(mem_ctx, acct_buf[i].acct_desc); - rids_out[i] = acct_buf[i].rid; - - if(!names_out[i] || !desc_out[i]) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - } - - op->out.resume_idx = resume_idx_out; - op->out.num_aliases = num_als_out; - op->out.rids = rids_out; - op->out.names = names_out; - op->out.descriptions = desc_out; - - return CAC_SUCCESS; +int cac_SamEnumAliases( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamEnumAliases *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + uint32 i = 0; + + uint32 resume_idx_out = 0; + char **names_out = NULL; + char **desc_out = NULL; + uint32 *rids_out = NULL; + uint32 num_als_out = 0; + + struct acct_info *acct_buf = NULL; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.dom_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + /*this is a hack.. but is the only reliable way to know if everything has been enumerated */ + if ( op->out.done == True ) { + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + resume_idx_out = op->out.resume_idx; + + hnd->status = + rpccli_samr_enum_als_groups( pipe_hnd, mem_ctx, + op->in.dom_hnd, &resume_idx_out, + SAMR_ENUM_MAX_SIZE, &acct_buf, + &num_als_out ); + + + if ( NT_STATUS_IS_OK( hnd->status ) ) + op->out.done = True; + + /*if there are no more entries, the operation will return NT_STATUS_OK. + * We want to return failure if no results were returned*/ + if ( !NT_STATUS_IS_OK( hnd->status ) + && NT_STATUS_V( hnd->status ) != + NT_STATUS_V( STATUS_MORE_ENTRIES ) ) + return CAC_FAILURE; + + names_out = talloc_array( mem_ctx, char *, num_als_out ); + if ( !names_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + TALLOC_FREE( acct_buf ); + return CAC_FAILURE; + } + + desc_out = talloc_array( mem_ctx, char *, num_als_out ); + if ( !desc_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + TALLOC_FREE( acct_buf ); + TALLOC_FREE( names_out ); + return CAC_FAILURE; + } + + rids_out = talloc_array( mem_ctx, uint32, num_als_out ); + if ( !rids_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + TALLOC_FREE( acct_buf ); + TALLOC_FREE( names_out ); + TALLOC_FREE( desc_out ); + return CAC_FAILURE; + } + + for ( i = 0; i < num_als_out; i++ ) { + names_out[i] = + talloc_strdup( mem_ctx, acct_buf[i].acct_name ); + desc_out[i] = talloc_strdup( mem_ctx, acct_buf[i].acct_desc ); + rids_out[i] = acct_buf[i].rid; + + if ( !names_out[i] || !desc_out[i] ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + } + + op->out.resume_idx = resume_idx_out; + op->out.num_aliases = num_als_out; + op->out.rids = rids_out; + op->out.names = names_out; + op->out.descriptions = desc_out; + + return CAC_SUCCESS; } -int cac_SamCreateAlias(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamCreateAlias *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamCreateAlias( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamCreateAlias *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND *als_hnd_out = NULL; + POLICY_HND *als_hnd_out = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.name || op->in.name[0] == '\0' || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.name || op->in.name[0] == '\0' || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - als_hnd_out = talloc(mem_ctx, POLICY_HND); - if(!als_hnd_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + als_hnd_out = talloc( mem_ctx, POLICY_HND ); + if ( !als_hnd_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_create_dom_alias( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.name, als_hnd_out); + hnd->status = + rpccli_samr_create_dom_alias( pipe_hnd, mem_ctx, + op->in.dom_hnd, op->in.name, + als_hnd_out ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.alias_hnd = als_hnd_out; + op->out.alias_hnd = als_hnd_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamOpenAlias(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamOpenAlias *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamOpenAlias( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamOpenAlias *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND *als_hnd_out = NULL; + POLICY_HND *als_hnd_out = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || op->in.access == 0 || op->in.rid == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || op->in.access == 0 || op->in.rid == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - als_hnd_out = talloc(mem_ctx, POLICY_HND); - if(!als_hnd_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + als_hnd_out = talloc( mem_ctx, POLICY_HND ); + if ( !als_hnd_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_open_alias( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.access, op->in.rid, als_hnd_out); + hnd->status = + rpccli_samr_open_alias( pipe_hnd, mem_ctx, op->in.dom_hnd, + op->in.access, op->in.rid, + als_hnd_out ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.alias_hnd = als_hnd_out; + op->out.alias_hnd = als_hnd_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamDeleteAlias(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *alias_hnd) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamDeleteAlias( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + POLICY_HND * alias_hnd ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!alias_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !alias_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_delete_dom_alias( pipe_hnd, mem_ctx, alias_hnd); + hnd->status = + rpccli_samr_delete_dom_alias( pipe_hnd, mem_ctx, alias_hnd ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamAddAliasMember(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamAddAliasMember *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamAddAliasMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamAddAliasMember *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.alias_hnd || !op->in.sid || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.alias_hnd || !op->in.sid || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd, op->in.sid); + hnd->status = + rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd, + op->in.sid ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamRemoveAliasMember(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamRemoveAliasMember *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamRemoveAliasMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamRemoveAliasMember *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.alias_hnd || !op->in.sid || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.alias_hnd || !op->in.sid || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_del_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd, op->in.sid); + hnd->status = + rpccli_samr_del_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd, + op->in.sid ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamGetAliasMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetAliasMembers *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamGetAliasMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetAliasMembers *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - uint32 num_mem_out; - DOM_SID *sids_out; + uint32 num_mem_out; + DOM_SID *sids_out; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.alias_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.alias_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_query_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd, &num_mem_out, &sids_out); + hnd->status = + rpccli_samr_query_aliasmem( pipe_hnd, mem_ctx, + op->in.alias_hnd, &num_mem_out, + &sids_out ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.num_members = num_mem_out; - op->out.sids = sids_out; + op->out.num_members = num_mem_out; + op->out.sids = sids_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamClearAliasMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *alias_hnd) { - struct rpc_pipe_client *pipe_hnd = NULL; - - int result = CAC_SUCCESS; - - int i = 0; - - uint32 num_mem = 0; - DOM_SID *sid = NULL; - - NTSTATUS status; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!alias_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } +int cac_SamClearAliasMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + POLICY_HND * alias_hnd ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - hnd->status = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx, alias_hnd, &num_mem, &sid); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + int result = CAC_SUCCESS; - /*try to delete the users one by one*/ - for(i = 0; i < num_mem && NT_STATUS_IS_OK(hnd->status); i++) { - hnd->status = rpccli_samr_del_aliasmem(pipe_hnd, mem_ctx, alias_hnd, &sid[i]); - } + int i = 0; - /*if not all members could be removed, then try to re-add the members that were already deleted*/ - if(!NT_STATUS_IS_OK(hnd->status)) { - status = NT_STATUS_OK; + uint32 num_mem = 0; + DOM_SID *sid = NULL; - for(i -= 1; i >= 0 && NT_STATUS_IS_OK(status); i--) { - status = rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx, alias_hnd, &sid[i]); - } + NTSTATUS status; - /*we return with the NTSTATUS error that we got when trying to delete users*/ - if(!NT_STATUS_IS_OK(status)) - result = CAC_FAILURE; - } + if ( !hnd ) + return CAC_FAILURE; - TALLOC_FREE(sid); - return result; -} + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } -int cac_SamSetAliasMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetAliasMembers *op) { - struct rpc_pipe_client *pipe_hnd = NULL; + if ( !alias_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - uint32 i = 0; - - if(!hnd) - return CAC_FAILURE; + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + hnd->status = + rpccli_samr_query_aliasmem( pipe_hnd, mem_ctx, alias_hnd, + &num_mem, &sid ); - if(!op || !op->in.alias_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + /*try to delete the users one by one */ + for ( i = 0; i < num_mem && NT_STATUS_IS_OK( hnd->status ); i++ ) { + hnd->status = + rpccli_samr_del_aliasmem( pipe_hnd, mem_ctx, + alias_hnd, &sid[i] ); + } - /*use cac_SamClearAliasMembers() to clear them*/ - if(!cac_SamClearAliasMembers(hnd, mem_ctx, op->in.alias_hnd)) - return CAC_FAILURE; /*hnd->status is already set*/ + /*if not all members could be removed, then try to re-add the members that were already deleted */ + if ( !NT_STATUS_IS_OK( hnd->status ) ) { + status = NT_STATUS_OK; + for ( i -= 1; i >= 0 && NT_STATUS_IS_OK( status ); i-- ) { + status = rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx, + alias_hnd, + &sid[i] ); + } - for(i = 0; i < op->in.num_members && NT_STATUS_IS_OK(hnd->status); i++) { - hnd->status = rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd, &(op->in.sids[i])); - } + /*we return with the NTSTATUS error that we got when trying to delete users */ + if ( !NT_STATUS_IS_OK( status ) ) + result = CAC_FAILURE; + } - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + TALLOC_FREE( sid ); + return result; +} - return CAC_SUCCESS; +int cac_SamSetAliasMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamSetAliasMembers *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; -} + uint32 i = 0; -int cac_SamUserChangePasswd(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamUserChangePasswd *op) { - SMBCSRV *srv = NULL; - struct rpc_pipe_client *pipe_hnd = NULL; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd) - return CAC_FAILURE; + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !op || !op->in.alias_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(!op || !op->in.username || !op->in.password || !op->in.new_password || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - srv = cac_GetServer(hnd); - if(!srv) { - hnd->status = NT_STATUS_INVALID_CONNECTION; - return CAC_FAILURE; - } + /*use cac_SamClearAliasMembers() to clear them */ + if ( !cac_SamClearAliasMembers( hnd, mem_ctx, op->in.alias_hnd ) ) + return CAC_FAILURE; /*hnd->status is already set */ - /*open a session on SAMR if we don't have one*/ - if(!hnd->_internal.pipes[PI_SAMR]) { - if(!(pipe_hnd = cli_rpc_pipe_open_noauth(&srv->cli, PI_SAMR, &(hnd->status)))) { - return CAC_FAILURE; - } - hnd->_internal.pipes[PI_SAMR] = True; - } + for ( i = 0; i < op->in.num_members && NT_STATUS_IS_OK( hnd->status ); + i++ ) { + hnd->status = + rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx, + op->in.alias_hnd, + &( op->in.sids[i] ) ); + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - hnd->status = rpccli_samr_chgpasswd_user(pipe_hnd, mem_ctx, op->in.username, op->in.new_password, op->in.password); + return CAC_SUCCESS; - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; +} - return CAC_SUCCESS; +int cac_SamUserChangePasswd( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamUserChangePasswd *op ) +{ + SMBCSRV *srv = NULL; + struct rpc_pipe_client *pipe_hnd = NULL; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || !op->in.username || !op->in.password + || !op->in.new_password || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + srv = cac_GetServer( hnd ); + if ( !srv ) { + hnd->status = NT_STATUS_INVALID_CONNECTION; + return CAC_FAILURE; + } + + /*open a session on SAMR if we don't have one */ + if ( !hnd->_internal.pipes[PI_SAMR] ) { + if ( ! + ( pipe_hnd = + cli_rpc_pipe_open_noauth( srv->cli, PI_SAMR, + &hnd->status ) ) ) { + return CAC_FAILURE; + } + + hnd->_internal.pipes[PI_SAMR] = True; + } + + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + hnd->status = + rpccli_samr_chgpasswd_user( pipe_hnd, mem_ctx, + op->in.username, + op->in.new_password, + op->in.password ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + return CAC_SUCCESS; } -int cac_SamEnableUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *user_hnd) { - SMBCSRV *srv = NULL; - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamEnableUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + POLICY_HND * user_hnd ) +{ + SMBCSRV *srv = NULL; + struct rpc_pipe_client *pipe_hnd = NULL; - SAM_USERINFO_CTR *ctr; + SAM_USERINFO_CTR *ctr; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!user_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !user_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - srv = cac_GetServer(hnd); - if(!srv) { - hnd->status = NT_STATUS_INVALID_CONNECTION; - return CAC_FAILURE; - } + srv = cac_GetServer( hnd ); + if ( !srv ) { + hnd->status = NT_STATUS_INVALID_CONNECTION; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - /*info_level = 21 is the only level that I have found to work reliably. It would be nice if user_level = 10 worked.*/ - hnd->status = rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, user_hnd, 0x10, &ctr); + /*info_level = 21 is the only level that I have found to work reliably. It would be nice if user_level = 10 worked. */ + hnd->status = + rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, user_hnd, 0x10, + &ctr ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; /**check the ACB mask*/ - if((ctr->info.id16->acb_info & ACB_DISABLED) == ACB_DISABLED) { - /*toggle the disabled bit*/ - ctr->info.id16->acb_info ^= ACB_DISABLED; - } - else { - /*the user is already enabled so just return success*/ - return CAC_SUCCESS; - } - - /*now set the userinfo*/ - hnd->status = rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, user_hnd, 0x10, &(srv->cli.user_session_key), ctr); - - /*this will only work properly if we use set_userinfo2 - fail if it is not supported*/ - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - return CAC_SUCCESS; + if ( ( ctr->info.id16->acb_info & ACB_DISABLED ) == ACB_DISABLED ) { + /*toggle the disabled bit */ + ctr->info.id16->acb_info ^= ACB_DISABLED; + } else { + /*the user is already enabled so just return success */ + return CAC_SUCCESS; + } + + /*now set the userinfo */ + hnd->status = + rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, user_hnd, 0x10, + &srv->cli->user_session_key, ctr ); + + /*this will only work properly if we use set_userinfo2 - fail if it is not supported */ + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + return CAC_SUCCESS; } -int cac_SamDisableUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *user_hnd) { - SMBCSRV *srv = NULL; - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamDisableUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + POLICY_HND * user_hnd ) +{ + SMBCSRV *srv = NULL; + struct rpc_pipe_client *pipe_hnd = NULL; - SAM_USERINFO_CTR *ctr; + SAM_USERINFO_CTR *ctr; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!user_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !user_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - srv = cac_GetServer(hnd); - if(!srv) { - hnd->status = NT_STATUS_INVALID_CONNECTION; - return CAC_FAILURE; - } + srv = cac_GetServer( hnd ); + if ( !srv ) { + hnd->status = NT_STATUS_INVALID_CONNECTION; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, user_hnd, 0x10, &ctr); + hnd->status = + rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, user_hnd, 0x10, + &ctr ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - if((ctr->info.id16->acb_info & ACB_DISABLED) == ACB_DISABLED) { - /*then the user is already disabled*/ - return CAC_SUCCESS; - } + if ( ( ctr->info.id16->acb_info & ACB_DISABLED ) == ACB_DISABLED ) { + /*then the user is already disabled */ + return CAC_SUCCESS; + } - /*toggle the disabled bit*/ - ctr->info.id16->acb_info ^= ACB_DISABLED; + /*toggle the disabled bit */ + ctr->info.id16->acb_info ^= ACB_DISABLED; - /*this will only work properly if we use set_userinfo2*/ - hnd->status = rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, user_hnd, 0x10, &(srv->cli.user_session_key), ctr); + /*this will only work properly if we use set_userinfo2 */ + hnd->status = + rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, user_hnd, 0x10, + &srv->cli->user_session_key, ctr ); - /*this will only work properly if we use set_userinfo2 fail if it is not supported*/ - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + /*this will only work properly if we use set_userinfo2 fail if it is not supported */ + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamSetPassword(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetPassword *op) { - SMBCSRV *srv = NULL; - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamSetPassword( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamSetPassword *op ) +{ + SMBCSRV *srv = NULL; + struct rpc_pipe_client *pipe_hnd = NULL; - SAM_USERINFO_CTR ctr; - SAM_USER_INFO_24 info24; - uint8 pw[516]; + SAM_USERINFO_CTR ctr; + SAM_USER_INFO_24 info24; + uint8 pw[516]; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op->in.user_hnd || !op->in.password || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op->in.user_hnd || !op->in.password || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - srv = cac_GetServer(hnd); - if(!srv) { - hnd->status = NT_STATUS_INVALID_CONNECTION; - return CAC_FAILURE; - } + srv = cac_GetServer( hnd ); + if ( !srv ) { + hnd->status = NT_STATUS_INVALID_CONNECTION; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - ZERO_STRUCT(ctr); - ZERO_STRUCT(info24); + ZERO_STRUCT( ctr ); + ZERO_STRUCT( info24 ); - encode_pw_buffer(pw, op->in.password, STR_UNICODE); + encode_pw_buffer( pw, op->in.password, STR_UNICODE ); - init_sam_user_info24(&info24, (char *)pw, 24); + init_sam_user_info24( &info24, ( char * ) pw, 24 ); - ctr.switch_value = 24; - ctr.info.id24 = &info24; + ctr.switch_value = 24; + ctr.info.id24 = &info24; - hnd->status = rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, 24, &(srv->cli.user_session_key), &ctr); + hnd->status = + rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, + 24, &srv->cli->user_session_key, + &ctr ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamGetUserInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetUserInfo *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamGetUserInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetUserInfo *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - SAM_USERINFO_CTR *ctr; + SAM_USERINFO_CTR *ctr; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op->in.user_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op->in.user_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, 21, &ctr); + hnd->status = + rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, + op->in.user_hnd, 21, &ctr ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.info = cac_MakeUserInfo(mem_ctx, ctr); + op->out.info = cac_MakeUserInfo( mem_ctx, ctr ); - if(!op->out.info) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + if ( !op->out.info ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamSetUserInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetUserInfo *op) { - SMBCSRV *srv = NULL; - struct rpc_pipe_client *pipe_hnd = NULL; - - SAM_USERINFO_CTR *ctr; - - if(!hnd) - return CAC_FAILURE; +int cac_SamSetUserInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamSetUserInfo *op ) +{ + SMBCSRV *srv = NULL; + struct rpc_pipe_client *pipe_hnd = NULL; + + SAM_USERINFO_CTR *ctr; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op->in.user_hnd || !op->in.info || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + ctr = cac_MakeUserInfoCtr( mem_ctx, op->in.info ); + if ( !ctr ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + srv = cac_GetServer( hnd ); + if ( !srv ) { + hnd->status = NT_STATUS_INVALID_CONNECTION; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( hnd->_internal.srv_level >= SRV_WIN_NT4 ) { + hnd->status = + rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, + op->in.user_hnd, 21, + &srv->cli-> + user_session_key, ctr ); + } + + if ( hnd->_internal.srv_level < SRV_WIN_NT4 + || !NT_STATUS_IS_OK( hnd->status ) ) { + hnd->status = + rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, + op->in.user_hnd, 21, + &srv->cli->user_session_key, + ctr ); + + if ( NT_STATUS_IS_OK( hnd->status ) + && hnd->_internal.srv_level > SRV_WIN_NT4 ) { + hnd->_internal.srv_level = SRV_WIN_NT4; + } + } + + + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + return CAC_SUCCESS; +} - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - if(!op->in.user_hnd || !op->in.info || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } +int cac_SamGetUserInfoCtr( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetUserInfoCtr *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - ctr = cac_MakeUserInfoCtr(mem_ctx, op->in.info); - if(!ctr) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + SAM_USERINFO_CTR *ctr_out; - srv = cac_GetServer(hnd); - if(!srv) { - hnd->status = NT_STATUS_INVALID_CONNECTION; - return CAC_FAILURE; - } + if ( !hnd ) + return CAC_FAILURE; - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(hnd->_internal.srv_level >= SRV_WIN_NT4) { - hnd->status = rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, op->in.user_hnd, 21, &(srv->cli.user_session_key), ctr); - } + if ( !op->in.user_hnd || op->in.info_class == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(hnd->_internal.srv_level < SRV_WIN_NT4 || !NT_STATUS_IS_OK(hnd->status)) { - hnd->status = rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, 21, &(srv->cli.user_session_key), ctr); + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(NT_STATUS_IS_OK(hnd->status) && hnd->_internal.srv_level > SRV_WIN_NT4) { - hnd->_internal.srv_level = SRV_WIN_NT4; - } - } + hnd->status = + rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, + op->in.user_hnd, + op->in.info_class, &ctr_out ); + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + op->out.ctr = ctr_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } +int cac_SamSetUserInfoCtr( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamSetUserInfoCtr *op ) +{ + SMBCSRV *srv = NULL; + struct rpc_pipe_client *pipe_hnd = NULL; -int cac_SamGetUserInfoCtr(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetUserInfoCtr *op) { - struct rpc_pipe_client *pipe_hnd = NULL; + if ( !hnd ) + return CAC_FAILURE; - SAM_USERINFO_CTR *ctr_out; + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!hnd) - return CAC_FAILURE; + if ( !op->in.user_hnd || !op->in.ctr || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + srv = cac_GetServer( hnd ); + if ( !srv ) { + hnd->status = NT_STATUS_INVALID_CONNECTION; + return CAC_FAILURE; + } - if(!op->in.user_hnd || op->in.info_class == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - hnd->status = rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, op->in.info_class, &ctr_out); + hnd->status = + rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, + op->in.ctr->switch_value, + &srv->cli->user_session_key, + op->in.ctr ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.ctr = ctr_out; + return CAC_SUCCESS; - return CAC_SUCCESS; } -int cac_SamSetUserInfoCtr(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetUserInfoCtr *op) { - SMBCSRV *srv = NULL; - struct rpc_pipe_client *pipe_hnd = NULL; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } +int cac_SamRenameUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamRenameUser *op ) +{ + SMBCSRV *srv = NULL; + struct rpc_pipe_client *pipe_hnd = NULL; - if(!op->in.user_hnd || !op->in.ctr || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + SAM_USERINFO_CTR ctr; + SAM_USER_INFO_7 info7; - srv = cac_GetServer(hnd); - if(!srv) { - hnd->status = NT_STATUS_INVALID_CONNECTION; - return CAC_FAILURE; - } + if ( !hnd ) + return CAC_FAILURE; - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + if ( !op->in.user_hnd || !op->in.new_name + || op->in.new_name[0] == '\0' || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, op->in.ctr->switch_value, &(srv->cli.user_session_key), op->in.ctr); + srv = cac_GetServer( hnd ); + if ( !srv ) { + hnd->status = NT_STATUS_INVALID_CONNECTION; + return CAC_FAILURE; + } - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - return CAC_SUCCESS; + ZERO_STRUCT( ctr ); + ZERO_STRUCT( info7 ); -} - -int cac_SamRenameUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamRenameUser *op) { - SMBCSRV *srv = NULL; - struct rpc_pipe_client *pipe_hnd = NULL; - - SAM_USERINFO_CTR ctr; - SAM_USER_INFO_7 info7; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + init_sam_user_info7( &info7, op->in.new_name ); - if(!op->in.user_hnd || !op->in.new_name || op->in.new_name[0] == '\0' || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + ctr.switch_value = 7; + ctr.info.id7 = &info7; - srv = cac_GetServer(hnd); - if(!srv) { - hnd->status = NT_STATUS_INVALID_CONNECTION; - return CAC_FAILURE; - } + hnd->status = + rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, + 7, &srv->cli->user_session_key, + &ctr ); - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - ZERO_STRUCT(ctr); - ZERO_STRUCT(info7); + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - init_sam_user_info7(&info7, op->in.new_name); - - ctr.switch_value = 7; - ctr.info.id7 = &info7; - - hnd->status = rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, 7, &(srv->cli.user_session_key), &ctr); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamGetGroupInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetGroupInfo *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamGetGroupInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetGroupInfo *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - GROUP_INFO_CTR *ctr; + GROUP_INFO_CTR *ctr; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op->in.group_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op->in.group_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - /*get a GROUP_INFO_1 structure*/ - hnd->status = rpccli_samr_query_groupinfo( pipe_hnd, mem_ctx, op->in.group_hnd, 1, &ctr); + /*get a GROUP_INFO_1 structure */ + hnd->status = + rpccli_samr_query_groupinfo( pipe_hnd, mem_ctx, + op->in.group_hnd, 1, &ctr ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.info = cac_MakeGroupInfo(mem_ctx, ctr); - if(!op->out.info) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + op->out.info = cac_MakeGroupInfo( mem_ctx, ctr ); + if ( !op->out.info ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamSetGroupInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetGroupInfo *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamSetGroupInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamSetGroupInfo *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - GROUP_INFO_CTR *ctr = NULL; + GROUP_INFO_CTR *ctr = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op->in.group_hnd || !op->in.info || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op->in.group_hnd || !op->in.info || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - ctr = cac_MakeGroupInfoCtr(mem_ctx, op->in.info); - if(!ctr) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + ctr = cac_MakeGroupInfoCtr( mem_ctx, op->in.info ); + if ( !ctr ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, op->in.group_hnd, ctr); + hnd->status = + rpccli_samr_set_groupinfo( pipe_hnd, mem_ctx, + op->in.group_hnd, ctr ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamRenameGroup(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamRenameGroup *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamRenameGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamRenameGroup *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - GROUP_INFO_CTR ctr; + GROUP_INFO_CTR ctr; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op->in.group_hnd || !op->in.new_name || op->in.new_name[0] == '\0' || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op->in.group_hnd || !op->in.new_name + || op->in.new_name[0] == '\0' || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - ZERO_STRUCT(ctr); + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - init_samr_group_info2(&ctr.group.info2, op->in.new_name); - ctr.switch_value1 = 2; - - hnd->status = rpccli_samr_set_groupinfo( pipe_hnd, mem_ctx, op->in.group_hnd, &ctr); + ZERO_STRUCT( ctr ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + init_samr_group_info2( &ctr.group.info2, op->in.new_name ); + ctr.switch_value1 = 2; - return CAC_SUCCESS; -} + hnd->status = + rpccli_samr_set_groupinfo( pipe_hnd, mem_ctx, + op->in.group_hnd, &ctr ); -int cac_SamGetAliasInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetAliasInfo *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - ALIAS_INFO_CTR ctr; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op->in.alias_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - /*get a GROUP_INFO_1 structure*/ - hnd->status = rpccli_samr_query_alias_info( pipe_hnd, mem_ctx, op->in.alias_hnd, 1, &ctr); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - op->out.info = cac_MakeAliasInfo(mem_ctx, ctr); - if(!op->out.info) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - return CAC_SUCCESS; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + return CAC_SUCCESS; } -int cac_SamSetAliasInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetAliasInfo *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamGetAliasInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetAliasInfo *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - ALIAS_INFO_CTR *ctr = NULL; + ALIAS_INFO_CTR ctr; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op->in.alias_hnd || !op->in.info || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op->in.alias_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - ctr = cac_MakeAliasInfoCtr(mem_ctx, op->in.info); - if(!ctr) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + /*get a GROUP_INFO_1 structure */ + hnd->status = + rpccli_samr_query_alias_info( pipe_hnd, mem_ctx, + op->in.alias_hnd, 1, &ctr ); - hnd->status = rpccli_samr_set_aliasinfo(pipe_hnd, mem_ctx, op->in.alias_hnd, ctr); + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + op->out.info = cac_MakeAliasInfo( mem_ctx, ctr ); + if ( !op->out.info ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - return CAC_SUCCESS; -} + return CAC_SUCCESS; -int cac_SamGetDomainInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetDomainInfo *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - SAM_UNK_CTR ctr; - SAM_UNK_INFO_1 info1; - SAM_UNK_INFO_2 info2; - SAM_UNK_INFO_12 info12; - - /*use this to keep track of a failed call*/ - NTSTATUS status_buf = NT_STATUS_OK; - - uint16 fail_count = 0; - - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op->in.dom_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - /*first try with info 1*/ - hnd->status = rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, 1, &ctr); - - if(NT_STATUS_IS_OK(hnd->status)) { - /*then we buffer the SAM_UNK_INFO_1 structure*/ - info1 = ctr.info.inf1; - } - else { - /*then the call failed, store the status and ZERO out the info structure*/ - ZERO_STRUCT(info1); - status_buf = hnd->status; - fail_count++; - } - - /*try again for the next one*/ - hnd->status = rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, 2, &ctr); - - if(NT_STATUS_IS_OK(hnd->status)) { - /*store the info*/ - info2 = ctr.info.inf2; - } - else { - /*ZERO out the structure and store the bad status*/ - ZERO_STRUCT(info2); - status_buf = hnd->status; - fail_count++; - } - - /*once more*/ - hnd->status = rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, 12, &ctr); - - if(NT_STATUS_IS_OK(hnd->status)) { - info12 = ctr.info.inf12; - } - else { - ZERO_STRUCT(info12); - status_buf = hnd->status; - fail_count++; - } - - /*return failure if all 3 calls failed*/ - if(fail_count == 3) - return CAC_FAILURE; - - op->out.info = cac_MakeDomainInfo(mem_ctx, &info1, &info2, &info12); - - if(!op->out.info) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - if(fail_count > 0) { - hnd->status = status_buf; - return CAC_PARTIAL_SUCCESS; - } - - return CAC_SUCCESS; } -int cac_SamGetDomainInfoCtr(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetDomainInfoCtr *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - SAM_UNK_CTR *ctr_out; +int cac_SamSetAliasInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamSetAliasInfo *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - if(!hnd) - return CAC_FAILURE; + ALIAS_INFO_CTR *ctr = NULL; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd ) + return CAC_FAILURE; - if(!op->in.dom_hnd || op->in.info_class == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !op->in.alias_hnd || !op->in.info || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - ctr_out = talloc(mem_ctx, SAM_UNK_CTR); - if(!ctr_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + ctr = cac_MakeAliasInfoCtr( mem_ctx, op->in.info ); + if ( !ctr ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.info_class, ctr_out); + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + hnd->status = + rpccli_samr_set_aliasinfo( pipe_hnd, mem_ctx, + op->in.alias_hnd, ctr ); - op->out.info = ctr_out; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamGetDisplayInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetDisplayInfo *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - - SAM_DISPINFO_CTR ctr_out; - - uint32 max_entries_buf = 0; - uint32 max_size_buf = 0; - - uint32 resume_idx_out; - uint32 num_entries_out; +int cac_SamGetDomainInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetDomainInfo *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + SAM_UNK_CTR ctr; + SAM_UNK_INFO_1 info1; + SAM_UNK_INFO_2 info2; + SAM_UNK_INFO_12 info12; + + /*use this to keep track of a failed call */ + NTSTATUS status_buf = NT_STATUS_OK; + + uint16 fail_count = 0; + + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op->in.dom_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + /*first try with info 1 */ + hnd->status = + rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, + 1, &ctr ); + + if ( NT_STATUS_IS_OK( hnd->status ) ) { + /*then we buffer the SAM_UNK_INFO_1 structure */ + info1 = ctr.info.inf1; + } else { + /*then the call failed, store the status and ZERO out the info structure */ + ZERO_STRUCT( info1 ); + status_buf = hnd->status; + fail_count++; + } + + /*try again for the next one */ + hnd->status = + rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, + 2, &ctr ); + + if ( NT_STATUS_IS_OK( hnd->status ) ) { + /*store the info */ + info2 = ctr.info.inf2; + } else { + /*ZERO out the structure and store the bad status */ + ZERO_STRUCT( info2 ); + status_buf = hnd->status; + fail_count++; + } + + /*once more */ + hnd->status = + rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, + 12, &ctr ); + + if ( NT_STATUS_IS_OK( hnd->status ) ) { + info12 = ctr.info.inf12; + } else { + ZERO_STRUCT( info12 ); + status_buf = hnd->status; + fail_count++; + } + + /*return failure if all 3 calls failed */ + if ( fail_count == 3 ) + return CAC_FAILURE; + + op->out.info = cac_MakeDomainInfo( mem_ctx, &info1, &info2, &info12 ); + + if ( !op->out.info ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + if ( fail_count > 0 ) { + hnd->status = status_buf; + return CAC_PARTIAL_SUCCESS; + } + + return CAC_SUCCESS; +} - if(!hnd) - return CAC_FAILURE; +int cac_SamGetDomainInfoCtr( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetDomainInfoCtr *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + SAM_UNK_CTR *ctr_out; - if(!op->in.dom_hnd || op->in.info_class == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !hnd ) + return CAC_FAILURE; - if(op->out.done == True) /*this is done so we can use the function as a loop condition*/ - return CAC_FAILURE; + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !op->in.dom_hnd || op->in.info_class == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(op->in.max_entries == 0 || op->in.max_size == 0) { - get_query_dispinfo_params(op->out.loop_count, &max_entries_buf, &max_size_buf); - } - else { - max_entries_buf = op->in.max_entries; - max_size_buf = op->in.max_size; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - resume_idx_out = op->out.resume_idx; + ctr_out = talloc( mem_ctx, SAM_UNK_CTR ); + if ( !ctr_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_query_dispinfo( pipe_hnd, mem_ctx, op->in.dom_hnd, &resume_idx_out, op->in.info_class, - &num_entries_out, max_entries_buf, max_size_buf, &ctr_out); + hnd->status = + rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, + op->in.info_class, ctr_out ); - if(!NT_STATUS_IS_OK(hnd->status) && !NT_STATUS_EQUAL(hnd->status, STATUS_MORE_ENTRIES)) { - /*be defensive, maybe they'll call again without zeroing the struct*/ - op->out.loop_count = 0; - op->out.resume_idx = 0; - return CAC_FAILURE; - } + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - if(NT_STATUS_IS_OK(hnd->status)) { - /*we want to quit once the function is called next. so it can be used in a loop*/ - op->out.done = True; - } + op->out.info = ctr_out; - op->out.resume_idx = resume_idx_out; - op->out.num_entries = num_entries_out; - op->out.ctr = ctr_out; - op->out.loop_count++; + return CAC_SUCCESS; +} - return CAC_SUCCESS; +int cac_SamGetDisplayInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetDisplayInfo *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + SAM_DISPINFO_CTR ctr_out; + + uint32 max_entries_buf = 0; + uint32 max_size_buf = 0; + + uint32 resume_idx_out; + uint32 num_entries_out; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op->in.dom_hnd || op->in.info_class == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + if ( op->out.done == True ) /*this is done so we can use the function as a loop condition */ + return CAC_FAILURE; + + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( op->in.max_entries == 0 || op->in.max_size == 0 ) { + get_query_dispinfo_params( op->out.loop_count, + &max_entries_buf, &max_size_buf ); + } else { + max_entries_buf = op->in.max_entries; + max_size_buf = op->in.max_size; + } + + resume_idx_out = op->out.resume_idx; + + hnd->status = + rpccli_samr_query_dispinfo( pipe_hnd, mem_ctx, op->in.dom_hnd, + &resume_idx_out, + op->in.info_class, + &num_entries_out, max_entries_buf, + max_size_buf, &ctr_out ); + + if ( !NT_STATUS_IS_OK( hnd->status ) + && !NT_STATUS_EQUAL( hnd->status, STATUS_MORE_ENTRIES ) ) { + /*be defensive, maybe they'll call again without zeroing the struct */ + op->out.loop_count = 0; + op->out.resume_idx = 0; + return CAC_FAILURE; + } + + if ( NT_STATUS_IS_OK( hnd->status ) ) { + /*we want to quit once the function is called next. so it can be used in a loop */ + op->out.done = True; + } + + op->out.resume_idx = resume_idx_out; + op->out.num_entries = num_entries_out; + op->out.ctr = ctr_out; + op->out.loop_count++; + + return CAC_SUCCESS; } -int cac_SamLookupDomain(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamLookupDomain *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamLookupDomain( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamLookupDomain *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + DOM_SID *sid_out = NULL; - DOM_SID *sid_out = NULL; - - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op->in.sam || !op->in.name || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op->in.sam || !op->in.name || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - sid_out = talloc(mem_ctx, DOM_SID); - if(!sid_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + sid_out = talloc( mem_ctx, DOM_SID ); + if ( !sid_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_lookup_domain( pipe_hnd, mem_ctx, op->in.sam, op->in.name, sid_out); + hnd->status = + rpccli_samr_lookup_domain( pipe_hnd, mem_ctx, op->in.sam, + op->in.name, sid_out ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.sid = sid_out; + op->out.sid = sid_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamGetSecurityObject(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetSecurityObject *op) { - struct rpc_pipe_client *pipe_hnd = NULL; +int cac_SamGetSecurityObject( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamGetSecurityObject *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; - /*this number taken from rpcclient/cmd_samr.c, I think it is the only supported level*/ - uint32 sec_info = DACL_SECURITY_INFORMATION; + /*this number taken from rpcclient/cmd_samr.c, I think it is the only supported level */ + uint32 sec_info = DACL_SECURITY_INFORMATION; - SEC_DESC_BUF *sec_out = NULL; + SEC_DESC_BUF *sec_out = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op->in.pol || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op->in.pol || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SAMR); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SAMR ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - hnd->status = rpccli_samr_query_sec_obj(pipe_hnd, mem_ctx, op->in.pol, sec_info, mem_ctx, &sec_out); + hnd->status = + rpccli_samr_query_sec_obj( pipe_hnd, mem_ctx, op->in.pol, + sec_info, mem_ctx, &sec_out ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.sec = sec_out; + op->out.sec = sec_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SamFlush(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamFlush *op) { - struct SamOpenDomain od; +int cac_SamFlush( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SamFlush *op ) +{ + struct SamOpenDomain od; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.dom_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.dom_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(!cac_SamClose(hnd, mem_ctx, op->in.dom_hnd)) - return CAC_FAILURE; + if ( !cac_SamClose( hnd, mem_ctx, op->in.dom_hnd ) ) + return CAC_FAILURE; - ZERO_STRUCT(od); - od.in.access = (op->in.access) ? op->in.access : MAXIMUM_ALLOWED_ACCESS; - od.in.sid = op->in.sid; + ZERO_STRUCT( od ); + od.in.access = + ( op->in.access ) ? op->in.access : MAXIMUM_ALLOWED_ACCESS; + od.in.sid = op->in.sid; - if(!cac_SamOpenDomain(hnd, mem_ctx, &od)) - return CAC_FAILURE; + if ( !cac_SamOpenDomain( hnd, mem_ctx, &od ) ) + return CAC_FAILURE; - /*this function does not use an output parameter to make it as convenient as possible to use*/ - *op->in.dom_hnd = *od.out.dom_hnd; + /*this function does not use an output parameter to make it as convenient as possible to use */ + *op->in.dom_hnd = *od.out.dom_hnd; - TALLOC_FREE(od.out.dom_hnd); + TALLOC_FREE( od.out.dom_hnd ); - return CAC_SUCCESS; + return CAC_SUCCESS; } diff --git a/source/libmsrpc/cac_svcctl.c b/source/libmsrpc/cac_svcctl.c index 83dc0364930..9f61b421298 100644 --- a/source/libmsrpc/cac_svcctl.c +++ b/source/libmsrpc/cac_svcctl.c @@ -1,3 +1,4 @@ + /* * Unix SMB/CIFS implementation. * MS-RPC client library implementation (SVCCTL pipe) @@ -23,259 +24,288 @@ #define WAIT_SLEEP_TIME 300000 -int cac_SvcOpenScm(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcOpenScm *op) { - SMBCSRV *srv = NULL; - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; - - POLICY_HND *scm_out = NULL; - - if(!hnd) - return CAC_FAILURE; - - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - if(!op || op->in.access == 0 || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } - - srv = cac_GetServer(hnd); - if(!srv) { - hnd->status = NT_STATUS_INVALID_CONNECTION; - return CAC_FAILURE; - } - - /*initialize for samr pipe if we have to*/ - if(!hnd->_internal.pipes[PI_SVCCTL]) { - if(!(pipe_hnd = cli_rpc_pipe_open_noauth(&srv->cli, PI_SVCCTL, &(hnd->status)))) { - hnd->status = NT_STATUS_UNSUCCESSFUL; - return CAC_FAILURE; - } - - hnd->_internal.pipes[PI_SVCCTL] = True; - } - - scm_out = talloc(mem_ctx, POLICY_HND); - if(!scm_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } - - err = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, scm_out, op->in.access); - hnd->status = werror_to_ntstatus(err); - - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; - - op->out.scm_hnd = scm_out; - - return CAC_SUCCESS; +int cac_SvcOpenScm( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SvcOpenScm *op ) +{ + SMBCSRV *srv = NULL; + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; + + POLICY_HND *scm_out = NULL; + + if ( !hnd ) + return CAC_FAILURE; + + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + if ( !op || op->in.access == 0 || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } + + srv = cac_GetServer( hnd ); + if ( !srv ) { + hnd->status = NT_STATUS_INVALID_CONNECTION; + return CAC_FAILURE; + } + + /*initialize for samr pipe if we have to */ + if ( !hnd->_internal.pipes[PI_SVCCTL] ) { + if ( ! + ( pipe_hnd = + cli_rpc_pipe_open_noauth( srv->cli, PI_SVCCTL, + &( hnd->status ) ) ) ) { + hnd->status = NT_STATUS_UNSUCCESSFUL; + return CAC_FAILURE; + } + + hnd->_internal.pipes[PI_SVCCTL] = True; + } + + scm_out = talloc( mem_ctx, POLICY_HND ); + if ( !scm_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } + + err = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, scm_out, + op->in.access ); + hnd->status = werror_to_ntstatus( err ); + + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; + + op->out.scm_hnd = scm_out; + + return CAC_SUCCESS; } -int cac_SvcClose(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *scm_hnd) { - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; +int cac_SvcClose( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + POLICY_HND * scm_hnd ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!scm_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !scm_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - err = rpccli_svcctl_close_service( pipe_hnd, mem_ctx, scm_hnd); - hnd->status = werror_to_ntstatus(err); + err = rpccli_svcctl_close_service( pipe_hnd, mem_ctx, scm_hnd ); + hnd->status = werror_to_ntstatus( err ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SvcEnumServices(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcEnumServices *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; +int cac_SvcEnumServices( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SvcEnumServices *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; - uint32 type_buf = 0; - uint32 state_buf = 0; + uint32 type_buf = 0; + uint32 state_buf = 0; - uint32 num_svc_out = 0; + uint32 num_svc_out = 0; - ENUM_SERVICES_STATUS *svc_buf = NULL; + ENUM_SERVICES_STATUS *svc_buf = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.scm_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.scm_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - type_buf = (op->in.type != 0) ? op->in.type : (SVCCTL_TYPE_DRIVER | SVCCTL_TYPE_WIN32); - state_buf = (op->in.state != 0) ? op->in.state : SVCCTL_STATE_ALL; + type_buf = + ( op->in.type != + 0 ) ? op->in. + type : ( SVCCTL_TYPE_DRIVER | SVCCTL_TYPE_WIN32 ); + state_buf = ( op->in.state != 0 ) ? op->in.state : SVCCTL_STATE_ALL; - err = rpccli_svcctl_enumerate_services( pipe_hnd, mem_ctx, op->in.scm_hnd, type_buf, state_buf, &num_svc_out, &svc_buf); - hnd->status = werror_to_ntstatus(err); + err = rpccli_svcctl_enumerate_services( pipe_hnd, mem_ctx, + op->in.scm_hnd, type_buf, + state_buf, &num_svc_out, + &svc_buf ); + hnd->status = werror_to_ntstatus( err ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.services = cac_MakeServiceArray(mem_ctx, svc_buf, num_svc_out); + op->out.services = + cac_MakeServiceArray( mem_ctx, svc_buf, num_svc_out ); - if(!op->out.services) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + if ( !op->out.services ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - TALLOC_FREE(svc_buf); + TALLOC_FREE( svc_buf ); - op->out.num_services = num_svc_out; + op->out.num_services = num_svc_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SvcOpenService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcOpenService *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; +int cac_SvcOpenService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SvcOpenService *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; - POLICY_HND *svc_hnd_out = NULL; + POLICY_HND *svc_hnd_out = NULL; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.scm_hnd || !op->in.name || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.scm_hnd || !op->in.name || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - svc_hnd_out = talloc(mem_ctx, POLICY_HND); - if(!svc_hnd_out) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + svc_hnd_out = talloc( mem_ctx, POLICY_HND ); + if ( !svc_hnd_out ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - err = rpccli_svcctl_open_service( pipe_hnd, mem_ctx, op->in.scm_hnd, svc_hnd_out, op->in.name, op->in.access); - hnd->status = werror_to_ntstatus(err); + err = rpccli_svcctl_open_service( pipe_hnd, mem_ctx, op->in.scm_hnd, + svc_hnd_out, op->in.name, + op->in.access ); + hnd->status = werror_to_ntstatus( err ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.svc_hnd = svc_hnd_out; + op->out.svc_hnd = svc_hnd_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SvcControlService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcControlService *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; +int cac_SvcControlService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SvcControlService *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; - SERVICE_STATUS status_out; + SERVICE_STATUS status_out; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.svc_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.svc_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(op->in.control < SVCCTL_CONTROL_STOP || op->in.control > SVCCTL_CONTROL_SHUTDOWN) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( op->in.control < SVCCTL_CONTROL_STOP + || op->in.control > SVCCTL_CONTROL_SHUTDOWN ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, op->in.svc_hnd, op->in.control, &status_out); - hnd->status = werror_to_ntstatus(err); + err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, + op->in.svc_hnd, op->in.control, + &status_out ); + hnd->status = werror_to_ntstatus( err ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SvcGetStatus(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcGetStatus *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; +int cac_SvcGetStatus( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SvcGetStatus *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; - SERVICE_STATUS status_out; + SERVICE_STATUS status_out; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.svc_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.svc_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - err = rpccli_svcctl_query_status( pipe_hnd, mem_ctx, op->in.svc_hnd, &status_out); - hnd->status = werror_to_ntstatus(err); + err = rpccli_svcctl_query_status( pipe_hnd, mem_ctx, op->in.svc_hnd, + &status_out ); + hnd->status = werror_to_ntstatus( err ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.status = status_out; + op->out.status = status_out; - return CAC_SUCCESS; + return CAC_SUCCESS; } @@ -288,273 +318,313 @@ int cac_SvcGetStatus(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcGetSta * returns CAC_FAILURE if the state is never reached * or CAC_SUCCESS if the state is reached */ -int cac_WaitForService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *svc_hnd, uint32 state, uint32 timeout, SERVICE_STATUS *status) { - struct rpc_pipe_client *pipe_hnd = NULL; - /*number of milliseconds we have spent*/ - uint32 time_spent = 0; - WERROR err; - - if(!hnd || !mem_ctx || !svc_hnd || !status) - return CAC_FAILURE; - - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } - - while(status->state != state && time_spent < (timeout * 1000000) && NT_STATUS_IS_OK(hnd->status)) { - /*if this is the first call, then we _just_ got the status.. sleep now*/ - usleep(WAIT_SLEEP_TIME); - time_spent += WAIT_SLEEP_TIME; - - err = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, svc_hnd, status); - hnd->status = werror_to_ntstatus(err); - } - - if(status->state == state) - return CAC_SUCCESS; - - return CAC_FAILURE; +int cac_WaitForService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + POLICY_HND * svc_hnd, uint32 state, uint32 timeout, + SERVICE_STATUS * status ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + + /*number of milliseconds we have spent */ + uint32 time_spent = 0; + WERROR err; + + if ( !hnd || !mem_ctx || !svc_hnd || !status ) + return CAC_FAILURE; + + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } + + while ( status->state != state && time_spent < ( timeout * 1000000 ) + && NT_STATUS_IS_OK( hnd->status ) ) { + /*if this is the first call, then we _just_ got the status.. sleep now */ + usleep( WAIT_SLEEP_TIME ); + time_spent += WAIT_SLEEP_TIME; + + err = rpccli_svcctl_query_status( pipe_hnd, mem_ctx, svc_hnd, + status ); + hnd->status = werror_to_ntstatus( err ); + } + + if ( status->state == state ) + return CAC_SUCCESS; + + return CAC_FAILURE; } -int cac_SvcStartService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcStartService *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; +int cac_SvcStartService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SvcStartService *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; - SERVICE_STATUS status_buf; + SERVICE_STATUS status_buf; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.svc_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.svc_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - if(op->in.num_parms != 0 && op->in.parms == NULL) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( op->in.num_parms != 0 && op->in.parms == NULL ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - err = rpccli_svcctl_start_service(pipe_hnd, mem_ctx, op->in.svc_hnd, (const char **)op->in.parms, op->in.num_parms); - hnd->status = werror_to_ntstatus(err); + err = rpccli_svcctl_start_service( pipe_hnd, mem_ctx, op->in.svc_hnd, + ( const char ** ) op->in.parms, + op->in.num_parms ); + hnd->status = werror_to_ntstatus( err ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - if(op->in.timeout == 0) - return CAC_SUCCESS; + if ( op->in.timeout == 0 ) + return CAC_SUCCESS; - return cac_WaitForService(hnd, mem_ctx, op->in.svc_hnd, SVCCTL_RUNNING, op->in.timeout, &status_buf); + return cac_WaitForService( hnd, mem_ctx, op->in.svc_hnd, + SVCCTL_RUNNING, op->in.timeout, + &status_buf ); } -int cac_SvcStopService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcStopService *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; +int cac_SvcStopService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SvcStopService *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; - SERVICE_STATUS status_out; + SERVICE_STATUS status_out; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.svc_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.svc_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, op->in.svc_hnd, SVCCTL_CONTROL_STOP, &status_out); - hnd->status = werror_to_ntstatus(err); + err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, + op->in.svc_hnd, + SVCCTL_CONTROL_STOP, + &status_out ); + hnd->status = werror_to_ntstatus( err ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.status = status_out; + op->out.status = status_out; - if(op->in.timeout == 0) - return CAC_SUCCESS; + if ( op->in.timeout == 0 ) + return CAC_SUCCESS; - return cac_WaitForService(hnd, mem_ctx, op->in.svc_hnd, SVCCTL_STOPPED, op->in.timeout, &op->out.status); + return cac_WaitForService( hnd, mem_ctx, op->in.svc_hnd, + SVCCTL_STOPPED, op->in.timeout, + &op->out.status ); } -int cac_SvcPauseService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcPauseService *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; +int cac_SvcPauseService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SvcPauseService *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; - SERVICE_STATUS status_out; + SERVICE_STATUS status_out; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.svc_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.svc_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, op->in.svc_hnd, SVCCTL_CONTROL_PAUSE, &status_out); - hnd->status = werror_to_ntstatus(err); + err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, + op->in.svc_hnd, + SVCCTL_CONTROL_PAUSE, + &status_out ); + hnd->status = werror_to_ntstatus( err ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.status = status_out; + op->out.status = status_out; - if(op->in.timeout == 0) - return CAC_SUCCESS; + if ( op->in.timeout == 0 ) + return CAC_SUCCESS; - return cac_WaitForService(hnd, mem_ctx, op->in.svc_hnd, SVCCTL_PAUSED, op->in.timeout, &op->out.status); + return cac_WaitForService( hnd, mem_ctx, op->in.svc_hnd, + SVCCTL_PAUSED, op->in.timeout, + &op->out.status ); } -int cac_SvcContinueService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcContinueService *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; +int cac_SvcContinueService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SvcContinueService *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; - SERVICE_STATUS status_out; + SERVICE_STATUS status_out; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.svc_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.svc_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, op->in.svc_hnd, SVCCTL_CONTROL_CONTINUE, &status_out); - hnd->status = werror_to_ntstatus(err); + err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, + op->in.svc_hnd, + SVCCTL_CONTROL_CONTINUE, + &status_out ); + hnd->status = werror_to_ntstatus( err ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.status = status_out; + op->out.status = status_out; - if(op->in.timeout == 0) - return CAC_SUCCESS; + if ( op->in.timeout == 0 ) + return CAC_SUCCESS; - return cac_WaitForService(hnd, mem_ctx, op->in.svc_hnd, SVCCTL_RUNNING, op->in.timeout, &op->out.status); + return cac_WaitForService( hnd, mem_ctx, op->in.svc_hnd, + SVCCTL_RUNNING, op->in.timeout, + &op->out.status ); } -int cac_SvcGetDisplayName(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcGetDisplayName *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; +int cac_SvcGetDisplayName( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SvcGetDisplayName *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; - fstring disp_name_out; + fstring disp_name_out; - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.svc_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.svc_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - err = rpccli_svcctl_get_dispname( pipe_hnd, mem_ctx, op->in.svc_hnd, disp_name_out); - hnd->status = werror_to_ntstatus(err); + err = rpccli_svcctl_get_dispname( pipe_hnd, mem_ctx, op->in.svc_hnd, + disp_name_out ); + hnd->status = werror_to_ntstatus( err ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - op->out.display_name = talloc_strdup(mem_ctx, disp_name_out); + op->out.display_name = talloc_strdup( mem_ctx, disp_name_out ); - if(!op->out.display_name) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + if ( !op->out.display_name ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - return CAC_SUCCESS; + return CAC_SUCCESS; } -int cac_SvcGetServiceConfig(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcGetServiceConfig *op) { - struct rpc_pipe_client *pipe_hnd = NULL; - WERROR err; +int cac_SvcGetServiceConfig( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, + struct SvcGetServiceConfig *op ) +{ + struct rpc_pipe_client *pipe_hnd = NULL; + WERROR err; + + SERVICE_CONFIG config_out; - SERVICE_CONFIG config_out; - - if(!hnd) - return CAC_FAILURE; + if ( !hnd ) + return CAC_FAILURE; - if(!hnd->_internal.ctx) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + if ( !hnd->_internal.ctx ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - if(!op || !op->in.svc_hnd || !mem_ctx) { - hnd->status = NT_STATUS_INVALID_PARAMETER; - return CAC_FAILURE; - } + if ( !op || !op->in.svc_hnd || !mem_ctx ) { + hnd->status = NT_STATUS_INVALID_PARAMETER; + return CAC_FAILURE; + } - pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL); - if(!pipe_hnd) { - hnd->status = NT_STATUS_INVALID_HANDLE; - return CAC_FAILURE; - } + pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL ); + if ( !pipe_hnd ) { + hnd->status = NT_STATUS_INVALID_HANDLE; + return CAC_FAILURE; + } - err = rpccli_svcctl_query_config( pipe_hnd, mem_ctx, op->in.svc_hnd, &config_out); - hnd->status = werror_to_ntstatus(err); + err = rpccli_svcctl_query_config( pipe_hnd, mem_ctx, op->in.svc_hnd, + &config_out ); + hnd->status = werror_to_ntstatus( err ); - if(!NT_STATUS_IS_OK(hnd->status)) - return CAC_FAILURE; + if ( !NT_STATUS_IS_OK( hnd->status ) ) + return CAC_FAILURE; - if(!cac_InitCacServiceConfig(mem_ctx, &config_out, &op->out.config)) { - hnd->status = NT_STATUS_NO_MEMORY; - return CAC_FAILURE; - } + if ( !cac_InitCacServiceConfig + ( mem_ctx, &config_out, &op->out.config ) ) { + hnd->status = NT_STATUS_NO_MEMORY; + return CAC_FAILURE; + } - return CAC_SUCCESS; + return CAC_SUCCESS; } diff --git a/source/libmsrpc/libmsrpc_internal.c b/source/libmsrpc/libmsrpc_internal.c index 1295c510da3..36e604f90ff 100644 --- a/source/libmsrpc/libmsrpc_internal.c +++ b/source/libmsrpc/libmsrpc_internal.c @@ -44,7 +44,7 @@ struct rpc_pipe_client *cac_GetPipe( CacServerHandle * hnd, int pi_idx ) return NULL; } - pipe_hnd = srv->cli.pipe_list; + pipe_hnd = srv->cli->pipe_list; while ( pipe_hnd != NULL && pipe_hnd->pipe_idx != pi_idx ) { pipe_hnd = pipe_hnd->next; @@ -129,7 +129,7 @@ RPC_DATA_BLOB *cac_MakeRpcDataBlob( TALLOC_CTX * mem_ctx, uint32 data_type, init_rpc_blob_uint32( blob, data.reg_dword ); break; - case REG_DWORD_BE: + case REG_DWORD_BIG_ENDIAN: init_rpc_blob_uint32( blob, data.reg_dword_be ); break; @@ -274,7 +274,7 @@ REG_VALUE_DATA *cac_MakeRegValueData( TALLOC_CTX * mem_ctx, uint32 data_type, data->reg_dword = *( ( uint32 * ) buf.buffer ); break; - case REG_DWORD_BE: + case REG_DWORD_BIG_ENDIAN: data->reg_dword_be = *( ( uint32 * ) buf.buffer ); break; @@ -511,7 +511,7 @@ CacUserInfo *cac_MakeUserInfo( TALLOC_CTX * mem_ctx, SAM_USERINFO_CTR * ctr ) info->logon_hours = ( LOGON_HRS * ) talloc_memdup( mem_ctx, &( id21->logon_hrs ), - sizeof( LOGON_HRS ) ); + sizeof( LOGON_HRS ) ); if ( !info->logon_hours ) return NULL; diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c index 783cf0c1853..f29449cfb22 100644 --- a/source/libsmb/cliconnect.c +++ b/source/libsmb/cliconnect.c @@ -56,16 +56,19 @@ static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_ Do an old lanman2 style session setup. ****************************************************************************/ -static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, - const char *pass, size_t passlen, const char *workgroup) +static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, + const char *user, + const char *pass, size_t passlen, + const char *workgroup) { DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB lm_response = data_blob(NULL, 0); fstring pword; char *p; - if (passlen > sizeof(pword)-1) - return False; + if (passlen > sizeof(pword)-1) { + return NT_STATUS_INVALID_PARAMETER; + } /* LANMAN servers predate NT status codes and Unicode and ignore those smb flags so we must disable the corresponding default capabilities @@ -83,7 +86,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, lm_response = data_blob(NULL, 24); if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) { DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { /* Encrypted mode needed, and encrypted password supplied. */ @@ -116,14 +119,15 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { + return cli_nt_error(cli); + } show_msg(cli->inbuf); - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -134,7 +138,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, cli_set_session_key(cli, session_key); } - return True; + return NT_STATUS_OK; } /**************************************************************************** @@ -159,7 +163,7 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) Do a NT1 guest session setup. ****************************************************************************/ -static BOOL cli_session_setup_guest(struct cli_state *cli) +static NTSTATUS cli_session_setup_guest(struct cli_state *cli) { char *p; uint32 capabilities = cli_session_setup_capabilities(cli); @@ -184,14 +188,15 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { + return cli_nt_error(cli); + } show_msg(cli->inbuf); - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -206,15 +211,16 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) fstrcpy(cli->user_name, ""); - return True; + return NT_STATUS_OK; } /**************************************************************************** Do a NT1 plaintext session setup. ****************************************************************************/ -static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, - const char *pass, const char *workgroup) +static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, + const char *user, const char *pass, + const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; @@ -253,14 +259,15 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, p += clistr_push(cli, p, lanman, -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { + return cli_nt_error(cli); + } show_msg(cli->inbuf); - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } cli->vuid = SVAL(cli->inbuf,smb_uid); p = smb_buf(cli->inbuf); @@ -273,7 +280,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, cli->is_samba = True; } - return True; + return NT_STATUS_OK; } /**************************************************************************** @@ -286,16 +293,16 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, @param workgroup The user's domain. ****************************************************************************/ -static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, - const char *pass, size_t passlen, - const char *ntpass, size_t ntpasslen, - const char *workgroup) +static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, + const char *pass, size_t passlen, + const char *ntpass, size_t ntpasslen, + const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); DATA_BLOB lm_response = data_blob(NULL, 0); DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); - BOOL ret = False; + NTSTATUS result; char *p; if (passlen == 0) { @@ -317,7 +324,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, &lm_response, &nt_response, &session_key)) { data_blob_free(&names_blob); data_blob_free(&server_chal); - return False; + return NT_STATUS_ACCESS_DENIED; } data_blob_free(&names_blob); data_blob_free(&server_chal); @@ -399,14 +406,14 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, cli_setup_bcc(cli, p); if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { - ret = False; + result = cli_nt_error(cli); goto end; } /* show_msg(cli->inbuf); */ if (cli_is_error(cli)) { - ret = False; + result = cli_nt_error(cli); goto end; } @@ -429,12 +436,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, cli_set_session_key(cli, session_key); } - ret = True; + result = NT_STATUS_OK; end: data_blob_free(&lm_response); data_blob_free(&nt_response); data_blob_free(&session_key); - return ret; + return result; } /**************************************************************************** @@ -600,6 +607,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return nt_status; } + ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { return nt_status; @@ -762,7 +770,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, * sent. -- VL */ DEBUG(1, ("Kerberos mech was offered, but no principal was " - "sent, disabling Kerberos\n")); + "sent, disabling Kerberos\n")); cli->use_kerberos = False; } @@ -811,11 +819,11 @@ ntlmssp: password is in plaintext, the same should be done. ****************************************************************************/ -BOOL cli_session_setup(struct cli_state *cli, - const char *user, - const char *pass, int passlen, - const char *ntpass, int ntpasslen, - const char *workgroup) +NTSTATUS cli_session_setup(struct cli_state *cli, + const char *user, + const char *pass, int passlen, + const char *ntpass, int ntpasslen, + const char *workgroup) { char *p; fstring user2; @@ -829,8 +837,9 @@ BOOL cli_session_setup(struct cli_state *cli, workgroup = user2; } - if (cli->protocol < PROTOCOL_LANMAN1) - return True; + if (cli->protocol < PROTOCOL_LANMAN1) { + return NT_STATUS_OK; + } /* now work out what sort of session setup we are going to do. I have split this into separate functions to make the @@ -842,17 +851,18 @@ BOOL cli_session_setup(struct cli_state *cli, if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) { DEBUG(1, ("Server requested LM password but 'client lanman auth'" " is disabled\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 && !lp_client_plaintext_auth() && (*pass)) { DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" " is disabled\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } - return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); + return cli_session_setup_lanman2(cli, user, pass, passlen, + workgroup); } /* if no user is supplied then we have to do an anonymous connection. @@ -875,7 +885,7 @@ BOOL cli_session_setup(struct cli_state *cli, if (!lp_client_plaintext_auth() && (*pass)) { DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" " is disabled\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } return cli_session_setup_plaintext(cli, user, pass, workgroup); } @@ -886,13 +896,18 @@ BOOL cli_session_setup(struct cli_state *cli, ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup); if (!ADS_ERR_OK(status)) { DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status))); - return False; + return ads_ntstatus(status); } } else { + NTSTATUS status; + /* otherwise do a NT1 style session setup */ - if ( !cli_session_setup_nt1(cli, user, pass, passlen, ntpass, ntpasslen, workgroup) ) { - DEBUG(3,("cli_session_setup: NT1 session setup failed!\n")); - return False; + status = cli_session_setup_nt1(cli, user, pass, passlen, + ntpass, ntpasslen, workgroup); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3,("cli_session_setup: NT1 session setup " + "failed: %s\n", nt_errstr(status))); + return status; } } @@ -900,7 +915,7 @@ BOOL cli_session_setup(struct cli_state *cli, cli->is_samba = True; } - return True; + return NT_STATUS_OK; } @@ -1406,8 +1421,9 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, if (!my_name) my_name = global_myname(); - if (!(cli = cli_initialise(NULL))) + if (!(cli = cli_initialise())) { return NT_STATUS_NO_MEMORY; + } make_nmb_name(&calling, my_name, 0x0); make_nmb_name(&called , dest_host, 0x20); @@ -1507,6 +1523,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct cli_state *cli = NULL; int pw_len = password ? strlen(password)+1 : 0; + *output_cli = NULL; + if (password == NULL) { password = ""; } @@ -1518,19 +1536,26 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, return nt_status; } - if (!cli_session_setup(cli, user, password, pw_len, password, pw_len, domain)) { - if ((flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK) - && cli_session_setup(cli, "", "", 0, "", 0, domain)) { - } else { - nt_status = cli_nt_error(cli); - DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status))); + nt_status = cli_session_setup(cli, user, password, pw_len, password, + pw_len, domain); + if (!NT_STATUS_IS_OK(nt_status)) { + + if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) { + DEBUG(1,("failed session setup with %s\n", + nt_errstr(nt_status))); cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) - nt_status = NT_STATUS_UNSUCCESSFUL; return nt_status; } - } + nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(1,("anonymous failed session setup with %s\n", + nt_errstr(nt_status))); + cli_shutdown(cli); + return nt_status; + } + } + if (service) { if (!cli_send_tconX(cli, service, service_type, password, pw_len)) { nt_status = cli_nt_error(cli); @@ -1553,7 +1578,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. ****************************************************************************/ -BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, const char *desthost, +BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost, struct in_addr *pdest_ip) { struct nmb_name calling, called; @@ -1571,7 +1596,7 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, make_nmb_name(&called, desthost, 0x20); } - if (!cli_session_request(cli, &calling, &called)) { + if (!cli_session_request(*ppcli, &calling, &called)) { struct nmb_name smbservername; make_nmb_name(&smbservername , "*SMBSERVER", 0x20); @@ -1588,23 +1613,23 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, */ DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ -with error %s.\n", desthost, cli_errstr(cli) )); +with error %s.\n", desthost, cli_errstr(*ppcli) )); return False; } - /* - * We need to close the connection here but can't call cli_shutdown as - * will free an allocated cli struct. cli_close_connection was invented - * for this purpose. JRA. Based on work by "Kim R. Pedersen" <krp@filanet.dk>. - */ + /* Try again... */ + cli_shutdown(*ppcli); - cli_close_connection(cli); + *ppcli = cli_initialise(); + if (!*ppcli) { + /* Out of memory... */ + return False; + } - if (!cli_initialise(cli) || - !cli_connect(cli, desthost, pdest_ip) || - !cli_session_request(cli, &calling, &smbservername)) { + if (!cli_connect(*ppcli, desthost, pdest_ip) || + !cli_session_request(*ppcli, &calling, &smbservername)) { DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ -name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); +name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) )); return False; } } diff --git a/source/libsmb/clidfs.c b/source/libsmb/clidfs.c index e0c55057675..916e4cefc6e 100644 --- a/source/libsmb/clidfs.c +++ b/source/libsmb/clidfs.c @@ -51,7 +51,7 @@ static struct client_connection *connections; static struct cli_state *do_connect( const char *server, const char *share, BOOL show_sessetup ) { - struct cli_state *c; + struct cli_state *c = NULL; struct nmb_name called, calling; const char *server_n; struct in_addr ip; @@ -83,7 +83,7 @@ static struct cli_state *do_connect( const char *server, const char *share, ip = dest_ip; /* have to open a new connection */ - if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) != port) || + if (!(c=cli_initialise()) || (cli_set_port(c, port) != port) || !cli_connect(c, server_n, &ip)) { d_printf("Connection to %s failed\n", server_n); return NULL; @@ -99,6 +99,7 @@ static struct cli_state *do_connect( const char *server, const char *share, d_printf("session request to %s failed (%s)\n", called.name, cli_errstr(c)); cli_shutdown(c); + c = NULL; if ((p=strchr_m(called.name, '.'))) { *p = 0; goto again; @@ -126,13 +127,14 @@ static struct cli_state *do_connect( const char *server, const char *share, } } - if (!cli_session_setup(c, username, - password, strlen(password), - password, strlen(password), - lp_workgroup())) { + if (!NT_STATUS_IS_OK(cli_session_setup(c, username, + password, strlen(password), + password, strlen(password), + lp_workgroup()))) { /* if a password was not supplied then try again with a null username */ if (password[0] || !username[0] || use_kerberos || - !cli_session_setup(c, "", "", 0, "", 0, lp_workgroup())) { + !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0, + lp_workgroup()))) { d_printf("session setup failed: %s\n", cli_errstr(c)); if (NT_STATUS_V(cli_nt_error(c)) == NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)) diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index 8342df0f1d1..24851961d03 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -107,8 +107,8 @@ BOOL cli_receive_smb(struct cli_state *cli) } /* If the server is not responding, note that now */ - if (!ret) { + DEBUG(0, ("Receiving SMB: Server stopped responding\n")); cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; @@ -255,12 +255,12 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state) } /**************************************************************************** - Initialise a client structure. + Initialise a client structure. Always returns a malloc'ed struct. ****************************************************************************/ -struct cli_state *cli_initialise(struct cli_state *cli) +struct cli_state *cli_initialise(void) { - BOOL alloced_cli = False; + struct cli_state *cli = NULL; /* Check the effective uid - make sure we are not setuid */ if (is_setuid_root()) { @@ -268,17 +268,11 @@ struct cli_state *cli_initialise(struct cli_state *cli) return NULL; } + cli = SMB_MALLOC_P(struct cli_state); if (!cli) { - cli = SMB_MALLOC_P(struct cli_state); - if (!cli) - return NULL; - ZERO_STRUCTP(cli); - alloced_cli = True; + return NULL; } - if (cli->initialised) - cli_close_connection(cli); - ZERO_STRUCTP(cli); cli->port = 0; @@ -333,7 +327,6 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli_null_set_signing(cli); cli->initialised = 1; - cli->allocated = alloced_cli; return cli; @@ -343,10 +336,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) SAFE_FREE(cli->inbuf); SAFE_FREE(cli->outbuf); - - if (alloced_cli) - SAFE_FREE(cli); - + SAFE_FREE(cli); return NULL; } @@ -403,10 +393,10 @@ void cli_nt_pipes_close(struct cli_state *cli) } /**************************************************************************** - Close a client connection and free the memory without destroying cli itself. + Shutdown a client structure. ****************************************************************************/ -void cli_close_connection(struct cli_state *cli) +void cli_shutdown(struct cli_state *cli) { cli_nt_pipes_close(cli); @@ -443,20 +433,8 @@ void cli_close_connection(struct cli_state *cli) } cli->fd = -1; cli->smb_rw_error = 0; -} -/**************************************************************************** - Shutdown a client structure. -****************************************************************************/ - -void cli_shutdown(struct cli_state *cli) -{ - BOOL allocated = cli->allocated; - cli_close_connection(cli); - ZERO_STRUCTP(cli); - if (allocated) { - free(cli); - } + SAFE_FREE(cli); } /**************************************************************************** diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c index 485f5abc0a8..14b5285e45a 100644 --- a/source/libsmb/clikrb5.c +++ b/source/libsmb/clikrb5.c @@ -852,6 +852,27 @@ failed: #endif } +static int get_kvno_from_ap_req(krb5_ap_req *ap_req) +{ +#ifdef HAVE_TICKET_POINTER_IN_KRB5_AP_REQ /* MIT */ + if (ap_req->ticket->enc_part.kvno) + return ap_req->ticket->enc_part.kvno; +#else /* Heimdal */ + if (ap_req->ticket.enc_part.kvno) + return *ap_req->ticket.enc_part.kvno; +#endif + return 0; +} + +static krb5_enctype get_enctype_from_ap_req(krb5_ap_req *ap_req) +{ +#ifdef HAVE_ETYPE_IN_ENCRYPTEDDATA /* Heimdal */ + return ap_req->ticket.enc_part.etype; +#else /* MIT */ + return ap_req->ticket->enc_part.enctype; +#endif +} + static krb5_error_code get_key_from_keytab(krb5_context context, krb5_const_principal server, diff --git a/source/libsmb/clirap.c b/source/libsmb/clirap.c index caa23b59d9a..61cdd79f36b 100644 --- a/source/libsmb/clirap.c +++ b/source/libsmb/clirap.c @@ -244,7 +244,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, )) { int res = rparam? SVAL(rparam,0) : -1; - if (res == 0 || res == ERRmoredata) { + if (res == 0 || res == ERRmoredata || + (res != -1 && cli_errno(cli) == 0)) { int i; int converter=SVAL(rparam,2); diff --git a/source/libsmb/libsmb_cache.c b/source/libsmb/libsmb_cache.c index 5d948ea5e25..8c4fd7c89f7 100644 --- a/source/libsmb/libsmb_cache.c +++ b/source/libsmb/libsmb_cache.c @@ -150,9 +150,10 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, * doesn't match the requested share, so * disconnect from the current share. */ - if (! cli_tdis(&srv->server->cli)) { + if (! cli_tdis(srv->server->cli)) { /* Sigh. Couldn't disconnect. */ - cli_shutdown(&srv->server->cli); + cli_shutdown(srv->server->cli); + srv->server->cli = NULL; context->callbacks.remove_cached_srv_fn(context, srv->server); continue; } @@ -166,7 +167,8 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, srv->share_name = SMB_STRDUP(share); if (!srv->share_name) { /* Out of memory. */ - cli_shutdown(&srv->server->cli); + cli_shutdown(srv->server->cli); + srv->server->cli = NULL; context->callbacks.remove_cached_srv_fn(context, srv->server); continue; } diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c index 8c6218c6431..c7f17d3d013 100644 --- a/source/libsmb/libsmbclient.c +++ b/source/libsmb/libsmbclient.c @@ -496,7 +496,7 @@ static int smbc_check_server(SMBCCTX * context, SMBCSRV * server) { - if ( send_keepalive(server->cli.fd) == False ) + if ( send_keepalive(server->cli->fd) == False ) return 1; /* connection is ok */ @@ -533,7 +533,8 @@ smbc_remove_unused_server(SMBCCTX * context, DLIST_REMOVE(context->internal->_servers, srv); - cli_shutdown(&srv->cli); + cli_shutdown(srv->cli); + srv->cli = NULL; DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); @@ -639,7 +640,7 @@ smbc_server(SMBCCTX *context, fstring password) { SMBCSRV *srv=NULL; - struct cli_state c; + struct cli_state *c; struct nmb_name called, calling; const char *server_n = server; pstring ipenv; @@ -675,7 +676,7 @@ smbc_server(SMBCCTX *context, * disconnect if the requested share is not the same as the * one that was already connected. */ - if (srv->cli.cnum == (uint16) -1) { + if (srv->cli->cnum == (uint16) -1) { /* Ensure we have accurate auth info */ if (context->internal->_auth_fn_with_context != NULL) { context->internal->_auth_fn_with_context( @@ -692,11 +693,12 @@ smbc_server(SMBCCTX *context, password, sizeof(fstring)); } - if (! cli_send_tconX(&srv->cli, share, "?????", + if (! cli_send_tconX(srv->cli, share, "?????", password, strlen(password)+1)) { - errno = smbc_errno(context, &srv->cli); - cli_shutdown(&srv->cli); + errno = smbc_errno(context, srv->cli); + cli_shutdown(srv->cli); + srv->cli = NULL; context->callbacks.remove_cached_srv_fn(context, srv); srv = NULL; @@ -739,19 +741,19 @@ smbc_server(SMBCCTX *context, zero_ip(&ip); /* have to open a new connection */ - if (!cli_initialise(&c)) { + if ((c = cli_initialise()) == NULL) { errno = ENOMEM; return NULL; } if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { - c.use_kerberos = True; + c->use_kerberos = True; } if (context->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) { - c.fallback_after_kerberos = True; + c->fallback_after_kerberos = True; } - c.timeout = context->timeout; + c->timeout = context->timeout; /* * Force use of port 139 for first try if share is $IPC, empty, or @@ -765,49 +767,47 @@ smbc_server(SMBCCTX *context, port_try_next = 139; } - c.port = port_try_first; + c->port = port_try_first; - if (!cli_connect(&c, server_n, &ip)) { + if (!cli_connect(c, server_n, &ip)) { /* First connection attempt failed. Try alternate port. */ - c.port = port_try_next; + c->port = port_try_next; - if (!cli_connect(&c, server_n, &ip)) { - cli_shutdown(&c); + if (!cli_connect(c, server_n, &ip)) { + cli_shutdown(c); errno = ETIMEDOUT; return NULL; } } - if (!cli_session_request(&c, &calling, &called)) { - cli_shutdown(&c); + if (!cli_session_request(c, &calling, &called)) { + cli_shutdown(c); if (strcmp(called.name, "*SMBSERVER")) { make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } else { /* Try one more time, but ensure we don't loop */ - /* Only try this if server is an IP address ... */ + /* Only try this if server is an IP address ... */ - if (is_ipaddress(server) && !tried_reverse) { - fstring remote_name; - struct in_addr rem_ip; + if (is_ipaddress(server) && !tried_reverse) { + fstring remote_name; + struct in_addr rem_ip; - if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { + if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { DEBUG(4, ("Could not convert IP address " "%s to struct in_addr\n", server)); - errno = ETIMEDOUT; - return NULL; - } - - tried_reverse++; /* Yuck */ - - if (name_status_find("*", 0, 0, rem_ip, remote_name)) { - make_nmb_name(&called, remote_name, 0x20); - goto again; - } + errno = ETIMEDOUT; + return NULL; + } + tried_reverse++; /* Yuck */ - } + if (name_status_find("*", 0, 0, rem_ip, remote_name)) { + make_nmb_name(&called, remote_name, 0x20); + goto again; + } + } } errno = ETIMEDOUT; return NULL; @@ -815,29 +815,29 @@ smbc_server(SMBCCTX *context, DEBUG(4,(" session request ok\n")); - if (!cli_negprot(&c)) { - cli_shutdown(&c); + if (!cli_negprot(c)) { + cli_shutdown(c); errno = ETIMEDOUT; return NULL; } username_used = username; - if (!cli_session_setup(&c, username_used, - password, strlen(password), - password, strlen(password), - workgroup)) { + if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, + password, strlen(password), + password, strlen(password), + workgroup))) { /* Failed. Try an anonymous login, if allowed by flags. */ username_used = ""; if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || - !cli_session_setup(&c, username_used, - password, 1, - password, 0, - workgroup)) { + !NT_STATUS_IS_OK(cli_session_setup(c, username_used, + password, 1, + password, 0, + workgroup))) { - cli_shutdown(&c); + cli_shutdown(c); errno = EPERM; return NULL; } @@ -845,10 +845,10 @@ smbc_server(SMBCCTX *context, DEBUG(4,(" session setup ok\n")); - if (!cli_send_tconX(&c, share, "?????", + if (!cli_send_tconX(c, share, "?????", password, strlen(password)+1)) { - errno = smbc_errno(context, &c); - cli_shutdown(&c); + errno = smbc_errno(context, c); + cli_shutdown(c); return NULL; } @@ -867,7 +867,6 @@ smbc_server(SMBCCTX *context, ZERO_STRUCTP(srv); srv->cli = c; - srv->cli.allocated = False; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); srv->no_pathinfo = False; srv->no_pathinfo2 = False; @@ -893,8 +892,10 @@ smbc_server(SMBCCTX *context, return srv; failed: - cli_shutdown(&c); - if (!srv) return NULL; + cli_shutdown(c); + if (!srv) { + return NULL; + } SAFE_FREE(srv); return NULL; @@ -969,19 +970,16 @@ smbc_attr_server(SMBCCTX *context, } ZERO_STRUCTP(ipc_srv); - ipc_srv->cli = *ipc_cli; - ipc_srv->cli.allocated = False; - - free(ipc_cli); + ipc_srv->cli = ipc_cli; if (pol) { - pipe_hnd = cli_rpc_pipe_open_noauth(&ipc_srv->cli, + pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, PI_LSARPC, &nt_status); if (!pipe_hnd) { DEBUG(1, ("cli_nt_session_open fail!\n")); errno = ENOTSUP; - cli_shutdown(&ipc_srv->cli); + cli_shutdown(ipc_srv->cli); free(ipc_srv); return NULL; } @@ -994,14 +992,14 @@ smbc_attr_server(SMBCCTX *context, nt_status = rpccli_lsa_open_policy( pipe_hnd, - ipc_srv->cli.mem_ctx, + ipc_srv->cli->mem_ctx, True, GENERIC_EXECUTE_ACCESS, pol); if (!NT_STATUS_IS_OK(nt_status)) { - errno = smbc_errno(context, &ipc_srv->cli); - cli_shutdown(&ipc_srv->cli); + errno = smbc_errno(context, ipc_srv->cli); + cli_shutdown(ipc_srv->cli); return NULL; } } @@ -1018,7 +1016,7 @@ smbc_attr_server(SMBCCTX *context, if (errno == 0) { errno = ENOMEM; } - cli_shutdown(&ipc_srv->cli); + cli_shutdown(ipc_srv->cli); free(ipc_srv); return NULL; } @@ -1107,7 +1105,7 @@ smbc_open_ctx(SMBCCTX *context, ZERO_STRUCTP(file); /*d_printf(">>>open: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); SAFE_FREE(file); @@ -1122,7 +1120,8 @@ smbc_open_ctx(SMBCCTX *context, cli_dfs_make_full_path( targetpath, targetcli->desthost, targetcli->share, temppath); } - if ((fd = cli_open(targetcli, targetpath, flags, DENY_NONE)) < 0) { + if ((fd = cli_open(targetcli, targetpath, flags, + context->internal->_share_mode)) < 0) { /* Handle the error ... */ @@ -1181,7 +1180,7 @@ smbc_open_ctx(SMBCCTX *context, if (fd == -1) { int eno = 0; - eno = smbc_errno(context, &srv->cli); + eno = smbc_errno(context, srv->cli); file = context->opendir(context, fname); if (!file) errno = eno; return file; @@ -1284,7 +1283,7 @@ smbc_read_ctx(SMBCCTX *context, } /*d_printf(">>>read: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -1292,7 +1291,7 @@ smbc_read_ctx(SMBCCTX *context, } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - ret = cli_read(targetcli, file->cli_fd, buf, offset, count); + ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); if (ret < 0) { @@ -1367,7 +1366,7 @@ smbc_write_ctx(SMBCCTX *context, } /*d_printf(">>>write: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -1376,7 +1375,7 @@ smbc_write_ctx(SMBCCTX *context, /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ - ret = cli_write(targetcli, file->cli_fd, 0, buf, offset, count); + ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); if (ret <= 0) { @@ -1439,7 +1438,7 @@ smbc_close_ctx(SMBCCTX *context, } /*d_printf(">>>close: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -1511,7 +1510,7 @@ smbc_getatr(SMBCCTX * context, } DEBUG(4,("smbc_getatr: sending qpathinfo\n")); - if (!cli_resolve_path( "", &srv->cli, fixedpath, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, fixedpath, &targetcli, targetpath)) { d_printf("Couldn't resolve %s\n", path); return False; @@ -1562,6 +1561,7 @@ smbc_getatr(SMBCCTX * context, if (change_time_ts != NULL) { *change_time_ts = w_time_ts; } + srv->no_pathinfo2 = True; return True; } @@ -1599,7 +1599,7 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * attributes manipulated. */ if (srv->no_pathinfo || - ! cli_setpathinfo(&srv->cli, path, + ! cli_setpathinfo(srv->cli, path, create_time, access_time, write_time, @@ -1620,20 +1620,20 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, srv->no_pathinfo = True; /* Open the file */ - if ((fd = cli_open(&srv->cli, path, O_RDWR, DENY_NONE)) < 0) { + if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } - /* Set the new attributes */ - ret = cli_setattrE(&srv->cli, fd, + /* Set the new attributes */ + ret = cli_setattrE(srv->cli, fd, change_time, access_time, write_time); /* Close the file */ - cli_close(&srv->cli, fd); + cli_close(srv->cli, fd); /* * Unfortunately, setattrE() doesn't have a provision for @@ -1642,11 +1642,11 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * seems to work on win98. */ if (ret && mode != (uint16) -1) { - ret = cli_setatr(&srv->cli, path, mode, 0); + ret = cli_setatr(srv->cli, path, mode, 0); } if (! ret) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return False; } } @@ -1706,7 +1706,7 @@ smbc_unlink_ctx(SMBCCTX *context, } /*d_printf(">>>unlink: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -1845,14 +1845,14 @@ smbc_rename_ctx(SMBCCTX *ocontext, } /*d_printf(">>>rename: resolving %s\n", path1);*/ - if (!cli_resolve_path( "", &srv->cli, path1, &targetcli1, targetpath1)) + if (!cli_resolve_path( "", srv->cli, path1, &targetcli1, targetpath1)) { d_printf("Could not resolve %s\n", path1); return -1; } /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ /*d_printf(">>>rename: resolving %s\n", path2);*/ - if (!cli_resolve_path( "", &srv->cli, path2, &targetcli2, targetpath2)) + if (!cli_resolve_path( "", srv->cli, path2, &targetcli2, targetpath2)) { d_printf("Could not resolve %s\n", path2); return -1; @@ -1947,7 +1947,7 @@ smbc_lseek_ctx(SMBCCTX *context, } /*d_printf(">>>lseek: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -2120,7 +2120,7 @@ smbc_stat_ctx(SMBCCTX *context, &change_time_ts, &ino)) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } @@ -2196,7 +2196,7 @@ smbc_fstat_ctx(SMBCCTX *context, } /*d_printf(">>>fstat: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -2213,12 +2213,12 @@ smbc_fstat_ctx(SMBCCTX *context, time_t change_time, access_time, write_time; - if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, + if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, &change_time, &access_time, &write_time)) { - errno = EINVAL; - return -1; - } + errno = EINVAL; + return -1; + } change_time_ts = convert_time_t_to_timespec(change_time); access_time_ts = convert_time_t_to_timespec(access_time); @@ -2472,16 +2472,16 @@ net_share_enum_rpc(struct cli_state *cli, void *state) { int i; - WERROR result; - ENUM_HND enum_hnd; + NTSTATUS result; + uint32 enum_hnd; + uint32 *penum_hnd = &enum_hnd; uint32 info_level = 1; uint32 preferred_len = 0xffffffff; - uint32 type; - SRV_SHARE_INFO_CTR ctr; - fstring name = ""; - fstring comment = ""; + struct srvsvc_NetShareCtr1 ctr1; + union srvsvc_NetShareCtr ctr; void *mem_ctx; struct rpc_pipe_client *pipe_hnd; + uint32 numentries; NTSTATUS nt_status; /* Open the server service pipe */ @@ -2499,37 +2499,28 @@ net_share_enum_rpc(struct cli_state *cli, return -1; } + ZERO_STRUCT(ctr1); + ctr.ctr1 = &ctr1; + /* Issue the NetShareEnum RPC call and retrieve the response */ - init_enum_hnd(&enum_hnd, 0); - result = rpccli_srvsvc_net_share_enum(pipe_hnd, - mem_ctx, - info_level, - &ctr, - preferred_len, - &enum_hnd); + enum_hnd = 0; + result = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, NULL, + &info_level, &ctr, preferred_len, + &numentries, &penum_hnd); /* Was it successful? */ - if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { + if (!NT_STATUS_IS_OK(result) || numentries == 0) { /* Nope. Go clean up. */ goto done; } /* For each returned entry... */ - for (i = 0; i < ctr.num_entries; i++) { - - /* pull out the share name */ - rpcstr_pull_unistr2_fstring( - name, &ctr.share.info1[i].info_1_str.uni_netname); - - /* pull out the share's comment */ - rpcstr_pull_unistr2_fstring( - comment, &ctr.share.info1[i].info_1_str.uni_remark); - - /* Get the type value */ - type = ctr.share.info1[i].info_1.type; + for (i = 0; i < numentries; i++) { /* Add this share to the list */ - (*fn)(name, type, comment, state); + (*fn)(ctr.ctr1->array[i].name, + ctr.ctr1->array[i].type, + ctr.ctr1->array[i].comment, state); } done: @@ -2540,7 +2531,7 @@ done: TALLOC_FREE(mem_ctx); /* Tell 'em if it worked */ - return W_ERROR_IS_OK(result) ? 0 : -1; + return NT_STATUS_IS_OK(result) ? 0 : -1; } @@ -2549,6 +2540,7 @@ static SMBCFILE * smbc_opendir_ctx(SMBCCTX *context, const char *fname) { + int saved_errno; fstring server, share, user, password, options; pstring workgroup; pstring path; @@ -2556,6 +2548,7 @@ smbc_opendir_ctx(SMBCCTX *context, char *p; SMBCSRV *srv = NULL; SMBCFILE *dir = NULL; + struct _smbc_callbacks *cb; struct in_addr rem_ip; if (!context || !context->internal || @@ -2708,7 +2701,7 @@ smbc_opendir_ctx(SMBCCTX *context, /* Now, list the stuff ... */ - if (!cli_NetServerEnum(&srv->cli, + if (!cli_NetServerEnum(srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn, @@ -2804,7 +2797,7 @@ smbc_opendir_ctx(SMBCCTX *context, dir->srv = srv; /* Now, list the servers ... */ - if (!cli_NetServerEnum(&srv->cli, server, + if (!cli_NetServerEnum(srv->cli, server, 0x0000FFFE, list_fn, (void *)dir)) { @@ -2840,15 +2833,15 @@ smbc_opendir_ctx(SMBCCTX *context, /* List the shares ... */ if (net_share_enum_rpc( - &srv->cli, + srv->cli, list_fn, (void *) dir) < 0 && cli_RNetShareEnum( - &srv->cli, + srv->cli, list_fn, (void *)dir) < 0) { - errno = cli_errno(&srv->cli); + errno = cli_errno(srv->cli); if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -2898,7 +2891,7 @@ smbc_opendir_ctx(SMBCCTX *context, p = path + strlen(path); pstrcat(path, "\\*"); - if (!cli_resolve_path("", &srv->cli, path, + if (!cli_resolve_path("", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -2917,9 +2910,9 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } - errno = smbc_errno(context, targetcli); + saved_errno = smbc_errno(context, targetcli); - if (errno == EINVAL) { + if (saved_errno == EINVAL) { /* * See if they asked to opendir something * other than a directory. If so, the @@ -2935,12 +2928,34 @@ smbc_opendir_ctx(SMBCCTX *context, ! IS_DOS_DIR(mode)) { /* It is. Correct the error value */ - errno = ENOTDIR; + saved_errno = ENOTDIR; } } - return NULL; + /* + * If there was an error and the server is no + * good any more... + */ + cb = &context->callbacks; + if (cli_is_error(targetcli) && + cb->check_server_fn(context, srv)) { + + /* ... then remove it. */ + if (cb->remove_unused_server_fn(context, + srv)) { + /* + * We could not remove the server + * completely, remove it from the + * cache so we will not get it + * again. It will be removed when the + * last file/dir is closed. + */ + cb->remove_cached_srv_fn(context, srv); + } + } + errno = saved_errno; + return NULL; } } @@ -3247,7 +3262,7 @@ smbc_mkdir_ctx(SMBCCTX *context, } /*d_printf(">>>mkdir: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -3344,7 +3359,7 @@ smbc_rmdir_ctx(SMBCCTX *context, } /*d_printf(">>>rmdir: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -3600,8 +3615,8 @@ smbc_chmod_ctx(SMBCCTX *context, if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; - if (!cli_setatr(&srv->cli, path, mode, 0)) { - errno = smbc_errno(context, &srv->cli); + if (!cli_setatr(srv->cli, path, mode, 0)) { + errno = smbc_errno(context, srv->cli); return -1; } @@ -3718,8 +3733,8 @@ ace_compare(SEC_ACE *ace1, if (ace1->flags != ace2->flags) return ace1->flags - ace2->flags; - if (ace1->info.mask != ace2->info.mask) - return ace1->info.mask - ace2->info.mask; + if (ace1->access_mask != ace2->access_mask) + return ace1->access_mask - ace2->access_mask; if (ace1->size != ace2->size) return ace1->size - ace2->size; @@ -3734,14 +3749,14 @@ sort_acl(SEC_ACL *the_acl) uint32 i; if (!the_acl) return; - qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]), + qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), QSORT_CAST ace_compare); for (i=1;i<the_acl->num_aces;) { - if (sec_ace_equal(&the_acl->ace[i-1], &the_acl->ace[i])) { + if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { int j; for (j=i; j<the_acl->num_aces-1; j++) { - the_acl->ace[j] = the_acl->ace[j+1]; + the_acl->aces[j] = the_acl->aces[j+1]; } the_acl->num_aces--; } else { @@ -3946,7 +3961,7 @@ parse_ace(struct cli_state *ipc_cli, } done: - mask.mask = amask; + mask = amask; init_sec_ace(ace, &sid, atype, mask, aflags); return True; } @@ -3968,7 +3983,7 @@ add_ace(SEC_ACL **the_acl, if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) { return False; } - memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE)); + memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE)); memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); newacl = make_sec_acl(ctx, (*the_acl)->revision, 1+(*the_acl)->num_aces, aces); @@ -4138,7 +4153,7 @@ dos_attr_query(SMBCCTX *context, &change_time_ts, &inode)) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); return NULL; @@ -4164,7 +4179,7 @@ dos_attr_parse(SMBCCTX *context, char *str) { int n; - const char *p = str; + const char *p = str; fstring tok; struct { const char * create_time_attr; @@ -4297,7 +4312,7 @@ cacl_get(SMBCCTX *context, SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; - struct cli_state *cli = &srv->cli; + struct cli_state *cli = srv->cli; struct { const char * create_time_attr; const char * access_time_attr; @@ -4540,10 +4555,10 @@ cacl_get(SMBCCTX *context, } if (! exclude_nt_group) { - if (sd->grp_sid) { + if (sd->group_sid) { convert_sid_to_string(ipc_cli, pol, sidstr, numeric, - sd->grp_sid); + sd->group_sid); } else { fstrcpy(sidstr, ""); } @@ -4588,7 +4603,7 @@ cacl_get(SMBCCTX *context, /* Add aces to value buffer */ for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { - SEC_ACE *ace = &sd->dacl->ace[i]; + SEC_ACE *ace = &sd->dacl->aces[i]; convert_sid_to_string(ipc_cli, pol, sidstr, numeric, &ace->trustee); @@ -4602,7 +4617,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); if (!p) { errno = ENOMEM; return -1; @@ -4615,7 +4630,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); } } else if ((StrnCaseCmp(name, "acl", 3) == 0 && StrCaseCmp(name+3, sidstr) == 0) || @@ -4627,7 +4642,7 @@ cacl_get(SMBCCTX *context, "%d/%d/0x%08x", ace->type, ace->flags, - ace->info.mask); + ace->access_mask); if (!p) { errno = ENOMEM; return -1; @@ -4638,7 +4653,7 @@ cacl_get(SMBCCTX *context, "%d/%d/0x%08x", ace->type, ace->flags, - ace->info.mask); + ace->access_mask); } } else if (all_nt_acls) { if (determine_size) { @@ -4649,7 +4664,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); if (!p) { errno = ENOMEM; return -1; @@ -4662,7 +4677,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); } } if (n > bufsize) { @@ -4691,11 +4706,11 @@ cacl_get(SMBCCTX *context, &change_time_ts, &ino)) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } - + create_time = convert_timespec_to_time_t(create_time_ts); access_time = convert_timespec_to_time_t(access_time_ts); write_time = convert_timespec_to_time_t(write_time_ts); @@ -4811,7 +4826,7 @@ cacl_get(SMBCCTX *context, attr_strings.create_time_attr, create_time); } - } else if (StrCaseCmp(name, "c_time") == 0) { + } else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) { if (determine_size) { p = talloc_asprintf(ctx, "%lu", create_time); if (!p) { @@ -4852,7 +4867,7 @@ cacl_get(SMBCCTX *context, attr_strings.access_time_attr, access_time); } - } else if (StrCaseCmp(name, "a_time") == 0) { + } else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) { if (determine_size) { p = talloc_asprintf(ctx, "%lu", access_time); if (!p) { @@ -5093,9 +5108,9 @@ cacl_set(TALLOC_CTX *ctx, switch (mode) { case SMBC_XATTR_MODE_REMOVE_ALL: old->dacl->num_aces = 0; - SAFE_FREE(old->dacl->ace); + SAFE_FREE(old->dacl->aces); SAFE_FREE(old->dacl); - old->off_dacl = 0; + old->dacl = NULL; dacl = old->dacl; break; @@ -5104,18 +5119,18 @@ cacl_set(TALLOC_CTX *ctx, BOOL found = False; for (j=0;old->dacl && j<old->dacl->num_aces;j++) { - if (sec_ace_equal(&sd->dacl->ace[i], - &old->dacl->ace[j])) { + if (sec_ace_equal(&sd->dacl->aces[i], + &old->dacl->aces[j])) { uint32 k; for (k=j; k<old->dacl->num_aces-1;k++) { - old->dacl->ace[k] = - old->dacl->ace[k+1]; + old->dacl->aces[k] = + old->dacl->aces[k+1]; } old->dacl->num_aces--; if (old->dacl->num_aces == 0) { - SAFE_FREE(old->dacl->ace); + SAFE_FREE(old->dacl->aces); SAFE_FREE(old->dacl); - old->off_dacl = 0; + old->dacl = NULL; } found = True; dacl = old->dacl; @@ -5136,14 +5151,14 @@ cacl_set(TALLOC_CTX *ctx, BOOL found = False; for (j=0;old->dacl && j<old->dacl->num_aces;j++) { - if (sid_equal(&sd->dacl->ace[i].trustee, - &old->dacl->ace[j].trustee)) { + if (sid_equal(&sd->dacl->aces[i].trustee, + &old->dacl->aces[j].trustee)) { if (!(flags & SMBC_XATTR_FLAG_CREATE)) { err = EEXIST; ret = -1; goto failed; } - old->dacl->ace[j] = sd->dacl->ace[i]; + old->dacl->aces[j] = sd->dacl->aces[i]; ret = -1; found = True; } @@ -5156,7 +5171,7 @@ cacl_set(TALLOC_CTX *ctx, } for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { - add_ace(&old->dacl, &sd->dacl->ace[i], ctx); + add_ace(&old->dacl, &sd->dacl->aces[i], ctx); } } dacl = old->dacl; @@ -5165,7 +5180,7 @@ cacl_set(TALLOC_CTX *ctx, case SMBC_XATTR_MODE_SET: old = sd; owner_sid = old->owner_sid; - grp_sid = old->grp_sid; + grp_sid = old->group_sid; dacl = old->dacl; break; @@ -5174,7 +5189,7 @@ cacl_set(TALLOC_CTX *ctx, break; case SMBC_XATTR_MODE_CHGRP: - grp_sid = sd->grp_sid; + grp_sid = sd->group_sid; break; } @@ -5310,8 +5325,8 @@ smbc_setxattr_ctx(SMBCCTX *context, } if (ipc_srv) { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, (*namevalue == '*' ? SMBC_XATTR_MODE_SET @@ -5374,8 +5389,8 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, (*namevalue == '*' ? SMBC_XATTR_MODE_SET @@ -5405,8 +5420,8 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, SMBC_XATTR_MODE_CHOWN, 0); } talloc_destroy(ctx); @@ -5432,8 +5447,8 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, SMBC_XATTR_MODE_CHOWN, 0); } talloc_destroy(ctx); @@ -5632,12 +5647,12 @@ smbc_getxattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_get(context, ctx, srv, - ipc_srv == NULL ? NULL : &ipc_srv->cli, + ipc_srv == NULL ? NULL : ipc_srv->cli, &pol, path, CONST_DISCARD(char *, name), CONST_DISCARD(char *, value), size); if (ret < 0 && errno == 0) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); } talloc_destroy(ctx); return ret; @@ -5728,8 +5743,8 @@ smbc_removexattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { /* Yup. */ - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); talloc_destroy(ctx); return ret; @@ -5748,8 +5763,8 @@ smbc_removexattr_ctx(SMBCCTX *context, StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { /* Yup. */ - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, name + 19, SMBC_XATTR_MODE_REMOVE, 0); talloc_destroy(ctx); return ret; @@ -6026,10 +6041,10 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, } - if (cli_print_queue(&srv->cli, + if (cli_print_queue(srv->cli, (void (*)(struct print_job_info *))fn) < 0) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } @@ -6096,10 +6111,10 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, } - if ((err = cli_printjob_del(&srv->cli, id)) != 0) { + if ((err = cli_printjob_del(srv->cli, id)) != 0) { if (err < 0) - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); else if (err == ERRnosuchprintjob) errno = EINVAL; return -1; @@ -6220,8 +6235,8 @@ smbc_free_context(SMBCCTX *context, s = context->internal->_servers; while (s) { DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", - s, s->cli.fd)); - cli_shutdown(&s->cli); + s, s->cli->fd)); + cli_shutdown(s->cli); context->callbacks.remove_cached_srv_fn(context, s); next = s->next; @@ -6350,9 +6365,9 @@ smbc_option_get(SMBCCTX *context, * Log to standard error instead of standard output. */ #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->internal->_debug_stderr; + return (void *) (intptr_t) context->internal->_debug_stderr; #else - return (void *) context->internal->_debug_stderr; + return (void *) context->internal->_debug_stderr; #endif } else if (strcmp(option_name, "full_time_names") == 0) { /* diff --git a/source/libsmb/passchange.c b/source/libsmb/passchange.c index 90eb67aceaa..5b4b0896c0f 100644 --- a/source/libsmb/passchange.c +++ b/source/libsmb/passchange.c @@ -29,7 +29,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam char *err_str, size_t err_str_len) { struct nmb_name calling, called; - struct cli_state cli; + struct cli_state *cli; struct rpc_pipe_client *pipe_hnd; struct in_addr ip; @@ -44,91 +44,96 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam return NT_STATUS_UNSUCCESSFUL; } - ZERO_STRUCT(cli); - - if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) { + cli = cli_initialise(); + if (!cli) { + return NT_STATUS_NO_MEMORY; + } + + if (!cli_connect(cli, remote_machine, &ip)) { slprintf(err_str, err_str_len-1, "unable to connect to SMB server on machine %s. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - return NT_STATUS_UNSUCCESSFUL; + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); + return result; } make_nmb_name(&calling, global_myname() , 0x0); make_nmb_name(&called , remote_machine, 0x20); - if (!cli_session_request(&cli, &calling, &called)) { + if (!cli_session_request(cli, &calling, &called)) { slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return NT_STATUS_UNSUCCESSFUL; + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); + return result; } - cli.protocol = PROTOCOL_NT1; + cli->protocol = PROTOCOL_NT1; - if (!cli_negprot(&cli)) { + if (!cli_negprot(cli)) { slprintf(err_str, err_str_len-1, "machine %s rejected the negotiate protocol. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } /* Given things like SMB signing, restrict anonymous and the like, try an authenticated connection first */ - if (!cli_session_setup(&cli, user_name, old_passwd, strlen(old_passwd)+1, old_passwd, strlen(old_passwd)+1, "")) { - - result = cli_nt_error(&cli); - - if (!NT_STATUS_IS_OK(result)) { - - /* Password must change or Password expired are the only valid - * error conditions here from where we can proceed, the rest like - * account locked out or logon failure will lead to errors later - * anyway */ - - if (!NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) && - !NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED)) { - - slprintf(err_str, err_str_len-1, "Could not " - "connect to machine %s: %s\n", - remote_machine, cli_errstr(&cli)); - cli_shutdown(&cli); - return result; - } - - pass_must_change = True; + result = cli_session_setup(cli, user_name, + old_passwd, strlen(old_passwd)+1, + old_passwd, strlen(old_passwd)+1, ""); + + if (!NT_STATUS_IS_OK(result)) { + + /* Password must change or Password expired are the only valid + * error conditions here from where we can proceed, the rest like + * account locked out or logon failure will lead to errors later + * anyway */ + + if (!NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) && + !NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED)) { + slprintf(err_str, err_str_len-1, "Could not " + "connect to machine %s: %s\n", + remote_machine, cli_errstr(cli)); + cli_shutdown(cli); + return result; } + pass_must_change = True; + /* * We should connect as the anonymous user here, in case * the server has "must change password" checked... * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix. */ - if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + result = cli_session_setup(cli, "", "", 0, "", 0, ""); + + if (!NT_STATUS_IS_OK(result)) { slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + cli_shutdown(cli); return result; } - cli_init_creds(&cli, "", "", NULL); + cli_init_creds(cli, "", "", NULL); } else { - cli_init_creds(&cli, user_name, "", old_passwd); + cli_init_creds(cli, user_name, "", old_passwd); } - if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { + if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) { slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } /* Try not to give the password away too easily */ if (!pass_must_change) { - pipe_hnd = cli_rpc_pipe_open_ntlmssp(&cli, + pipe_hnd = cli_rpc_pipe_open_ntlmssp(cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY, "", /* what domain... ? */ @@ -144,17 +149,17 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam * will just fail. So we do it anonymously, there's no other * way. */ - pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result); + pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); } if (!pipe_hnd) { if (lp_client_lanman_auth()) { /* Use the old RAP method. */ - if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + if (!cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } } else { @@ -162,16 +167,16 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam "SAMR connection to machine %s failed. Error was %s, " "but LANMAN password changed are disabled\n", nt_errstr(result), remote_machine); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } } - if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli.mem_ctx, user_name, + if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli->mem_ctx, user_name, new_passwd, old_passwd))) { /* Great - it all worked! */ - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_OK; } else if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) @@ -180,7 +185,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", remote_machine, get_friendly_nt_error_msg(result)); - cli_shutdown(&cli); + cli_shutdown(cli); return result; } @@ -188,21 +193,21 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam cli_rpc_pipe_close(pipe_hnd); /* Try anonymous NTLMSSP... */ - cli_init_creds(&cli, "", "", NULL); + cli_init_creds(cli, "", "", NULL); result = NT_STATUS_UNSUCCESSFUL; /* OK, this is ugly, but... try an anonymous pipe. */ - pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result); + pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); if ( pipe_hnd && (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, - cli.mem_ctx, + cli->mem_ctx, user_name, new_passwd, old_passwd)))) { /* Great - it all worked! */ - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_OK; } else { if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) @@ -212,7 +217,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam slprintf(err_str, err_str_len-1, "machine %s rejected the (anonymous) password change: Error was : %s.\n", remote_machine, get_friendly_nt_error_msg(result)); - cli_shutdown(&cli); + cli_shutdown(cli); return result; } @@ -221,24 +226,24 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam if (lp_client_lanman_auth()) { /* Use the old RAP method. */ - if (cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + if (cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { /* SAMR failed, but the old LanMan protocol worked! */ - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_OK; } slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } else { slprintf(err_str, err_str_len-1, "SAMR connection to machine %s failed. Error was %s, " "but LANMAN password changed are disabled\n", nt_errstr(result), remote_machine); - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; } } diff --git a/source/locking/brlock.c b/source/locking/brlock.c index 267a08d15fa..872ed2bbeaf 100644 --- a/source/locking/brlock.c +++ b/source/locking/brlock.c @@ -32,29 +32,6 @@ #define ZERO_ZERO 0 -/* This contains elements that differentiate locks. The smbpid is a - client supplied pid, and is essentially the locking context for - this client */ - -struct lock_context { - uint16 smbpid; - uint16 tid; - struct process_id pid; -}; - -/* The data in brlock records is an unsorted linear array of these - records. It is unnecessary to store the count as tdb provides the - size of the record */ - -struct lock_struct { - struct lock_context context; - br_off start; - br_off size; - int fnum; - enum brl_type lock_type; - enum brl_flavour lock_flav; -}; - /* The open brlock.tdb database. */ static TDB_CONTEXT *tdb; @@ -83,7 +60,7 @@ static void print_lock_struct(unsigned int i, struct lock_struct *pls) See if two locking contexts are equal. ****************************************************************************/ -static BOOL brl_same_context(const struct lock_context *ctx1, +BOOL brl_same_context(const struct lock_context *ctx1, const struct lock_context *ctx2) { return (procid_equal(&ctx1->pid, &ctx2->pid) && @@ -121,7 +98,7 @@ static BOOL brl_conflict(const struct lock_struct *lck1, const struct lock_struct *lck2) { /* Ignore PENDING locks. */ - if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type)) return False; /* Read locks never conflict. */ @@ -152,7 +129,7 @@ static BOOL brl_conflict_posix(const struct lock_struct *lck1, #endif /* Ignore PENDING locks. */ - if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type)) return False; /* Read locks never conflict. */ @@ -174,7 +151,7 @@ static BOOL brl_conflict_posix(const struct lock_struct *lck1, static BOOL brl_conflict1(const struct lock_struct *lck1, const struct lock_struct *lck2) { - if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type)) return False; if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { @@ -207,7 +184,7 @@ static BOOL brl_conflict1(const struct lock_struct *lck1, static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock_struct *lck2) { - if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type)) return False; if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) @@ -234,30 +211,47 @@ static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock } /**************************************************************************** - Amazingly enough, w2k3 "remembers" whether the last lock failure + Check if an unlock overlaps a pending lock. +****************************************************************************/ + +static BOOL brl_pending_overlap(const struct lock_struct *lock, const struct lock_struct *pend_lock) +{ + if ((lock->start <= pend_lock->start) && (lock->start + lock->size > pend_lock->start)) + return True; + if ((lock->start >= pend_lock->start) && (lock->start <= pend_lock->start + pend_lock->size)) + return True; + return False; +} + +/**************************************************************************** + Amazingly enough, w2k3 "remembers" whether the last lock failure on a fnum is the same as this one and changes its error code. I wonder if any app depends on this ? ****************************************************************************/ -static NTSTATUS brl_lock_failed(const struct lock_struct *lock) +static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, BOOL blocking_lock) { - static struct lock_struct last_lock_failure; - - if (brl_same_context(&lock->context, &last_lock_failure.context) && - lock->fnum == last_lock_failure.fnum && - lock->start == last_lock_failure.start && - lock->size == last_lock_failure.size) { - return NT_STATUS_FILE_LOCK_CONFLICT; - } - last_lock_failure = *lock; - if (lock->start >= 0xEF000000 && - (lock->start >> 63) == 0) { + if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) { /* amazing the little things you learn with a test suite. Locks beyond this offset (as a 64 bit number!) always generate the conflict error code, unless the top bit is set */ + if (!blocking_lock) { + fsp->last_lock_failure = *lock; + } return NT_STATUS_FILE_LOCK_CONFLICT; } + + if (procid_equal(&lock->context.pid, &fsp->last_lock_failure.context.pid) && + lock->context.tid == fsp->last_lock_failure.context.tid && + lock->fnum == fsp->last_lock_failure.fnum && + lock->start == fsp->last_lock_failure.start) { + return NT_STATUS_FILE_LOCK_CONFLICT; + } + + if (!blocking_lock) { + fsp->last_lock_failure = *lock; + } return NT_STATUS_LOCK_NOT_GRANTED; } @@ -316,8 +310,7 @@ static int lock_compare(const struct lock_struct *lck1, ****************************************************************************/ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, - const struct lock_struct *plock, - BOOL *my_lock_ctx) + const struct lock_struct *plock, BOOL blocking_lock) { unsigned int i; files_struct *fsp = br_lck->fsp; @@ -326,12 +319,7 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, for (i=0; i < br_lck->num_locks; i++) { /* Do any Windows or POSIX locks conflict ? */ if (brl_conflict(&locks[i], plock)) { - NTSTATUS status = brl_lock_failed(plock);; - /* Did we block ourselves ? */ - if (brl_same_context(&locks[i].context, &plock->context)) { - *my_lock_ctx = True; - } - return status; + return brl_lock_failed(fsp,plock,blocking_lock); } #if ZERO_ZERO if (plock->start == 0 && plock->size == 0 && @@ -343,13 +331,19 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, /* We can get the Windows lock, now see if it needs to be mapped into a lower level POSIX one, and if so can - we get it ? We tell the lower lock layer about the - lock type so it can cope with the difference between - Windows "stacking" locks and POSIX "flat" ones. */ - - if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(fsp->conn))) { - if (!set_posix_lock(fsp, plock->start, plock->size, plock->lock_type, WINDOWS_LOCK)) { - if (errno == EACCES || errno == EAGAIN) { + we get it ? */ + + if (!IS_PENDING_LOCK(plock->lock_type) && lp_posix_locking(fsp->conn->params)) { + int errno_ret; + if (!set_posix_lock_windows_flavour(fsp, + plock->start, + plock->size, + plock->lock_type, + &plock->context, + locks, + br_lck->num_locks, + &errno_ret)) { + if (errno_ret == EACCES || errno_ret == EAGAIN) { return NT_STATUS_FILE_LOCK_CONFLICT; } else { return map_nt_error_from_unix(errno); @@ -375,9 +369,9 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, Cope with POSIX range splits and merges. ****************************************************************************/ -static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr, - const struct lock_struct *ex, - const struct lock_struct *plock, +static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr, /* Output array. */ + const struct lock_struct *ex, /* existing lock. */ + const struct lock_struct *plock, /* proposed lock. */ BOOL *lock_was_added) { BOOL lock_types_differ = (ex->lock_type != plock->lock_type); @@ -398,26 +392,26 @@ static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr, +---------+ | ex | +---------+ - +-------+ - | plock | - +-------+ + +-------+ + | plock | + +-------+ OR.... +---------+ | ex | +---------+ **********************************************/ - if ( (ex->start >= (plock->start + plock->size)) || - (plock->start >= (ex->start + ex->size))) { + if ( (ex->start > (plock->start + plock->size)) || + (plock->start > (ex->start + ex->size))) { /* No overlap with this lock - copy existing. */ memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); return 1; } /********************************************* - +---------+ - | ex | - +---------+ + +---------------------------+ + | ex | + +---------------------------+ +---------------------------+ | plock | -> replace with plock. +---------------------------+ @@ -431,24 +425,32 @@ OR.... } /********************************************* - +---------------+ - | ex | - +---------------+ + +-----------------------+ + | ex | + +-----------------------+ + +---------------+ + | plock | + +---------------+ +OR.... + +-------+ + | ex | + +-------+ +---------------+ | plock | +---------------+ + BECOMES.... +---------------+-------+ | plock | ex | - different lock types. +---------------+-------+ -OR.... +OR.... (merge) +-----------------------+ | ex | - same lock type. +-----------------------+ **********************************************/ if ( (ex->start >= plock->start) && - (ex->start < plock->start + plock->size) && + (ex->start <= plock->start + plock->size) && (ex->start + ex->size > plock->start + plock->size) ) { *lock_was_added = True; @@ -475,9 +477,16 @@ OR.... } /********************************************* - +---------------+ - | ex | - +---------------+ + +-----------------------+ + | ex | + +-----------------------+ + +---------------+ + | plock | + +---------------+ +OR.... + +-------+ + | ex | + +-------+ +---------------+ | plock | +---------------+ @@ -486,7 +495,7 @@ BECOMES.... | ex | plock | - different lock types +-------+---------------+ -OR +OR.... (merge) +-----------------------+ | ex | - same lock type. +-----------------------+ @@ -494,7 +503,7 @@ OR **********************************************/ if ( (ex->start < plock->start) && - (ex->start + ex->size > plock->start) && + (ex->start + ex->size >= plock->start) && (ex->start + ex->size <= plock->start + plock->size) ) { *lock_was_added = True; @@ -573,13 +582,13 @@ OR ****************************************************************************/ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, - const struct lock_struct *plock, - BOOL *my_lock_ctx) + const struct lock_struct *plock) { unsigned int i, count; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; struct lock_struct *tp; BOOL lock_was_added = False; + BOOL signal_pending_read = False; /* No zero-zero locks for POSIX. */ if (plock->start == 0 && plock->size == 0) { @@ -603,23 +612,28 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, count = 0; for (i=0; i < br_lck->num_locks; i++) { - if (locks[i].lock_flav == WINDOWS_LOCK) { + struct lock_struct *curr_lock = &locks[i]; + + /* If we have a pending read lock, a lock downgrade should + trigger a lock re-evaluation. */ + if (curr_lock->lock_type == PENDING_READ_LOCK && + brl_pending_overlap(plock, curr_lock)) { + signal_pending_read = True; + } + + if (curr_lock->lock_flav == WINDOWS_LOCK) { /* Do any Windows flavour locks conflict ? */ - if (brl_conflict(&locks[i], plock)) { - /* Did we block ourselves ? */ - if (brl_same_context(&locks[i].context, &plock->context)) { - *my_lock_ctx = True; - } + if (brl_conflict(curr_lock, plock)) { /* No games with error messages. */ SAFE_FREE(tp); return NT_STATUS_FILE_LOCK_CONFLICT; } /* Just copy the Windows lock into the new array. */ - memcpy(&tp[count], &locks[i], sizeof(struct lock_struct)); + memcpy(&tp[count], curr_lock, sizeof(struct lock_struct)); count++; } else { /* POSIX conflict semantics are different. */ - if (brl_conflict_posix(&locks[i], plock)) { + if (brl_conflict_posix(curr_lock, plock)) { /* Can't block ourselves with POSIX locks. */ /* No games with error messages. */ SAFE_FREE(tp); @@ -627,24 +641,32 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, } /* Work out overlaps. */ - count += brlock_posix_split_merge(&tp[count], &locks[i], plock, &lock_was_added); + count += brlock_posix_split_merge(&tp[count], curr_lock, plock, &lock_was_added); } } + if (!lock_was_added) { + memcpy(&tp[count], plock, sizeof(struct lock_struct)); + count++; + } + /* We can get the POSIX lock, now see if it needs to be mapped into a lower level POSIX one, and if so can - we get it ? We well the lower lock layer about the - lock type so it can cope with the difference between - Windows "stacking" locks and POSIX "flat" ones. */ + we get it ? */ -#if 0 - /* FIXME - this call doesn't work correctly yet for POSIX locks... */ + if (!IS_PENDING_LOCK(plock->lock_type) && lp_posix_locking(br_lck->fsp->conn->params)) { + int errno_ret; - if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(fsp->conn))) { - files_struct *fsp = br_lck->fsp; + /* The lower layer just needs to attempt to + get the system POSIX lock. We've weeded out + any conflicts above. */ - if (!set_posix_lock(fsp, plock->start, plock->size, plock->lock_type, POSIX_LOCK)) { - if (errno == EACCES || errno == EAGAIN) { + if (!set_posix_lock_posix_flavour(br_lck->fsp, + plock->start, + plock->size, + plock->lock_type, + &errno_ret)) { + if (errno_ret == EACCES || errno_ret == EAGAIN) { SAFE_FREE(tp); return NT_STATUS_FILE_LOCK_CONFLICT; } else { @@ -653,12 +675,6 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, } } } -#endif - - if (!lock_was_added) { - memcpy(&tp[count], plock, sizeof(struct lock_struct)); - count++; - } /* Realloc so we don't leak entries per lock call. */ tp = (struct lock_struct *)SMB_REALLOC(tp, count * sizeof(*locks)); @@ -668,7 +684,34 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, br_lck->num_locks = count; SAFE_FREE(br_lck->lock_data); br_lck->lock_data = (void *)tp; + locks = tp; br_lck->modified = True; + + /* A successful downgrade from write to read lock can trigger a lock + re-evalutation where waiting readers can now proceed. */ + + if (signal_pending_read) { + /* Send unlock messages to any pending read waiters that overlap. */ + for (i=0; i < br_lck->num_locks; i++) { + struct lock_struct *pend_lock = &locks[i]; + + /* Ignore non-pending locks. */ + if (!IS_PENDING_LOCK(pend_lock->lock_type)) { + continue; + } + + if (pend_lock->lock_type == PENDING_READ_LOCK && + brl_pending_overlap(plock, pend_lock)) { + DEBUG(10,("brl_lock_posix: sending unlock message to pid %s\n", + procid_str_static(&pend_lock->context.pid ))); + + message_send_pid(pend_lock->context.pid, + MSG_SMB_UNLOCK, + NULL, 0, True); + } + } + } + return NT_STATUS_OK; } @@ -677,19 +720,17 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, ****************************************************************************/ NTSTATUS brl_lock(struct byte_range_lock *br_lck, - uint16 smbpid, + uint32 smbpid, struct process_id pid, br_off start, br_off size, enum brl_type lock_type, enum brl_flavour lock_flav, - BOOL *my_lock_ctx) + BOOL blocking_lock) { NTSTATUS ret; struct lock_struct lock; - *my_lock_ctx = False; - #if !ZERO_ZERO if (start == 0 && size == 0) { DEBUG(0,("client sent 0/0 lock - please report this\n")); @@ -706,9 +747,9 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck, lock.lock_flav = lock_flav; if (lock_flav == WINDOWS_LOCK) { - ret = brl_lock_windows(br_lck, &lock, my_lock_ctx); + ret = brl_lock_windows(br_lck, &lock, blocking_lock); } else { - ret = brl_lock_posix(br_lck, &lock, my_lock_ctx); + ret = brl_lock_posix(br_lck, &lock); } #if ZERO_ZERO @@ -720,19 +761,6 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck, } /**************************************************************************** - Check if an unlock overlaps a pending lock. -****************************************************************************/ - -static BOOL brl_pending_overlap(const struct lock_struct *lock, const struct lock_struct *pend_lock) -{ - if ((lock->start <= pend_lock->start) && (lock->start + lock->size > pend_lock->start)) - return True; - if ((lock->start >= pend_lock->start) && (lock->start <= pend_lock->start + pend_lock->size)) - return True; - return False; -} - -/**************************************************************************** Unlock a range of bytes - Windows semantics. ****************************************************************************/ @@ -740,8 +768,12 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock { unsigned int i, j; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + enum brl_type deleted_lock_type = READ_LOCK; /* shut the compiler up.... */ #if ZERO_ZERO + /* Delete write locks by preference... The lock list + is sorted in the zero zero case. */ + for (i = 0; i < br_lck->num_locks; i++) { struct lock_struct *lock = &locks[i]; @@ -753,16 +785,15 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock lock->size == plock->size) { /* found it - delete it */ - if (i < br_lck->num_locks - 1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((br_lck->num_locks-1) - i)); - } - - br_lck->num_locks -= 1; - br_lck->modified = True; - return True; + deleted_lock_type = lock->lock_type; + break; } } + + if (i != br_lck->num_locks) { + /* We found it - don't search again. */ + goto unlock_continue; + } #endif for (i = 0; i < br_lck->num_locks; i++) { @@ -774,6 +805,7 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock lock->lock_flav == WINDOWS_LOCK && lock->start == plock->start && lock->size == plock->size ) { + deleted_lock_type = lock->lock_type; break; } } @@ -783,9 +815,28 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock return False; } - /* Unlock any POSIX regions. */ - if(lp_posix_locking(br_lck->fsp->conn->cnum)) { - release_posix_lock(br_lck->fsp, plock->start, plock->size); +#if ZERO_ZERO + unlock_continue: +#endif + + /* Actually delete the lock. */ + if (i < br_lck->num_locks - 1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((br_lck->num_locks-1) - i)); + } + + br_lck->num_locks -= 1; + br_lck->modified = True; + + /* Unlock the underlying POSIX regions. */ + if(lp_posix_locking(br_lck->fsp->conn->params)) { + release_posix_lock_windows_flavour(br_lck->fsp, + plock->start, + plock->size, + deleted_lock_type, + &plock->context, + locks, + br_lck->num_locks); } /* Send unlock messages to any pending waiters that overlap. */ @@ -793,7 +844,7 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock struct lock_struct *pend_lock = &locks[j]; /* Ignore non-pending locks. */ - if (pend_lock->lock_type != PENDING_LOCK) { + if (!IS_PENDING_LOCK(pend_lock->lock_type)) { continue; } @@ -802,22 +853,12 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", procid_str_static(&pend_lock->context.pid ))); - become_root(); message_send_pid(pend_lock->context.pid, MSG_SMB_UNLOCK, NULL, 0, True); - unbecome_root(); } } - /* Actually delete the lock. */ - if (i < br_lck->num_locks - 1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((br_lck->num_locks-1) - i)); - } - - br_lck->num_locks -= 1; - br_lck->modified = True; return True; } @@ -861,9 +902,8 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s BOOL lock_was_added = False; unsigned int tmp_count; - /* Only remove our own locks - ignore fnum. */ - if (lock->lock_type == PENDING_LOCK || + if (IS_PENDING_LOCK(lock->lock_type) || !brl_same_context(&lock->context, &plock->context)) { memcpy(&tp[count], lock, sizeof(struct lock_struct)); count++; @@ -894,13 +934,18 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s SMB_ASSERT(tmp_lock[0].lock_type == locks[i].lock_type); SMB_ASSERT(tmp_lock[1].lock_type == UNLOCK_LOCK); memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct)); + if (tmp_lock[0].size != locks[i].size) { + overlap_found = True; + } } else { SMB_ASSERT(tmp_lock[0].lock_type == UNLOCK_LOCK); SMB_ASSERT(tmp_lock[1].lock_type == locks[i].lock_type); memcpy(&tp[count], &tmp_lock[1], sizeof(struct lock_struct)); + if (tmp_lock[1].start != locks[i].start) { + overlap_found = True; + } } count++; - overlap_found = True; continue; } else { /* tmp_count == 3 - (we split a lock range in two). */ @@ -932,14 +977,15 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s return True; } -#if 0 - /* FIXME - this call doesn't work correctly yet for POSIX locks... */ - /* Unlock any POSIX regions. */ - if(lp_posix_locking(br_lck->fsp->conn->cnum)) { - release_posix_lock(br_lck->fsp, plock->start, plock->size); + if(lp_posix_locking(br_lck->fsp->conn->params)) { + release_posix_lock_posix_flavour(br_lck->fsp, + plock->start, + plock->size, + &plock->context, + tp, + count); } -#endif /* Realloc so we don't leak entries per unlock call. */ if (count) { @@ -956,7 +1002,8 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s br_lck->num_locks = count; SAFE_FREE(br_lck->lock_data); - locks = br_lck->lock_data = (void *)tp; + locks = tp; + br_lck->lock_data = (void *)tp; br_lck->modified = True; /* Send unlock messages to any pending waiters that overlap. */ @@ -965,7 +1012,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s struct lock_struct *pend_lock = &locks[j]; /* Ignore non-pending locks. */ - if (pend_lock->lock_type != PENDING_LOCK) { + if (!IS_PENDING_LOCK(pend_lock->lock_type)) { continue; } @@ -974,11 +1021,9 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", procid_str_static(&pend_lock->context.pid ))); - become_root(); message_send_pid(pend_lock->context.pid, MSG_SMB_UNLOCK, NULL, 0, True); - unbecome_root(); } } @@ -990,7 +1035,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s ****************************************************************************/ BOOL brl_unlock(struct byte_range_lock *br_lck, - uint16 smbpid, + uint32 smbpid, struct process_id pid, br_off start, br_off size, @@ -1020,7 +1065,7 @@ BOOL brl_unlock(struct byte_range_lock *br_lck, ****************************************************************************/ BOOL brl_locktest(struct byte_range_lock *br_lck, - uint16 smbpid, + uint32 smbpid, struct process_id pid, br_off start, br_off size, @@ -1030,7 +1075,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck, BOOL ret = True; unsigned int i; struct lock_struct lock; - struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + const struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; files_struct *fsp = br_lck->fsp; lock.context.smbpid = smbpid; @@ -1058,7 +1103,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck, * This only conflicts with Windows locks, not POSIX locks. */ - if(lp_posix_locking(fsp->conn->cnum) && (lock_flav == WINDOWS_LOCK)) { + if(lp_posix_locking(fsp->conn->params) && (lock_flav == WINDOWS_LOCK)) { ret = is_posix_locked(fsp, &start, &size, &lock_type, WINDOWS_LOCK); DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for fnum %d file %s\n", @@ -1078,7 +1123,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck, ****************************************************************************/ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, - uint16 *psmbpid, + uint32 *psmbpid, struct process_id pid, br_off *pstart, br_off *psize, @@ -1087,7 +1132,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, { unsigned int i; struct lock_struct lock; - struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + const struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; files_struct *fsp = br_lck->fsp; lock.context.smbpid = *psmbpid; @@ -1101,7 +1146,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, /* Make sure existing locks don't conflict */ for (i=0; i < br_lck->num_locks; i++) { - struct lock_struct *exlock = &locks[i]; + const struct lock_struct *exlock = &locks[i]; BOOL conflict = False; if (exlock->lock_flav == WINDOWS_LOCK) { @@ -1124,7 +1169,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, * see if there is a POSIX lock from a UNIX or NFS process. */ - if(lp_posix_locking(fsp->conn->cnum)) { + if(lp_posix_locking(fsp->conn->params)) { BOOL ret = is_posix_locked(fsp, pstart, psize, plock_type, POSIX_LOCK); DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n", @@ -1141,13 +1186,12 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, return NT_STATUS_OK; } - /**************************************************************************** Remove a particular pending lock. ****************************************************************************/ -BOOL brl_remove_pending_lock(struct byte_range_lock *br_lck, - uint16 smbpid, +BOOL brl_lock_cancel(struct byte_range_lock *br_lck, + uint32 smbpid, struct process_id pid, br_off start, br_off size, @@ -1167,7 +1211,7 @@ BOOL brl_remove_pending_lock(struct byte_range_lock *br_lck, /* For pending locks we *always* care about the fnum. */ if (brl_same_context(&lock->context, &context) && lock->fnum == br_lck->fsp->fnum && - lock->lock_type == PENDING_LOCK && + IS_PENDING_LOCK(lock->lock_type) && lock->lock_flav == lock_flav && lock->start == start && lock->size == size) { @@ -1191,18 +1235,75 @@ BOOL brl_remove_pending_lock(struct byte_range_lock *br_lck, return True; } - /**************************************************************************** Remove any locks associated with a open file. + We return True if this process owns any other Windows locks on this + fd and so we should not immediately close the fd. ****************************************************************************/ -void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid) +void brl_close_fnum(struct byte_range_lock *br_lck) { files_struct *fsp = br_lck->fsp; uint16 tid = fsp->conn->cnum; int fnum = fsp->fnum; unsigned int i, j, dcount=0; + int num_deleted_windows_locks = 0; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + struct process_id pid = procid_self(); + BOOL unlock_individually = False; + + if(lp_posix_locking(fsp->conn->params)) { + + /* Check if there are any Windows locks associated with this dev/ino + pair that are not this fnum. If so we need to call unlock on each + one in order to release the system POSIX locks correctly. */ + + for (i=0; i < br_lck->num_locks; i++) { + struct lock_struct *lock = &locks[i]; + + if (!procid_equal(&lock->context.pid, &pid)) { + continue; + } + + if (lock->lock_type != READ_LOCK && lock->lock_type != WRITE_LOCK) { + continue; /* Ignore pending. */ + } + + if (lock->context.tid != tid || lock->fnum != fnum) { + unlock_individually = True; + break; + } + } + + if (unlock_individually) { + struct lock_struct *locks_copy; + unsigned int num_locks_copy; + + /* Copy the current lock array. */ + locks_copy = (struct lock_struct *)TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct)); + if (!locks_copy) { + smb_panic("brl_close_fnum: talloc fail.\n"); + } + num_locks_copy = br_lck->num_locks; + + for (i=0; i < num_locks_copy; i++) { + struct lock_struct *lock = &locks_copy[i]; + + if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid) && + (lock->fnum == fnum)) { + brl_unlock(br_lck, + lock->context.smbpid, + pid, + lock->start, + lock->size, + lock->lock_flav); + } + } + return; + } + } + + /* We can bulk delete - any POSIX locks will be removed when the fd closes. */ /* Remove any existing locks for this fnum (or any fnum if they're POSIX). */ @@ -1213,6 +1314,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid) if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid)) { if ((lock->lock_flav == WINDOWS_LOCK) && (lock->fnum == fnum)) { del_this_lock = True; + num_deleted_windows_locks++; } else if (lock->lock_flav == POSIX_LOCK) { del_this_lock = True; } @@ -1224,7 +1326,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid) struct lock_struct *pend_lock = &locks[j]; /* Ignore our own or non-pending locks. */ - if (pend_lock->lock_type != PENDING_LOCK) { + if (!IS_PENDING_LOCK(pend_lock->lock_type)) { continue; } @@ -1238,11 +1340,9 @@ void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid) /* We could send specific lock info here... */ if (brl_pending_overlap(lock, pend_lock)) { - become_root(); message_send_pid(pend_lock->context.pid, MSG_SMB_UNLOCK, NULL, 0, True); - unbecome_root(); } } @@ -1257,6 +1357,11 @@ void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid) dcount++; } } + + if(lp_posix_locking(fsp->conn->params) && num_deleted_windows_locks) { + /* Reduce the Windows lock POSIX reference count on this dev/ino pair. */ + reduce_windows_lock_ref_count(fsp, num_deleted_windows_locks); + } } /**************************************************************************** @@ -1345,7 +1450,7 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st } if (orig_num_locks != num_locks) { - dbuf.dptr = (void *)locks; + dbuf.dptr = (char *)locks; dbuf.dsize = num_locks * sizeof(*locks); if (dbuf.dsize) { @@ -1387,13 +1492,17 @@ int brl_forall(BRLOCK_FN(fn)) Unlock the record. ********************************************************************/ -int byte_range_lock_destructor(struct byte_range_lock *br_lck) +static int byte_range_lock_destructor(struct byte_range_lock *br_lck) { TDB_DATA key; key.dptr = (char *)&br_lck->key; key.dsize = sizeof(struct lock_key); + if (br_lck->read_only) { + SMB_ASSERT(!br_lck->modified); + } + if (!br_lck->modified) { goto done; } @@ -1405,7 +1514,7 @@ int byte_range_lock_destructor(struct byte_range_lock *br_lck) } } else { TDB_DATA data; - data.dptr = br_lck->lock_data; + data.dptr = (char *)br_lck->lock_data; data.dsize = br_lck->num_locks * sizeof(struct lock_struct); if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) { @@ -1415,22 +1524,25 @@ int byte_range_lock_destructor(struct byte_range_lock *br_lck) done: - tdb_chainunlock(tdb, key); + if (!br_lck->read_only) { + tdb_chainunlock(tdb, key); + } SAFE_FREE(br_lck->lock_data); - SAFE_FREE(br_lck); return 0; } /******************************************************************* Fetch a set of byte range lock data from the database. Leave the record locked. + TALLOC_FREE(brl) will release the lock in the destructor. ********************************************************************/ -struct byte_range_lock *brl_get_locks(files_struct *fsp) +static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, + files_struct *fsp, BOOL read_only) { TDB_DATA key; TDB_DATA data; - struct byte_range_lock *br_lck = SMB_MALLOC_P(struct byte_range_lock); + struct byte_range_lock *br_lck = TALLOC_P(mem_ctx, struct byte_range_lock); if (br_lck == NULL) { return NULL; @@ -1446,12 +1558,25 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp) key.dptr = (char *)&br_lck->key; key.dsize = sizeof(struct lock_key); - if (tdb_chainlock(tdb, key) != 0) { - DEBUG(3, ("Could not lock byte range lock entry\n")); - SAFE_FREE(br_lck); - return NULL; + if (!fsp->lockdb_clean) { + /* We must be read/write to clean + the dead entries. */ + read_only = False; } + if (read_only) { + br_lck->read_only = True; + } else { + if (tdb_chainlock(tdb, key) != 0) { + DEBUG(3, ("Could not lock byte range lock entry\n")); + TALLOC_FREE(br_lck); + return NULL; + } + br_lck->read_only = False; + } + + talloc_set_destructor(br_lck, byte_range_lock_destructor); + data = tdb_fetch(tdb, key); br_lck->lock_data = (void *)data.dptr; br_lck->num_locks = data.dsize / sizeof(struct lock_struct); @@ -1462,13 +1587,22 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp) /* Go through and ensure all entries exist - remove any that don't. */ /* Makes the lockdb self cleaning at low cost. */ - if (!validate_lock_entries(&br_lck->num_locks, (struct lock_struct **)&br_lck->lock_data)) { - tdb_chainunlock(tdb, key); + struct lock_struct *locks = + (struct lock_struct *)br_lck->lock_data; + + if (!validate_lock_entries(&br_lck->num_locks, &locks)) { SAFE_FREE(br_lck->lock_data); - SAFE_FREE(br_lck); + TALLOC_FREE(br_lck); return NULL; } + /* + * validate_lock_entries might have changed locks. We can't + * use a direct pointer here because otherwise gcc warnes + * about strict aliasing rules being violated. + */ + br_lck->lock_data = locks; + /* Mark the lockdb as "clean" as seen from this open file. */ fsp->lockdb_clean = True; } @@ -1476,7 +1610,7 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp) if (DEBUGLEVEL >= 10) { unsigned int i; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; - DEBUG(10,("brl_get_locks: %u current locks on dev=%.0f, inode=%.0f\n", + DEBUG(10,("brl_get_locks_internal: %u current locks on dev=%.0f, inode=%.0f\n", br_lck->num_locks, (double)fsp->dev, (double)fsp->inode )); for( i = 0; i < br_lck->num_locks; i++) { @@ -1485,3 +1619,15 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp) } return br_lck; } + +struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, + files_struct *fsp) +{ + return brl_get_locks_internal(mem_ctx, fsp, False); +} + +struct byte_range_lock *brl_get_locks_readonly(TALLOC_CTX *mem_ctx, + files_struct *fsp) +{ + return brl_get_locks_internal(mem_ctx, fsp, True); +} diff --git a/source/locking/locking.c b/source/locking/locking.c index 9d3ca956014..13c7724656e 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -37,7 +37,6 @@ */ #include "includes.h" -uint16 global_smbpid; #undef DBGC_CLASS #define DBGC_CLASS DBGC_LOCKING @@ -56,8 +55,10 @@ const char *lock_type_name(enum brl_type lock_type) return "READ"; case WRITE_LOCK: return "WRITE"; - case PENDING_LOCK: - return "PENDING"; + case PENDING_READ_LOCK: + return "PENDING_READ"; + case PENDING_WRITE_LOCK: + return "PENDING_WRITE"; default: return "other"; } @@ -74,12 +75,12 @@ const char *lock_flav_name(enum brl_flavour lock_flav) ****************************************************************************/ BOOL is_locked(files_struct *fsp, + uint32 smbpid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type) { - int snum = SNUM(fsp->conn); - int strict_locking = lp_strict_locking(snum); + int strict_locking = lp_strict_locking(fsp->conn->params); enum brl_flavour lock_flav = lp_posix_cifsu_locktype(); BOOL ret = True; @@ -87,7 +88,7 @@ BOOL is_locked(files_struct *fsp, return False; } - if (!lp_locking(snum) || !strict_locking) { + if (!lp_locking(fsp->conn->params) || !strict_locking) { return False; } @@ -100,32 +101,32 @@ BOOL is_locked(files_struct *fsp, DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); ret = False; } else { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp); if (!br_lck) { return False; } ret = !brl_locktest(br_lck, - global_smbpid, + smbpid, procid_self(), offset, count, lock_type, lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } } else { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp); if (!br_lck) { return False; } ret = !brl_locktest(br_lck, - global_smbpid, + smbpid, procid_self(), offset, count, lock_type, lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n", @@ -141,7 +142,7 @@ BOOL is_locked(files_struct *fsp, ****************************************************************************/ NTSTATUS query_lock(files_struct *fsp, - uint16 *psmbpid, + uint32 *psmbpid, SMB_BIG_UINT *pcount, SMB_BIG_UINT *poffset, enum brl_type *plock_type, @@ -150,15 +151,15 @@ NTSTATUS query_lock(files_struct *fsp, struct byte_range_lock *br_lck = NULL; NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; - if (!OPEN_FSP(fsp) || !fsp->can_lock) { - return NT_STATUS_INVALID_HANDLE; + if (!fsp->can_lock) { + return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } - if (!lp_locking(SNUM(fsp->conn))) { + if (!lp_locking(fsp->conn->params)) { return NT_STATUS_OK; } - br_lck = brl_get_locks(fsp); + br_lck = brl_get_locks_readonly(NULL, fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } @@ -171,7 +172,7 @@ NTSTATUS query_lock(files_struct *fsp, plock_type, lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); return status; } @@ -179,23 +180,25 @@ NTSTATUS query_lock(files_struct *fsp, Utility function called by locking requests. ****************************************************************************/ -NTSTATUS do_lock(files_struct *fsp, - uint16 lock_pid, +struct byte_range_lock *do_lock(files_struct *fsp, + uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type, enum brl_flavour lock_flav, - BOOL *my_lock_ctx) + BOOL blocking_lock, + NTSTATUS *perr) { struct byte_range_lock *br_lck = NULL; - NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; - if (!OPEN_FSP(fsp) || !fsp->can_lock) { - return NT_STATUS_INVALID_HANDLE; + if (!fsp->can_lock) { + *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; + return NULL; } - if (!lp_locking(SNUM(fsp->conn))) { - return NT_STATUS_OK; + if (!lp_locking(fsp->conn->params)) { + *perr = NT_STATUS_OK; + return NULL; } /* NOTE! 0 byte long ranges ARE allowed and should be stored */ @@ -204,89 +207,76 @@ NTSTATUS do_lock(files_struct *fsp, lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - br_lck = brl_get_locks(fsp); + br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { - return NT_STATUS_NO_MEMORY; + *perr = NT_STATUS_NO_MEMORY; + return NULL; } - status = brl_lock(br_lck, + *perr = brl_lock(br_lck, lock_pid, procid_self(), offset, count, lock_type, lock_flav, - my_lock_ctx); + blocking_lock); - byte_range_lock_destructor(br_lck); - return status; + return br_lck; } /**************************************************************************** - Utility function called by locking requests. This is *DISGUSTING*. It also - appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000 - is so slow on the locking tests...... ? This is the reason. Much though I hate - it, we need this. JRA. + Utility function called by unlocking requests. ****************************************************************************/ -NTSTATUS do_lock_spin(files_struct *fsp, - uint16 lock_pid, +NTSTATUS do_unlock(files_struct *fsp, + uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, - enum brl_type lock_type, - enum brl_flavour lock_flav, - BOOL *my_lock_ctx) + enum brl_flavour lock_flav) { - int j, maxj = lp_lock_spin_count(); - int sleeptime = lp_lock_sleep_time(); - NTSTATUS status, ret; - - if (maxj <= 0) { - maxj = 1; + BOOL ok = False; + struct byte_range_lock *br_lck = NULL; + + if (!fsp->can_lock) { + return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } + + if (!lp_locking(fsp->conn->params)) { + return NT_STATUS_OK; + } + + DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n", + (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - ret = NT_STATUS_OK; /* to keep dumb compilers happy */ - - for (j = 0; j < maxj; j++) { - status = do_lock(fsp, - lock_pid, - count, - offset, - lock_type, - lock_flav, - my_lock_ctx); - - if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) && - !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { - return status; - } - /* if we do fail then return the first error code we got */ - if (j == 0) { - ret = status; - /* Don't spin if we blocked ourselves. */ - if (*my_lock_ctx) { - return ret; - } + br_lck = brl_get_locks(NULL, fsp); + if (!br_lck) { + return NT_STATUS_NO_MEMORY; + } - /* Only spin for Windows locks. */ - if (lock_flav == POSIX_LOCK) { - return ret; - } - } + ok = brl_unlock(br_lck, + lock_pid, + procid_self(), + offset, + count, + lock_flav); + + TALLOC_FREE(br_lck); - if (sleeptime) { - sys_usleep(sleeptime); - } + if (!ok) { + DEBUG(10,("do_unlock: returning ERRlock.\n" )); + return NT_STATUS_RANGE_NOT_LOCKED; } - return ret; + + return NT_STATUS_OK; } /**************************************************************************** - Utility function called by unlocking requests. + Cancel any pending blocked locks. ****************************************************************************/ -NTSTATUS do_unlock(files_struct *fsp, - uint16 lock_pid, +NTSTATUS do_lock_cancel(files_struct *fsp, + uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_flavour lock_flav) @@ -294,34 +284,35 @@ NTSTATUS do_unlock(files_struct *fsp, BOOL ok = False; struct byte_range_lock *br_lck = NULL; - if (!lp_locking(SNUM(fsp->conn))) { - return NT_STATUS_OK; + if (!fsp->can_lock) { + return fsp->is_directory ? + NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } - if (!OPEN_FSP(fsp) || !fsp->can_lock) { - return NT_STATUS_INVALID_HANDLE; + if (!lp_locking(fsp->conn->params)) { + return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } - - DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n", + + DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n", (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - br_lck = brl_get_locks(fsp); + br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } - ok = brl_unlock(br_lck, + ok = brl_lock_cancel(br_lck, lock_pid, procid_self(), offset, count, lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); if (!ok) { - DEBUG(10,("do_unlock: returning ERRlock.\n" )); - return NT_STATUS_RANGE_NOT_LOCKED; + DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" )); + return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } return NT_STATUS_OK; @@ -334,25 +325,17 @@ NTSTATUS do_unlock(files_struct *fsp, void locking_close_file(files_struct *fsp) { struct byte_range_lock *br_lck; - struct process_id pid = procid_self(); - if (!lp_locking(SNUM(fsp->conn))) + if (!lp_locking(fsp->conn->params)) { return; - - /* - * Just release all the brl locks, no need to release individually. - */ - - br_lck = brl_get_locks(fsp); - if (br_lck) { - brl_close_fnum(br_lck, pid); - byte_range_lock_destructor(br_lck); } - if(lp_posix_locking(SNUM(fsp->conn))) { - /* Release all the POSIX locks.*/ - posix_locking_close_file(fsp); + br_lck = brl_get_locks(NULL,fsp); + if (br_lck) { + cancel_pending_lock_requests_by_fid(fsp, br_lck); + brl_close_fnum(br_lck); + TALLOC_FREE(br_lck); } } @@ -516,9 +499,10 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) smb_panic("PANIC: parse_share_modes: buffer too short.\n"); } - lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data), - lck->num_share_modes * - sizeof(struct share_mode_entry)); + lck->share_modes = (struct share_mode_entry *) + talloc_memdup(lck, dbuf.dptr+sizeof(*data), + lck->num_share_modes * + sizeof(struct share_mode_entry)); if (lck->share_modes == NULL) { smb_panic("talloc failed\n"); @@ -577,12 +561,18 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) (lck->num_share_modes * sizeof(struct share_mode_entry)) + data->u.s.delete_token_size ); + if (lck->servicepath == NULL) { + smb_panic("talloc_strdup failed\n"); + } lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + (lck->num_share_modes * sizeof(struct share_mode_entry)) + data->u.s.delete_token_size + strlen(lck->servicepath) + 1 ); + if (lck->filename == NULL) { + smb_panic("talloc_strdup failed\n"); + } /* * Ensure that each entry has a real process attached. @@ -635,7 +625,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) delete_token_size + sp_len + 1 + strlen(lck->filename) + 1; - result.dptr = talloc_size(lck, result.dsize); + result.dptr = TALLOC_ARRAY(lck, char, result.dsize); if (result.dptr == NULL) { smb_panic("talloc failed\n"); @@ -687,10 +677,8 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) return result; } -static int share_mode_lock_destructor(void *p) +static int share_mode_lock_destructor(struct share_mode_lock *lck) { - struct share_mode_lock *lck = - talloc_get_type_abort(p, struct share_mode_lock); TDB_DATA key = locking_key(lck->dev, lck->ino); TDB_DATA data; @@ -838,7 +826,7 @@ BOOL rename_share_filename(struct share_mode_lock *lck, msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1; /* Set up the name changed message. */ - frm = TALLOC(lck, msg_len); + frm = TALLOC_ARRAY(lck, char, msg_len); if (!frm) { return False; } @@ -862,16 +850,14 @@ BOOL rename_share_filename(struct share_mode_lock *lck, continue; } - DEBUG(10,("rename_share_filename: sending rename message to pid %u " + DEBUG(10,("rename_share_filename: sending rename message to pid %s " "dev %x, inode %.0f sharepath %s newname %s\n", - (unsigned int)procid_to_pid(&se->pid), + procid_str_static(&se->pid), (unsigned int)lck->dev, (double)lck->ino, lck->servicepath, lck->filename )); - become_root(); message_send_pid(se->pid, MSG_SMB_FILE_RENAME, frm, msg_len, True); - unbecome_root(); } return True; @@ -1266,15 +1252,23 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKE return True; } +struct forall_state { + void (*fn)(const struct share_mode_entry *entry, + const char *sharepath, + const char *fname, + void *private_data); + void *private_data; +}; + static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, - void *state) + void *_state) { + struct forall_state *state = (struct forall_state *)_state; struct locking_data *data; struct share_mode_entry *shares; const char *sharepath; const char *fname; int i; - LOCKING_FN(traverse_callback) = (LOCKING_FN_CAST())state; /* Ensure this is a locking_key record. */ if (kbuf.dsize != sizeof(struct locking_key)) @@ -1291,7 +1285,8 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, strlen(sharepath) + 1; for (i=0;i<data->u.s.num_share_mode_entries;i++) { - traverse_callback(&shares[i], sharepath, fname); + state->fn(&shares[i], sharepath, fname, + state->private_data); } return 0; } @@ -1301,9 +1296,17 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, share mode system. ********************************************************************/ -int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, const char *)) +int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, + const char *, void *), + void *private_data) { + struct forall_state state; + if (tdb == NULL) return 0; - return tdb_traverse(tdb, traverse_fn, fn); + + state.fn = fn; + state.private_data = private_data; + + return tdb_traverse(tdb, traverse_fn, (void *)&state); } diff --git a/source/locking/posix.c b/source/locking/posix.c index 4a5f59b622d..806018da816 100644 --- a/source/locking/posix.c +++ b/source/locking/posix.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. Locking functions - Copyright (C) Jeremy Allison 1992-2000 + Copyright (C) Jeremy Allison 1992-2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,481 +28,17 @@ #define DBGC_CLASS DBGC_LOCKING /* - * The POSIX locking database handle. - */ - -static TDB_CONTEXT *posix_lock_tdb; - -/* * The pending close database handle. */ static TDB_CONTEXT *posix_pending_close_tdb; -/* - * The data in POSIX lock records is an unsorted linear array of these - * records. It is unnecessary to store the count as tdb provides the - * size of the record. - */ - -struct posix_lock { - int fd; - SMB_OFF_T start; - SMB_OFF_T size; - int lock_type; -}; - -/* - * The data in POSIX pending close records is an unsorted linear array of int - * records. It is unnecessary to store the count as tdb provides the - * size of the record. - */ - -/* The key used in both the POSIX databases. */ - -struct posix_lock_key { - SMB_DEV_T device; - SMB_INO_T inode; -}; - -/******************************************************************* - Form a static locking key for a dev/inode pair. -******************************************************************/ - -static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) -{ - static struct posix_lock_key key; - TDB_DATA kbuf; - - memset(&key, '\0', sizeof(key)); - key.device = dev; - key.inode = inode; - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); - return kbuf; -} - -/******************************************************************* - Convenience function to get a key from an fsp. -******************************************************************/ - -static TDB_DATA locking_key_fsp(files_struct *fsp) -{ - return locking_key(fsp->dev, fsp->inode); -} - -/**************************************************************************** - Add an fd to the pending close tdb. -****************************************************************************/ - -static BOOL add_fd_to_close_entry(files_struct *fsp) -{ - TDB_DATA kbuf = locking_key_fsp(fsp); - TDB_DATA dbuf; - - dbuf.dptr = NULL; - dbuf.dsize = 0; - - dbuf = tdb_fetch(posix_pending_close_tdb, kbuf); - - dbuf.dptr = SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(int)); - if (!dbuf.dptr) { - DEBUG(0,("add_fd_to_close_entry: Realloc fail !\n")); - return False; - } - - memcpy(dbuf.dptr + dbuf.dsize, &fsp->fh->fd, sizeof(int)); - dbuf.dsize += sizeof(int); - - if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) { - DEBUG(0,("add_fd_to_close_entry: tdb_store fail !\n")); - } - - SAFE_FREE(dbuf.dptr); - return True; -} - -/**************************************************************************** - Remove all fd entries for a specific dev/inode pair from the tdb. -****************************************************************************/ - -static void delete_close_entries(files_struct *fsp) -{ - TDB_DATA kbuf = locking_key_fsp(fsp); - - if (tdb_delete(posix_pending_close_tdb, kbuf) == -1) - DEBUG(0,("delete_close_entries: tdb_delete fail !\n")); -} - -/**************************************************************************** - Get the array of POSIX pending close records for an open fsp. Caller must - free. Returns number of entries. -****************************************************************************/ - -static size_t get_posix_pending_close_entries(files_struct *fsp, int **entries) -{ - TDB_DATA kbuf = locking_key_fsp(fsp); - TDB_DATA dbuf; - size_t count = 0; - - *entries = NULL; - dbuf.dptr = NULL; - - dbuf = tdb_fetch(posix_pending_close_tdb, kbuf); - - if (!dbuf.dptr) { - return 0; - } - - *entries = (int *)dbuf.dptr; - count = (size_t)(dbuf.dsize / sizeof(int)); - - return count; -} - -/**************************************************************************** - Get the array of POSIX locks for an fsp. Caller must free. Returns - number of entries. -****************************************************************************/ - -static size_t get_posix_lock_entries(files_struct *fsp, struct posix_lock **entries) -{ - TDB_DATA kbuf = locking_key_fsp(fsp); - TDB_DATA dbuf; - size_t count = 0; - - *entries = NULL; - - dbuf.dptr = NULL; - - dbuf = tdb_fetch(posix_lock_tdb, kbuf); - - if (!dbuf.dptr) { - return 0; - } - - *entries = (struct posix_lock *)dbuf.dptr; - count = (size_t)(dbuf.dsize / sizeof(struct posix_lock)); - - return count; -} - -/**************************************************************************** - Deal with pending closes needed by POSIX locking support. - Note that posix_locking_close_file() is expected to have been called - to delete all locks on this fsp before this function is called. -****************************************************************************/ - -int fd_close_posix(struct connection_struct *conn, files_struct *fsp) -{ - int saved_errno = 0; - int ret; - size_t count, i; - struct posix_lock *entries = NULL; - int *fd_array = NULL; - BOOL locks_on_other_fds = False; - - if (!lp_posix_locking(SNUM(conn))) { - /* - * No POSIX to worry about, just close. - */ - ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd); - fsp->fh->fd = -1; - return ret; - } - - /* - * Get the number of outstanding POSIX locks on this dev/inode pair. - */ - - count = get_posix_lock_entries(fsp, &entries); - - /* - * Check if there are any outstanding locks belonging to - * other fd's. This should never be the case if posix_locking_close_file() - * has been called first, but it never hurts to be *sure*. - */ - - for (i = 0; i < count; i++) { - if (entries[i].fd != fsp->fh->fd) { - locks_on_other_fds = True; - break; - } - } - - if (locks_on_other_fds) { - - /* - * There are outstanding locks on this dev/inode pair on other fds. - * Add our fd to the pending close tdb and set fsp->fh->fd to -1. - */ - - if (!add_fd_to_close_entry(fsp)) { - SAFE_FREE(entries); - return -1; - } - - SAFE_FREE(entries); - fsp->fh->fd = -1; - return 0; - } - - SAFE_FREE(entries); - - /* - * No outstanding POSIX locks. Get the pending close fd's - * from the tdb and close them all. - */ - - count = get_posix_pending_close_entries(fsp, &fd_array); - - if (count) { - DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count )); - - for(i = 0; i < count; i++) { - if (SMB_VFS_CLOSE(fsp,fd_array[i]) == -1) { - saved_errno = errno; - } - } - - /* - * Delete all fd's stored in the tdb - * for this dev/inode pair. - */ - - delete_close_entries(fsp); - } - - SAFE_FREE(fd_array); - - /* - * Finally close the fd associated with this fsp. - */ - - ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd); - - if (saved_errno != 0) { - errno = saved_errno; - ret = -1; - } - - fsp->fh->fd = -1; - - return ret; -} - -/**************************************************************************** - Debugging aid :-). -****************************************************************************/ - -static const char *posix_lock_type_name(int lock_type) -{ - return (lock_type == F_RDLCK) ? "READ" : "WRITE"; -} - -/**************************************************************************** - Delete a POSIX lock entry by index number. Used if the tdb add succeeds, but - then the POSIX fcntl lock fails. -****************************************************************************/ - -static BOOL delete_posix_lock_entry_by_index(files_struct *fsp, size_t entry) -{ - TDB_DATA kbuf = locking_key_fsp(fsp); - TDB_DATA dbuf; - struct posix_lock *locks; - size_t count; - - dbuf.dptr = NULL; - - dbuf = tdb_fetch(posix_lock_tdb, kbuf); - - if (!dbuf.dptr) { - DEBUG(10,("delete_posix_lock_entry_by_index: tdb_fetch failed !\n")); - goto fail; - } - - count = (size_t)(dbuf.dsize / sizeof(struct posix_lock)); - locks = (struct posix_lock *)dbuf.dptr; - - if (count == 1) { - tdb_delete(posix_lock_tdb, kbuf); - } else { - if (entry < count-1) { - memmove(&locks[entry], &locks[entry+1], sizeof(struct posix_lock)*((count-1) - entry)); - } - dbuf.dsize -= sizeof(struct posix_lock); - tdb_store(posix_lock_tdb, kbuf, dbuf, TDB_REPLACE); - } - - SAFE_FREE(dbuf.dptr); - - return True; - - fail: - - SAFE_FREE(dbuf.dptr); - return False; -} - -/**************************************************************************** - Add an entry into the POSIX locking tdb. We return the index number of the - added lock (used in case we need to delete *exactly* this entry). Returns - False on fail, True on success. -****************************************************************************/ - -static BOOL add_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T size, int lock_type, size_t *pentry_num) -{ - TDB_DATA kbuf = locking_key_fsp(fsp); - TDB_DATA dbuf; - struct posix_lock pl; - - dbuf.dptr = NULL; - dbuf.dsize = 0; - - dbuf = tdb_fetch(posix_lock_tdb, kbuf); - - *pentry_num = (size_t)(dbuf.dsize / sizeof(struct posix_lock)); - - /* - * Add new record. - */ - - pl.fd = fsp->fh->fd; - pl.start = start; - pl.size = size; - pl.lock_type = lock_type; - - dbuf.dptr = SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(struct posix_lock)); - if (!dbuf.dptr) { - DEBUG(0,("add_posix_lock_entry: Realloc fail !\n")); - goto fail; - } - - memcpy(dbuf.dptr + dbuf.dsize, &pl, sizeof(struct posix_lock)); - dbuf.dsize += sizeof(struct posix_lock); - - if (tdb_store(posix_lock_tdb, kbuf, dbuf, TDB_REPLACE) == -1) { - DEBUG(0,("add_posix_lock: Failed to add lock entry on file %s\n", fsp->fsp_name)); - goto fail; - } - - SAFE_FREE(dbuf.dptr); - - DEBUG(10,("add_posix_lock: File %s: type = %s: start=%.0f size=%.0f: dev=%.0f inode=%.0f\n", - fsp->fsp_name, posix_lock_type_name(lock_type), (double)start, (double)size, - (double)fsp->dev, (double)fsp->inode )); - - return True; - - fail: - - SAFE_FREE(dbuf.dptr); - return False; -} - /**************************************************************************** - Calculate if locks have any overlap at all. + First - the functions that deal with the underlying system locks - these + functions are used no matter if we're mapping CIFS Windows locks or CIFS + POSIX locks onto POSIX. ****************************************************************************/ -static BOOL does_lock_overlap(SMB_OFF_T start1, SMB_OFF_T size1, SMB_OFF_T start2, SMB_OFF_T size2) -{ - if (start1 >= start2 && start1 <= start2 + size2) - return True; - - if (start1 < start2 && start1 + size1 > start2) - return True; - - return False; -} - -/**************************************************************************** - Delete an entry from the POSIX locking tdb. Returns a copy of the entry being - deleted and the number of records that are overlapped by this one, or -1 on error. -****************************************************************************/ - -static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T size, struct posix_lock *pl) -{ - TDB_DATA kbuf = locking_key_fsp(fsp); - TDB_DATA dbuf; - struct posix_lock *locks; - size_t i, count; - BOOL found = False; - int num_overlapping_records = 0; - - dbuf.dptr = NULL; - - dbuf = tdb_fetch(posix_lock_tdb, kbuf); - - if (!dbuf.dptr) { - DEBUG(10,("delete_posix_lock_entry: tdb_fetch failed !\n")); - goto fail; - } - - /* There are existing locks - find a match. */ - locks = (struct posix_lock *)dbuf.dptr; - count = (size_t)(dbuf.dsize / sizeof(struct posix_lock)); - - /* - * Search for and delete the first record that matches the - * unlock criteria. - */ - - for (i=0; i<count; i++) { - struct posix_lock *entry = &locks[i]; - - if (entry->fd == fsp->fh->fd && - entry->start == start && - entry->size == size) { - - /* Make a copy */ - *pl = *entry; - - /* Found it - delete it. */ - if (count == 1) { - tdb_delete(posix_lock_tdb, kbuf); - } else { - if (i < count-1) { - memmove(&locks[i], &locks[i+1], sizeof(struct posix_lock)*((count-1) - i)); - } - dbuf.dsize -= sizeof(struct posix_lock); - tdb_store(posix_lock_tdb, kbuf, dbuf, TDB_REPLACE); - } - count--; - found = True; - break; - } - } - - if (!found) - goto fail; - - /* - * Count the number of entries that are - * overlapped by this unlock request. - */ - - for (i = 0; i < count; i++) { - struct posix_lock *entry = &locks[i]; - - if (fsp->fh->fd == entry->fd && - does_lock_overlap( start, size, entry->start, entry->size)) - num_overlapping_records++; - } - - DEBUG(10,("delete_posix_lock_entry: type = %s: start=%.0f size=%.0f, num_records = %d\n", - posix_lock_type_name(pl->lock_type), (double)pl->start, (double)pl->size, - (unsigned int)num_overlapping_records )); - - SAFE_FREE(dbuf.dptr); - - return num_overlapping_records; - - fail: - - SAFE_FREE(dbuf.dptr); - return -1; -} - /**************************************************************************** Utility function to map a lock type correctly depending on the open mode of a file. @@ -519,16 +55,6 @@ static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type) DEBUG(10,("map_posix_lock_type: Downgrading write lock to read due to read-only file.\n")); return F_RDLCK; } -#if 0 - /* We no longer open files write-only. */ - else if((lock_type == READ_LOCK) && !fsp->can_read) { - /* - * Ditto for read locks on write only files. - */ - DEBUG(10,("map_posix_lock_type: Changing read lock to write due to write-only file.\n")); - return F_WRLCK; - } -#endif /* * This return should be the most normal, as we attempt @@ -539,6 +65,15 @@ static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type) } /**************************************************************************** + Debugging aid :-). +****************************************************************************/ + +static const char *posix_lock_type_name(int lock_type) +{ + return (lock_type == F_RDLCK) ? "READ" : "WRITE"; +} + +/**************************************************************************** Check to see if the given unsigned lock range is within the possible POSIX range. Modifies the given args to be in range if possible, just returns False if not. @@ -608,15 +143,17 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out, * We must truncate the count to less than max_positive_lock_offset. */ - if (u_count & ~((SMB_BIG_UINT)max_positive_lock_offset)) + if (u_count & ~((SMB_BIG_UINT)max_positive_lock_offset)) { count = max_positive_lock_offset; + } /* * Truncate count to end at max lock offset. */ - if (offset + count < 0 || offset + count > max_positive_lock_offset) + if (offset + count < 0 || offset + count > max_positive_lock_offset) { count = max_positive_lock_offset - offset; + } /* * If we ate all the count, ignore this lock. @@ -729,7 +266,6 @@ static BOOL posix_fcntl_getlock(files_struct *fsp, SMB_OFF_T *poffset, SMB_OFF_T return ret; } - /**************************************************************************** POSIX function to see if a file region is locked. Returns True if the region is locked, False otherwise. @@ -774,6 +310,412 @@ BOOL is_posix_locked(files_struct *fsp, return True; } +/**************************************************************************** + Next - the functions that deal with in memory database storing representations + of either Windows CIFS locks or POSIX CIFS locks. +****************************************************************************/ + +/* The key used in the in-memory POSIX databases. */ + +struct lock_ref_count_key { + SMB_DEV_T device; + SMB_INO_T inode; + char r; +}; + +struct fd_key { + SMB_DEV_T device; + SMB_INO_T inode; +}; + +/******************************************************************* + Form a static locking key for a dev/inode pair for the fd array. +******************************************************************/ + +static TDB_DATA fd_array_key(SMB_DEV_T dev, SMB_INO_T inode) +{ + static struct fd_key key; + TDB_DATA kbuf; + + memset(&key, '\0', sizeof(key)); + key.device = dev; + key.inode = inode; + kbuf.dptr = (char *)&key; + kbuf.dsize = sizeof(key); + return kbuf; +} + +/******************************************************************* + Form a static locking key for a dev/inode pair for the lock ref count +******************************************************************/ + +static TDB_DATA locking_ref_count_key(SMB_DEV_T dev, SMB_INO_T inode) +{ + static struct lock_ref_count_key key; + TDB_DATA kbuf; + + memset(&key, '\0', sizeof(key)); + key.device = dev; + key.inode = inode; + key.r = 'r'; + kbuf.dptr = (char *)&key; + kbuf.dsize = sizeof(key); + return kbuf; +} + +/******************************************************************* + Convenience function to get an fd_array key from an fsp. +******************************************************************/ + +static TDB_DATA fd_array_key_fsp(files_struct *fsp) +{ + return fd_array_key(fsp->dev, fsp->inode); +} + +/******************************************************************* + Convenience function to get a lock ref count key from an fsp. +******************************************************************/ + +static TDB_DATA locking_ref_count_key_fsp(files_struct *fsp) +{ + return locking_ref_count_key(fsp->dev, fsp->inode); +} + +/******************************************************************* + Create the in-memory POSIX lock databases. +********************************************************************/ + +BOOL posix_locking_init(int read_only) +{ + if (posix_pending_close_tdb) { + return True; + } + + if (!posix_pending_close_tdb) { + posix_pending_close_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, + read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); + } + if (!posix_pending_close_tdb) { + DEBUG(0,("Failed to open POSIX pending close database.\n")); + return False; + } + + return True; +} + +/******************************************************************* + Delete the in-memory POSIX lock databases. +********************************************************************/ + +BOOL posix_locking_end(void) +{ + if (posix_pending_close_tdb && tdb_close(posix_pending_close_tdb) != 0) { + return False; + } + return True; +} + +/**************************************************************************** + Next - the functions that deal with storing fd's that have outstanding + POSIX locks when closed. +****************************************************************************/ + +/**************************************************************************** + The records in posix_pending_close_tdb are composed of an array of ints + keyed by dev/ino pair. + The first int is a reference count of the number of outstanding locks on + all open fd's on this dev/ino pair. Any subsequent ints are the fd's that + were open on this dev/ino pair that should have been closed, but can't as + the lock ref count is non zero. +****************************************************************************/ + +/**************************************************************************** + Keep a reference count of the number of Windows locks open on this dev/ino + pair. Creates entry if it doesn't exist. +****************************************************************************/ + +static void increment_windows_lock_ref_count(files_struct *fsp) +{ + TDB_DATA kbuf = locking_ref_count_key_fsp(fsp); + TDB_DATA dbuf; + int lock_ref_count; + + dbuf = tdb_fetch(posix_pending_close_tdb, kbuf); + if (dbuf.dptr == NULL) { + dbuf.dptr = (char *)SMB_MALLOC_P(int); + if (!dbuf.dptr) { + smb_panic("increment_windows_lock_ref_count: malloc fail.\n"); + } + memset(dbuf.dptr, '\0', sizeof(int)); + dbuf.dsize = sizeof(int); + } + + memcpy(&lock_ref_count, dbuf.dptr, sizeof(int)); + lock_ref_count++; + memcpy(dbuf.dptr, &lock_ref_count, sizeof(int)); + + if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) { + smb_panic("increment_windows_lock_ref_count: tdb_store_fail.\n"); + } + SAFE_FREE(dbuf.dptr); + + DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n", + fsp->fsp_name, lock_ref_count )); +} + +static void decrement_windows_lock_ref_count(files_struct *fsp) +{ + TDB_DATA kbuf = locking_ref_count_key_fsp(fsp); + TDB_DATA dbuf; + int lock_ref_count; + + dbuf = tdb_fetch(posix_pending_close_tdb, kbuf); + if (!dbuf.dptr) { + smb_panic("decrement_windows_lock_ref_count: logic error.\n"); + } + + memcpy(&lock_ref_count, dbuf.dptr, sizeof(int)); + lock_ref_count--; + memcpy(dbuf.dptr, &lock_ref_count, sizeof(int)); + + if (lock_ref_count < 0) { + smb_panic("decrement_windows_lock_ref_count: lock_count logic error.\n"); + } + + if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) { + smb_panic("decrement_windows_lock_ref_count: tdb_store_fail.\n"); + } + SAFE_FREE(dbuf.dptr); + + DEBUG(10,("decrement_windows_lock_ref_count for file now %s = %d\n", + fsp->fsp_name, lock_ref_count )); +} + +/**************************************************************************** + Bulk delete - subtract as many locks as we've just deleted. +****************************************************************************/ + +void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount) +{ + TDB_DATA kbuf = locking_ref_count_key_fsp(fsp); + TDB_DATA dbuf; + int lock_ref_count; + + dbuf = tdb_fetch(posix_pending_close_tdb, kbuf); + if (!dbuf.dptr) { + return; + } + + memcpy(&lock_ref_count, dbuf.dptr, sizeof(int)); + lock_ref_count -= dcount; + + if (lock_ref_count < 0) { + smb_panic("reduce_windows_lock_ref_count: lock_count logic error.\n"); + } + memcpy(dbuf.dptr, &lock_ref_count, sizeof(int)); + + if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) { + smb_panic("reduce_windows_lock_ref_count: tdb_store_fail.\n"); + } + SAFE_FREE(dbuf.dptr); + + DEBUG(10,("reduce_windows_lock_ref_count for file now %s = %d\n", + fsp->fsp_name, lock_ref_count )); +} + +/**************************************************************************** + Fetch the lock ref count. +****************************************************************************/ + +static int get_windows_lock_ref_count(files_struct *fsp) +{ + TDB_DATA kbuf = locking_ref_count_key_fsp(fsp); + TDB_DATA dbuf; + int lock_ref_count; + + dbuf = tdb_fetch(posix_pending_close_tdb, kbuf); + if (!dbuf.dptr) { + lock_ref_count = 0; + } else { + memcpy(&lock_ref_count, dbuf.dptr, sizeof(int)); + } + SAFE_FREE(dbuf.dptr); + + DEBUG(10,("get_windows_lock_count for file %s = %d\n", + fsp->fsp_name, lock_ref_count )); + return lock_ref_count; +} + +/**************************************************************************** + Delete a lock_ref_count entry. +****************************************************************************/ + +static void delete_windows_lock_ref_count(files_struct *fsp) +{ + TDB_DATA kbuf = locking_ref_count_key_fsp(fsp); + + /* Not a bug if it doesn't exist - no locks were ever granted. */ + tdb_delete(posix_pending_close_tdb, kbuf); + DEBUG(10,("delete_windows_lock_ref_count for file %s\n", fsp->fsp_name)); +} + +/**************************************************************************** + Add an fd to the pending close tdb. +****************************************************************************/ + +static void add_fd_to_close_entry(files_struct *fsp) +{ + TDB_DATA kbuf = fd_array_key_fsp(fsp); + TDB_DATA dbuf; + + dbuf.dptr = NULL; + dbuf.dsize = 0; + + dbuf = tdb_fetch(posix_pending_close_tdb, kbuf); + + dbuf.dptr = (char *)SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(int)); + if (!dbuf.dptr) { + smb_panic("add_fd_to_close_entry: Realloc fail !\n"); + } + + memcpy(dbuf.dptr + dbuf.dsize, &fsp->fh->fd, sizeof(int)); + dbuf.dsize += sizeof(int); + + if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) { + smb_panic("add_fd_to_close_entry: tdb_store_fail.\n"); + } + + DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n", + fsp->fh->fd, fsp->fsp_name )); + + SAFE_FREE(dbuf.dptr); +} + +/**************************************************************************** + Remove all fd entries for a specific dev/inode pair from the tdb. +****************************************************************************/ + +static void delete_close_entries(files_struct *fsp) +{ + TDB_DATA kbuf = fd_array_key_fsp(fsp); + + if (tdb_delete(posix_pending_close_tdb, kbuf) == -1) { + smb_panic("delete_close_entries: tdb_delete fail !\n"); + } +} + +/**************************************************************************** + Get the array of POSIX pending close records for an open fsp. Caller must + free. Returns number of entries. +****************************************************************************/ + +static size_t get_posix_pending_close_entries(files_struct *fsp, int **entries) +{ + TDB_DATA kbuf = fd_array_key_fsp(fsp); + TDB_DATA dbuf; + size_t count = 0; + + *entries = NULL; + dbuf.dptr = NULL; + + dbuf = tdb_fetch(posix_pending_close_tdb, kbuf); + + if (!dbuf.dptr) { + return 0; + } + + *entries = (int *)dbuf.dptr; + count = (size_t)(dbuf.dsize / sizeof(int)); + + return count; +} + +/**************************************************************************** + Deal with pending closes needed by POSIX locking support. + Note that posix_locking_close_file() is expected to have been called + to delete all locks on this fsp before this function is called. +****************************************************************************/ + +int fd_close_posix(struct connection_struct *conn, files_struct *fsp) +{ + int saved_errno = 0; + int ret; + int *fd_array = NULL; + size_t count, i; + + if (!lp_locking(fsp->conn->params) || !lp_posix_locking(conn->params)) { + /* + * No locking or POSIX to worry about or we want POSIX semantics + * which will lose all locks on all fd's open on this dev/inode, + * just close. + */ + ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd); + fsp->fh->fd = -1; + return ret; + } + + if (get_windows_lock_ref_count(fsp)) { + + /* + * There are outstanding locks on this dev/inode pair on other fds. + * Add our fd to the pending close tdb and set fsp->fh->fd to -1. + */ + + add_fd_to_close_entry(fsp); + fsp->fh->fd = -1; + return 0; + } + + /* + * No outstanding locks. Get the pending close fd's + * from the tdb and close them all. + */ + + count = get_posix_pending_close_entries(fsp, &fd_array); + + if (count) { + DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count )); + + for(i = 0; i < count; i++) { + if (SMB_VFS_CLOSE(fsp,fd_array[i]) == -1) { + saved_errno = errno; + } + } + + /* + * Delete all fd's stored in the tdb + * for this dev/inode pair. + */ + + delete_close_entries(fsp); + } + + SAFE_FREE(fd_array); + + /* Don't need a lock ref count on this dev/ino anymore. */ + delete_windows_lock_ref_count(fsp); + + /* + * Finally close the fd associated with this fsp. + */ + + ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd); + + if (saved_errno != 0) { + errno = saved_errno; + ret = -1; + } + + fsp->fh->fd = -1; + + return ret; +} + +/**************************************************************************** + Next - the functions that deal with the mapping CIFS Windows locks onto + the underlying system POSIX locks. +****************************************************************************/ + /* * Structure used when splitting a lock range * into a POSIX lock range. Doubly linked list. @@ -792,22 +734,14 @@ struct lock_list { understand it :-). ****************************************************************************/ -static struct lock_list *posix_lock_list(TALLOC_CTX *ctx, struct lock_list *lhead, files_struct *fsp) +static struct lock_list *posix_lock_list(TALLOC_CTX *ctx, + struct lock_list *lhead, + const struct lock_context *lock_ctx, /* Lock context lhead belongs to. */ + files_struct *fsp, + const struct lock_struct *plocks, + int num_locks) { - TDB_DATA kbuf = locking_key_fsp(fsp); - TDB_DATA dbuf; - struct posix_lock *locks; - size_t num_locks, i; - - dbuf.dptr = NULL; - - dbuf = tdb_fetch(posix_lock_tdb, kbuf); - - if (!dbuf.dptr) - return lhead; - - locks = (struct posix_lock *)dbuf.dptr; - num_locks = (size_t)(dbuf.dsize / sizeof(struct posix_lock)); + int i; /* * Check the current lock list on this dev/inode pair. @@ -818,10 +752,19 @@ static struct lock_list *posix_lock_list(TALLOC_CTX *ctx, struct lock_list *lhea (double)lhead->start, (double)lhead->size )); for (i=0; i<num_locks && lhead; i++) { - - struct posix_lock *lock = &locks[i]; + const struct lock_struct *lock = &plocks[i]; struct lock_list *l_curr; + /* Ignore all but read/write locks. */ + if (lock->lock_type != READ_LOCK && lock->lock_type != WRITE_LOCK) { + continue; + } + + /* Ignore locks not owned by this process. */ + if (!procid_equal(&lock->context.pid, &lock_ctx->pid)) { + continue; + } + /* * Walk the lock list, checking for overlaps. Note that * the lock list can expand within this loop if the current @@ -830,13 +773,13 @@ static struct lock_list *posix_lock_list(TALLOC_CTX *ctx, struct lock_list *lhea for (l_curr = lhead; l_curr;) { - DEBUG(10,("posix_lock_list: lock: fd=%d: start=%.0f,size=%.0f:type=%s", lock->fd, + DEBUG(10,("posix_lock_list: lock: fnum=%d: start=%.0f,size=%.0f:type=%s", lock->fnum, (double)lock->start, (double)lock->size, posix_lock_type_name(lock->lock_type) )); if ( (l_curr->start >= (lock->start + lock->size)) || (lock->start >= (l_curr->start + l_curr->size))) { - /* No overlap with this lock - leave this range alone. */ + /* No overlap with existing lock - leave this range alone. */ /********************************************* +---------+ | l_curr | @@ -850,7 +793,7 @@ OR.... +---------+ **********************************************/ - DEBUG(10,("no overlap case.\n" )); + DEBUG(10,(" no overlap case.\n" )); l_curr = l_curr->next; @@ -858,8 +801,8 @@ OR.... (l_curr->start + l_curr->size <= lock->start + lock->size) ) { /* - * This unlock is completely overlapped by this existing lock range - * and thus should have no effect (not be unlocked). Delete it from the list. + * This range is completely overlapped by this existing lock range + * and thus should have no effect. Delete it from the list. */ /********************************************* +---------+ @@ -872,11 +815,12 @@ OR.... /* Save the next pointer */ struct lock_list *ul_next = l_curr->next; - DEBUG(10,("delete case.\n" )); + DEBUG(10,(" delete case.\n" )); DLIST_REMOVE(lhead, l_curr); - if(lhead == NULL) + if(lhead == NULL) { break; /* No more list... */ + } l_curr = ul_next; @@ -885,7 +829,7 @@ OR.... (l_curr->start + l_curr->size > lock->start + lock->size) ) { /* - * This unlock overlaps the existing lock range at the high end. + * This range overlaps the existing lock range at the high end. * Truncate by moving start to existing range end and reducing size. */ /********************************************* @@ -904,7 +848,7 @@ BECOMES.... l_curr->size = (l_curr->start + l_curr->size) - (lock->start + lock->size); l_curr->start = lock->start + lock->size; - DEBUG(10,("truncate high case: start=%.0f,size=%.0f\n", + DEBUG(10,(" truncate high case: start=%.0f,size=%.0f\n", (double)l_curr->start, (double)l_curr->size )); l_curr = l_curr->next; @@ -914,7 +858,7 @@ BECOMES.... (l_curr->start + l_curr->size <= lock->start + lock->size) ) { /* - * This unlock overlaps the existing lock range at the low end. + * This range overlaps the existing lock range at the low end. * Truncate by reducing size. */ /********************************************* @@ -932,7 +876,7 @@ BECOMES.... l_curr->size = lock->start - l_curr->start; - DEBUG(10,("truncate low case: start=%.0f,size=%.0f\n", + DEBUG(10,(" truncate low case: start=%.0f,size=%.0f\n", (double)l_curr->start, (double)l_curr->size )); l_curr = l_curr->next; @@ -940,10 +884,10 @@ BECOMES.... } else if ( (l_curr->start < lock->start) && (l_curr->start + l_curr->size > lock->start + lock->size) ) { /* - * Worst case scenario. Unlock request completely overlaps an existing + * Worst case scenario. Range completely overlaps an existing * lock range. Split the request into two, push the new (upper) request - * into the dlink list, and continue with the entry after ul_new (as we - * know that ul_new will not overlap with this lock). + * into the dlink list, and continue with the entry after l_new (as we + * know that l_new will not overlap with this lock). */ /********************************************* +---------------------------+ @@ -971,7 +915,7 @@ BECOMES..... /* Truncate the l_curr. */ l_curr->size = lock->start - l_curr->start; - DEBUG(10,("split case: curr: start=%.0f,size=%.0f \ + DEBUG(10,(" split case: curr: start=%.0f,size=%.0f \ new: start=%.0f,size=%.0f\n", (double)l_curr->start, (double)l_curr->size, (double)l_new->start, (double)l_new->size )); @@ -1003,34 +947,33 @@ lock: start = %.0f, size = %.0f\n", (double)l_curr->start, (double)l_curr->size, } /* end for ( l_curr = lhead; l_curr;) */ } /* end for (i=0; i<num_locks && ul_head; i++) */ - SAFE_FREE(dbuf.dptr); - return lhead; } /**************************************************************************** POSIX function to acquire a lock. Returns True if the lock could be granted, False if not. - TODO -- Fix POSIX lock flavour semantics. ****************************************************************************/ -BOOL set_posix_lock(files_struct *fsp, +BOOL set_posix_lock_windows_flavour(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type, - enum brl_flavour lock_flav) + const struct lock_context *lock_ctx, + const struct lock_struct *plocks, + int num_locks, + int *errno_ret) { SMB_OFF_T offset; SMB_OFF_T count; + int posix_lock_type = map_posix_lock_type(fsp,lock_type); BOOL ret = True; - size_t entry_num = 0; size_t lock_count; TALLOC_CTX *l_ctx = NULL; struct lock_list *llist = NULL; struct lock_list *ll = NULL; - int posix_lock_type = map_posix_lock_type(fsp,lock_type); - DEBUG(5,("set_posix_lock: File %s, offset = %.0f, count = %.0f, type = %s\n", + DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n", fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) )); /* @@ -1038,8 +981,10 @@ BOOL set_posix_lock(files_struct *fsp, * pretend it was successful. */ - if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) + if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) { + increment_windows_lock_ref_count(fsp); return True; + } /* * Windows is very strange. It allows read locks to be overlayed @@ -1056,21 +1001,18 @@ BOOL set_posix_lock(files_struct *fsp, * READ LOCK: start =0, len = 10 - OK * * Under POSIX, the same sequence in steps 1 and 2 would not be reference counted, but - * would leave a single read lock over the 0-14 region. In order to - * re-create Windows semantics mapped to POSIX locks, we create multiple TDB - * entries, one for each overlayed lock request. We are guarenteed by the brlock - * semantics that if a write lock is added, then it will be first in the array. + * would leave a single read lock over the 0-14 region. */ if ((l_ctx = talloc_init("set_posix_lock")) == NULL) { - DEBUG(0,("set_posix_lock: unable to init talloc context.\n")); - return True; /* Not a fatal error. */ + DEBUG(0,("set_posix_lock_windows_flavour: unable to init talloc context.\n")); + return False; } if ((ll = TALLOC_P(l_ctx, struct lock_list)) == NULL) { - DEBUG(0,("set_posix_lock: unable to talloc unlock list.\n")); + DEBUG(0,("set_posix_lock_windows_flavour: unable to talloc unlock list.\n")); talloc_destroy(l_ctx); - return True; /* Not a fatal error. */ + return False; } /* @@ -1092,19 +1034,12 @@ BOOL set_posix_lock(files_struct *fsp, * POSIX locks. */ - llist = posix_lock_list(l_ctx, llist, fsp); - - /* - * Now we have the list of ranges to lock it is safe to add the - * entry into the POSIX lock tdb. We take note of the entry we - * added here in case we have to remove it on POSIX lock fail. - */ - - if (!add_posix_lock_entry(fsp,offset,count,posix_lock_type,&entry_num)) { - DEBUG(0,("set_posix_lock: Unable to create posix lock entry !\n")); - talloc_destroy(l_ctx); - return False; - } + llist = posix_lock_list(l_ctx, + llist, + lock_ctx, /* Lock context llist belongs to. */ + fsp, + plocks, + num_locks); /* * Add the POSIX locks on the list of ranges returned. @@ -1116,11 +1051,12 @@ BOOL set_posix_lock(files_struct *fsp, offset = ll->start; count = ll->size; - DEBUG(5,("set_posix_lock: Real lock: Type = %s: offset = %.0f, count = %.0f\n", + DEBUG(5,("set_posix_lock_windows_flavour: Real lock: Type = %s: offset = %.0f, count = %.0f\n", posix_lock_type_name(posix_lock_type), (double)offset, (double)count )); if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,posix_lock_type)) { - DEBUG(5,("set_posix_lock: Lock fail !: Type = %s: offset = %.0f, count = %.0f. Errno = %s\n", + *errno_ret = errno; + DEBUG(5,("set_posix_lock_windows_flavour: Lock fail !: Type = %s: offset = %.0f, count = %.0f. Errno = %s\n", posix_lock_type_name(posix_lock_type), (double)offset, (double)count, strerror(errno) )); ret = False; break; @@ -1137,17 +1073,14 @@ BOOL set_posix_lock(files_struct *fsp, offset = ll->start; count = ll->size; - DEBUG(5,("set_posix_lock: Backing out locks: Type = %s: offset = %.0f, count = %.0f\n", + DEBUG(5,("set_posix_lock_windows_flavour: Backing out locks: Type = %s: offset = %.0f, count = %.0f\n", posix_lock_type_name(posix_lock_type), (double)offset, (double)count )); posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_UNLCK); } - - /* - * Remove the tdb entry for this lock. - */ - - delete_posix_lock_entry_by_index(fsp,entry_num); + } else { + /* Remember the number of Windows locks we have on this dev/ino pair. */ + increment_windows_lock_ref_count(fsp); } talloc_destroy(l_ctx); @@ -1159,7 +1092,13 @@ BOOL set_posix_lock(files_struct *fsp, lock could be released, False if not. ****************************************************************************/ -BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count) +BOOL release_posix_lock_windows_flavour(files_struct *fsp, + SMB_BIG_UINT u_offset, + SMB_BIG_UINT u_count, + enum brl_type deleted_lock_type, + const struct lock_context *lock_ctx, + const struct lock_struct *plocks, + int num_locks) { SMB_OFF_T offset; SMB_OFF_T count; @@ -1167,56 +1106,31 @@ BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u TALLOC_CTX *ul_ctx = NULL; struct lock_list *ulist = NULL; struct lock_list *ul = NULL; - struct posix_lock deleted_lock; - int num_overlapped_entries; - DEBUG(5,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n", + DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f\n", fsp->fsp_name, (double)u_offset, (double)u_count )); + /* Remember the number of Windows locks we have on this dev/ino pair. */ + decrement_windows_lock_ref_count(fsp); + /* * If the requested lock won't fit in the POSIX range, we will * pretend it was successful. */ - if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) + if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) { return True; - - /* - * We treat this as one unlock request for POSIX accounting purposes even - * if it may later be split into multiple smaller POSIX unlock ranges. - * num_overlapped_entries is the number of existing locks that have any - * overlap with this unlock request. - */ - - num_overlapped_entries = delete_posix_lock_entry(fsp, offset, count, &deleted_lock); - - if (num_overlapped_entries == -1) { - smb_panic("release_posix_lock: unable find entry to delete !\n"); - } - - /* - * If num_overlapped_entries is > 0, and the lock_type we just deleted from the tdb was - * a POSIX write lock, then before doing the unlock we need to downgrade - * the POSIX lock to a read lock. This allows any overlapping read locks - * to be atomically maintained. - */ - - if (num_overlapped_entries > 0 && deleted_lock.lock_type == F_WRLCK) { - if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_RDLCK)) { - DEBUG(0,("release_posix_lock: downgrade of lock failed with error %s !\n", strerror(errno) )); - return False; - } } if ((ul_ctx = talloc_init("release_posix_lock")) == NULL) { - DEBUG(0,("release_posix_lock: unable to init talloc context.\n")); - return True; /* Not a fatal error. */ + DEBUG(0,("release_posix_lock_windows_flavour: unable to init talloc context.\n")); + return False; } if ((ul = TALLOC_P(ul_ctx, struct lock_list)) == NULL) { - DEBUG(0,("release_posix_lock: unable to talloc unlock list.\n")); + DEBUG(0,("release_posix_lock_windows_flavour: unable to talloc unlock list.\n")); talloc_destroy(ul_ctx); - return True; /* Not a fatal error. */ + return False; } /* @@ -1239,7 +1153,33 @@ BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u * unlocks are performed. */ - ulist = posix_lock_list(ul_ctx, ulist, fsp); + ulist = posix_lock_list(ul_ctx, + ulist, + lock_ctx, /* Lock context ulist belongs to. */ + fsp, + plocks, + num_locks); + + /* + * If there were any overlapped entries (list is > 1 or size or start have changed), + * and the lock_type we just deleted from + * the upper layer tdb was a write lock, then before doing the unlock we need to downgrade + * the POSIX lock to a read lock. This allows any overlapping read locks + * to be atomically maintained. + */ + + if (deleted_lock_type == WRITE_LOCK && + (!ulist || ulist->next != NULL || ulist->start != offset || ulist->size != count)) { + + DEBUG(5,("release_posix_lock_windows_flavour: downgrading lock to READ: offset = %.0f, count = %.0f\n", + (double)offset, (double)count )); + + if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_RDLCK)) { + DEBUG(0,("release_posix_lock_windows_flavour: downgrade of lock failed with error %s !\n", strerror(errno) )); + talloc_destroy(ul_ctx); + return False; + } + } /* * Release the POSIX locks on the list of ranges returned. @@ -1249,129 +1189,148 @@ BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u offset = ulist->start; count = ulist->size; - DEBUG(5,("release_posix_lock: Real unlock: offset = %.0f, count = %.0f\n", + DEBUG(5,("release_posix_lock_windows_flavour: Real unlock: offset = %.0f, count = %.0f\n", (double)offset, (double)count )); - if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_UNLCK)) + if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_UNLCK)) { ret = False; + } } talloc_destroy(ul_ctx); - return ret; } /**************************************************************************** - Remove all lock entries for a specific dev/inode pair from the tdb. + Next - the functions that deal with mapping CIFS POSIX locks onto + the underlying system POSIX locks. ****************************************************************************/ -static void delete_posix_lock_entries(files_struct *fsp) -{ - TDB_DATA kbuf = locking_key_fsp(fsp); - - if (tdb_delete(posix_lock_tdb, kbuf) == -1) - DEBUG(0,("delete_close_entries: tdb_delete fail !\n")); -} - /**************************************************************************** - Debug function. + POSIX function to acquire a lock. Returns True if the + lock could be granted, False if not. + As POSIX locks don't stack or conflict (they just overwrite) + we can map the requested lock directly onto a system one. We + know it doesn't conflict with locks on other contexts as the + upper layer would have refused it. ****************************************************************************/ -static void dump_entry(struct posix_lock *pl) +BOOL set_posix_lock_posix_flavour(files_struct *fsp, + SMB_BIG_UINT u_offset, + SMB_BIG_UINT u_count, + enum brl_type lock_type, + int *errno_ret) { - DEBUG(10,("entry: start=%.0f, size=%.0f, type=%d, fd=%i\n", - (double)pl->start, (double)pl->size, (int)pl->lock_type, pl->fd )); + SMB_OFF_T offset; + SMB_OFF_T count; + int posix_lock_type = map_posix_lock_type(fsp,lock_type); + + DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n", + fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) )); + + /* + * If the requested lock won't fit in the POSIX range, we will + * pretend it was successful. + */ + + if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) { + return True; + } + + if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,posix_lock_type)) { + *errno_ret = errno; + DEBUG(5,("set_posix_lock_posix_flavour: Lock fail !: Type = %s: offset = %.0f, count = %.0f. Errno = %s\n", + posix_lock_type_name(posix_lock_type), (double)offset, (double)count, strerror(errno) )); + return False; + } + return True; } /**************************************************************************** - Remove any locks on this fd. Called from file_close(). + POSIX function to release a lock. Returns True if the + lock could be released, False if not. + We are given a complete lock state from the upper layer which is what the lock + state should be after the unlock has already been done, so what + we do is punch out holes in the unlock range where locks owned by this process + have a different lock context. ****************************************************************************/ -void posix_locking_close_file(files_struct *fsp) +BOOL release_posix_lock_posix_flavour(files_struct *fsp, + SMB_BIG_UINT u_offset, + SMB_BIG_UINT u_count, + const struct lock_context *lock_ctx, + const struct lock_struct *plocks, + int num_locks) { - struct posix_lock *entries = NULL; - size_t count, i; + BOOL ret = True; + SMB_OFF_T offset; + SMB_OFF_T count; + TALLOC_CTX *ul_ctx = NULL; + struct lock_list *ulist = NULL; + struct lock_list *ul = NULL; + + DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f\n", + fsp->fsp_name, (double)u_offset, (double)u_count )); /* - * Optimization for the common case where we are the only - * opener of a file. If all fd entries are our own, we don't - * need to explicitly release all the locks via the POSIX functions, - * we can just remove all the entries in the tdb and allow the - * close to remove the real locks. + * If the requested lock won't fit in the POSIX range, we will + * pretend it was successful. */ - count = get_posix_lock_entries(fsp, &entries); - - if (count == 0) { - DEBUG(10,("posix_locking_close_file: file %s has no outstanding locks.\n", fsp->fsp_name )); - return; + if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) { + return True; } - for (i = 0; i < count; i++) { - if (entries[i].fd != fsp->fh->fd ) - break; - - dump_entry(&entries[i]); + if ((ul_ctx = talloc_init("release_posix_lock")) == NULL) { + DEBUG(0,("release_posix_lock_windows_flavour: unable to init talloc context.\n")); + return False; } - if (i == count) { - /* All locks are ours. */ - DEBUG(10,("posix_locking_close_file: file %s has %u outstanding locks, but all on one fd.\n", - fsp->fsp_name, (unsigned int)count )); - SAFE_FREE(entries); - delete_posix_lock_entries(fsp); - return; + if ((ul = TALLOC_P(ul_ctx, struct lock_list)) == NULL) { + DEBUG(0,("release_posix_lock_windows_flavour: unable to talloc unlock list.\n")); + talloc_destroy(ul_ctx); + return False; } /* - * Difficult case. We need to delete all our locks, whilst leaving - * all other POSIX locks in place. + * Create the initial list entry containing the + * lock we want to remove. */ - for (i = 0; i < count; i++) { - struct posix_lock *pl = &entries[i]; - if (pl->fd == fsp->fh->fd) - release_posix_lock(fsp, (SMB_BIG_UINT)pl->start, (SMB_BIG_UINT)pl->size ); - } - SAFE_FREE(entries); -} + ZERO_STRUCTP(ul); + ul->start = offset; + ul->size = count; -/******************************************************************* - Create the in-memory POSIX lock databases. -********************************************************************/ + DLIST_ADD(ulist, ul); -BOOL posix_locking_init(int read_only) -{ - if (posix_lock_tdb && posix_pending_close_tdb) - return True; - - if (!posix_lock_tdb) - posix_lock_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, - read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); - if (!posix_lock_tdb) { - DEBUG(0,("Failed to open POSIX byte range locking database.\n")); - return False; - } - if (!posix_pending_close_tdb) - posix_pending_close_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, - read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); - if (!posix_pending_close_tdb) { - DEBUG(0,("Failed to open POSIX pending close database.\n")); - return False; - } + /* + * Walk the given array creating a linked list + * of unlock requests. + */ - return True; -} + ulist = posix_lock_list(ul_ctx, + ulist, + lock_ctx, /* Lock context ulist belongs to. */ + fsp, + plocks, + num_locks); -/******************************************************************* - Delete the in-memory POSIX lock databases. -********************************************************************/ + /* + * Release the POSIX locks on the list of ranges returned. + */ -BOOL posix_locking_end(void) -{ - if (posix_lock_tdb && tdb_close(posix_lock_tdb) != 0) - return False; - if (posix_pending_close_tdb && tdb_close(posix_pending_close_tdb) != 0) - return False; - return True; + for(; ulist; ulist = ulist->next) { + offset = ulist->start; + count = ulist->size; + + DEBUG(5,("release_posix_lock_posix_flavour: Real unlock: offset = %.0f, count = %.0f\n", + (double)offset, (double)count )); + + if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_UNLCK)) { + ret = False; + } + } + + talloc_destroy(ul_ctx); + return ret; } diff --git a/source/modules/vfs_audit.c b/source/modules/vfs_audit.c index 9f5179a47ce..b240cafd29f 100644 --- a/source/modules/vfs_audit.c +++ b/source/modules/vfs_audit.c @@ -29,17 +29,17 @@ /* Function prototypes */ -static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user); -static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn); -static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr); -static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); -static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path); -static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode); +static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user); +static void audit_disconnect(vfs_handle_struct *handle); +static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr); +static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode); +static int audit_rmdir(vfs_handle_struct *handle, const char *path); +static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode); static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd); -static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname); -static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path); -static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); -static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode); +static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname); +static int audit_unlink(vfs_handle_struct *handle, const char *path); +static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode); +static int audit_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode); static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); @@ -120,7 +120,7 @@ static int audit_syslog_priority(vfs_handle_struct *handle) /* Implementation of vfs_ops. Pass everything on to the default operation but log event first. */ -static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user) +static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user) { int result; @@ -129,24 +129,24 @@ static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, con syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n", svc, user); - result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user); + result = SMB_VFS_NEXT_CONNECT(handle, svc, user); return result; } -static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn) +static void audit_disconnect(vfs_handle_struct *handle) { syslog(audit_syslog_priority(handle), "disconnected\n"); - SMB_VFS_NEXT_DISCONNECT(handle, conn); + SMB_VFS_NEXT_DISCONNECT(handle); return; } -static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) +static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) { SMB_STRUCT_DIR *result; - result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr); + result = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); syslog(audit_syslog_priority(handle), "opendir %s %s%s\n", fname, @@ -156,11 +156,11 @@ static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struc return result; } -static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) +static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) { int result; - result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode); + result = SMB_VFS_NEXT_MKDIR(handle, path, mode); syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n", path, @@ -170,11 +170,11 @@ static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const return result; } -static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) +static int audit_rmdir(vfs_handle_struct *handle, const char *path) { int result; - result = SMB_VFS_NEXT_RMDIR(handle, conn, path); + result = SMB_VFS_NEXT_RMDIR(handle, path); syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n", path, @@ -184,11 +184,11 @@ static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const return result; } -static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) +static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode) { int result; - result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode); + result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n", fname, result, @@ -213,11 +213,11 @@ static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd) return result; } -static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname) +static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname) { int result; - result = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname); + result = SMB_VFS_NEXT_RENAME(handle, oldname, newname); syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n", oldname, newname, @@ -227,11 +227,11 @@ static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, cons return result; } -static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) +static int audit_unlink(vfs_handle_struct *handle, const char *path) { int result; - result = SMB_VFS_NEXT_UNLINK(handle, conn, path); + result = SMB_VFS_NEXT_UNLINK(handle, path); syslog(audit_syslog_priority(handle), "unlink %s %s%s\n", path, @@ -241,11 +241,11 @@ static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, cons return result; } -static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) +static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) { int result; - result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode); + result = SMB_VFS_NEXT_CHMOD(handle, path, mode); syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n", path, mode, @@ -255,11 +255,11 @@ static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const return result; } -static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) +static int audit_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode) { int result; - result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode); + result = SMB_VFS_NEXT_CHMOD_ACL(handle, path, mode); syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n", path, mode, diff --git a/source/modules/vfs_cacheprime.c b/source/modules/vfs_cacheprime.c new file mode 100644 index 00000000000..196441c4dda --- /dev/null +++ b/source/modules/vfs_cacheprime.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) James Peach 2005-2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +/* Cache priming module. + * + * The purpose of this module is to do RAID stripe width reads to prime the + * buffer cache to do zero-copy I/O for subsequent sendfile calls. The idea is + * to do a single large read at the start of the file to make sure that most or + * all of the file is pulled into the buffer cache. Subsequent I/Os have + * reduced latency. + * + * Tunables. + * + * cacheprime:rsize Amount of readahead in bytes. This should be a + * multiple of the RAID stripe width. + * cacheprime:debug Debug level at which to emit messages. + */ + +#define READAHEAD_MIN (128 * 1024) /* min is 128 KiB */ +#define READAHEAD_MAX (100 * 1024 * 1024) /* max is 100 MiB */ + +#define MODULE "cacheprime" + +static int module_debug; +static ssize_t g_readsz = 0; +static void * g_readbuf = NULL; + +/* Prime the kernel buffer cache with data from the specified file. We use + * per-fsp data to make sure we only ever do this once. If pread is being + * emulated by seek/read/seek, when this will suck quite a lot. + */ +static BOOL prime_cache( + struct vfs_handle_struct * handle, + files_struct * fsp, + int fd, + SMB_OFF_T offset, + size_t count) +{ + SMB_OFF_T * last; + ssize_t nread; + + last = VFS_ADD_FSP_EXTENSION(handle, fsp, SMB_OFF_T); + if (!last) { + return False; + } + + if (*last == -1) { + /* Readahead disabled. */ + return False; + } + + if ((*last + g_readsz) > (offset + count)) { + /* Skip readahead ... we've already been here. */ + return False; + } + + DEBUG(module_debug, + ("%s: doing readahead of %lld bytes at %lld for %s\n", + MODULE, (long long)g_readsz, (long long)*last, + fsp->fsp_name)); + + nread = sys_pread(fd, g_readbuf, g_readsz, *last); + if (nread < 0) { + *last = -1; + return False; + } + + *last += nread; + return True; +} + +static int cprime_connect( + struct vfs_handle_struct * handle, + const char * service, + const char * user) +{ + module_debug = lp_parm_int(SNUM(handle->conn), MODULE, "debug", 100); + if (g_readbuf) { + /* Only allocate g_readbuf once. If the config changes and + * another client multiplexes onto this smbd, we don't want + * to risk memory corruption. + */ + return SMB_VFS_NEXT_CONNECT(handle, service, user); + } + + g_readsz = conv_str_size(lp_parm_const_string(SNUM(handle->conn), + MODULE, "rsize", NULL)); + + if (g_readsz < READAHEAD_MIN) { + DEBUG(module_debug, ("%s: %ld bytes of readahead " + "requested, using minimum of %u\n", + MODULE, (long)g_readsz, READAHEAD_MIN)); + g_readsz = READAHEAD_MIN; + } else if (g_readsz > READAHEAD_MAX) { + DEBUG(module_debug, ("%s: %ld bytes of readahead " + "requested, using maximum of %u\n", + MODULE, (long)g_readsz, READAHEAD_MAX)); + g_readsz = READAHEAD_MAX; + } + + if ((g_readbuf = SMB_MALLOC(g_readsz)) == NULL) { + /* Turn off readahead if we can't get a buffer. */ + g_readsz = 0; + } + + return SMB_VFS_NEXT_CONNECT(handle, service, user); +} + +static ssize_t cprime_sendfile( + struct vfs_handle_struct * handle, + int tofd, + files_struct * fsp, + int fromfd, + const DATA_BLOB * header, + SMB_OFF_T offset, + size_t count) +{ + if (g_readbuf && offset == 0) { + prime_cache(handle, fsp, fromfd, offset, count); + } + + return SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, fromfd, + header, offset, count); +} + +static ssize_t cprime_read( + vfs_handle_struct * handle, + files_struct * fsp, + int fd, + void * data, + size_t count) +{ + SMB_OFF_T offset; + + offset = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); + if (offset >= 0 && g_readbuf) { + prime_cache(handle, fsp, fd, offset, count); + SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET); + } + + return SMB_VFS_NEXT_READ(handle, fsp, fd, data, count); +} + +static ssize_t cprime_pread( + vfs_handle_struct * handle, + files_struct * fsp, + int fd, + void * data, + size_t count, + SMB_OFF_T offset) +{ + if (g_readbuf) { + prime_cache(handle, fsp, fd, offset, count); + } + + return SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, count, offset); +} + +static vfs_op_tuple cprime_ops [] = +{ + {SMB_VFS_OP(cprime_sendfile), + SMB_VFS_OP_SENDFILE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(cprime_pread), + SMB_VFS_OP_PREAD, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(cprime_read), + SMB_VFS_OP_READ, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(cprime_connect), + SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +/* ------------------------------------------------------------------------- + * Samba module initialisation entry point. + * ------------------------------------------------------------------------- + */ + +NTSTATUS vfs_cacheprime_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE, cprime_ops); +} + +/* vim: set sw=4 ts=4 tw=79 et: */ diff --git a/source/modules/vfs_cap.c b/source/modules/vfs_cap.c index b1bfcd75f2f..c4539ca34a8 100644 --- a/source/modules/vfs_cap.c +++ b/source/modules/vfs_cap.c @@ -28,28 +28,28 @@ static char *capencode(char *to, const char *from); static char *capdecode(char *to, const char *from); -static SMB_BIG_UINT cap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path, +static SMB_BIG_UINT cap_disk_free(vfs_handle_struct *handle, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_DISK_FREE(handle, conn, cappath, small_query, bsize, + return SMB_VFS_NEXT_DISK_FREE(handle, cappath, small_query, bsize, dfree, dsize); } -static SMB_STRUCT_DIR *cap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) +static SMB_STRUCT_DIR *cap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) { pstring capname; capencode(capname, fname); - return SMB_VFS_NEXT_OPENDIR(handle, conn, capname, mask, attr); + return SMB_VFS_NEXT_OPENDIR(handle, capname, mask, attr); } -static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp) +static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) { SMB_STRUCT_DIRENT *result; DEBUG(3,("cap: cap_readdir\n")); - result = SMB_VFS_NEXT_READDIR(handle, conn, dirp); + result = SMB_VFS_NEXT_READDIR(handle, dirp); if (result) { DEBUG(3,("cap: cap_readdir: %s\n", result->d_name)); capdecode(result->d_name, result->d_name); @@ -57,134 +57,134 @@ static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, connection_stru return result; } -static int cap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) +static int cap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_MKDIR(handle, conn, cappath, mode); + return SMB_VFS_NEXT_MKDIR(handle, cappath, mode); } -static int cap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) +static int cap_rmdir(vfs_handle_struct *handle, const char *path) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_RMDIR(handle, conn, cappath); + return SMB_VFS_NEXT_RMDIR(handle, cappath); } -static int cap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) +static int cap_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode) { pstring capname; DEBUG(3,("cap: cap_open for %s\n", fname)); capencode(capname, fname); - return SMB_VFS_NEXT_OPEN(handle, conn, capname, flags, mode); + return SMB_VFS_NEXT_OPEN(handle, capname, fsp, flags, mode); } -static int cap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname) +static int cap_rename(vfs_handle_struct *handle, const char *oldname, const char *newname) { pstring capold, capnew; capencode(capold, oldname); capencode(capnew, newname); - return SMB_VFS_NEXT_RENAME(handle, conn, capold, capnew); + return SMB_VFS_NEXT_RENAME(handle, capold, capnew); } -static int cap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) +static int cap_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf) { pstring capname; capencode(capname, fname); - return SMB_VFS_NEXT_STAT(handle, conn, capname, sbuf); + return SMB_VFS_NEXT_STAT(handle, capname, sbuf); } -static int cap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) +static int cap_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_LSTAT(handle, conn, cappath, sbuf); + return SMB_VFS_NEXT_LSTAT(handle, cappath, sbuf); } -static int cap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) +static int cap_unlink(vfs_handle_struct *handle, const char *path) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_UNLINK(handle, conn, cappath); + return SMB_VFS_NEXT_UNLINK(handle, cappath); } -static int cap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) +static int cap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_CHMOD(handle, conn, cappath, mode); + return SMB_VFS_NEXT_CHMOD(handle, cappath, mode); } -static int cap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid) +static int cap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_CHOWN(handle, conn, cappath, uid, gid); + return SMB_VFS_NEXT_CHOWN(handle, cappath, uid, gid); } -static int cap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) +static int cap_chdir(vfs_handle_struct *handle, const char *path) { pstring cappath; DEBUG(3,("cap: cap_chdir for %s\n", path)); capencode(cappath, path); - return SMB_VFS_NEXT_CHDIR(handle, conn, cappath); + return SMB_VFS_NEXT_CHDIR(handle, cappath); } -static int cap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times) +static int cap_utime(vfs_handle_struct *handle, const char *path, struct utimbuf *times) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_UTIME(handle, conn, cappath, times); + return SMB_VFS_NEXT_UTIME(handle, cappath, times); } -static BOOL cap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) +static BOOL cap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath) { pstring capoldpath, capnewpath; capencode(capoldpath, oldpath); capencode(capnewpath, newpath); - return SMB_VFS_NEXT_SYMLINK(handle, conn, capoldpath, capnewpath); + return SMB_VFS_NEXT_SYMLINK(handle, capoldpath, capnewpath); } -static BOOL cap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz) +static BOOL cap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_READLINK(handle, conn, cappath, buf, bufsiz); + return SMB_VFS_NEXT_READLINK(handle, cappath, buf, bufsiz); } -static int cap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) +static int cap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath) { pstring capoldpath, capnewpath; capencode(capoldpath, oldpath); capencode(capnewpath, newpath); - return SMB_VFS_NEXT_LINK(handle, conn, capoldpath, capnewpath); + return SMB_VFS_NEXT_LINK(handle, capoldpath, capnewpath); } -static int cap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev) +static int cap_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_MKNOD(handle, conn, cappath, mode, dev); + return SMB_VFS_NEXT_MKNOD(handle, cappath, mode, dev); } -static char *cap_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path) +static char *cap_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path) { /* monyo need capencode'ed and capdecode'ed? */ pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path); + return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path); } -static BOOL cap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd) +static BOOL cap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor *psd) { pstring capname; capencode(capname, name); return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, capname, security_info_sent, psd); } -static int cap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode) +static int cap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode) { pstring capname; capencode(capname, name); @@ -194,45 +194,45 @@ static int cap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, con errno = ENOSYS; return -1; } - return SMB_VFS_NEXT_CHMOD_ACL(handle, conn, capname, mode); + return SMB_VFS_NEXT_CHMOD_ACL(handle, capname, mode); } -static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type) +static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type) { pstring cappath_p; capencode(cappath_p, path_p); - return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, conn, cappath_p, type); + return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cappath_p, type); } -static int cap_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) +static int cap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) { pstring capname; capencode(capname, name); - return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, conn, capname, acltype, theacl); + return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, capname, acltype, theacl); } -static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path) +static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, conn, cappath); + return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cappath); } -static ssize_t cap_getxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t size) +static ssize_t cap_getxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t size) { pstring cappath, capname; capencode(cappath, path); capencode(capname, name); - return SMB_VFS_NEXT_GETXATTR(handle, conn, cappath, capname, value, size); + return SMB_VFS_NEXT_GETXATTR(handle, cappath, capname, value, size); } -static ssize_t cap_lgetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t +static ssize_t cap_lgetxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t size) { pstring cappath, capname; capencode(cappath, path); capencode(capname, name); - return SMB_VFS_NEXT_LGETXATTR(handle, conn, cappath, capname, value, size); + return SMB_VFS_NEXT_LGETXATTR(handle, cappath, capname, value, size); } static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size) @@ -242,34 +242,34 @@ static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp return SMB_VFS_NEXT_FGETXATTR(handle, fsp, fd, capname, value, size); } -static ssize_t cap_listxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size) +static ssize_t cap_listxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_LISTXATTR(handle, conn, cappath, list, size); + return SMB_VFS_NEXT_LISTXATTR(handle, cappath, list, size); } -static ssize_t cap_llistxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size) +static ssize_t cap_llistxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_LLISTXATTR(handle, conn, cappath, list, size); + return SMB_VFS_NEXT_LLISTXATTR(handle, cappath, list, size); } -static int cap_removexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name) +static int cap_removexattr(vfs_handle_struct *handle, const char *path, const char *name) { pstring cappath, capname; capencode(cappath, path); capencode(capname, name); - return SMB_VFS_NEXT_REMOVEXATTR(handle, conn, cappath, capname); + return SMB_VFS_NEXT_REMOVEXATTR(handle, cappath, capname); } -static int cap_lremovexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name) +static int cap_lremovexattr(vfs_handle_struct *handle, const char *path, const char *name) { pstring cappath, capname; capencode(cappath, path); capencode(capname, name); - return SMB_VFS_NEXT_LREMOVEXATTR(handle, conn, cappath, capname); + return SMB_VFS_NEXT_LREMOVEXATTR(handle, cappath, capname); } static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name) @@ -279,20 +279,20 @@ static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, fd, capname); } -static int cap_setxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags) +static int cap_setxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags) { pstring cappath, capname; capencode(cappath, path); capencode(capname, name); - return SMB_VFS_NEXT_SETXATTR(handle, conn, cappath, capname, value, size, flags); + return SMB_VFS_NEXT_SETXATTR(handle, cappath, capname, value, size, flags); } -static int cap_lsetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags) +static int cap_lsetxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags) { pstring cappath, capname; capencode(cappath, path); capencode(capname, name); - return SMB_VFS_NEXT_LSETXATTR(handle, conn, cappath, capname, value, size, flags); + return SMB_VFS_NEXT_LSETXATTR(handle, cappath, capname, value, size, flags); } static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags) diff --git a/source/modules/vfs_catia.c b/source/modules/vfs_catia.c index 69735de3f43..ccf637c3bcf 100644 --- a/source/modules/vfs_catia.c +++ b/source/modules/vfs_catia.c @@ -71,20 +71,20 @@ static void to_unix(char *s) catia_string_replace(s, '\xb1', ' '); } -static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle, connection_struct - *conn, const char *fname, const char *mask, uint32 attr) +static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle, + const char *fname, const char *mask, uint32 attr) { pstring name; pstrcpy(name, fname); to_unix(name); - return SMB_VFS_NEXT_OPENDIR(handle, conn, name, mask, attr); + return SMB_VFS_NEXT_OPENDIR(handle, name, mask, attr); } static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle, - connection_struct *conn, SMB_STRUCT_DIR *dirp) + SMB_STRUCT_DIR *dirp) { - SMB_STRUCT_DIRENT *result = SMB_VFS_NEXT_READDIR(handle, conn, dirp); + SMB_STRUCT_DIRENT *result = SMB_VFS_NEXT_READDIR(handle, dirp); if (result == NULL) return result; @@ -93,18 +93,18 @@ static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle, return result; } -static int catia_open(vfs_handle_struct *handle, connection_struct *conn, - const char *fname, int flags, mode_t mode) +static int catia_open(vfs_handle_struct *handle, + const char *fname, files_struct *fsp, int flags, mode_t mode) { pstring name; pstrcpy(name, fname); to_unix(name); - return SMB_VFS_NEXT_OPEN(handle, conn, name, flags, mode); + return SMB_VFS_NEXT_OPEN(handle, name, fsp, flags, mode); } -static int catia_rename(vfs_handle_struct *handle, connection_struct *conn, +static int catia_rename(vfs_handle_struct *handle, const char *oldname, const char *newname) { pstring oname, nname; @@ -117,114 +117,112 @@ static int catia_rename(vfs_handle_struct *handle, connection_struct *conn, DEBUG(10, ("converted old name: %s\n", oname)); DEBUG(10, ("converted new name: %s\n", nname)); - return SMB_VFS_NEXT_RENAME(handle, conn, oname, nname); + return SMB_VFS_NEXT_RENAME(handle, oname, nname); } -static int catia_stat(vfs_handle_struct *handle, connection_struct *conn, +static int catia_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf) { pstring name; pstrcpy(name, fname); to_unix(name); - return SMB_VFS_NEXT_STAT(handle, conn, name, sbuf); + return SMB_VFS_NEXT_STAT(handle, name, sbuf); } -static int catia_lstat(vfs_handle_struct *handle, connection_struct *conn, +static int catia_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf) { pstring name; pstrcpy(name, path); to_unix(name); - return SMB_VFS_NEXT_LSTAT(handle, conn, name, sbuf); + return SMB_VFS_NEXT_LSTAT(handle, name, sbuf); } -static int catia_unlink(vfs_handle_struct *handle, connection_struct *conn, - const char *path) +static int catia_unlink(vfs_handle_struct *handle, const char *path) { pstring name; pstrcpy(name, path); to_unix(name); - return SMB_VFS_NEXT_UNLINK(handle, conn, name); + return SMB_VFS_NEXT_UNLINK(handle, name); } -static int catia_chmod(vfs_handle_struct *handle, connection_struct *conn, +static int catia_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) { pstring name; pstrcpy(name, path); to_unix(name); - return SMB_VFS_NEXT_CHMOD(handle, conn, name, mode); + return SMB_VFS_NEXT_CHMOD(handle, name, mode); } -static int catia_chown(vfs_handle_struct *handle, connection_struct *conn, +static int catia_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) { pstring name; pstrcpy(name, path); to_unix(name); - return SMB_VFS_NEXT_CHOWN(handle, conn, name, uid, gid); + return SMB_VFS_NEXT_CHOWN(handle, name, uid, gid); } -static int catia_chdir(vfs_handle_struct *handle, connection_struct *conn, +static int catia_chdir(vfs_handle_struct *handle, const char *path) { pstring name; pstrcpy(name, path); to_unix(name); - return SMB_VFS_NEXT_CHDIR(handle, conn, name); + return SMB_VFS_NEXT_CHDIR(handle, name); } -static char *catia_getwd(vfs_handle_struct *handle, connection_struct *conn, - char *buf) +static char *catia_getwd(vfs_handle_struct *handle, char *buf) { - return SMB_VFS_NEXT_GETWD(handle, conn, buf); + return SMB_VFS_NEXT_GETWD(handle, buf); } -static int catia_utime(vfs_handle_struct *handle, connection_struct *conn, +static int catia_utime(vfs_handle_struct *handle, const char *path, struct utimbuf *times) { - return SMB_VFS_NEXT_UTIME(handle, conn, path, times); + return SMB_VFS_NEXT_UTIME(handle, path, times); } -static BOOL catia_symlink(vfs_handle_struct *handle, connection_struct *conn, +static BOOL catia_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath) { - return SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath); + return SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath); } -static BOOL catia_readlink(vfs_handle_struct *handle, connection_struct *conn, +static BOOL catia_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz) { - return SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz); + return SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz); } -static int catia_link(vfs_handle_struct *handle, connection_struct *conn, +static int catia_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath) { - return SMB_VFS_NEXT_LINK(handle, conn, oldpath, newpath); + return SMB_VFS_NEXT_LINK(handle, oldpath, newpath); } -static int catia_mknod(vfs_handle_struct *handle, connection_struct *conn, +static int catia_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev) { - return SMB_VFS_NEXT_MKNOD(handle, conn, path, mode, dev); + return SMB_VFS_NEXT_MKNOD(handle, path, mode, dev); } -static char *catia_realpath(vfs_handle_struct *handle, connection_struct *conn, +static char *catia_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path) { - return SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path); + return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path); } static size_t catia_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, - struct security_descriptor_info **ppdesc) + struct security_descriptor **ppdesc) { return SMB_VFS_NEXT_GET_NT_ACL(handle, fsp, name, security_info, ppdesc); @@ -232,13 +230,13 @@ static size_t catia_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, static BOOL catia_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, - struct security_descriptor_info *psd) + struct security_descriptor *psd) { return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent, psd); } -static int catia_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, +static int catia_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode) { /* If the underlying VFS doesn't have ACL support... */ @@ -246,7 +244,7 @@ static int catia_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, errno = ENOSYS; return -1; } - return SMB_VFS_NEXT_CHMOD_ACL(handle, conn, name, mode); + return SMB_VFS_NEXT_CHMOD_ACL(handle, name, mode); } /* VFS operations structure */ @@ -310,7 +308,7 @@ SMB_VFS_LAYER_TRANSPARENT}, SMB_VFS_LAYER_NOOP} }; -NTSTATUS init_module(void) +NTSTATUS vfs_catia_init(void) { return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "catia", catia_op_tuples); diff --git a/source/modules/vfs_commit.c b/source/modules/vfs_commit.c new file mode 100644 index 00000000000..9d817c017d2 --- /dev/null +++ b/source/modules/vfs_commit.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) James Peach 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +/* Commit data module. + * + * The purpose of this module is to flush data to disk at regular intervals, + * just like the NFS commit operation. There's two rationales for this. First, + * it minimises the data loss in case of a power outage without incurring + * the poor performance of synchronous I/O. Second, a steady flush rate + * can produce better throughput than suddenly dumping massive amounts of + * writes onto a disk. + * + * Tunables: + * + * commit: dthresh Amount of dirty data that can accumulate + * before we commit (sync) it. + * + * commit: debug Debug level at which to emit messages. + * + */ + +#define MODULE "commit" + +static int module_debug; + +struct commit_info +{ + SMB_OFF_T dbytes; /* Dirty (uncommitted) bytes */ + SMB_OFF_T dthresh; /* Dirty data threshold */ +}; + +static void commit_all( + struct vfs_handle_struct * handle, + files_struct * fsp) +{ + struct commit_info *c; + + if ((c = VFS_FETCH_FSP_EXTENSION(handle, fsp))) { + if (c->dbytes) { + DEBUG(module_debug, + ("%s: flushing %lu dirty bytes\n", + MODULE, (unsigned long)c->dbytes)); + + fdatasync(fsp->fh->fd); + c->dbytes = 0; + } + } +} + +static void commit( + struct vfs_handle_struct * handle, + files_struct * fsp, + ssize_t last_write) +{ + struct commit_info *c; + + if ((c = VFS_FETCH_FSP_EXTENSION(handle, fsp))) { + + if (last_write > 0) { + c->dbytes += last_write; + } + + if (c->dbytes > c->dthresh) { + DEBUG(module_debug, + ("%s: flushing %lu dirty bytes\n", + MODULE, (unsigned long)c->dbytes)); + + fdatasync(fsp->fh->fd); + c->dbytes = 0; + } + } +} + +static int commit_connect( + struct vfs_handle_struct * handle, + const char * service, + const char * user) +{ + module_debug = lp_parm_int(SNUM(handle->conn), MODULE, "debug", 100); + return SMB_VFS_NEXT_CONNECT(handle, service, user); +} + +static int commit_open( + vfs_handle_struct * handle, + const char * fname, + files_struct * fsp, + int flags, + mode_t mode) +{ + SMB_OFF_T dthresh; + + /* Don't bother with read-only files. */ + if ((flags & O_ACCMODE) == O_RDONLY) { + return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); + } + + dthresh = conv_str_size(lp_parm_const_string(SNUM(handle->conn), + MODULE, "dthresh", NULL)); + + if (dthresh > 0) { + struct commit_info * c; + c = VFS_ADD_FSP_EXTENSION(handle, fsp, struct commit_info); + if (c) { + c->dthresh = dthresh; + c->dbytes = 0; + } + } + + return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); +} + +static ssize_t commit_write( + vfs_handle_struct * handle, + files_struct * fsp, + int fd, + void * data, + size_t count) +{ + ssize_t ret; + + ret = SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, count); + commit(handle, fsp, ret); + + return ret; +} + +static ssize_t commit_pwrite( + vfs_handle_struct * handle, + files_struct * fsp, + int fd, + void * data, + size_t count, + SMB_OFF_T offset) +{ + ssize_t ret; + + ret = SMB_VFS_NEXT_PWRITE(handle, fsp, fd, data, count, offset); + commit(handle, fsp, ret); + + return ret; +} + +static ssize_t commit_close( + vfs_handle_struct * handle, + files_struct * fsp, + int fd) +{ + commit_all(handle, fsp); + return SMB_VFS_NEXT_CLOSE(handle, fsp, fd); +} + +static vfs_op_tuple commit_ops [] = +{ + {SMB_VFS_OP(commit_open), + SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(commit_close), + SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(commit_write), + SMB_VFS_OP_WRITE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(commit_pwrite), + SMB_VFS_OP_PWRITE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(commit_connect), + SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_commit_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE, commit_ops); +} + diff --git a/source/modules/vfs_default.c b/source/modules/vfs_default.c new file mode 100644 index 00000000000..486a76ac88a --- /dev/null +++ b/source/modules/vfs_default.c @@ -0,0 +1,1338 @@ +/* + Unix SMB/CIFS implementation. + Wrap disk only vfs functions to sidestep dodgy compilers. + Copyright (C) Tim Potter 1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS + +/* Check for NULL pointer parameters in vfswrap_* functions */ + +/* We don't want to have NULL function pointers lying around. Someone + is sure to try and execute them. These stubs are used to prevent + this possibility. */ + +static int vfswrap_connect(vfs_handle_struct *handle, const char *service, const char *user) +{ + return 0; /* Return >= 0 for success */ +} + +static void vfswrap_disconnect(vfs_handle_struct *handle) +{ +} + +/* Disk operations */ + +static SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, + SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +{ + SMB_BIG_UINT result; + + result = sys_disk_free(handle->conn, path, small_query, bsize, dfree, dsize); + return result; +} + +static int vfswrap_get_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) +{ +#ifdef HAVE_SYS_QUOTAS + int result; + + START_PROFILE(syscall_get_quota); + result = sys_get_quota(handle->conn->connectpath, qtype, id, qt); + END_PROFILE(syscall_get_quota); + return result; +#else + errno = ENOSYS; + return -1; +#endif +} + +static int vfswrap_set_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) +{ +#ifdef HAVE_SYS_QUOTAS + int result; + + START_PROFILE(syscall_set_quota); + result = sys_set_quota(handle->conn->connectpath, qtype, id, qt); + END_PROFILE(syscall_set_quota); + return result; +#else + errno = ENOSYS; + return -1; +#endif +} + +static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels) +{ + errno = ENOSYS; + return -1; /* Not implemented. */ +} + +static int vfswrap_statvfs(struct vfs_handle_struct *handle, const char *path, vfs_statvfs_struct *statbuf) +{ + return sys_statvfs(path, statbuf); +} + +/* Directory operations */ + +static SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) +{ + SMB_STRUCT_DIR *result; + + START_PROFILE(syscall_opendir); + result = sys_opendir(fname); + END_PROFILE(syscall_opendir); + return result; +} + +static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + SMB_STRUCT_DIRENT *result; + + START_PROFILE(syscall_readdir); + result = sys_readdir(dirp); + END_PROFILE(syscall_readdir); + return result; +} + +static void vfswrap_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset) +{ + START_PROFILE(syscall_seekdir); + sys_seekdir(dirp, offset); + END_PROFILE(syscall_seekdir); +} + +static long vfswrap_telldir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + long result; + START_PROFILE(syscall_telldir); + result = sys_telldir(dirp); + END_PROFILE(syscall_telldir); + return result; +} + +static void vfswrap_rewinddir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + START_PROFILE(syscall_rewinddir); + sys_rewinddir(dirp); + END_PROFILE(syscall_rewinddir); +} + +static int vfswrap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) +{ + int result; + BOOL has_dacl = False; + + START_PROFILE(syscall_mkdir); + + if (lp_inherit_acls(SNUM(handle->conn)) && (has_dacl = directory_has_default_acl(handle->conn, parent_dirname(path)))) + mode = 0777; + + result = mkdir(path, mode); + + if (result == 0 && !has_dacl) { + /* + * We need to do this as the default behavior of POSIX ACLs + * is to set the mask to be the requested group permission + * bits, not the group permission bits to be the requested + * group permission bits. This is not what we want, as it will + * mess up any inherited ACL bits that were set. JRA. + */ + int saved_errno = errno; /* We may get ENOSYS */ + if ((SMB_VFS_CHMOD_ACL(handle->conn, path, mode) == -1) && (errno == ENOSYS)) + errno = saved_errno; + } + + END_PROFILE(syscall_mkdir); + return result; +} + +static int vfswrap_rmdir(vfs_handle_struct *handle, const char *path) +{ + int result; + + START_PROFILE(syscall_rmdir); + result = rmdir(path); + END_PROFILE(syscall_rmdir); + return result; +} + +static int vfswrap_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + int result; + + START_PROFILE(syscall_closedir); + result = sys_closedir(dirp); + END_PROFILE(syscall_closedir); + return result; +} + +/* File operations */ + +static int vfswrap_open(vfs_handle_struct *handle, const char *fname, + files_struct *fsp, int flags, mode_t mode) +{ + int result; + + START_PROFILE(syscall_open); + result = sys_open(fname, flags, mode); + END_PROFILE(syscall_open); + return result; +} + +static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd) +{ + int result; + + START_PROFILE(syscall_close); + + result = close(fd); + END_PROFILE(syscall_close); + return result; +} + +static ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n) +{ + ssize_t result; + + START_PROFILE_BYTES(syscall_read, n); + result = sys_read(fd, data, n); + END_PROFILE(syscall_read); + return result; +} + +static ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, + size_t n, SMB_OFF_T offset) +{ + ssize_t result; + +#if defined(HAVE_PREAD) || defined(HAVE_PREAD64) + START_PROFILE_BYTES(syscall_pread, n); + result = sys_pread(fd, data, n, offset); + END_PROFILE(syscall_pread); + + if (result == -1 && errno == ESPIPE) { + /* Maintain the fiction that pipes can be seeked (sought?) on. */ + result = SMB_VFS_READ(fsp, fd, data, n); + fsp->fh->pos = 0; + } + +#else /* HAVE_PREAD */ + SMB_OFF_T curr; + int lerrno; + + curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); + if (curr == -1 && errno == ESPIPE) { + /* Maintain the fiction that pipes can be seeked (sought?) on. */ + result = SMB_VFS_READ(fsp, fd, data, n); + fsp->fh->pos = 0; + return result; + } + + if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) { + return -1; + } + + errno = 0; + result = SMB_VFS_READ(fsp, fd, data, n); + lerrno = errno; + + SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET); + errno = lerrno; + +#endif /* HAVE_PREAD */ + + return result; +} + +static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n) +{ + ssize_t result; + + START_PROFILE_BYTES(syscall_write, n); + result = sys_write(fd, data, n); + END_PROFILE(syscall_write); + return result; +} + +static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, + size_t n, SMB_OFF_T offset) +{ + ssize_t result; + +#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64) + START_PROFILE_BYTES(syscall_pwrite, n); + result = sys_pwrite(fd, data, n, offset); + END_PROFILE(syscall_pwrite); + + if (result == -1 && errno == ESPIPE) { + /* Maintain the fiction that pipes can be sought on. */ + result = SMB_VFS_WRITE(fsp, fd, data, n); + } + +#else /* HAVE_PWRITE */ + SMB_OFF_T curr; + int lerrno; + + curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); + if (curr == -1) { + return -1; + } + + if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) { + return -1; + } + + result = SMB_VFS_WRITE(fsp, fd, data, n); + lerrno = errno; + + SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET); + errno = lerrno; + +#endif /* HAVE_PWRITE */ + + return result; +} + +static SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence) +{ + SMB_OFF_T result = 0; + + START_PROFILE(syscall_lseek); + + /* Cope with 'stat' file opens. */ + if (filedes != -1) + result = sys_lseek(filedes, offset, whence); + + /* + * We want to maintain the fiction that we can seek + * on a fifo for file system purposes. This allows + * people to set up UNIX fifo's that feed data to Windows + * applications. JRA. + */ + + if((result == -1) && (errno == ESPIPE)) { + result = 0; + errno = 0; + } + + END_PROFILE(syscall_lseek); + return result; +} + +static ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr, + SMB_OFF_T offset, size_t n) +{ + ssize_t result; + + START_PROFILE_BYTES(syscall_sendfile, n); + result = sys_sendfile(tofd, fromfd, hdr, offset, n); + END_PROFILE(syscall_sendfile); + return result; +} + +/********************************************************* + For rename across filesystems Patch from Warren Birnbaum + <warrenb@hpcvscdp.cv.hp.com> +**********************************************************/ + +static int copy_reg(const char *source, const char *dest) +{ + SMB_STRUCT_STAT source_stats; + int saved_errno; + int ifd = -1; + int ofd = -1; + + if (sys_lstat (source, &source_stats) == -1) + return -1; + + if (!S_ISREG (source_stats.st_mode)) + return -1; + + if((ifd = sys_open (source, O_RDONLY, 0)) < 0) + return -1; + + if (unlink (dest) && errno != ENOENT) + return -1; + +#ifdef O_NOFOLLOW + if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 ) +#else + if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 ) +#endif + goto err; + + if (transfer_file(ifd, ofd, (size_t)-1) == -1) + goto err; + + /* + * Try to preserve ownership. For non-root it might fail, but that's ok. + * But root probably wants to know, e.g. if NFS disallows it. + */ + +#ifdef HAVE_FCHOWN + if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) +#else + if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) +#endif + goto err; + + /* + * fchown turns off set[ug]id bits for non-root, + * so do the chmod last. + */ + +#if defined(HAVE_FCHMOD) + if (fchmod (ofd, source_stats.st_mode & 07777)) +#else + if (chmod (dest, source_stats.st_mode & 07777)) +#endif + goto err; + + if (close (ifd) == -1) + goto err; + + if (close (ofd) == -1) + return -1; + + /* Try to copy the old file's modtime and access time. */ + { + struct utimbuf tv; + + tv.actime = source_stats.st_atime; + tv.modtime = source_stats.st_mtime; + utime(dest, &tv); + } + + if (unlink (source) == -1) + return -1; + + return 0; + + err: + + saved_errno = errno; + if (ifd != -1) + close(ifd); + if (ofd != -1) + close(ofd); + errno = saved_errno; + return -1; +} + +static int vfswrap_rename(vfs_handle_struct *handle, const char *oldname, const char *newname) +{ + int result; + + START_PROFILE(syscall_rename); + result = rename(oldname, newname); + if (errno == EXDEV) { + /* Rename across filesystems needed. */ + result = copy_reg(oldname, newname); + } + + END_PROFILE(syscall_rename); + return result; +} + +static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd) +{ +#ifdef HAVE_FSYNC + int result; + + START_PROFILE(syscall_fsync); + result = fsync(fd); + END_PROFILE(syscall_fsync); + return result; +#else + return 0; +#endif +} + +static int vfswrap_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf) +{ + int result; + + START_PROFILE(syscall_stat); + result = sys_stat(fname, sbuf); + END_PROFILE(syscall_stat); + return result; +} + +static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) +{ + int result; + + START_PROFILE(syscall_fstat); + result = sys_fstat(fd, sbuf); + END_PROFILE(syscall_fstat); + return result; +} + +int vfswrap_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf) +{ + int result; + + START_PROFILE(syscall_lstat); + result = sys_lstat(path, sbuf); + END_PROFILE(syscall_lstat); + return result; +} + +static int vfswrap_unlink(vfs_handle_struct *handle, const char *path) +{ + int result; + + START_PROFILE(syscall_unlink); + result = unlink(path); + END_PROFILE(syscall_unlink); + return result; +} + +static int vfswrap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) +{ + int result; + + START_PROFILE(syscall_chmod); + + /* + * We need to do this due to the fact that the default POSIX ACL + * chmod modifies the ACL *mask* for the group owner, not the + * group owner bits directly. JRA. + */ + + + { + int saved_errno = errno; /* We might get ENOSYS */ + if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) { + END_PROFILE(syscall_chmod); + return result; + } + /* Error - return the old errno. */ + errno = saved_errno; + } + + result = chmod(path, mode); + END_PROFILE(syscall_chmod); + return result; +} + +static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) +{ + int result; + + START_PROFILE(syscall_fchmod); + + /* + * We need to do this due to the fact that the default POSIX ACL + * chmod modifies the ACL *mask* for the group owner, not the + * group owner bits directly. JRA. + */ + + { + int saved_errno = errno; /* We might get ENOSYS */ + if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) { + END_PROFILE(syscall_fchmod); + return result; + } + /* Error - return the old errno. */ + errno = saved_errno; + } + +#if defined(HAVE_FCHMOD) + result = fchmod(fd, mode); +#else + result = -1; + errno = ENOSYS; +#endif + + END_PROFILE(syscall_fchmod); + return result; +} + +static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) +{ + int result; + + START_PROFILE(syscall_chown); + result = sys_chown(path, uid, gid); + END_PROFILE(syscall_chown); + return result; +} + +static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid) +{ +#ifdef HAVE_FCHOWN + int result; + + START_PROFILE(syscall_fchown); + result = fchown(fd, uid, gid); + END_PROFILE(syscall_fchown); + return result; +#else + errno = ENOSYS; + return -1; +#endif +} + +static int vfswrap_chdir(vfs_handle_struct *handle, const char *path) +{ + int result; + + START_PROFILE(syscall_chdir); + result = chdir(path); + END_PROFILE(syscall_chdir); + return result; +} + +static char *vfswrap_getwd(vfs_handle_struct *handle, char *path) +{ + char *result; + + START_PROFILE(syscall_getwd); + result = sys_getwd(path); + END_PROFILE(syscall_getwd); + return result; +} + +static int vfswrap_utime(vfs_handle_struct *handle, const char *path, struct utimbuf *times) +{ + int result; + + START_PROFILE(syscall_utime); + result = utime(path, times); + END_PROFILE(syscall_utime); + return result; +} + +/********************************************************************* + A version of ftruncate that will write the space on disk if strict + allocate is set. +**********************************************************************/ + +static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len) +{ + SMB_STRUCT_STAT st; + SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); + unsigned char zero_space[4096]; + SMB_OFF_T space_to_write; + + if (currpos == -1) + return -1; + + if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) + return -1; + + space_to_write = len - st.st_size; + +#ifdef S_ISFIFO + if (S_ISFIFO(st.st_mode)) + return 0; +#endif + + if (st.st_size == len) + return 0; + + /* Shrink - just ftruncate. */ + if (st.st_size > len) + return sys_ftruncate(fd, len); + + /* Write out the real space on disk. */ + if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size) + return -1; + + space_to_write = len - st.st_size; + + memset(zero_space, '\0', sizeof(zero_space)); + while ( space_to_write > 0) { + SMB_OFF_T retlen; + SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write); + + retlen = SMB_VFS_WRITE(fsp,fsp->fh->fd,(char *)zero_space,current_len_to_write); + if (retlen <= 0) + return -1; + + space_to_write -= retlen; + } + + /* Seek to where we were */ + if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos) + return -1; + + return 0; +} + +static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len) +{ + int result = -1; + SMB_STRUCT_STAT st; + char c = 0; + SMB_OFF_T currpos; + + START_PROFILE(syscall_ftruncate); + + if (lp_strict_allocate(SNUM(fsp->conn))) { + result = strict_allocate_ftruncate(handle, fsp, fd, len); + END_PROFILE(syscall_ftruncate); + return result; + } + + /* we used to just check HAVE_FTRUNCATE_EXTEND and only use + sys_ftruncate if the system supports it. Then I discovered that + you can have some filesystems that support ftruncate + expansion and some that don't! On Linux fat can't do + ftruncate extend but ext2 can. */ + + result = sys_ftruncate(fd, len); + if (result == 0) + goto done; + + /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot + extend a file with ftruncate. Provide alternate implementation + for this */ + currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); + if (currpos == -1) { + goto done; + } + + /* Do an fstat to see if the file is longer than the requested + size in which case the ftruncate above should have + succeeded or shorter, in which case seek to len - 1 and + write 1 byte of zero */ + if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) { + goto done; + } + +#ifdef S_ISFIFO + if (S_ISFIFO(st.st_mode)) { + result = 0; + goto done; + } +#endif + + if (st.st_size == len) { + result = 0; + goto done; + } + + if (st.st_size > len) { + /* the sys_ftruncate should have worked */ + goto done; + } + + if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1) + goto done; + + if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1) + goto done; + + /* Seek to where we were */ + if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos) + goto done; + result = 0; + + done: + + END_PROFILE(syscall_ftruncate); + return result; +} + +static BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) +{ + BOOL result; + + START_PROFILE(syscall_fcntl_lock); + result = fcntl_lock(fd, op, offset, count, type); + END_PROFILE(syscall_fcntl_lock); + return result; +} + +static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, int fd, + uint32 share_mode) +{ + START_PROFILE(syscall_kernel_flock); + kernel_flock(fd, share_mode); + END_PROFILE(syscall_kernel_flock); + return 0; +} + +static BOOL vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid) +{ + BOOL result; + + START_PROFILE(syscall_fcntl_getlock); + result = fcntl_getlock(fd, poffset, pcount, ptype, ppid); + END_PROFILE(syscall_fcntl_getlock); + return result; +} + +static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath) +{ + int result; + + START_PROFILE(syscall_symlink); + result = sys_symlink(oldpath, newpath); + END_PROFILE(syscall_symlink); + return result; +} + +static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz) +{ + int result; + + START_PROFILE(syscall_readlink); + result = sys_readlink(path, buf, bufsiz); + END_PROFILE(syscall_readlink); + return result; +} + +static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath) +{ + int result; + + START_PROFILE(syscall_link); + result = sys_link(oldpath, newpath); + END_PROFILE(syscall_link); + return result; +} + +static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev) +{ + int result; + + START_PROFILE(syscall_mknod); + result = sys_mknod(pathname, mode, dev); + END_PROFILE(syscall_mknod); + return result; +} + +static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path) +{ + char *result; + + START_PROFILE(syscall_realpath); + result = sys_realpath(path, resolved_path); + END_PROFILE(syscall_realpath); + return result; +} + +static size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc) +{ + size_t result; + + START_PROFILE(fget_nt_acl); + result = get_nt_acl(fsp, security_info, ppdesc); + END_PROFILE(fget_nt_acl); + return result; +} + +static size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc) +{ + size_t result; + + START_PROFILE(get_nt_acl); + result = get_nt_acl(fsp, security_info, ppdesc); + END_PROFILE(get_nt_acl); + return result; +} + +static BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) +{ + BOOL result; + + START_PROFILE(fset_nt_acl); + result = set_nt_acl(fsp, security_info_sent, psd); + END_PROFILE(fset_nt_acl); + return result; +} + +static BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) +{ + BOOL result; + + START_PROFILE(set_nt_acl); + result = set_nt_acl(fsp, security_info_sent, psd); + END_PROFILE(set_nt_acl); + return result; +} + +static int vfswrap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode) +{ +#ifdef HAVE_NO_ACL + errno = ENOSYS; + return -1; +#else + int result; + + START_PROFILE(chmod_acl); + result = chmod_acl(handle->conn, name, mode); + END_PROFILE(chmod_acl); + return result; +#endif +} + +static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) +{ +#ifdef HAVE_NO_ACL + errno = ENOSYS; + return -1; +#else + int result; + + START_PROFILE(fchmod_acl); + result = fchmod_acl(fsp, fd, mode); + END_PROFILE(fchmod_acl); + return result; +#endif +} + +static int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) +{ + return sys_acl_get_entry(theacl, entry_id, entry_p); +} + +static int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) +{ + return sys_acl_get_tag_type(entry_d, tag_type_p); +} + +static int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) +{ + return sys_acl_get_permset(entry_d, permset_p); +} + +static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d) +{ + return sys_acl_get_qualifier(entry_d); +} + +static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type) +{ + return sys_acl_get_file(handle, path_p, type); +} + +static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) +{ + return sys_acl_get_fd(handle, fsp, fd); +} + +static int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset) +{ + return sys_acl_clear_perms(permset); +} + +static int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) +{ + return sys_acl_add_perm(permset, perm); +} + +static char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, SMB_ACL_T theacl, ssize_t *plen) +{ + return sys_acl_to_text(theacl, plen); +} + +static SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, int count) +{ + return sys_acl_init(count); +} + +static int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) +{ + return sys_acl_create_entry(pacl, pentry); +} + +static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) +{ + return sys_acl_set_tag_type(entry, tagtype); +} + +static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, void *qual) +{ + return sys_acl_set_qualifier(entry, qual); +} + +static int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) +{ + return sys_acl_set_permset(entry, permset); +} + +static int vfswrap_sys_acl_valid(vfs_handle_struct *handle, SMB_ACL_T theacl ) +{ + return sys_acl_valid(theacl ); +} + +static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) +{ + return sys_acl_set_file(handle, name, acltype, theacl); +} + +static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl) +{ + return sys_acl_set_fd(handle, fsp, fd, theacl); +} + +static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path) +{ + return sys_acl_delete_def_file(handle, path); +} + +static int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) +{ + return sys_acl_get_perm(permset, perm); +} + +static int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, char *text) +{ + return sys_acl_free_text(text); +} + +static int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, SMB_ACL_T posix_acl) +{ + return sys_acl_free_acl(posix_acl); +} + +static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, void *qualifier, SMB_ACL_TAG_T tagtype) +{ + return sys_acl_free_qualifier(qualifier, tagtype); +} + +/**************************************************************** + Extended attribute operations. +*****************************************************************/ + +static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size) +{ + return sys_getxattr(path, name, value, size); +} + +static ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size) +{ + return sys_lgetxattr(path, name, value, size); +} + +static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size) +{ + return sys_fgetxattr(fd, name, value, size); +} + +static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size) +{ + return sys_listxattr(path, list, size); +} + +ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size) +{ + return sys_llistxattr(path, list, size); +} + +ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size) +{ + return sys_flistxattr(fd, list, size); +} + +static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name) +{ + return sys_removexattr(path, name); +} + +static int vfswrap_lremovexattr(struct vfs_handle_struct *handle, const char *path, const char *name) +{ + return sys_lremovexattr(path, name); +} + +static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name) +{ + return sys_fremovexattr(fd, name); +} + +static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags) +{ + return sys_setxattr(path, name, value, size, flags); +} + +static int vfswrap_lsetxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags) +{ + return sys_lsetxattr(path, name, value, size, flags); +} + +static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags) +{ + return sys_fsetxattr(fd, name, value, size, flags); +} + +static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_read(aiocb); +} + +static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_write(aiocb); +} + +static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_return(aiocb); +} + +static int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_cancel(fd, aiocb); +} + +static int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_error(aiocb); +} + +static int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb) +{ + return sys_aio_fsync(op, aiocb); +} + +static int vfswrap_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *timeout) +{ + return sys_aio_suspend(aiocb, n, timeout); +} + +static vfs_op_tuple vfs_default_ops[] = { + + /* Disk operations */ + + {SMB_VFS_OP(vfswrap_connect), SMB_VFS_OP_CONNECT, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_disconnect), SMB_VFS_OP_DISCONNECT, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_disk_free), SMB_VFS_OP_DISK_FREE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_get_quota), SMB_VFS_OP_GET_QUOTA, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_set_quota), SMB_VFS_OP_SET_QUOTA, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_statvfs), SMB_VFS_OP_STATVFS, + SMB_VFS_LAYER_OPAQUE}, + + /* Directory operations */ + + {SMB_VFS_OP(vfswrap_opendir), SMB_VFS_OP_OPENDIR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_readdir), SMB_VFS_OP_READDIR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_seekdir), SMB_VFS_OP_SEEKDIR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_telldir), SMB_VFS_OP_TELLDIR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_rewinddir), SMB_VFS_OP_REWINDDIR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_mkdir), SMB_VFS_OP_MKDIR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_rmdir), SMB_VFS_OP_RMDIR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_closedir), SMB_VFS_OP_CLOSEDIR, + SMB_VFS_LAYER_OPAQUE}, + + /* File operations */ + + {SMB_VFS_OP(vfswrap_open), SMB_VFS_OP_OPEN, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_close), SMB_VFS_OP_CLOSE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_read), SMB_VFS_OP_READ, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_pread), SMB_VFS_OP_PREAD, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_write), SMB_VFS_OP_WRITE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_pwrite), SMB_VFS_OP_PWRITE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_lseek), SMB_VFS_OP_LSEEK, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sendfile), SMB_VFS_OP_SENDFILE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_rename), SMB_VFS_OP_RENAME, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_fsync), SMB_VFS_OP_FSYNC, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_stat), SMB_VFS_OP_STAT, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_fstat), SMB_VFS_OP_FSTAT, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_lstat), SMB_VFS_OP_LSTAT, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_unlink), SMB_VFS_OP_UNLINK, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_chmod), SMB_VFS_OP_CHMOD, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_fchmod), SMB_VFS_OP_FCHMOD, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_chown), SMB_VFS_OP_CHOWN, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_fchown), SMB_VFS_OP_FCHOWN, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_chdir), SMB_VFS_OP_CHDIR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_getwd), SMB_VFS_OP_GETWD, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_utime), SMB_VFS_OP_UTIME, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_ftruncate), SMB_VFS_OP_FTRUNCATE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_lock), SMB_VFS_OP_LOCK, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_kernel_flock), SMB_VFS_OP_KERNEL_FLOCK, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_getlock), SMB_VFS_OP_GETLOCK, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_symlink), SMB_VFS_OP_SYMLINK, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_readlink), SMB_VFS_OP_READLINK, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_link), SMB_VFS_OP_LINK, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_mknod), SMB_VFS_OP_MKNOD, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_realpath), SMB_VFS_OP_REALPATH, + SMB_VFS_LAYER_OPAQUE}, + + /* NT ACL operations. */ + + {SMB_VFS_OP(vfswrap_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_set_nt_acl), SMB_VFS_OP_SET_NT_ACL, + SMB_VFS_LAYER_OPAQUE}, + + /* POSIX ACL operations. */ + + {SMB_VFS_OP(vfswrap_chmod_acl), SMB_VFS_OP_CHMOD_ACL, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_get_entry), SMB_VFS_OP_SYS_ACL_GET_ENTRY, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_get_tag_type), SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_get_permset), SMB_VFS_OP_SYS_ACL_GET_PERMSET, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_get_qualifier), SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_get_fd), SMB_VFS_OP_SYS_ACL_GET_FD, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_clear_perms), SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_add_perm), SMB_VFS_OP_SYS_ACL_ADD_PERM, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_to_text), SMB_VFS_OP_SYS_ACL_TO_TEXT, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_init), SMB_VFS_OP_SYS_ACL_INIT, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_create_entry), SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_set_tag_type), SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_set_qualifier), SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_set_permset), SMB_VFS_OP_SYS_ACL_SET_PERMSET, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_valid), SMB_VFS_OP_SYS_ACL_VALID, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_set_fd), SMB_VFS_OP_SYS_ACL_SET_FD, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_delete_def_file), SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_get_perm), SMB_VFS_OP_SYS_ACL_GET_PERM, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_free_text), SMB_VFS_OP_SYS_ACL_FREE_TEXT, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_free_acl), SMB_VFS_OP_SYS_ACL_FREE_ACL, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_sys_acl_free_qualifier), SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, + SMB_VFS_LAYER_OPAQUE}, + + /* EA operations. */ + + {SMB_VFS_OP(vfswrap_getxattr), SMB_VFS_OP_GETXATTR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_lgetxattr), SMB_VFS_OP_LGETXATTR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_fgetxattr), SMB_VFS_OP_FGETXATTR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_listxattr), SMB_VFS_OP_LISTXATTR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_llistxattr), SMB_VFS_OP_LLISTXATTR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_flistxattr), SMB_VFS_OP_FLISTXATTR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_removexattr), SMB_VFS_OP_REMOVEXATTR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_lremovexattr), SMB_VFS_OP_LREMOVEXATTR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_fremovexattr), SMB_VFS_OP_FREMOVEXATTR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_setxattr), SMB_VFS_OP_SETXATTR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_lsetxattr), SMB_VFS_OP_LSETXATTR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_fsetxattr), SMB_VFS_OP_FSETXATTR, + SMB_VFS_LAYER_OPAQUE}, + + {SMB_VFS_OP(vfswrap_aio_read), SMB_VFS_OP_AIO_READ, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_aio_write), SMB_VFS_OP_AIO_WRITE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_aio_return), SMB_VFS_OP_AIO_RETURN, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_aio_cancel), SMB_VFS_OP_AIO_CANCEL, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_aio_error), SMB_VFS_OP_AIO_ERROR, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_aio_fsync), SMB_VFS_OP_AIO_FSYNC, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_aio_suspend),SMB_VFS_OP_AIO_SUSPEND, + SMB_VFS_LAYER_OPAQUE}, + + /* Finish VFS operations definition */ + + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, + SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_default_init(void) +{ + unsigned int needed = SMB_VFS_OP_LAST + 1; /* convert from index to count */ + + if (ARRAY_SIZE(vfs_default_ops) != needed) { + DEBUG(0, ("%s: %u ops registered, but %u ops are required\n", + DEFAULT_VFS_MODULE_NAME, (unsigned int)ARRAY_SIZE(vfs_default_ops), needed)); + smb_panic("operation(s) missing from default VFS module"); + } + + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, + DEFAULT_VFS_MODULE_NAME, vfs_default_ops); +} diff --git a/source/modules/vfs_default_quota.c b/source/modules/vfs_default_quota.c index 9922a30315d..55dc287b88a 100644 --- a/source/modules/vfs_default_quota.c +++ b/source/modules/vfs_default_quota.c @@ -92,11 +92,11 @@ #define DEFAULT_QUOTA_GID_NOLIMIT(handle) \ lp_parm_bool(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"gid nolimit",DEFAULT_QUOTA_GID_NOLIMIT_DEFAULT) -static int default_quota_get_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq) +static int default_quota_get_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq) { int ret = -1; - if ((ret=SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, dq))!=0) { + if ((ret=SMB_VFS_NEXT_GET_QUOTA(handle, qtype, id, dq))!=0) { return ret; } @@ -122,7 +122,7 @@ static int default_quota_get_quota(vfs_handle_struct *handle, connection_struct unid_t qid; uint32 qflags = dq->qflags; qid.uid = DEFAULT_QUOTA_UID(handle); - SMB_VFS_NEXT_GET_QUOTA(handle, conn, SMB_USER_QUOTA_TYPE, qid, dq); + SMB_VFS_NEXT_GET_QUOTA(handle, SMB_USER_QUOTA_TYPE, qid, dq); dq->qflags = qflags; } break; @@ -132,7 +132,7 @@ static int default_quota_get_quota(vfs_handle_struct *handle, connection_struct unid_t qid; uint32 qflags = dq->qflags; qid.gid = DEFAULT_QUOTA_GID(handle); - SMB_VFS_NEXT_GET_QUOTA(handle, conn, SMB_GROUP_QUOTA_TYPE, qid, dq); + SMB_VFS_NEXT_GET_QUOTA(handle, SMB_GROUP_QUOTA_TYPE, qid, dq); dq->qflags = qflags; } break; @@ -146,7 +146,7 @@ static int default_quota_get_quota(vfs_handle_struct *handle, connection_struct return ret; } -static int default_quota_set_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq) +static int default_quota_set_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq) { int ret = -1; @@ -179,7 +179,7 @@ static int default_quota_set_quota(vfs_handle_struct *handle, connection_struct break; } - if ((ret=SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, dq))!=0) { + if ((ret=SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, dq))!=0) { return ret; } @@ -194,7 +194,7 @@ static int default_quota_set_quota(vfs_handle_struct *handle, connection_struct { unid_t qid; qid.uid = DEFAULT_QUOTA_UID(handle); - ret = SMB_VFS_NEXT_SET_QUOTA(handle, conn, SMB_USER_QUOTA_TYPE, qid, dq); + ret = SMB_VFS_NEXT_SET_QUOTA(handle, SMB_USER_QUOTA_TYPE, qid, dq); } break; #ifdef HAVE_GROUP_QUOTA @@ -202,7 +202,7 @@ static int default_quota_set_quota(vfs_handle_struct *handle, connection_struct { unid_t qid; qid.gid = DEFAULT_QUOTA_GID(handle); - ret = SMB_VFS_NEXT_SET_QUOTA(handle, conn, SMB_GROUP_QUOTA_TYPE, qid, dq); + ret = SMB_VFS_NEXT_SET_QUOTA(handle, SMB_GROUP_QUOTA_TYPE, qid, dq); } break; #endif /* HAVE_GROUP_QUOTA */ diff --git a/source/modules/vfs_expand_msdfs.c b/source/modules/vfs_expand_msdfs.c index d22f6a7f98e..fdd9ac6fbd8 100644 --- a/source/modules/vfs_expand_msdfs.c +++ b/source/modules/vfs_expand_msdfs.c @@ -110,6 +110,7 @@ static BOOL expand_msdfs_target(connection_struct* conn, pstring target) int filename_len; pstring targethost; pstring new_target; + extern userdom_struct current_user_info; if (filename_start == NULL) { DEBUG(10, ("No filename start in %s\n", target)); @@ -135,7 +136,11 @@ static BOOL expand_msdfs_target(connection_struct* conn, pstring target) return False; } - standard_sub_conn(conn, mapfilename, sizeof(mapfilename)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + mapfilename, sizeof(mapfilename)); DEBUG(10, ("Expanded targethost to %s\n", targethost)); @@ -150,13 +155,12 @@ static BOOL expand_msdfs_target(connection_struct* conn, pstring target) } static int expand_msdfs_readlink(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, char *buf, size_t bufsiz) { pstring target; int result; - result = SMB_VFS_NEXT_READLINK(handle, conn, path, target, + result = SMB_VFS_NEXT_READLINK(handle, path, target, sizeof(target)); if (result < 0) @@ -166,7 +170,7 @@ static int expand_msdfs_readlink(struct vfs_handle_struct *handle, if ((strncmp(target, "msdfs:", strlen("msdfs:")) == 0) && (strchr_m(target, '@') != NULL)) { - if (!expand_msdfs_target(conn, target)) { + if (!expand_msdfs_target(handle->conn, target)) { errno = ENOENT; return -1; } diff --git a/source/modules/vfs_extd_audit.c b/source/modules/vfs_extd_audit.c index cb8c3ffd6ab..1c3b25103c8 100644 --- a/source/modules/vfs_extd_audit.c +++ b/source/modules/vfs_extd_audit.c @@ -32,17 +32,17 @@ static int vfs_extd_audit_debug_level = DBGC_VFS; /* Function prototypes */ -static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user); -static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn); -static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr); -static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); -static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path); -static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode); +static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user); +static void audit_disconnect(vfs_handle_struct *handle); +static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr); +static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode); +static int audit_rmdir(vfs_handle_struct *handle, const char *path); +static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode); static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd); -static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname); -static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path); -static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); -static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode); +static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname); +static int audit_unlink(vfs_handle_struct *handle, const char *path); +static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode); +static int audit_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode); static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); @@ -123,7 +123,7 @@ static int audit_syslog_priority(vfs_handle_struct *handle) /* Implementation of vfs_ops. Pass everything on to the default operation but log event first. */ -static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user) +static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user) { int result; @@ -134,25 +134,25 @@ static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, con DEBUG(10, ("Connected to service %s as user %s\n", svc, user)); - result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user); + result = SMB_VFS_NEXT_CONNECT(handle, svc, user); return result; } -static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn) +static void audit_disconnect(vfs_handle_struct *handle) { syslog(audit_syslog_priority(handle), "disconnected\n"); DEBUG(10, ("Disconnected from VFS module extd_audit\n")); - SMB_VFS_NEXT_DISCONNECT(handle, conn); + SMB_VFS_NEXT_DISCONNECT(handle); return; } -static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) +static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) { SMB_STRUCT_DIR *result; - result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr); + result = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); syslog(audit_syslog_priority(handle), "opendir %s %s%s\n", fname, @@ -166,11 +166,11 @@ static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struc return result; } -static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) +static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) { int result; - result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode); + result = SMB_VFS_NEXT_MKDIR(handle, path, mode); syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n", path, @@ -184,11 +184,11 @@ static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const return result; } -static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) +static int audit_rmdir(vfs_handle_struct *handle, const char *path) { int result; - result = SMB_VFS_NEXT_RMDIR(handle, conn, path); + result = SMB_VFS_NEXT_RMDIR(handle, path); syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n", path, @@ -202,11 +202,11 @@ static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const return result; } -static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) +static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode) { int result; - result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode); + result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n", fname, result, @@ -239,11 +239,11 @@ static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd) return result; } -static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname) +static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname) { int result; - result = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname); + result = SMB_VFS_NEXT_RENAME(handle, oldname, newname); syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n", oldname, newname, @@ -257,11 +257,11 @@ static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, cons return result; } -static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) +static int audit_unlink(vfs_handle_struct *handle, const char *path) { int result; - result = SMB_VFS_NEXT_UNLINK(handle, conn, path); + result = SMB_VFS_NEXT_UNLINK(handle, path); syslog(audit_syslog_priority(handle), "unlink %s %s%s\n", path, @@ -275,11 +275,11 @@ static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, cons return result; } -static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) +static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) { int result; - result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode); + result = SMB_VFS_NEXT_CHMOD(handle, path, mode); syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n", path, mode, @@ -293,11 +293,11 @@ static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const return result; } -static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) +static int audit_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode) { int result; - result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode); + result = SMB_VFS_NEXT_CHMOD_ACL(handle, path, mode); syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n", path, mode, diff --git a/source/modules/vfs_fake_perms.c b/source/modules/vfs_fake_perms.c index decbe01d3ca..8bd8bbf5321 100644 --- a/source/modules/vfs_fake_perms.c +++ b/source/modules/vfs_fake_perms.c @@ -29,11 +29,11 @@ extern struct current_user current_user; #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS -static int fake_perms_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) +static int fake_perms_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf) { int ret = -1; - ret = SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf); + ret = SMB_VFS_NEXT_STAT(handle, fname, sbuf); if (ret == 0) { if (S_ISDIR(sbuf->st_mode)) { sbuf->st_mode = S_IFDIR | S_IRWXU; diff --git a/source/modules/vfs_full_audit.c b/source/modules/vfs_full_audit.c index b9ffd6fc05f..fd15c5c3585 100644 --- a/source/modules/vfs_full_audit.c +++ b/source/modules/vfs_full_audit.c @@ -72,48 +72,44 @@ struct vfs_full_audit_private_data { /* Function prototypes */ -static int smb_full_audit_connect(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_connect(vfs_handle_struct *handle, const char *svc, const char *user); -static void smb_full_audit_disconnect(vfs_handle_struct *handle, - connection_struct *conn); +static void smb_full_audit_disconnect(vfs_handle_struct *handle); static SMB_BIG_UINT smb_full_audit_disk_free(vfs_handle_struct *handle, - connection_struct *conn, const char *path, + const char *path, BOOL small_query, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize); static int smb_full_audit_get_quota(struct vfs_handle_struct *handle, - struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); static int smb_full_audit_set_quota(struct vfs_handle_struct *handle, - struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); static int smb_full_audit_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels); static int smb_full_audit_statvfs(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, struct vfs_statvfs_struct *statbuf); -static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connection_struct *conn, +static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr); static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle, - connection_struct *conn, SMB_STRUCT_DIR *dirp); -static void smb_full_audit_seekdir(vfs_handle_struct *handle, connection_struct *conn, + SMB_STRUCT_DIR *dirp); +static void smb_full_audit_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset); -static long smb_full_audit_telldir(vfs_handle_struct *handle, connection_struct *conn, +static long smb_full_audit_telldir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp); -static void smb_full_audit_rewinddir(vfs_handle_struct *handle, connection_struct *conn, +static void smb_full_audit_rewinddir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp); -static int smb_full_audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode); -static int smb_full_audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_rmdir(vfs_handle_struct *handle, const char *path); -static int smb_full_audit_closedir(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp); -static int smb_full_audit_open(vfs_handle_struct *handle, connection_struct *conn, - const char *fname, int flags, mode_t mode); +static int smb_full_audit_open(vfs_handle_struct *handle, + const char *fname, files_struct *fsp, int flags, mode_t mode); static int smb_full_audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd); static ssize_t smb_full_audit_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n); @@ -130,30 +126,30 @@ static ssize_t smb_full_audit_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr, SMB_OFF_T offset, size_t n); -static int smb_full_audit_rename(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname); static int smb_full_audit_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd); -static int smb_full_audit_stat(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf); static int smb_full_audit_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf); -static int smb_full_audit_lstat(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf); -static int smb_full_audit_unlink(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_unlink(vfs_handle_struct *handle, const char *path); -static int smb_full_audit_chmod(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode); static int smb_full_audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); -static int smb_full_audit_chown(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid); static int smb_full_audit_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid); -static int smb_full_audit_chdir(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_chdir(vfs_handle_struct *handle, const char *path); -static char *smb_full_audit_getwd(vfs_handle_struct *handle, connection_struct *conn, +static char *smb_full_audit_getwd(vfs_handle_struct *handle, char *path); -static int smb_full_audit_utime(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_utime(vfs_handle_struct *handle, const char *path, struct utimbuf *times); static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len); @@ -161,15 +157,15 @@ static BOOL smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp, in int op, SMB_OFF_T offset, SMB_OFF_T count, int type); static BOOL smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid); -static int smb_full_audit_symlink(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath); -static int smb_full_audit_readlink(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz); -static int smb_full_audit_link(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath); -static int smb_full_audit_mknod(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev); -static char *smb_full_audit_realpath(vfs_handle_struct *handle, connection_struct *conn, +static char *smb_full_audit_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path); static size_t smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, @@ -183,120 +179,99 @@ static BOOL smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_struct * static BOOL smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd); -static int smb_full_audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode); static int smb_full_audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); static int smb_full_audit_sys_acl_get_entry(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p); static int smb_full_audit_sys_acl_get_tag_type(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); static int smb_full_audit_sys_acl_get_permset(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); static void * smb_full_audit_sys_acl_get_qualifier(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_ENTRY_T entry_d); static SMB_ACL_T smb_full_audit_sys_acl_get_file(vfs_handle_struct *handle, - connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type); static SMB_ACL_T smb_full_audit_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd); static int smb_full_audit_sys_acl_clear_perms(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_PERMSET_T permset); static int smb_full_audit_sys_acl_add_perm(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); static char * smb_full_audit_sys_acl_to_text(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_T theacl, + SMB_ACL_T theacl, ssize_t *plen); static SMB_ACL_T smb_full_audit_sys_acl_init(vfs_handle_struct *handle, - connection_struct *conn, int count); static int smb_full_audit_sys_acl_create_entry(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_T *pacl, + SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry); static int smb_full_audit_sys_acl_set_tag_type(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype); static int smb_full_audit_sys_acl_set_qualifier(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual); static int smb_full_audit_sys_acl_set_permset(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset); static int smb_full_audit_sys_acl_valid(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_T theacl ); static int smb_full_audit_sys_acl_set_file(vfs_handle_struct *handle, - connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); static int smb_full_audit_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl); static int smb_full_audit_sys_acl_delete_def_file(vfs_handle_struct *handle, - connection_struct *conn, const char *path); static int smb_full_audit_sys_acl_get_perm(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); static int smb_full_audit_sys_acl_free_text(vfs_handle_struct *handle, - connection_struct *conn, char *text); static int smb_full_audit_sys_acl_free_acl(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_T posix_acl); static int smb_full_audit_sys_acl_free_qualifier(vfs_handle_struct *handle, - connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype); static ssize_t smb_full_audit_getxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, + const char *path, const char *name, void *value, size_t size); static ssize_t smb_full_audit_lgetxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, const char *name, void *value, size_t size); static ssize_t smb_full_audit_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const char *name, void *value, size_t size); static ssize_t smb_full_audit_listxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, char *list, size_t size); static ssize_t smb_full_audit_llistxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, char *list, size_t size); static ssize_t smb_full_audit_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, char *list, size_t size); static int smb_full_audit_removexattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, + const char *path, const char *name); static int smb_full_audit_lremovexattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, + const char *path, const char *name); static int smb_full_audit_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const char *name); static int smb_full_audit_setxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, + const char *path, const char *name, const void *value, size_t size, int flags); static int smb_full_audit_lsetxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, + const char *path, const char *name, const void *value, size_t size, int flags); static int smb_full_audit_fsetxattr(struct vfs_handle_struct *handle, @@ -666,10 +641,15 @@ static int audit_syslog_priority(vfs_handle_struct *handle) static char *audit_prefix(connection_struct *conn) { static pstring prefix; + extern userdom_struct current_user_info; pstrcpy(prefix, lp_parm_const_string(SNUM(conn), "full_audit", "prefix", "%u|%I")); - standard_sub_snum(SNUM(conn), prefix, sizeof(prefix)-1); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + prefix, sizeof(prefix)); return prefix; } @@ -811,7 +791,7 @@ static void free_private_data(void **p_data) /* Implementation of vfs_ops. Pass everything on to the default operation but log event first. */ -static int smb_full_audit_connect(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_connect(vfs_handle_struct *handle, const char *svc, const char *user) { int result; @@ -832,17 +812,17 @@ static int smb_full_audit_connect(vfs_handle_struct *handle, connection_struct * openlog("smbd_audit", 0, audit_syslog_facility(handle)); init_bitmap(&pd->success_ops, - lp_parm_string_list(SNUM(conn), "full_audit", "success", + lp_parm_string_list(SNUM(handle->conn), "full_audit", "success", none)); init_bitmap(&pd->failure_ops, - lp_parm_string_list(SNUM(conn), "full_audit", "failure", + lp_parm_string_list(SNUM(handle->conn), "full_audit", "failure", all)); /* Store the private data. */ SMB_VFS_HANDLE_SET_DATA(handle, pd, free_private_data, struct vfs_full_audit_private_data, return -1); - result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user); + result = SMB_VFS_NEXT_CONNECT(handle, svc, user); do_log(SMB_VFS_OP_CONNECT, True, handle, "%s", svc); @@ -850,13 +830,12 @@ static int smb_full_audit_connect(vfs_handle_struct *handle, connection_struct * return result; } -static void smb_full_audit_disconnect(vfs_handle_struct *handle, - connection_struct *conn) +static void smb_full_audit_disconnect(vfs_handle_struct *handle) { - SMB_VFS_NEXT_DISCONNECT(handle, conn); + SMB_VFS_NEXT_DISCONNECT(handle); do_log(SMB_VFS_OP_DISCONNECT, True, handle, - "%s", lp_servicename(SNUM(conn))); + "%s", lp_servicename(SNUM(handle->conn))); /* The bitmaps will be disconnected when the private data is deleted. */ @@ -865,13 +844,13 @@ static void smb_full_audit_disconnect(vfs_handle_struct *handle, } static SMB_BIG_UINT smb_full_audit_disk_free(vfs_handle_struct *handle, - connection_struct *conn, const char *path, + const char *path, BOOL small_query, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { SMB_BIG_UINT result; - result = SMB_VFS_NEXT_DISK_FREE(handle, conn, path, small_query, bsize, + result = SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, bsize, dfree, dsize); /* Don't have a reasonable notion of failure here */ @@ -882,13 +861,12 @@ static SMB_BIG_UINT smb_full_audit_disk_free(vfs_handle_struct *handle, } static int smb_full_audit_get_quota(struct vfs_handle_struct *handle, - struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) { int result; - result = SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, qt); + result = SMB_VFS_NEXT_GET_QUOTA(handle, qtype, id, qt); do_log(SMB_VFS_OP_GET_QUOTA, (result >= 0), handle, ""); @@ -897,13 +875,12 @@ static int smb_full_audit_get_quota(struct vfs_handle_struct *handle, static int smb_full_audit_set_quota(struct vfs_handle_struct *handle, - struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) { int result; - result = SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, qt); + result = SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, qt); do_log(SMB_VFS_OP_SET_QUOTA, (result >= 0), handle, ""); @@ -924,25 +901,24 @@ static int smb_full_audit_get_shadow_copy_data(struct vfs_handle_struct *handle, } static int smb_full_audit_statvfs(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, struct vfs_statvfs_struct *statbuf) { int result; - result = SMB_VFS_NEXT_STATVFS(handle, conn, path, statbuf); + result = SMB_VFS_NEXT_STATVFS(handle, path, statbuf); do_log(SMB_VFS_OP_STATVFS, (result >= 0), handle, ""); return result; } -static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connection_struct *conn, +static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) { SMB_STRUCT_DIR *result; - result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr); + result = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); do_log(SMB_VFS_OP_OPENDIR, (result != NULL), handle, "%s", fname); @@ -950,11 +926,11 @@ static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connect } static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle, - connection_struct *conn, SMB_STRUCT_DIR *dirp) + SMB_STRUCT_DIR *dirp) { SMB_STRUCT_DIRENT *result; - result = SMB_VFS_NEXT_READDIR(handle, conn, dirp); + result = SMB_VFS_NEXT_READDIR(handle, dirp); /* This operation has no reasonable error condition * (End of dir is also failure), so always succeed. @@ -964,78 +940,78 @@ static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle, return result; } -static void smb_full_audit_seekdir(vfs_handle_struct *handle, connection_struct *conn, +static void smb_full_audit_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset) { - SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp, offset); + SMB_VFS_NEXT_SEEKDIR(handle, dirp, offset); do_log(SMB_VFS_OP_SEEKDIR, True, handle, ""); return; } -static long smb_full_audit_telldir(vfs_handle_struct *handle, connection_struct *conn, +static long smb_full_audit_telldir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) { long result; - result = SMB_VFS_NEXT_TELLDIR(handle, conn, dirp); + result = SMB_VFS_NEXT_TELLDIR(handle, dirp); do_log(SMB_VFS_OP_TELLDIR, True, handle, ""); return result; } -static void smb_full_audit_rewinddir(vfs_handle_struct *handle, connection_struct *conn, +static void smb_full_audit_rewinddir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) { - SMB_VFS_NEXT_REWINDDIR(handle, conn, dirp); + SMB_VFS_NEXT_REWINDDIR(handle, dirp); do_log(SMB_VFS_OP_REWINDDIR, True, handle, ""); return; } -static int smb_full_audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) { int result; - result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode); + result = SMB_VFS_NEXT_MKDIR(handle, path, mode); do_log(SMB_VFS_OP_MKDIR, (result >= 0), handle, "%s", path); return result; } -static int smb_full_audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_rmdir(vfs_handle_struct *handle, const char *path) { int result; - result = SMB_VFS_NEXT_RMDIR(handle, conn, path); + result = SMB_VFS_NEXT_RMDIR(handle, path); do_log(SMB_VFS_OP_RMDIR, (result >= 0), handle, "%s", path); return result; } -static int smb_full_audit_closedir(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) { int result; - result = SMB_VFS_NEXT_CLOSEDIR(handle, conn, dirp); + result = SMB_VFS_NEXT_CLOSEDIR(handle, dirp); do_log(SMB_VFS_OP_CLOSEDIR, (result >= 0), handle, ""); return result; } -static int smb_full_audit_open(vfs_handle_struct *handle, connection_struct *conn, - const char *fname, int flags, mode_t mode) +static int smb_full_audit_open(vfs_handle_struct *handle, + const char *fname, files_struct *fsp, int flags, mode_t mode) { int result; - result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode); + result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); do_log(SMB_VFS_OP_OPEN, (result >= 0), handle, "%s|%s", ((flags & O_WRONLY) || (flags & O_RDWR))?"w":"r", @@ -1133,12 +1109,12 @@ static ssize_t smb_full_audit_sendfile(vfs_handle_struct *handle, int tofd, return result; } -static int smb_full_audit_rename(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname) { int result; - result = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname); + result = SMB_VFS_NEXT_RENAME(handle, oldname, newname); do_log(SMB_VFS_OP_RENAME, (result >= 0), handle, "%s|%s", oldname, newname); @@ -1156,12 +1132,12 @@ static int smb_full_audit_fsync(vfs_handle_struct *handle, files_struct *fsp, in return result; } -static int smb_full_audit_stat(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf) { int result; - result = SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf); + result = SMB_VFS_NEXT_STAT(handle, fname, sbuf); do_log(SMB_VFS_OP_STAT, (result >= 0), handle, "%s", fname); @@ -1180,36 +1156,36 @@ static int smb_full_audit_fstat(vfs_handle_struct *handle, files_struct *fsp, in return result; } -static int smb_full_audit_lstat(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf) { int result; - result = SMB_VFS_NEXT_LSTAT(handle, conn, path, sbuf); + result = SMB_VFS_NEXT_LSTAT(handle, path, sbuf); do_log(SMB_VFS_OP_LSTAT, (result >= 0), handle, "%s", path); return result; } -static int smb_full_audit_unlink(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_unlink(vfs_handle_struct *handle, const char *path) { int result; - result = SMB_VFS_NEXT_UNLINK(handle, conn, path); + result = SMB_VFS_NEXT_UNLINK(handle, path); do_log(SMB_VFS_OP_UNLINK, (result >= 0), handle, "%s", path); return result; } -static int smb_full_audit_chmod(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) { int result; - result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode); + result = SMB_VFS_NEXT_CHMOD(handle, path, mode); do_log(SMB_VFS_OP_CHMOD, (result >= 0), handle, "%s|%o", path, mode); @@ -1229,12 +1205,12 @@ static int smb_full_audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, i return result; } -static int smb_full_audit_chown(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) { int result; - result = SMB_VFS_NEXT_CHOWN(handle, conn, path, uid, gid); + result = SMB_VFS_NEXT_CHOWN(handle, path, uid, gid); do_log(SMB_VFS_OP_CHOWN, (result >= 0), handle, "%s|%ld|%ld", path, (long int)uid, (long int)gid); @@ -1255,36 +1231,36 @@ static int smb_full_audit_fchown(vfs_handle_struct *handle, files_struct *fsp, i return result; } -static int smb_full_audit_chdir(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_chdir(vfs_handle_struct *handle, const char *path) { int result; - result = SMB_VFS_NEXT_CHDIR(handle, conn, path); + result = SMB_VFS_NEXT_CHDIR(handle, path); do_log(SMB_VFS_OP_CHDIR, (result >= 0), handle, "chdir|%s", path); return result; } -static char *smb_full_audit_getwd(vfs_handle_struct *handle, connection_struct *conn, +static char *smb_full_audit_getwd(vfs_handle_struct *handle, char *path) { char *result; - result = SMB_VFS_NEXT_GETWD(handle, conn, path); + result = SMB_VFS_NEXT_GETWD(handle, path); do_log(SMB_VFS_OP_GETWD, (result != NULL), handle, "%s", path); return result; } -static int smb_full_audit_utime(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_utime(vfs_handle_struct *handle, const char *path, struct utimbuf *times) { int result; - result = SMB_VFS_NEXT_UTIME(handle, conn, path, times); + result = SMB_VFS_NEXT_UTIME(handle, path, times); do_log(SMB_VFS_OP_UTIME, (result >= 0), handle, "%s", path); @@ -1328,12 +1304,12 @@ static BOOL smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp, return result; } -static int smb_full_audit_symlink(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath) { int result; - result = SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath); + result = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath); do_log(SMB_VFS_OP_SYMLINK, (result >= 0), handle, "%s|%s", oldpath, newpath); @@ -1341,24 +1317,24 @@ static int smb_full_audit_symlink(vfs_handle_struct *handle, connection_struct * return result; } -static int smb_full_audit_readlink(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz) { int result; - result = SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz); + result = SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz); do_log(SMB_VFS_OP_READLINK, (result >= 0), handle, "%s", path); return result; } -static int smb_full_audit_link(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath) { int result; - result = SMB_VFS_NEXT_LINK(handle, conn, oldpath, newpath); + result = SMB_VFS_NEXT_LINK(handle, oldpath, newpath); do_log(SMB_VFS_OP_LINK, (result >= 0), handle, "%s|%s", oldpath, newpath); @@ -1366,24 +1342,24 @@ static int smb_full_audit_link(vfs_handle_struct *handle, connection_struct *con return result; } -static int smb_full_audit_mknod(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev) { int result; - result = SMB_VFS_NEXT_MKNOD(handle, conn, pathname, mode, dev); + result = SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev); do_log(SMB_VFS_OP_MKNOD, (result >= 0), handle, "%s", pathname); return result; } -static char *smb_full_audit_realpath(vfs_handle_struct *handle, connection_struct *conn, +static char *smb_full_audit_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path) { char *result; - result = SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path); + result = SMB_VFS_NEXT_REALPATH(handle, path, resolved_path); do_log(SMB_VFS_OP_REALPATH, (result != NULL), handle, "%s", path); @@ -1448,12 +1424,12 @@ static BOOL smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *f return result; } -static int smb_full_audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, +static int smb_full_audit_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode) { int result; - result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode); + result = SMB_VFS_NEXT_CHMOD_ACL(handle, path, mode); do_log(SMB_VFS_OP_CHMOD_ACL, (result >= 0), handle, "%s|%o", path, mode); @@ -1475,13 +1451,13 @@ static int smb_full_audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fs } static int smb_full_audit_sys_acl_get_entry(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) { int result; - result = SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, conn, theacl, entry_id, + result = SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, theacl, entry_id, entry_p); do_log(SMB_VFS_OP_SYS_ACL_GET_ENTRY, (result >= 0), handle, @@ -1491,13 +1467,13 @@ static int smb_full_audit_sys_acl_get_entry(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_get_tag_type(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) { int result; - result = SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, conn, entry_d, + result = SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, entry_d, tag_type_p); do_log(SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, (result >= 0), handle, @@ -1507,13 +1483,13 @@ static int smb_full_audit_sys_acl_get_tag_type(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_get_permset(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) { int result; - result = SMB_VFS_NEXT_SYS_ACL_GET_PERMSET(handle, conn, entry_d, + result = SMB_VFS_NEXT_SYS_ACL_GET_PERMSET(handle, entry_d, permset_p); do_log(SMB_VFS_OP_SYS_ACL_GET_PERMSET, (result >= 0), handle, @@ -1523,12 +1499,12 @@ static int smb_full_audit_sys_acl_get_permset(vfs_handle_struct *handle, } static void * smb_full_audit_sys_acl_get_qualifier(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_ENTRY_T entry_d) { void *result; - result = SMB_VFS_NEXT_SYS_ACL_GET_QUALIFIER(handle, conn, entry_d); + result = SMB_VFS_NEXT_SYS_ACL_GET_QUALIFIER(handle, entry_d); do_log(SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, (result != NULL), handle, ""); @@ -1537,13 +1513,12 @@ static void * smb_full_audit_sys_acl_get_qualifier(vfs_handle_struct *handle, } static SMB_ACL_T smb_full_audit_sys_acl_get_file(vfs_handle_struct *handle, - connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type) { SMB_ACL_T result; - result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, conn, path_p, type); + result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type); do_log(SMB_VFS_OP_SYS_ACL_GET_FILE, (result != NULL), handle, "%s", path_p); @@ -1565,12 +1540,12 @@ static SMB_ACL_T smb_full_audit_sys_acl_get_fd(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_clear_perms(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_PERMSET_T permset) { int result; - result = SMB_VFS_NEXT_SYS_ACL_CLEAR_PERMS(handle, conn, permset); + result = SMB_VFS_NEXT_SYS_ACL_CLEAR_PERMS(handle, permset); do_log(SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, (result >= 0), handle, ""); @@ -1579,13 +1554,13 @@ static int smb_full_audit_sys_acl_clear_perms(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_add_perm(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) { int result; - result = SMB_VFS_NEXT_SYS_ACL_ADD_PERM(handle, conn, permset, perm); + result = SMB_VFS_NEXT_SYS_ACL_ADD_PERM(handle, permset, perm); do_log(SMB_VFS_OP_SYS_ACL_ADD_PERM, (result >= 0), handle, ""); @@ -1594,12 +1569,12 @@ static int smb_full_audit_sys_acl_add_perm(vfs_handle_struct *handle, } static char * smb_full_audit_sys_acl_to_text(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_T theacl, + SMB_ACL_T theacl, ssize_t *plen) { char * result; - result = SMB_VFS_NEXT_SYS_ACL_TO_TEXT(handle, conn, theacl, plen); + result = SMB_VFS_NEXT_SYS_ACL_TO_TEXT(handle, theacl, plen); do_log(SMB_VFS_OP_SYS_ACL_TO_TEXT, (result != NULL), handle, ""); @@ -1608,12 +1583,12 @@ static char * smb_full_audit_sys_acl_to_text(vfs_handle_struct *handle, } static SMB_ACL_T smb_full_audit_sys_acl_init(vfs_handle_struct *handle, - connection_struct *conn, + int count) { SMB_ACL_T result; - result = SMB_VFS_NEXT_SYS_ACL_INIT(handle, conn, count); + result = SMB_VFS_NEXT_SYS_ACL_INIT(handle, count); do_log(SMB_VFS_OP_SYS_ACL_INIT, (result != NULL), handle, ""); @@ -1622,12 +1597,12 @@ static SMB_ACL_T smb_full_audit_sys_acl_init(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_create_entry(vfs_handle_struct *handle, - connection_struct *conn, SMB_ACL_T *pacl, + SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) { int result; - result = SMB_VFS_NEXT_SYS_ACL_CREATE_ENTRY(handle, conn, pacl, pentry); + result = SMB_VFS_NEXT_SYS_ACL_CREATE_ENTRY(handle, pacl, pentry); do_log(SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, (result >= 0), handle, ""); @@ -1636,13 +1611,13 @@ static int smb_full_audit_sys_acl_create_entry(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_set_tag_type(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) { int result; - result = SMB_VFS_NEXT_SYS_ACL_SET_TAG_TYPE(handle, conn, entry, + result = SMB_VFS_NEXT_SYS_ACL_SET_TAG_TYPE(handle, entry, tagtype); do_log(SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, (result >= 0), handle, @@ -1652,13 +1627,13 @@ static int smb_full_audit_sys_acl_set_tag_type(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_set_qualifier(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_ENTRY_T entry, void *qual) { int result; - result = SMB_VFS_NEXT_SYS_ACL_SET_QUALIFIER(handle, conn, entry, qual); + result = SMB_VFS_NEXT_SYS_ACL_SET_QUALIFIER(handle, entry, qual); do_log(SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, (result >= 0), handle, ""); @@ -1667,13 +1642,13 @@ static int smb_full_audit_sys_acl_set_qualifier(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_set_permset(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) { int result; - result = SMB_VFS_NEXT_SYS_ACL_SET_PERMSET(handle, conn, entry, permset); + result = SMB_VFS_NEXT_SYS_ACL_SET_PERMSET(handle, entry, permset); do_log(SMB_VFS_OP_SYS_ACL_SET_PERMSET, (result >= 0), handle, ""); @@ -1682,12 +1657,12 @@ static int smb_full_audit_sys_acl_set_permset(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_valid(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_T theacl ) { int result; - result = SMB_VFS_NEXT_SYS_ACL_VALID(handle, conn, theacl); + result = SMB_VFS_NEXT_SYS_ACL_VALID(handle, theacl); do_log(SMB_VFS_OP_SYS_ACL_VALID, (result >= 0), handle, ""); @@ -1696,13 +1671,13 @@ static int smb_full_audit_sys_acl_valid(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_set_file(vfs_handle_struct *handle, - connection_struct *conn, + const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) { int result; - result = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, conn, name, acltype, + result = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype, theacl); do_log(SMB_VFS_OP_SYS_ACL_SET_FILE, (result >= 0), handle, @@ -1725,12 +1700,12 @@ static int smb_full_audit_sys_acl_set_fd(vfs_handle_struct *handle, files_struct } static int smb_full_audit_sys_acl_delete_def_file(vfs_handle_struct *handle, - connection_struct *conn, + const char *path) { int result; - result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, conn, path); + result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path); do_log(SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, (result >= 0), handle, "%s", path); @@ -1739,13 +1714,13 @@ static int smb_full_audit_sys_acl_delete_def_file(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_get_perm(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) { int result; - result = SMB_VFS_NEXT_SYS_ACL_GET_PERM(handle, conn, permset, perm); + result = SMB_VFS_NEXT_SYS_ACL_GET_PERM(handle, permset, perm); do_log(SMB_VFS_OP_SYS_ACL_GET_PERM, (result >= 0), handle, ""); @@ -1754,12 +1729,12 @@ static int smb_full_audit_sys_acl_get_perm(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_free_text(vfs_handle_struct *handle, - connection_struct *conn, + char *text) { int result; - result = SMB_VFS_NEXT_SYS_ACL_FREE_TEXT(handle, conn, text); + result = SMB_VFS_NEXT_SYS_ACL_FREE_TEXT(handle, text); do_log(SMB_VFS_OP_SYS_ACL_FREE_TEXT, (result >= 0), handle, ""); @@ -1768,12 +1743,12 @@ static int smb_full_audit_sys_acl_free_text(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_free_acl(vfs_handle_struct *handle, - connection_struct *conn, + SMB_ACL_T posix_acl) { int result; - result = SMB_VFS_NEXT_SYS_ACL_FREE_ACL(handle, conn, posix_acl); + result = SMB_VFS_NEXT_SYS_ACL_FREE_ACL(handle, posix_acl); do_log(SMB_VFS_OP_SYS_ACL_FREE_ACL, (result >= 0), handle, ""); @@ -1782,13 +1757,12 @@ static int smb_full_audit_sys_acl_free_acl(vfs_handle_struct *handle, } static int smb_full_audit_sys_acl_free_qualifier(vfs_handle_struct *handle, - connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype) { int result; - result = SMB_VFS_NEXT_SYS_ACL_FREE_QUALIFIER(handle, conn, qualifier, + result = SMB_VFS_NEXT_SYS_ACL_FREE_QUALIFIER(handle, qualifier, tagtype); do_log(SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, (result >= 0), handle, @@ -1798,12 +1772,12 @@ static int smb_full_audit_sys_acl_free_qualifier(vfs_handle_struct *handle, } static ssize_t smb_full_audit_getxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, + const char *path, const char *name, void *value, size_t size) { ssize_t result; - result = SMB_VFS_NEXT_GETXATTR(handle, conn, path, name, value, size); + result = SMB_VFS_NEXT_GETXATTR(handle, path, name, value, size); do_log(SMB_VFS_OP_GETXATTR, (result >= 0), handle, "%s|%s", path, name); @@ -1812,13 +1786,12 @@ static ssize_t smb_full_audit_getxattr(struct vfs_handle_struct *handle, } static ssize_t smb_full_audit_lgetxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, const char *name, void *value, size_t size) { ssize_t result; - result = SMB_VFS_NEXT_LGETXATTR(handle, conn, path, name, value, size); + result = SMB_VFS_NEXT_LGETXATTR(handle, path, name, value, size); do_log(SMB_VFS_OP_LGETXATTR, (result >= 0), handle, "%s|%s", path, name); @@ -1841,12 +1814,11 @@ static ssize_t smb_full_audit_fgetxattr(struct vfs_handle_struct *handle, } static ssize_t smb_full_audit_listxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, char *list, size_t size) { ssize_t result; - result = SMB_VFS_NEXT_LISTXATTR(handle, conn, path, list, size); + result = SMB_VFS_NEXT_LISTXATTR(handle, path, list, size); do_log(SMB_VFS_OP_LISTXATTR, (result >= 0), handle, "%s", path); @@ -1854,12 +1826,11 @@ static ssize_t smb_full_audit_listxattr(struct vfs_handle_struct *handle, } static ssize_t smb_full_audit_llistxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, char *list, size_t size) { ssize_t result; - result = SMB_VFS_NEXT_LLISTXATTR(handle, conn, path, list, size); + result = SMB_VFS_NEXT_LLISTXATTR(handle, path, list, size); do_log(SMB_VFS_OP_LLISTXATTR, (result >= 0), handle, "%s", path); @@ -1881,12 +1852,12 @@ static ssize_t smb_full_audit_flistxattr(struct vfs_handle_struct *handle, } static int smb_full_audit_removexattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, + const char *path, const char *name) { int result; - result = SMB_VFS_NEXT_REMOVEXATTR(handle, conn, path, name); + result = SMB_VFS_NEXT_REMOVEXATTR(handle, path, name); do_log(SMB_VFS_OP_REMOVEXATTR, (result >= 0), handle, "%s|%s", path, name); @@ -1895,12 +1866,12 @@ static int smb_full_audit_removexattr(struct vfs_handle_struct *handle, } static int smb_full_audit_lremovexattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, + const char *path, const char *name) { int result; - result = SMB_VFS_NEXT_LREMOVEXATTR(handle, conn, path, name); + result = SMB_VFS_NEXT_LREMOVEXATTR(handle, path, name); do_log(SMB_VFS_OP_LREMOVEXATTR, (result >= 0), handle, "%s|%s", path, name); @@ -1923,13 +1894,13 @@ static int smb_full_audit_fremovexattr(struct vfs_handle_struct *handle, } static int smb_full_audit_setxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, + const char *path, const char *name, const void *value, size_t size, int flags) { int result; - result = SMB_VFS_NEXT_SETXATTR(handle, conn, path, name, value, size, + result = SMB_VFS_NEXT_SETXATTR(handle, path, name, value, size, flags); do_log(SMB_VFS_OP_SETXATTR, (result >= 0), handle, @@ -1939,13 +1910,13 @@ static int smb_full_audit_setxattr(struct vfs_handle_struct *handle, } static int smb_full_audit_lsetxattr(struct vfs_handle_struct *handle, - struct connection_struct *conn, const char *path, + const char *path, const char *name, const void *value, size_t size, int flags) { int result; - result = SMB_VFS_NEXT_LSETXATTR(handle, conn, path, name, value, size, + result = SMB_VFS_NEXT_LSETXATTR(handle, path, name, value, size, flags); do_log(SMB_VFS_OP_LSETXATTR, (result >= 0), handle, diff --git a/source/modules/vfs_netatalk.c b/source/modules/vfs_netatalk.c index e9d4360cd80..279160d9665 100644 --- a/source/modules/vfs_netatalk.c +++ b/source/modules/vfs_netatalk.c @@ -172,11 +172,11 @@ static void atalk_rrmdir(TALLOC_CTX *ctx, char *path) /* Directory operations */ -SMB_STRUCT_DIR *atalk_opendir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, const char *mask, uint32 attr) +SMB_STRUCT_DIR *atalk_opendir(struct vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) { SMB_STRUCT_DIR *ret = 0; - ret = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr); + ret = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); /* * when we try to perform delete operation upon file which has fork @@ -187,19 +187,19 @@ SMB_STRUCT_DIR *atalk_opendir(struct vfs_handle_struct *handle, struct connectio * list then it would be nice to add one. */ - atalk_add_to_list(&conn->hide_list); - atalk_add_to_list(&conn->veto_list); + atalk_add_to_list(&handle->conn->hide_list); + atalk_add_to_list(&handle->conn->veto_list); return ret; } -static int atalk_rmdir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path) +static int atalk_rmdir(struct vfs_handle_struct *handle, const char *path) { BOOL add = False; TALLOC_CTX *ctx = 0; char *dpath; - if (!conn || !conn->origpath || !path) goto exit_rmdir; + if (!handle->conn->origpath || !path) goto exit_rmdir; /* due to there is no way to change bDeleteVetoFiles variable * from this module, gotta use talloc stuff.. @@ -211,19 +211,19 @@ static int atalk_rmdir(struct vfs_handle_struct *handle, struct connection_struc goto exit_rmdir; if (!(dpath = talloc_asprintf(ctx, "%s/%s%s", - conn->origpath, path, add ? "/"APPLEDOUBLE : ""))) + handle->conn->origpath, path, add ? "/"APPLEDOUBLE : ""))) goto exit_rmdir; atalk_rrmdir(ctx, dpath); exit_rmdir: talloc_destroy(ctx); - return SMB_VFS_NEXT_RMDIR(handle, conn, path); + return SMB_VFS_NEXT_RMDIR(handle, path); } /* File operations */ -static int atalk_rename(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldname, const char *newname) +static int atalk_rename(struct vfs_handle_struct *handle, const char *oldname, const char *newname) { int ret = 0; char *adbl_path = 0; @@ -232,14 +232,14 @@ static int atalk_rename(struct vfs_handle_struct *handle, struct connection_stru SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname); + ret = SMB_VFS_NEXT_RENAME(handle, oldname, newname); - if (!conn || !oldname) return ret; + if (!oldname) return ret; if (!(ctx = talloc_init("rename_file"))) return ret; - if (atalk_build_paths(ctx, conn->origpath, oldname, &adbl_path, &orig_path, + if (atalk_build_paths(ctx, handle->conn->origpath, oldname, &adbl_path, &orig_path, &adbl_info, &orig_info) != 0) return ret; @@ -255,7 +255,7 @@ exit_rename: return ret; } -static int atalk_unlink(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path) +static int atalk_unlink(struct vfs_handle_struct *handle, const char *path) { int ret = 0, i; char *adbl_path = 0; @@ -264,25 +264,25 @@ static int atalk_unlink(struct vfs_handle_struct *handle, struct connection_stru SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = SMB_VFS_NEXT_UNLINK(handle, conn, path); + ret = SMB_VFS_NEXT_UNLINK(handle, path); - if (!conn || !path) return ret; + if (!path) return ret; /* no .AppleDouble sync if veto or hide list is empty, * otherwise "Cannot find the specified file" error will be caused */ - if (!conn->veto_list) return ret; - if (!conn->hide_list) return ret; + if (!handle->conn->veto_list) return ret; + if (!handle->conn->hide_list) return ret; - for (i = 0; conn->veto_list[i].name; i ++) { - if (strstr(conn->veto_list[i].name, APPLEDOUBLE)) + for (i = 0; handle->conn->veto_list[i].name; i ++) { + if (strstr(handle->conn->veto_list[i].name, APPLEDOUBLE)) break; } - if (!conn->veto_list[i].name) { - for (i = 0; conn->hide_list[i].name; i ++) { - if (strstr(conn->hide_list[i].name, APPLEDOUBLE)) + if (!handle->conn->veto_list[i].name) { + for (i = 0; handle->conn->hide_list[i].name; i ++) { + if (strstr(handle->conn->hide_list[i].name, APPLEDOUBLE)) break; else { DEBUG(3, ("ATALK: %s is not hidden, skipped..\n", @@ -295,7 +295,7 @@ static int atalk_unlink(struct vfs_handle_struct *handle, struct connection_stru if (!(ctx = talloc_init("unlink_file"))) return ret; - if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path, + if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path, &adbl_info, &orig_info) != 0) return ret; @@ -311,7 +311,7 @@ exit_unlink: return ret; } -static int atalk_chmod(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode) +static int atalk_chmod(struct vfs_handle_struct *handle, const char *path, mode_t mode) { int ret = 0; char *adbl_path = 0; @@ -320,14 +320,14 @@ static int atalk_chmod(struct vfs_handle_struct *handle, struct connection_struc SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode); + ret = SMB_VFS_NEXT_CHMOD(handle, path, mode); - if (!conn || !path) return ret; + if (!path) return ret; if (!(ctx = talloc_init("chmod_file"))) return ret; - if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path, + if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path, &adbl_info, &orig_info) != 0) return ret; @@ -343,7 +343,7 @@ exit_chmod: return ret; } -static int atalk_chown(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, uid_t uid, gid_t gid) +static int atalk_chown(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) { int ret = 0; char *adbl_path = 0; @@ -352,14 +352,14 @@ static int atalk_chown(struct vfs_handle_struct *handle, struct connection_struc SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = SMB_VFS_NEXT_CHOWN(handle, conn, path, uid, gid); + ret = SMB_VFS_NEXT_CHOWN(handle, path, uid, gid); - if (!conn || !path) return ret; + if (!path) return ret; if (!(ctx = talloc_init("chown_file"))) return ret; - if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path, + if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path, &adbl_info, &orig_info) != 0) return ret; diff --git a/source/modules/vfs_prealloc.c b/source/modules/vfs_prealloc.c new file mode 100644 index 00000000000..94db6423700 --- /dev/null +++ b/source/modules/vfs_prealloc.c @@ -0,0 +1,214 @@ +/* + * XFS preallocation support module. + * + * Copyright (c) James Peach 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +/* Extent preallocation module. + * + * The purpose of this module is to preallocate space on the filesystem when + * we have a good idea of how large files are supposed to be. This lets writes + * proceed without having to allocate new extents and results in better file + * layouts on disk. + * + * Currently only implemented for XFS. This module is based on an original idea + * and implementation by Sebastian Brings. + * + * Tunables. + * + * prealloc: <ext> Number of bytes to preallocate for a file with + * the matching extension. + * prealloc:debug Debug level at which to emit messages. + * + * Example. + * + * prealloc:mpeg = 500M # Preallocate *.mpeg to 500 MiB. + */ + +#ifdef HAVE_XFS_LIBXFS_H +#include <xfs/libxfs.h> +#define lock_type xfs_flock64_t +#else +#define lock_type struct flock64 +#endif + +#define MODULE "prealloc" +static int module_debug; + +static int preallocate_space(int fd, SMB_OFF_T size) +{ + lock_type fl = {0}; + int err; + + if (size <= 0) { + return 0; + } + + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = size; + + /* IMPORTANT: We use RESVSP because we want the extents to be + * allocated, but we don't want the allocation to show up in + * st_size or persist after the close(2). + */ + +#if defined(XFS_IOC_RESVSP64) + /* On Linux this comes in via libxfs.h. */ + err = xfsctl(NULL, fd, XFS_IOC_RESVSP64, &fl); +#elif defined(F_RESVSP64) + /* On IRIX, this comes from fcntl.h. */ + err = fcntl(fd, F_RESVSP64, &fl); +#else + err = -1; + errno = ENOSYS; +#endif + + if (err) { + DEBUG(module_debug, + ("%s: preallocate failed on fd=%d size=%lld: %s\n", + MODULE, fd, (long long)size, strerror(errno))); + } + + return err; +} + +static int prealloc_connect( + struct vfs_handle_struct * handle, + const char * service, + const char * user) +{ + module_debug = lp_parm_int(SNUM(handle->conn), + MODULE, "debug", 100); + + return SMB_VFS_NEXT_CONNECT(handle, service, user); +} + +static int prealloc_open(vfs_handle_struct* handle, + const char * fname, + files_struct * fsp, + int flags, + mode_t mode) +{ + int fd; + off64_t size = 0; + + const char * dot; + char fext[10]; + + if (!(flags & (O_CREAT|O_TRUNC))) { + /* Caller is not intending to rewrite the file. Let's not mess + * with the allocation in this case. + */ + goto normal_open; + } + + *fext = '\0'; + dot = strrchr(fname, '.'); + if (dot && *++dot) { + if (strlen(dot) < sizeof(fext)) { + strncpy(fext, dot, sizeof(fext)); + strnorm(fext, CASE_LOWER); + } + } + + if (*fext == '\0') { + goto normal_open; + } + + /* Syntax for specifying preallocation size is: + * MODULE: <extension> = <size> + * where + * <extension> is the file extension in lower case + * <size> is a size like 10, 10K, 10M + */ + size = conv_str_size(lp_parm_const_string(SNUM(handle->conn), MODULE, + fext, NULL)); + if (size <= 0) { + /* No need to preallocate this file. */ + goto normal_open; + } + + fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); + if (fd < 0) { + return fd; + } + + /* Prellocate only if the file is being created or replaced. Note that + * Samba won't ever pass down O_TRUNC, which is why we have to handle + * truncate calls specially. + */ + if ((flags & O_CREAT) || (flags & O_TRUNC)) { + SMB_OFF_T * psize; + + psize = VFS_ADD_FSP_EXTENSION(handle, fsp, SMB_OFF_T); + if (psize == NULL || *psize == -1) { + return fd; + } + + DEBUG(module_debug, + ("%s: preallocating %s (fd=%d) to %lld bytes\n", + MODULE, fname, fd, (long long)size)); + + *psize = size; + if (preallocate_space(fd, *psize) < 0) { + VFS_REMOVE_FSP_EXTENSION(handle, fsp); + } + } + + return fd; + +normal_open: + /* We are not creating or replacing a file. Skip the + * preallocation. + */ + DEBUG(module_debug, ("%s: skipping preallocation for %s\n", + MODULE, fname)); + return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); +} + +static int prealloc_ftruncate(vfs_handle_struct * handle, + files_struct * fsp, + int fd, + SMB_OFF_T offset) +{ + SMB_OFF_T *psize; + int ret = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, fd, offset); + + /* Maintain the allocated space even in the face of truncates. */ + if ((psize = VFS_FETCH_FSP_EXTENSION(handle, fsp))) { + preallocate_space(fd, *psize); + } + + return ret; +} + +static vfs_op_tuple prealloc_op_tuples[] = { + {SMB_VFS_OP(prealloc_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(prealloc_ftruncate), SMB_VFS_OP_FTRUNCATE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(prealloc_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT}, + {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_prealloc_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, + MODULE, prealloc_op_tuples); +} + diff --git a/source/modules/vfs_readonly.c b/source/modules/vfs_readonly.c index ee9e40c2fca..e69f7dac016 100644 --- a/source/modules/vfs_readonly.c +++ b/source/modules/vfs_readonly.c @@ -55,7 +55,6 @@ #define MODULE_NAME "readonly" static int readonly_connect(vfs_handle_struct *handle, - connection_struct *conn, const char *service, const char *user) { @@ -71,10 +70,10 @@ static int readonly_connect(vfs_handle_struct *handle, time_t end_period = get_date(period[1], ¤t_time); if ((current_time >= begin_period) && (current_time <= end_period)) { - conn->read_only = True; + handle->conn->read_only = True; } - return SMB_VFS_NEXT_CONNECT(handle, conn, service, user); + return SMB_VFS_NEXT_CONNECT(handle, service, user); } else { diff --git a/source/modules/vfs_recycle.c b/source/modules/vfs_recycle.c index 42f2f51416e..4ffd683bfd5 100644 --- a/source/modules/vfs_recycle.c +++ b/source/modules/vfs_recycle.c @@ -32,9 +32,9 @@ static int vfs_recycle_debug_level = DBGC_VFS; #undef DBGC_CLASS #define DBGC_CLASS vfs_recycle_debug_level -static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user); -static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn); -static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *name); +static int recycle_connect(vfs_handle_struct *handle, const char *service, const char *user); +static void recycle_disconnect(vfs_handle_struct *handle); +static int recycle_unlink(vfs_handle_struct *handle, const char *name); static vfs_op_tuple recycle_ops[] = { @@ -48,20 +48,20 @@ static vfs_op_tuple recycle_ops[] = { {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; -static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user) +static int recycle_connect(vfs_handle_struct *handle, const char *service, const char *user) { DEBUG(10,("recycle_connect() connect to service[%s] as user[%s].\n", service,user)); - return SMB_VFS_NEXT_CONNECT(handle, conn, service, user); + return SMB_VFS_NEXT_CONNECT(handle, service, user); } -static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn) +static void recycle_disconnect(vfs_handle_struct *handle) { DEBUG(10,("recycle_disconnect() connect to service[%s].\n", - lp_servicename(SNUM(conn)))); + lp_servicename(SNUM(handle->conn)))); - SMB_VFS_NEXT_DISCONNECT(handle, conn); + SMB_VFS_NEXT_DISCONNECT(handle); } static const char *recycle_repository(vfs_handle_struct *handle) @@ -202,7 +202,7 @@ static BOOL recycle_directory_exist(vfs_handle_struct *handle, const char *dname { SMB_STRUCT_STAT st; - if (SMB_VFS_NEXT_STAT(handle, handle->conn, dname, &st) == 0) { + if (SMB_VFS_NEXT_STAT(handle, dname, &st) == 0) { if (S_ISDIR(st.st_mode)) { return True; } @@ -215,7 +215,7 @@ static BOOL recycle_file_exist(vfs_handle_struct *handle, const char *fname) { SMB_STRUCT_STAT st; - if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) == 0) { + if (SMB_VFS_NEXT_STAT(handle, fname, &st) == 0) { if (S_ISREG(st.st_mode)) { return True; } @@ -234,7 +234,7 @@ static SMB_OFF_T recycle_get_file_size(vfs_handle_struct *handle, const char *fn { SMB_STRUCT_STAT st; - if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) { + if (SMB_VFS_NEXT_STAT(handle, fname, &st) != 0) { DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno))); return (SMB_OFF_T)0; } @@ -280,7 +280,7 @@ static BOOL recycle_create_dir(vfs_handle_struct *handle, const char *dname) DEBUG(10, ("recycle: dir %s already exists\n", new_dir)); else { DEBUG(5, ("recycle: creating new dir %s\n", new_dir)); - if (SMB_VFS_NEXT_MKDIR(handle, handle->conn, new_dir, mode) != 0) { + if (SMB_VFS_NEXT_MKDIR(handle, new_dir, mode) != 0) { DEBUG(1,("recycle: mkdir failed for %s with error: %s\n", new_dir, strerror(errno))); ret = False; goto done; @@ -354,7 +354,7 @@ static void recycle_do_touch(vfs_handle_struct *handle, const char *fname, BOOL struct utimbuf tb; time_t currtime; - if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) { + if (SMB_VFS_NEXT_STAT(handle, fname, &st) != 0) { DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno))); return; } @@ -362,16 +362,19 @@ static void recycle_do_touch(vfs_handle_struct *handle, const char *fname, BOOL tb.actime = currtime; tb.modtime = touch_mtime ? currtime : st.st_mtime; - if (SMB_VFS_NEXT_UTIME(handle, handle->conn, fname, &tb) == -1 ) { + if (SMB_VFS_NEXT_UTIME(handle, fname, &tb) == -1 ) { DEBUG(0, ("recycle: touching %s failed, reason = %s\n", fname, strerror(errno))); } } +extern userdom_struct current_user_info; + /** * Check if file should be recycled **/ -static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *file_name) +static int recycle_unlink(vfs_handle_struct *handle, const char *file_name) { + connection_struct *conn = handle->conn; char *path_name = NULL; char *temp_name = NULL; char *final_name = NULL; @@ -383,7 +386,12 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co BOOL exist; int rc = -1; - repository = alloc_sub_conn(conn, recycle_repository(handle)); + repository = talloc_sub_advanced(NULL, lp_servicename(SNUM(conn)), + conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + recycle_repository(handle)); ALLOC_CHECK(repository, done); /* shouldn't we allow absolute path names here? --metze */ /* Yes :-). JRA. */ @@ -391,14 +399,14 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co if(!repository || *(repository) == '\0') { DEBUG(3, ("recycle: repository path not set, purging %s...\n", file_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); + rc = SMB_VFS_NEXT_UNLINK(handle, file_name); goto done; } /* we don't recycle the recycle bin... */ if (strncmp(file_name, repository, strlen(repository)) == 0) { DEBUG(3, ("recycle: File is within recycling bin, unlinking ...\n")); - rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); + rc = SMB_VFS_NEXT_UNLINK(handle, file_name); goto done; } @@ -408,7 +416,7 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co * if(fsize == 0) { DEBUG(3, ("recycle: File %s is empty, purging...\n", file_name)); - rc = SMB_VFS_NEXT_UNLINK(handle,conn,file_name); + rc = SMB_VFS_NEXT_UNLINK(handle,file_name); goto done; } */ @@ -420,18 +428,18 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co maxsize = recycle_maxsize(handle); if(maxsize > 0 && file_size > maxsize) { DEBUG(3, ("recycle: File %s exceeds maximum recycle size, purging... \n", file_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); + rc = SMB_VFS_NEXT_UNLINK(handle, file_name); goto done; } /* FIXME: this is wrong: moving files with rename does not change the disk space * allocation * - space_avail = SMB_VFS_NEXT_DISK_FREE(handle, conn, ".", True, &bsize, &dfree, &dsize) * 1024L; + space_avail = SMB_VFS_NEXT_DISK_FREE(handle, ".", True, &bsize, &dfree, &dsize) * 1024L; DEBUG(5, ("space_avail = %Lu, file_size = %Lu\n", space_avail, file_size)); if(space_avail < file_size) { DEBUG(3, ("recycle: Not enough diskspace, purging file %s\n", file_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); + rc = SMB_VFS_NEXT_UNLINK(handle, file_name); goto done; } */ @@ -456,7 +464,7 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co if (matchparam(recycle_exclude(handle), base)) { DEBUG(3, ("recycle: file %s is excluded \n", base)); - rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); + rc = SMB_VFS_NEXT_UNLINK(handle, file_name); goto done; } @@ -466,7 +474,7 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co */ if (checkparam(recycle_exclude_dir(handle), path_name)) { DEBUG(3, ("recycle: directory %s is excluded \n", path_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); + rc = SMB_VFS_NEXT_UNLINK(handle, file_name); goto done; } @@ -484,7 +492,7 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co DEBUG(10, ("recycle: Creating directory %s\n", temp_name)); if (recycle_create_dir(handle, temp_name) == False) { DEBUG(3, ("recycle: Could not create directory, purging %s...\n", file_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); + rc = SMB_VFS_NEXT_UNLINK(handle, file_name); goto done; } } @@ -497,7 +505,7 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co if (recycle_file_exist(handle, final_name)) { if (recycle_versions(handle) == False || matchparam(recycle_noversions(handle), base) == True) { DEBUG(3, ("recycle: Removing old file %s from recycle bin\n", final_name)); - if (SMB_VFS_NEXT_UNLINK(handle, conn, final_name) != 0) { + if (SMB_VFS_NEXT_UNLINK(handle, final_name) != 0) { DEBUG(1, ("recycle: Error deleting old file: %s\n", strerror(errno))); } } @@ -511,10 +519,10 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co } DEBUG(10, ("recycle: Moving %s to %s\n", file_name, final_name)); - rc = SMB_VFS_NEXT_RENAME(handle, conn, file_name, final_name); + rc = SMB_VFS_NEXT_RENAME(handle, file_name, final_name); if (rc != 0) { DEBUG(3, ("recycle: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); + rc = SMB_VFS_NEXT_UNLINK(handle, file_name); goto done; } @@ -526,7 +534,7 @@ done: SAFE_FREE(path_name); SAFE_FREE(temp_name); SAFE_FREE(final_name); - SAFE_FREE(repository); + TALLOC_FREE(repository); return rc; } diff --git a/source/modules/vfs_shadow_copy.c b/source/modules/vfs_shadow_copy.c index db1c8d007dc..447c53d773a 100644 --- a/source/modules/vfs_shadow_copy.c +++ b/source/modules/vfs_shadow_copy.c @@ -72,10 +72,10 @@ static BOOL shadow_copy_match_name(const char *name) return False; } -static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) +static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) { shadow_copy_Dir *dirp; - SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,conn,fname,mask,attr); + SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fname,mask,attr); if (!p) { DEBUG(0,("shadow_copy_opendir: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fname)); @@ -85,7 +85,7 @@ static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection dirp = SMB_MALLOC_P(shadow_copy_Dir); if (!dirp) { DEBUG(0,("shadow_copy_opendir: Out of memory\n")); - SMB_VFS_NEXT_CLOSEDIR(handle,conn,p); + SMB_VFS_NEXT_CLOSEDIR(handle,p); return NULL; } @@ -94,7 +94,7 @@ static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection while (True) { SMB_STRUCT_DIRENT *d; - d = SMB_VFS_NEXT_READDIR(handle, conn, p); + d = SMB_VFS_NEXT_READDIR(handle, p); if (d == NULL) { break; } @@ -115,11 +115,11 @@ static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection dirp->dirs[dirp->num++] = *d; } - SMB_VFS_NEXT_CLOSEDIR(handle,conn,p); + SMB_VFS_NEXT_CLOSEDIR(handle,p); return((SMB_STRUCT_DIR *)dirp); } -SMB_STRUCT_DIRENT *shadow_copy_readdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *_dirp) +SMB_STRUCT_DIRENT *shadow_copy_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp) { shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; @@ -130,7 +130,7 @@ SMB_STRUCT_DIRENT *shadow_copy_readdir(vfs_handle_struct *handle, connection_str return NULL; } -static void shadow_copy_seekdir(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *_dirp, long offset) +static void shadow_copy_seekdir(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp, long offset) { shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; @@ -139,19 +139,19 @@ static void shadow_copy_seekdir(struct vfs_handle_struct *handle, struct connect } } -static long shadow_copy_telldir(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *_dirp) +static long shadow_copy_telldir(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp) { shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; return( dirp->pos ) ; } -static void shadow_copy_rewinddir(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *_dirp) +static void shadow_copy_rewinddir(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp) { shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; dirp->pos = 0 ; } -int shadow_copy_closedir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *_dirp) +int shadow_copy_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp) { shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; @@ -163,7 +163,7 @@ int shadow_copy_closedir(vfs_handle_struct *handle, connection_struct *conn, SMB static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels) { - SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn,fsp->conn->connectpath,NULL,0); + SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn->connectpath,NULL,0); shadow_copy_data->num_volumes = 0; shadow_copy_data->labels = NULL; @@ -177,7 +177,7 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_str SHADOW_COPY_LABEL *tlabels; SMB_STRUCT_DIRENT *d; - d = SMB_VFS_NEXT_READDIR(handle, fsp->conn, p); + d = SMB_VFS_NEXT_READDIR(handle, p); if (d == NULL) { break; } @@ -200,7 +200,7 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_str (shadow_copy_data->num_volumes+1)*sizeof(SHADOW_COPY_LABEL)); if (tlabels == NULL) { DEBUG(0,("shadow_copy_get_shadow_copy_data: Out of memory\n")); - SMB_VFS_NEXT_CLOSEDIR(handle,fsp->conn,p); + SMB_VFS_NEXT_CLOSEDIR(handle,p); return -1; } @@ -209,7 +209,7 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_str shadow_copy_data->labels = tlabels; } - SMB_VFS_NEXT_CLOSEDIR(handle,fsp->conn,p); + SMB_VFS_NEXT_CLOSEDIR(handle,p); return 0; } diff --git a/source/nmbd/nmbd_synclists.c b/source/nmbd/nmbd_synclists.c index 28ad92ed108..7fe39676c6f 100644 --- a/source/nmbd/nmbd_synclists.c +++ b/source/nmbd/nmbd_synclists.c @@ -68,7 +68,7 @@ static void sync_child(char *name, int nm_type, char *fname) { fstring unix_workgroup; - static struct cli_state cli; + struct cli_state *cli; uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0; struct nmb_name called, calling; @@ -76,50 +76,56 @@ static void sync_child(char *name, int nm_type, * Patch from Andy Levine andyl@epicrealm.com. */ - if (!cli_initialise(&cli) || !cli_set_port(&cli, 139) || !cli_connect(&cli, name, &ip)) { + cli = cli_initialise(); + if (!cli) { + return; + } + + if (!cli_set_port(cli, 139) || !cli_connect(cli, name, &ip)) { return; } make_nmb_name(&calling, local_machine, 0x0); make_nmb_name(&called , name, nm_type); - if (!cli_session_request(&cli, &calling, &called)) { - cli_shutdown(&cli); + if (!cli_session_request(cli, &calling, &called)) { + cli_shutdown(cli); return; } - if (!cli_negprot(&cli)) { - cli_shutdown(&cli); + if (!cli_negprot(cli)) { + cli_shutdown(cli); return; } - if (!cli_session_setup(&cli, "", "", 1, "", 0, workgroup)) { - cli_shutdown(&cli); + if (!NT_STATUS_IS_OK(cli_session_setup(cli, "", "", 1, "", 0, + workgroup))) { + cli_shutdown(cli); return; } - if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { - cli_shutdown(&cli); + if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) { + cli_shutdown(cli); return; } /* All the cli_XX functions take UNIX character set. */ - fstrcpy(unix_workgroup, cli.server_domain?cli.server_domain:workgroup); + fstrcpy(unix_workgroup, cli->server_domain ? cli->server_domain : workgroup); /* Fetch a workgroup list. */ - cli_NetServerEnum(&cli, unix_workgroup, + cli_NetServerEnum(cli, unix_workgroup, local_type|SV_TYPE_DOMAIN_ENUM, callback, NULL); /* Now fetch a server list. */ if (servers) { fstrcpy(unix_workgroup, workgroup); - cli_NetServerEnum(&cli, unix_workgroup, + cli_NetServerEnum(cli, unix_workgroup, local?SV_TYPE_LOCAL_LIST_ONLY:SV_TYPE_ALL, callback, NULL); } - cli_shutdown(&cli); + cli_shutdown(cli); } /******************************************************************* diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c index 0be7093c641..3f392c48259 100644 --- a/source/nsswitch/winbindd_cm.c +++ b/source/nsswitch/winbindd_cm.c @@ -426,7 +426,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, goto done; } - if ((*cli = cli_initialise(NULL)) == NULL) { + if ((*cli = cli_initialise()) == NULL) { DEBUG(1, ("Could not cli_initialize\n")); result = NT_STATUS_NO_MEMORY; goto done; @@ -538,10 +538,11 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, "[%s]\\[%s]\n", controller, global_myname(), ipc_domain, ipc_username)); - if (cli_session_setup(*cli, ipc_username, + if (NT_STATUS_IS_OK(cli_session_setup( + *cli, ipc_username, ipc_password, strlen(ipc_password)+1, ipc_password, strlen(ipc_password)+1, - ipc_domain)) { + ipc_domain))) { /* Successful logon with given username. */ cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password); goto session_setup_done; @@ -553,7 +554,8 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, /* Fall back to anonymous connection, this might fail later */ - if (cli_session_setup(*cli, "", NULL, 0, NULL, 0, "")) { + if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0, + NULL, 0, ""))) { DEBUG(5, ("Connected anonymously\n")); cli_init_creds(*cli, "", "", ""); goto session_setup_done; diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 1c3afef1f52..5e39544420d 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -58,6 +58,7 @@ BOOL bLoaded = False; extern pstring user_socket_options; extern enum protocol_types Protocol; +extern userdom_struct current_user_info; #ifndef GLOBAL_NAME #define GLOBAL_NAME "global" @@ -1545,8 +1546,8 @@ static void init_globals(BOOL first_time_only) Globals.map_to_guest = 0; /* By Default, "Never" */ Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */ Globals.enhanced_browsing = True; - Globals.iLockSpinCount = 3; /* Try 3 times. */ - Globals.iLockSpinTime = 10; /* usec. */ + Globals.iLockSpinCount = 0; /* Unused. */ + Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */ #ifdef MMAP_BLACKLIST Globals.bUseMmap = False; #else @@ -1702,11 +1703,13 @@ static char *lp_string(const char *s) if (!lp_talloc) lp_talloc = talloc_init("lp_talloc"); - tmpstr = alloc_sub_basic(get_current_username(), s); + tmpstr = alloc_sub_basic(get_current_username(), + current_user_info.domain, s); if (trim_char(tmpstr, '\"', '\"')) { if (strchr(tmpstr,'\"') != NULL) { SAFE_FREE(tmpstr); - tmpstr = alloc_sub_basic(get_current_username(),s); + tmpstr = alloc_sub_basic(get_current_username(), + current_user_info.domain, s); } } ret = talloc_strdup(lp_talloc, tmpstr); @@ -1947,7 +1950,7 @@ FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest) FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time) FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount) -FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime) +FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime) FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares) FN_LOCAL_STRING(lp_preexec, szPreExec) @@ -2015,9 +2018,9 @@ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden) FN_LOCAL_BOOL(lp_map_archive, bMap_archive) FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes) FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport) -FN_LOCAL_BOOL(lp_locking, bLocking) -FN_LOCAL_INTEGER(lp_strict_locking, iStrictLocking) -FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking) +FN_LOCAL_PARM_BOOL(lp_locking, bLocking) +FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking) +FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking) FN_LOCAL_BOOL(lp_share_modes, bShareModes) FN_LOCAL_BOOL(lp_oplocks, bOpLocks) FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks) @@ -3009,7 +3012,9 @@ BOOL lp_file_list_changed(void) time_t mod_time; pstrcpy(n2, f->name); - standard_sub_basic( get_current_username(), n2, sizeof(n2) ); + standard_sub_basic( get_current_username(), + current_user_info.domain, + n2, sizeof(n2) ); DEBUGADD(6, ("file %s -> %s last mod_time: %s\n", f->name, n2, ctime(&f->modtime))); @@ -3043,7 +3048,8 @@ static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr) pstrcpy(netbios_name, pszParmValue); - standard_sub_basic(get_current_username(), netbios_name,sizeof(netbios_name)); + standard_sub_basic(get_current_username(), current_user_info.domain, + netbios_name, sizeof(netbios_name)); ret = set_global_myname(netbios_name); string_set(&Globals.szNetbiosName,global_myname()); @@ -3101,7 +3107,8 @@ static BOOL handle_include(int snum, const char *pszParmValue, char **ptr) pstring fname; pstrcpy(fname, pszParmValue); - standard_sub_basic(get_current_username(), fname,sizeof(fname)); + standard_sub_basic(get_current_username(), current_user_info.domain, + fname,sizeof(fname)); add_to_file_list(pszParmValue, fname); @@ -3859,7 +3866,6 @@ static void dump_a_service(service * pService, FILE * f) BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal) { - service * pService = ServicePtrs[snum]; int i; BOOL result = False; parm_class p_class; @@ -3902,11 +3908,13 @@ BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal) { void *ptr; - if (isGlobal) + if (isGlobal) { ptr = parm_table[i].ptr; - else + } else { + service * pService = ServicePtrs[snum]; ptr = ((char *)pService) + PTR_DIFF(parm_table[i].ptr, &sDefault); + } print_parameter(&parm_table[i], ptr, f); @@ -4194,7 +4202,8 @@ static void set_server_role(void) case SEC_SERVER: if (lp_domain_logons()) DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n")); - server_role = ROLE_DOMAIN_MEMBER; + /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */ + server_role = ROLE_STANDALONE; break; case SEC_DOMAIN: if (lp_domain_logons()) { @@ -4562,7 +4571,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i /* Should we allow printers to be shared... ? */ ctx = talloc_init("usershare_sd_xctx"); if (!ctx) { - SAFE_FREE(lines); + file_lines_free(lines); return 1; } @@ -4570,11 +4579,11 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i iService, lines, numlines, sharepath, comment, &psd, &guest_ok) != USERSHARE_OK) { talloc_destroy(ctx); - SAFE_FREE(lines); + file_lines_free(lines); return -1; } - SAFE_FREE(lines); + file_lines_free(lines); /* Everything ok - add the service possibly using a template. */ if (iService < 0) { @@ -4595,7 +4604,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i } /* Write the ACL of the new/modified share. */ - if (!set_share_security(ctx, service_name, psd)) { + if (!set_share_security(service_name, psd)) { DEBUG(0, ("process_usershare_file: Failed to set share " "security for user share %s\n", service_name )); @@ -4868,7 +4877,7 @@ int load_usershare_shares(void) /* Remove from the share ACL db. */ DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n", lp_servicename(iService) )); - delete_share_security(iService); + delete_share_security(snum2params_static(iService)); free_service_byindex(iService); } } @@ -4943,7 +4952,8 @@ BOOL lp_load(const char *pszFname, pstrcpy(n2, pszFname); - standard_sub_basic( get_current_username(), n2,sizeof(n2) ); + standard_sub_basic( get_current_username(), current_user_info.domain, + n2,sizeof(n2) ); add_to_file_list(pszFname, n2); @@ -5087,7 +5097,9 @@ int lp_servicenumber(const char *pszServiceName) * service names */ fstrcpy(serviceName, ServicePtrs[iService]->szService); - standard_sub_basic(get_current_username(), serviceName,sizeof(serviceName)); + standard_sub_basic(get_current_username(), + current_user_info.domain, + serviceName,sizeof(serviceName)); if (strequal(serviceName, pszServiceName)) { break; } @@ -5099,7 +5111,7 @@ int lp_servicenumber(const char *pszServiceName) if (!usershare_exists(iService, &last_mod)) { /* Remove the share security tdb entry for it. */ - delete_share_security(iService); + delete_share_security(snum2params_static(iService)); /* Remove it from the array. */ free_service_byindex(iService); /* Doesn't exist anymore. */ @@ -5123,6 +5135,98 @@ int lp_servicenumber(const char *pszServiceName) return (iService); } +BOOL share_defined(const char *service_name) +{ + return (lp_servicenumber(service_name) != -1); +} + +struct share_params *get_share_params(TALLOC_CTX *mem_ctx, + const char *sharename) +{ + struct share_params *result; + char *sname; + int snum; + + if (!(sname = SMB_STRDUP(sharename))) { + return NULL; + } + + snum = find_service(sname); + SAFE_FREE(sname); + + if (snum < 0) { + return NULL; + } + + if (!(result = TALLOC_P(mem_ctx, struct share_params))) { + DEBUG(0, ("talloc failed\n")); + return NULL; + } + + result->service = snum; + return result; +} + +struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx) +{ + struct share_iterator *result; + + if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) { + DEBUG(0, ("talloc failed\n")); + return NULL; + } + + result->next_id = 0; + return result; +} + +struct share_params *next_share(struct share_iterator *list) +{ + struct share_params *result; + + while (!lp_snum_ok(list->next_id) && + (list->next_id < lp_numservices())) { + list->next_id += 1; + } + + if (list->next_id >= lp_numservices()) { + return NULL; + } + + if (!(result = TALLOC_P(list, struct share_params))) { + DEBUG(0, ("talloc failed\n")); + return NULL; + } + + result->service = list->next_id; + list->next_id += 1; + return result; +} + +struct share_params *next_printer(struct share_iterator *list) +{ + struct share_params *result; + + while ((result = next_share(list)) != NULL) { + if (lp_print_ok(result->service)) { + break; + } + } + return result; +} + +/* + * This is a hack for a transition period until we transformed all code from + * service numbers to struct share_params. + */ + +struct share_params *snum2params_static(int snum) +{ + static struct share_params result; + result.service = snum; + return &result; +} + /******************************************************************* A useful volume label function. ********************************************************************/ diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c index 444262a59d7..4bdceec5717 100644 --- a/source/passdb/passdb.c +++ b/source/passdb/passdb.c @@ -930,14 +930,15 @@ BOOL init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen) if (homedir) { fstrcpy( tmpstring, homedir ); if (expand_explicit) { - standard_sub_basic( username, tmpstring, + standard_sub_basic( username, domain, tmpstring, sizeof(tmpstring) ); } pdb_set_homedir(sampass, tmpstring, PDB_SET); } else { pdb_set_homedir(sampass, - talloc_sub_basic(sampass, username, lp_logon_home()), + talloc_sub_basic(sampass, username, domain, + lp_logon_home()), PDB_DEFAULT); } @@ -949,28 +950,29 @@ BOOL init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen) if (logon_script) { fstrcpy( tmpstring, logon_script ); if (expand_explicit) { - standard_sub_basic( username, tmpstring, + standard_sub_basic( username, domain, tmpstring, sizeof(tmpstring) ); } pdb_set_logon_script(sampass, tmpstring, PDB_SET); } else { pdb_set_logon_script(sampass, - talloc_sub_basic(sampass, username, lp_logon_script()), + talloc_sub_basic(sampass, username, domain, + lp_logon_script()), PDB_DEFAULT); } if (profile_path) { fstrcpy( tmpstring, profile_path ); if (expand_explicit) { - standard_sub_basic( username, tmpstring, + standard_sub_basic( username, domain, tmpstring, sizeof(tmpstring) ); } pdb_set_profile_path(sampass, tmpstring, PDB_SET); } else { pdb_set_profile_path(sampass, - talloc_sub_basic(sampass, username, lp_logon_path()), + talloc_sub_basic(sampass, username, domain, lp_logon_path()), PDB_DEFAULT); } diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c index c0b78cde5e5..f1c17100286 100644 --- a/source/passdb/pdb_ldap.c +++ b/source/passdb/pdb_ldap.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. LDAP protocol helper functions for SAMBA - Copyright (C) Jean François Micouleau 1998 + Copyright (C) Jean François Micouleau 1998 Copyright (C) Gerald Carter 2001-2003 Copyright (C) Shahms King 2001 Copyright (C) Andrew Bartlett 2002-2003 @@ -650,12 +650,13 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir)) { pdb_set_homedir( sampass, - talloc_sub_basic(sampass, username, lp_logon_home()), + talloc_sub_basic(sampass, username, domain, + lp_logon_home()), PDB_DEFAULT ); } else { pstrcpy( tmpstring, homedir ); if (expand_explicit) { - standard_sub_basic( username, tmpstring, + standard_sub_basic( username, domain, tmpstring, sizeof(tmpstring) ); } pdb_set_homedir(sampass, tmpstring, PDB_SET); @@ -665,12 +666,13 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script)) { pdb_set_logon_script( sampass, - talloc_sub_basic(sampass, username, lp_logon_script()), + talloc_sub_basic(sampass, username, domain, + lp_logon_script()), PDB_DEFAULT ); } else { pstrcpy( tmpstring, logon_script ); if (expand_explicit) { - standard_sub_basic( username, tmpstring, + standard_sub_basic( username, domain, tmpstring, sizeof(tmpstring) ); } pdb_set_logon_script(sampass, tmpstring, PDB_SET); @@ -680,12 +682,13 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path)) { pdb_set_profile_path( sampass, - talloc_sub_basic( sampass, username, lp_logon_path()), + talloc_sub_basic( sampass, username, domain, + lp_logon_path()), PDB_DEFAULT ); } else { pstrcpy( tmpstring, profile_path ); if (expand_explicit) { - standard_sub_basic( username, tmpstring, + standard_sub_basic( username, domain, tmpstring, sizeof(tmpstring) ); } pdb_set_profile_path(sampass, tmpstring, PDB_SET); diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c index 873850bfa97..e9beaa05368 100644 --- a/source/passdb/pdb_tdb.c +++ b/source/passdb/pdb_tdb.c @@ -169,7 +169,8 @@ static BOOL init_sam_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buf } else { pdb_set_homedir(sampass, - talloc_sub_basic(sampass, username, lp_logon_home()), + talloc_sub_basic(sampass, username, domain, + lp_logon_home()), PDB_DEFAULT); } @@ -177,7 +178,8 @@ static BOOL init_sam_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buf pdb_set_dir_drive(sampass, dir_drive, PDB_SET); else { pdb_set_dir_drive(sampass, - talloc_sub_basic(sampass, username, lp_logon_drive()), + talloc_sub_basic(sampass, username, domain, + lp_logon_drive()), PDB_DEFAULT); } @@ -185,7 +187,8 @@ static BOOL init_sam_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buf pdb_set_logon_script(sampass, logon_script, PDB_SET); else { pdb_set_logon_script(sampass, - talloc_sub_basic(sampass, username, lp_logon_script()), + talloc_sub_basic(sampass, username, domain, + lp_logon_script()), PDB_DEFAULT); } @@ -193,7 +196,8 @@ static BOOL init_sam_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buf pdb_set_profile_path(sampass, profile_path, PDB_SET); } else { pdb_set_profile_path(sampass, - talloc_sub_basic(sampass, username, lp_logon_path()), + talloc_sub_basic(sampass, username, domain, + lp_logon_path()), PDB_DEFAULT); } @@ -356,7 +360,8 @@ static BOOL init_sam_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buf } else { pdb_set_homedir(sampass, - talloc_sub_basic(sampass, username, lp_logon_home()), + talloc_sub_basic(sampass, username, domain, + lp_logon_home()), PDB_DEFAULT); } @@ -364,7 +369,8 @@ static BOOL init_sam_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buf pdb_set_dir_drive(sampass, dir_drive, PDB_SET); else { pdb_set_dir_drive(sampass, - talloc_sub_basic(sampass, username, lp_logon_drive()), + talloc_sub_basic(sampass, username, domain, + lp_logon_drive()), PDB_DEFAULT); } @@ -372,7 +378,8 @@ static BOOL init_sam_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buf pdb_set_logon_script(sampass, logon_script, PDB_SET); else { pdb_set_logon_script(sampass, - talloc_sub_basic(sampass, username, lp_logon_script()), + talloc_sub_basic(sampass, username, domain, + lp_logon_script()), PDB_DEFAULT); } @@ -380,7 +387,8 @@ static BOOL init_sam_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buf pdb_set_profile_path(sampass, profile_path, PDB_SET); } else { pdb_set_profile_path(sampass, - talloc_sub_basic(sampass, username, lp_logon_path()), + talloc_sub_basic(sampass, username, domain, + lp_logon_path()), PDB_DEFAULT); } @@ -541,14 +549,15 @@ BOOL init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen) if (homedir) { fstrcpy( tmpstring, homedir ); if (expand_explicit) { - standard_sub_basic( username, tmpstring, + standard_sub_basic( username, domain, tmpstring, sizeof(tmpstring) ); } pdb_set_homedir(sampass, tmpstring, PDB_SET); } else { pdb_set_homedir(sampass, - talloc_sub_basic(sampass, username, lp_logon_home()), + talloc_sub_basic(sampass, username, domain, + lp_logon_home()), PDB_DEFAULT); } @@ -560,28 +569,30 @@ BOOL init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen) if (logon_script) { fstrcpy( tmpstring, logon_script ); if (expand_explicit) { - standard_sub_basic( username, tmpstring, + standard_sub_basic( username, domain, tmpstring, sizeof(tmpstring) ); } pdb_set_logon_script(sampass, tmpstring, PDB_SET); } else { pdb_set_logon_script(sampass, - talloc_sub_basic(sampass, username, lp_logon_script()), + talloc_sub_basic(sampass, username, domain, + lp_logon_script()), PDB_DEFAULT); } if (profile_path) { fstrcpy( tmpstring, profile_path ); if (expand_explicit) { - standard_sub_basic( username, tmpstring, + standard_sub_basic( username, domain, tmpstring, sizeof(tmpstring) ); } pdb_set_profile_path(sampass, tmpstring, PDB_SET); } else { pdb_set_profile_path(sampass, - talloc_sub_basic(sampass, username, lp_logon_path()), + talloc_sub_basic(sampass, username, domain, + lp_logon_path()), PDB_DEFAULT); } diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c index 427ed37229e..b74763b2e5e 100644 --- a/source/printing/nt_printing.c +++ b/source/printing/nt_printing.c @@ -1035,7 +1035,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 char *buf = NULL; ssize_t byte_count; - if ((buf=SMB_MALLOC(PE_HEADER_SIZE)) == NULL) { + if ((buf=(char *)SMB_MALLOC(PE_HEADER_SIZE)) == NULL) { DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n", fname, PE_HEADER_SIZE)); goto error_exit; @@ -1091,7 +1091,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 goto error_exit; SAFE_FREE(buf); - if ((buf=SMB_MALLOC(section_table_bytes)) == NULL) { + if ((buf=(char *)SMB_MALLOC(section_table_bytes)) == NULL) { DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n", fname, section_table_bytes)); goto error_exit; @@ -1281,6 +1281,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr SMB_STRUCT_STAT stat_buf; BOOL bad_path; + NTSTATUS status; + SET_STAT_INVALID(st); SET_STAT_INVALID(stat_buf); new_create_time = (time_t)0; @@ -1291,16 +1293,16 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf); - fsp = open_file_ntcreate(conn, filepath, &stat_buf, + status = open_file_ntcreate(conn, filepath, &stat_buf, FILE_GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - NULL); + NULL, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { /* Old file not found, so by definition new file is in fact newer */ DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n", filepath, errno)); @@ -1327,16 +1329,16 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr pstrcpy(filepath, new_file); driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf); - fsp = open_file_ntcreate(conn, filepath, &stat_buf, + status = open_file_ntcreate(conn, filepath, &stat_buf, FILE_GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - NULL); + NULL, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { /* New file not found, this shouldn't occur if the caller did its job */ DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n", filepath, errno)); @@ -1405,6 +1407,7 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_ BOOL bad_path; SMB_STRUCT_STAT st; connection_struct *conn; + NTSTATUS status; SET_STAT_INVALID(st); @@ -1460,16 +1463,16 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_ goto error_exit; } - fsp = open_file_ntcreate(conn, driverpath, &st, + status = open_file_ntcreate(conn, driverpath, &st, FILE_GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - NULL); + NULL, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n", driverpath, errno)); *perr = WERR_ACCESS_DENIED; @@ -4368,7 +4371,8 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print fstrcpy( servername, print_hnd->servername ); else { fstrcpy( servername, "%L" ); - standard_sub_basic( "", servername, sizeof(servername)-1 ); + standard_sub_basic( "", "", servername, + sizeof(servername)-1 ); } result = get_a_printer_2( (*pp_printer)->info_2, servername, sharename ); @@ -5441,7 +5445,7 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type) Check the time parameters allow a print operation. *****************************************************************************/ -BOOL print_time_access_check(int snum) +BOOL print_time_access_check(const char *servicename) { NT_PRINTER_INFO_LEVEL *printer = NULL; BOOL ok = False; @@ -5449,7 +5453,7 @@ BOOL print_time_access_check(int snum) struct tm *t; uint32 mins; - if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum)))) + if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename))) return False; if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0) diff --git a/source/printing/print_generic.c b/source/printing/print_generic.c index 1ea762695b1..aef4e50bfaa 100644 --- a/source/printing/print_generic.c +++ b/source/printing/print_generic.c @@ -30,7 +30,9 @@ for local substitution strings static int print_run_command(int snum, const char* printername, BOOL do_sub, const char *command, int *outfd, ...) { - + extern struct current_user current_user; + extern userdom_struct current_user_info; + pstring syscmd; char *arg; int ret; @@ -56,7 +58,12 @@ static int print_run_command(int snum, const char* printername, BOOL do_sub, pstring_sub( syscmd, "%p", printername ); if ( do_sub && snum != -1 ) - standard_sub_snum(snum,syscmd,sizeof(syscmd)); + standard_sub_advanced(lp_servicename(snum), + current_user_info.unix_name, "", + current_user.ut.gid, + get_current_username(), + current_user_info.domain, + syscmd, sizeof(syscmd)); ret = smbrun(syscmd,outfd); diff --git a/source/printing/print_test.c b/source/printing/print_test.c new file mode 100644 index 00000000000..d34bc2153a1 --- /dev/null +++ b/source/printing/print_test.c @@ -0,0 +1,81 @@ +/* + * Printing backend for the build farm + * + * Copyright (C) Volker Lendecke 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" +#include "printing.h" + +#if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS) + +static int test_queue_get(const char *printer_name, + enum printing_types printing_type, + char *lpq_command, + print_queue_struct **q, + print_status_struct *status) +{ + return -1; +} + +static int test_queue_pause(int snum) +{ + return -1; +} + +static int test_queue_resume(int snum) +{ + return -1; +} + +static int test_job_delete(const char *sharename, const char *lprm_command, + struct printjob *pjob) +{ + return -1; +} + +static int test_job_pause(int snum, struct printjob *pjob) +{ + return -1; +} + +static int test_job_resume(int snum, struct printjob *pjob) +{ + return -1; +} + +static int test_job_submit(int snum, struct printjob *pjob) +{ + return -1; +}; + +struct printif test_printif = +{ + PRINT_TEST, + test_queue_get, + test_queue_pause, + test_queue_resume, + test_job_delete, + test_job_pause, + test_job_resume, + test_job_submit, +}; + +#else + /* this keeps fussy compilers happy */ + void print_test_dummy(void) {} +#endif /* DEVELOPER||ENABLE_BUILD_FARM_HACKS */ diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c index c248851822b..5278c60f992 100644 --- a/source/printing/printfsp.c +++ b/source/printing/printfsp.c @@ -28,15 +28,19 @@ open a print file and setup a fsp for it. This is a wrapper around print_job_start(). ***************************************************************************/ -files_struct *print_fsp_open(connection_struct *conn, const char *fname) +NTSTATUS print_fsp_open(connection_struct *conn, const char *fname, + files_struct **result) { int jobid; SMB_STRUCT_STAT sbuf; - files_struct *fsp = file_new(conn); + files_struct *fsp; fstring name; + NTSTATUS status; - if(!fsp) - return NULL; + status = file_new(conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + return status; + } fstrcpy( name, "Remote Downlevel Document"); if (fname) { @@ -50,8 +54,9 @@ files_struct *print_fsp_open(connection_struct *conn, const char *fname) jobid = print_job_start(¤t_user, SNUM(conn), name, NULL); if (jobid == -1) { + status = map_nt_error_from_unix(errno); file_free(fsp); - return NULL; + return status; } /* Convert to RAP id. */ @@ -60,7 +65,7 @@ files_struct *print_fsp_open(connection_struct *conn, const char *fname) /* We need to delete the entry in the tdb. */ pjob_delete(lp_const_servicename(SNUM(conn)), jobid); file_free(fsp); - return NULL; + return NT_STATUS_ACCESS_DENIED; /* No errno around here */ } /* setup a full fsp */ @@ -87,7 +92,8 @@ files_struct *print_fsp_open(connection_struct *conn, const char *fname) conn->num_files_open++; - return fsp; + *result = fsp; + return NT_STATUS_OK; } /**************************************************************************** diff --git a/source/printing/printing.c b/source/printing/printing.c index 9dd6bec0be4..0d9ae02545a 100644 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -271,7 +271,7 @@ static TDB_DATA print_key(uint32 jobid) TDB_DATA ret; SIVAL(&j, 0, jobid); - ret.dptr = (void *)&j; + ret.dptr = (char *)&j; ret.dsize = sizeof(j); return ret; } @@ -839,10 +839,9 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void Check if the print queue has been updated recently enough. ****************************************************************************/ -static void print_cache_flush(int snum) +static void print_cache_flush(const char *sharename) { fstring key; - const char *sharename = lp_const_servicename(snum); struct tdb_print_db *pdb = get_print_db_byname(sharename); if (!pdb) @@ -918,7 +917,7 @@ static void set_updating_pid(const fstring sharename, BOOL updating) } SIVAL( buffer, 0, updating_pid); - data.dptr = (void *)buffer; + data.dptr = (char *)buffer; data.dsize = 4; /* we always assume this is a 4 byte value */ tdb_store(pdb->tdb, key, data, TDB_REPLACE); @@ -985,7 +984,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct queue[i].fs_file); } - if ((data.dptr = SMB_MALLOC(data.dsize)) == NULL) + if ((data.dptr = (char *)SMB_MALLOC(data.dsize)) == NULL) return; len = 0; @@ -1236,7 +1235,7 @@ static void print_queue_update_internal( const char *sharename, key.dsize = strlen(keystr); status.qcount = qcount; - data.dptr = (void *)&status; + data.dptr = (char *)&status; data.dsize = sizeof(status); tdb_store(pdb->tdb, key, data, TDB_REPLACE); @@ -1358,7 +1357,7 @@ static void print_queue_receive(int msg_type, struct process_id src, int printing_type; size_t len; - len = tdb_unpack( buf, msglen, "fdPP", + len = tdb_unpack( (char *)buf, msglen, "fdPP", sharename, &printing_type, lpqcommand, @@ -1439,6 +1438,8 @@ update the internal database from the system print queue for a queue static void print_queue_update(int snum, BOOL force) { + extern struct current_user current_user; + extern userdom_struct current_user_info; fstring key; fstring sharename; pstring lpqcommand, lprmcommand; @@ -1456,12 +1457,22 @@ static void print_queue_update(int snum, BOOL force) pstrcpy( lpqcommand, lp_lpqcommand(snum)); string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), False, False, False ); - standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) ); + standard_sub_advanced(lp_servicename(snum), + current_user_info.unix_name, "", + current_user.ut.gid, + get_current_username(), + current_user_info.domain, + lpqcommand, sizeof(lpqcommand) ); pstrcpy( lprmcommand, lp_lprmcommand(snum)); string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), False, False, False ); - standard_sub_snum( snum, lprmcommand, sizeof(lprmcommand) ); + standard_sub_advanced(lp_servicename(snum), + current_user_info.unix_name, "", + current_user.ut.gid, + get_current_username(), + current_user_info.domain, + lprmcommand, sizeof(lprmcommand) ); /* * Make sure that the background queue process exists. @@ -1524,10 +1535,8 @@ static void print_queue_update(int snum, BOOL force) /* finally send the message */ - become_root(); message_send_pid(pid_to_procid(background_lpq_updater_pid), MSG_PRINTER_UPDATE, buffer, len, False); - unbecome_root(); SAFE_FREE( buffer ); @@ -1596,7 +1605,7 @@ BOOL print_notify_register_pid(int snum) if (i == data.dsize) { /* We weren't in the list. Realloc. */ - data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8); + data.dptr = (char *)SMB_REALLOC(data.dptr, data.dsize + 8); if (!data.dptr) { DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n", printername)); @@ -1781,7 +1790,7 @@ NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid) Set the place in the queue for a job. ****************************************************************************/ -BOOL print_job_set_place(int snum, uint32 jobid, int place) +BOOL print_job_set_place(const char *sharename, uint32 jobid, int place) { DEBUG(2,("print_job_set_place not implemented yet\n")); return False; @@ -1791,9 +1800,8 @@ BOOL print_job_set_place(int snum, uint32 jobid, int place) Set the name of a job. Only possible for owner. ****************************************************************************/ -BOOL print_job_set_name(int snum, uint32 jobid, char *name) +BOOL print_job_set_name(const char *sharename, uint32 jobid, char *name) { - const char* sharename = lp_const_servicename(snum); struct printjob *pjob; pjob = print_job_find(sharename, jobid); @@ -1930,9 +1938,10 @@ static BOOL print_job_delete1(int snum, uint32 jobid) Return true if the current user owns the print job. ****************************************************************************/ -static BOOL is_owner(struct current_user *user, int snum, uint32 jobid) +static BOOL is_owner(struct current_user *user, const char *servicename, + uint32 jobid) { - struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid); + struct printjob *pjob = print_job_find(servicename, jobid); user_struct *vuser; if (!pjob || !user) @@ -1958,7 +1967,7 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode = WERR_OK; - owner = is_owner(user, snum, jobid); + owner = is_owner(user, lp_const_servicename(snum), jobid); /* Check access against security descriptor or whether the user owns their job. */ @@ -2037,7 +2046,7 @@ BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR * return False; } - if (!is_owner(user, snum, jobid) && + if (!is_owner(user, lp_const_servicename(snum), jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); @@ -2061,7 +2070,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", } /* force update the database */ - print_cache_flush(snum); + print_cache_flush(lp_const_servicename(snum)); /* Send a printer notify message */ @@ -2097,7 +2106,7 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR return False; } - if (!is_owner(user, snum, jobid) && + if (!is_owner(user, lp_const_servicename(snum), jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); *errcode = WERR_ACCESS_DENIED; @@ -2119,7 +2128,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", } /* force update the database */ - print_cache_flush(snum); + print_cache_flush(lp_const_servicename(snum)); /* Send a printer notify message */ @@ -2325,7 +2334,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE return (uint32)-1; } - if (!print_time_access_check(snum)) { + if (!print_time_access_check(lp_servicename(snum))) { DEBUG(3, ("print_job_start: job start denied by time check\n")); release_print_db(pdb); return (uint32)-1; @@ -2739,7 +2748,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) } /* force update the database */ - print_cache_flush(snum); + print_cache_flush(lp_const_servicename(snum)); /* Send a printer notify message */ @@ -2805,7 +2814,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) become_root(); for (i=0;i<njobs;i++) { - BOOL owner = is_owner(user, snum, queue[i].job); + BOOL owner = is_owner(user, lp_const_servicename(snum), queue[i].job); if (owner || can_job_admin) { print_job_delete1(snum, queue[i].job); diff --git a/source/python/py_smb.c b/source/python/py_smb.c index 679c113f397..2f5d1161d87 100644 --- a/source/python/py_smb.c +++ b/source/python/py_smb.c @@ -43,7 +43,7 @@ static PyObject *py_smb_connect(PyObject *self, PyObject *args, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &server)) return NULL; - if (!(cli = cli_initialise(NULL))) + if (!(cli = cli_initialise())) return NULL; ZERO_STRUCT(ip); @@ -99,7 +99,7 @@ static PyObject *py_smb_session_setup(PyObject *self, PyObject *args, static char *kwlist[] = { "creds", NULL }; PyObject *creds; char *username, *domain, *password, *errstr; - BOOL result; + NTSTATUS result; if (!PyArg_ParseTupleAndKeywords(args, kw, "|O", kwlist, &creds)) return NULL; @@ -118,7 +118,7 @@ static PyObject *py_smb_session_setup(PyObject *self, PyObject *args, return NULL; } - return Py_BuildValue("i", result); + return Py_BuildValue("i", NT_STATUS_IS_OK(result)); } static PyObject *py_smb_tconx(PyObject *self, PyObject *args, PyObject *kw) diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c index 9cce7159674..e2562506975 100644 --- a/source/rpc_server/srv_srvsvc_nt.c +++ b/source/rpc_server/srv_srvsvc_nt.c @@ -137,43 +137,6 @@ static void map_generic_share_sd_bits(SEC_DESC *psd) } /******************************************************************* - Can this user access with share with the required permissions ? -********************************************************************/ - -BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access) -{ - uint32 granted; - NTSTATUS status; - TALLOC_CTX *mem_ctx = NULL; - SEC_DESC *psd = NULL; - size_t sd_size; - NT_USER_TOKEN *token = NULL; - BOOL ret = True; - - mem_ctx = talloc_init("share_access_check"); - if (mem_ctx == NULL) - return False; - - psd = get_share_security(mem_ctx, snum, &sd_size); - - if (!psd) - goto out; - - if (conn->nt_user_token) - token = conn->nt_user_token; - else - token = vuser->nt_user_token; - - ret = se_access_check(psd, token, desired_access, &granted, &status); - -out: - - talloc_destroy(mem_ctx); - - return ret; -} - -/******************************************************************* Fill in a share info level 501 structure. ********************************************************************/ diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c index 934857c2c09..f489a8e96b2 100644 --- a/source/smbd/blocking.c +++ b/source/smbd/blocking.c @@ -19,6 +19,8 @@ */ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_LOCKING /**************************************************************************** This is the structure to queue to implement blocking locks. @@ -30,26 +32,29 @@ typedef struct _blocking_lock_record { struct _blocking_lock_record *prev; int com_type; files_struct *fsp; - time_t expire_time; + struct timeval expire_time; int lock_num; SMB_BIG_UINT offset; SMB_BIG_UINT count; - uint16 lock_pid; + uint32 lock_pid; enum brl_flavour lock_flav; enum brl_type lock_type; char *inbuf; int length; } blocking_lock_record; +/* dlink list we store pending lock records on. */ static blocking_lock_record *blocking_lock_queue; +/* dlink list we move cancelled lock records onto. */ +static blocking_lock_record *blocking_lock_cancelled_queue; + /**************************************************************************** Destructor for the above structure. ****************************************************************************/ static void free_blocking_lock_record(blocking_lock_record *blr) { - DLIST_REMOVE(blocking_lock_queue, blr); SAFE_FREE(blr->inbuf); SAFE_FREE(blr); } @@ -70,19 +75,18 @@ static void received_unlock_msg(int msg_type, struct process_id src, Function to push a blocking lock request onto the lock queue. ****************************************************************************/ -BOOL push_blocking_lock_request( char *inbuf, int length, +BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, + char *inbuf, int length, files_struct *fsp, int lock_timeout, int lock_num, - uint16 lock_pid, + uint32 lock_pid, enum brl_type lock_type, enum brl_flavour lock_flav, SMB_BIG_UINT offset, SMB_BIG_UINT count) { static BOOL set_lock_msg; blocking_lock_record *blr; - BOOL my_lock_ctx = False; - struct byte_range_lock *br_lck = NULL; NTSTATUS status; if(in_chained_smb() ) { @@ -111,7 +115,13 @@ BOOL push_blocking_lock_request( char *inbuf, int length, blr->com_type = CVAL(inbuf,smb_com); blr->fsp = fsp; - blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; + if (lock_timeout == -1) { + blr->expire_time.tv_sec = 0; + blr->expire_time.tv_usec = 0; /* Never expire. */ + } else { + blr->expire_time = timeval_current_ofs(lock_timeout/1000, + (lock_timeout % 1000) * 1000); + } blr->lock_num = lock_num; blr->lock_pid = lock_pid; blr->lock_flav = lock_flav; @@ -121,25 +131,19 @@ BOOL push_blocking_lock_request( char *inbuf, int length, memcpy(blr->inbuf, inbuf, length); blr->length = length; - br_lck = brl_get_locks(blr->fsp); - if (!br_lck) { - free_blocking_lock_record(blr); - return False; - } - /* Add a pending lock record for this. */ status = brl_lock(br_lck, lock_pid, procid_self(), offset, count, - PENDING_LOCK, + lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK, blr->lock_flav, - &my_lock_ctx); - byte_range_lock_destructor(br_lck); + lock_timeout ? True : False); /* blocking_lock. */ if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); return False; } @@ -152,8 +156,10 @@ BOOL push_blocking_lock_request( char *inbuf, int length, set_lock_msg = True; } - DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \ -for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout, + DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with " + "expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n", + length, (unsigned int)blr->expire_time.tv_sec, + (unsigned int)blr->expire_time.tv_usec, lock_timeout, blr->fsp->fnum, blr->fsp->fsp_name )); /* Push the MID of this packet on the signing queue. */ @@ -220,9 +226,24 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat status = NT_STATUS_FILE_LOCK_CONFLICT; } + if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { + /* Store the last lock error. */ + files_struct *fsp = blr->fsp; + + fsp->last_lock_failure.context.smbpid = blr->lock_pid; + fsp->last_lock_failure.context.tid = fsp->conn->cnum; + fsp->last_lock_failure.context.pid = procid_self(); + fsp->last_lock_failure.start = blr->offset; + fsp->last_lock_failure.size = blr->count; + fsp->last_lock_failure.fnum = fsp->fnum; + fsp->last_lock_failure.lock_type = READ_LOCK; /* Don't care. */ + fsp->last_lock_failure.lock_flav = blr->lock_flav; + } + ERROR_NT(status); - if (!send_smb(smbd_server_fd(),outbuf)) + if (!send_smb(smbd_server_fd(),outbuf)) { exit_server("generic_blocking_lock_error: send_smb failed."); + } } /**************************************************************************** @@ -236,7 +257,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) files_struct *fsp = blr->fsp; uint16 num_ulocks = SVAL(inbuf,smb_vwv6); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; - uint16 lock_pid; + uint32 lock_pid; unsigned char locktype = CVAL(inbuf,smb_vwv3); BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; @@ -284,13 +305,6 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status) { switch(blr->com_type) { -#if 0 - /* We no longer push blocking lock requests for anything but lockingX and trans2. */ - case SMBlock: - case SMBlockread: - generic_blocking_lock_error(blr, status); - break; -#endif case SMBlockingX: reply_lockingX_error(blr, status); break; @@ -316,148 +330,6 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status } } -#if 0 -/* We no longer push blocking lock requests for anything but lockingX and trans2. */ - -/**************************************************************************** - Attempt to finish off getting all pending blocking locks for a lockread call. - Returns True if we want to be removed from the list. -*****************************************************************************/ - -static BOOL process_lockread(blocking_lock_record *blr) -{ - char *outbuf = get_OutBuffer(); - char *inbuf = blr->inbuf; - ssize_t nread = -1; - char *data, *p; - int outsize = 0; - SMB_BIG_UINT startpos; - size_t numtoread; - NTSTATUS status; - files_struct *fsp = blr->fsp; - BOOL my_lock_ctx = False; - - numtoread = SVAL(inbuf,smb_vwv1); - startpos = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv2); - - numtoread = MIN(BUFFER_SIZE-outsize,numtoread); - data = smb_buf(outbuf) + 3; - - status = do_lock_spin(fsp, - SVAL(inbuf,smb_pid), - (SMB_BIG_UINT)numtoread, - startpos, - READ_LOCK, - WINDOWS_LOCK, - &my_lock_ctx); - - if (NT_STATUS_V(status)) { - if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && - !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { - /* - * We have other than a "can't get lock" - * error. Send an error. - * Return True so we get dequeued. - */ - generic_blocking_lock_error(blr, status); - return True; - } - - /* - * Still waiting for lock.... - */ - - DEBUG(10,("process_lockread: failed to get lock for file = %s. Still waiting....\n", - fsp->fsp_name)); - return False; - } - - nread = read_file(fsp,data,startpos,numtoread); - - if (nread < 0) { - generic_blocking_lock_error(blr,NT_STATUS_ACCESS_DENIED); - return True; - } - - construct_reply_common(inbuf, outbuf); - outsize = set_message(outbuf,5,0,True); - - outsize += nread; - SSVAL(outbuf,smb_vwv0,nread); - SSVAL(outbuf,smb_vwv5,nread+3); - p = smb_buf(outbuf); - *p++ = 1; - SSVAL(p,0,nread); p += 2; - set_message_end(outbuf, p+nread); - - DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%lu nread=%ld\n", - fsp->fsp_name, fsp->fnum, (unsigned long)numtoread, (long)nread ) ); - - send_blocking_reply(outbuf,outsize); - return True; -} - -/**************************************************************************** - Attempt to finish off getting all pending blocking locks for a lock call. - Returns True if we want to be removed from the list. -*****************************************************************************/ - -static BOOL process_lock(blocking_lock_record *blr) -{ - char *outbuf = get_OutBuffer(); - char *inbuf = blr->inbuf; - int outsize; - SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; - NTSTATUS status; - files_struct *fsp = blr->fsp; - BOOL my_lock_ctx = False; - - count = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1); - offset = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3); - - errno = 0; - status = do_lock_spin(fsp, - SVAL(inbuf,smb_pid), - count, - offset, - WRITE_LOCK, - WINDOWS_LOCK, - &my_lock_ctx); - - if (NT_STATUS_IS_ERR(status)) { - if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && - !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { - /* - * We have other than a "can't get lock" - * error. Send an error. - * Return True so we get dequeued. - */ - - blocking_lock_reply_error(blr, status); - return True; - } - /* - * Still can't get the lock - keep waiting. - */ - DEBUG(10,("process_lock: failed to get lock for file = %s. Still waiting....\n", - fsp->fsp_name)); - return False; - } - - /* - * Success - we got the lock. - */ - - DEBUG(3,("process_lock : file=%s fnum=%d offset=%.0f count=%.0f\n", - fsp->fsp_name, fsp->fnum, (double)offset, (double)count)); - - construct_reply_common(inbuf, outbuf); - outsize = set_message(outbuf,0,0,True); - send_blocking_reply(outbuf,outsize); - return True; -} -#endif - /**************************************************************************** Attempt to finish off getting all pending blocking locks for a lockingX call. Returns True if we want to be removed from the list. @@ -471,10 +343,9 @@ static BOOL process_lockingX(blocking_lock_record *blr) uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; - uint16 lock_pid; + uint32 lock_pid; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; - BOOL my_lock_ctx = False; NTSTATUS status = NT_STATUS_OK; data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); @@ -483,8 +354,9 @@ static BOOL process_lockingX(blocking_lock_record *blr) * Data now points at the beginning of the list * of smb_lkrng structs. */ - + for(; blr->lock_num < num_locks; blr->lock_num++) { + struct byte_range_lock *br_lck = NULL; BOOL err; lock_pid = get_lock_pid( data, blr->lock_num, large_file_format); @@ -496,13 +368,17 @@ static BOOL process_lockingX(blocking_lock_record *blr) * request would never have been queued. JRA. */ errno = 0; - status = do_lock_spin(fsp, + br_lck = do_lock(fsp, lock_pid, count, offset, - ((locktype & 1) ? READ_LOCK : WRITE_LOCK), + ((locktype & LOCKING_ANDX_SHARED_LOCK) ? + READ_LOCK : WRITE_LOCK), WINDOWS_LOCK, - &my_lock_ctx); + True, + &status); + + TALLOC_FREE(br_lck); if (NT_STATUS_IS_ERR(status)) { break; @@ -552,17 +428,17 @@ static BOOL process_trans2(blocking_lock_record *blr) extern int max_send; char *inbuf = blr->inbuf; char *outbuf; - BOOL my_lock_ctx = False; char params[2]; NTSTATUS status; - - status = do_lock(blr->fsp, - blr->lock_pid, - blr->count, - blr->offset, - blr->lock_type, - blr->lock_flav, - &my_lock_ctx); + struct byte_range_lock *br_lck = do_lock(blr->fsp, + blr->lock_pid, + blr->count, + blr->offset, + blr->lock_type, + blr->lock_flav, + True, + &status); + TALLOC_FREE(br_lck); if (!NT_STATUS_IS_OK(status)) { if (ERROR_WAS_LOCK_DENIED(status)) { @@ -582,7 +458,8 @@ static BOOL process_trans2(blocking_lock_record *blr) construct_reply_common(inbuf, outbuf); SCVAL(outbuf,smb_com,SMBtrans2); SSVAL(params,0,0); - send_trans2_replies(outbuf, max_send, params, 2, NULL, 0); + /* Fake up max_data_bytes here - we know it fits. */ + send_trans2_replies(outbuf, max_send, params, 2, NULL, 0, 0xffff); return True; } @@ -595,13 +472,6 @@ static BOOL process_trans2(blocking_lock_record *blr) static BOOL blocking_lock_record_process(blocking_lock_record *blr) { switch(blr->com_type) { -#if 0 - /* We no longer push blocking lock requests for anything but lockingX and trans2. */ - case SMBlock: - return process_lock(blr); - case SMBlockread: - return process_lockread(blr); -#endif case SMBlockingX: return process_lockingX(blr); case SMBtrans2: @@ -615,33 +485,41 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) } /**************************************************************************** - Delete entries by fnum from the blocking lock pending queue. + Cancel entries by fnum from the blocking lock pending queue. *****************************************************************************/ -void remove_pending_lock_requests_by_fid(files_struct *fsp) +void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lock *br_lck) { blocking_lock_record *blr, *next = NULL; for(blr = blocking_lock_queue; blr; blr = next) { next = blr->next; if(blr->fsp->fnum == fsp->fnum) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + unsigned char locktype = 0; + + if (blr->com_type == SMBlockingX) { + locktype = CVAL(blr->inbuf,smb_vwv3); + } if (br_lck) { DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); - brl_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + blocking_lock_cancel(fsp, + blr->lock_pid, + blr->offset, + blr->count, + blr->lock_flav, + locktype, + NT_STATUS_RANGE_NOT_LOCKED); } - - free_blocking_lock_record(blr); } } } @@ -658,22 +536,23 @@ void remove_pending_lock_requests_by_mid(int mid) next = blr->next; if(SVAL(blr->inbuf,smb_mid) == mid) { files_struct *fsp = blr->fsp; - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (br_lck) { DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); - brl_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); } } @@ -687,44 +566,60 @@ static void received_unlock_msg(int msg_type, struct process_id src, void *buf, size_t len) { DEBUG(10,("received_unlock_msg\n")); - process_blocking_lock_queue(time(NULL)); + process_blocking_lock_queue(); } /**************************************************************************** - Return the number of seconds to the next blocking locks timeout, or default_timeout + Return the number of milliseconds to the next blocking locks timeout, or default_timeout *****************************************************************************/ -unsigned blocking_locks_timeout(unsigned default_timeout) +unsigned int blocking_locks_timeout_ms(unsigned int default_timeout_ms) { - unsigned timeout = default_timeout; - time_t t; + unsigned int timeout_ms = default_timeout_ms; + struct timeval tv_curr; + SMB_BIG_INT min_tv_dif_us = 0x7FFFFFFF; /* A large +ve number. */ blocking_lock_record *blr = blocking_lock_queue; - /* note that we avoid the time() syscall if there are no blocking locks */ - if (!blr) - return timeout; + /* note that we avoid the GetTimeOfDay() syscall if there are no blocking locks */ + if (!blr) { + return timeout_ms; + } - t = time(NULL); + tv_curr = timeval_current(); for (; blr; blr = blr->next) { - if ((blr->expire_time != (time_t)-1) && - (timeout > (blr->expire_time - t))) { - timeout = blr->expire_time - t; + SMB_BIG_INT tv_dif_us; + + if (timeval_is_zero(&blr->expire_time)) { + continue; /* Never timeout. */ } + + tv_dif_us = usec_time_diff(&blr->expire_time, &tv_curr); + min_tv_dif_us = MIN(min_tv_dif_us, tv_dif_us); } - if (timeout < 1) - timeout = 1; + if (min_tv_dif_us < 0) { + min_tv_dif_us = 0; + } + + timeout_ms = (unsigned int)(min_tv_dif_us / (SMB_BIG_INT)1000); + + if (timeout_ms < 1) { + timeout_ms = 1; + } + + DEBUG(10,("blocking_locks_timeout_ms: returning %u\n", timeout_ms)); - return timeout; + return timeout_ms; } /**************************************************************************** Process the blocking lock queue. Note that this is only called as root. *****************************************************************************/ -void process_blocking_lock_queue(time_t t) +void process_blocking_lock_queue(void) { + struct timeval tv_curr = timeval_current(); blocking_lock_record *blr, *next = NULL; /* @@ -753,8 +648,8 @@ void process_blocking_lock_queue(time_t t) DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", fsp->fnum, fsp->fsp_name )); - if((blr->expire_time != -1) && (blr->expire_time <= t)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* * Lock expired - throw away all previously @@ -765,63 +660,66 @@ void process_blocking_lock_queue(time_t t) DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", fsp->fnum, fsp->fsp_name )); - brl_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); continue; } if(!change_to_user(conn,vuid)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* * Remove the entry and return an error to the client. */ if (br_lck) { - brl_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", vuid )); blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); continue; } if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* * Remove the entry and return an error to the client. */ if (br_lck) { - brl_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); change_to_root_user(); continue; @@ -834,20 +732,115 @@ void process_blocking_lock_queue(time_t t) */ if(blocking_lock_record_process(blr)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (br_lck) { - brl_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); } change_to_root_user(); } } + +/**************************************************************************** + Handle a cancel message. Lock already moved onto the cancel queue. +*****************************************************************************/ + +#define MSG_BLOCKING_LOCK_CANCEL_SIZE (sizeof(blocking_lock_record *) + sizeof(NTSTATUS)) + +static void process_blocking_lock_cancel_message(int msg_type, struct process_id src, + void *buf, size_t len) +{ + NTSTATUS err; + const char *msg = (const char *)buf; + blocking_lock_record *blr; + + if (buf == NULL) { + smb_panic("process_blocking_lock_cancel_message: null msg\n"); + } + + if (len != MSG_BLOCKING_LOCK_CANCEL_SIZE) { + DEBUG(0, ("process_blocking_lock_cancel_message: " + "Got invalid msg len %d\n", (int)len)); + smb_panic("process_blocking_lock_cancel_message: bad msg\n"); + } + + memcpy(&blr, msg, sizeof(blr)); + memcpy(&err, &msg[sizeof(blr)], sizeof(NTSTATUS)); + + DEBUG(10,("process_blocking_lock_cancel_message: returning error %s\n", + nt_errstr(err) )); + + blocking_lock_reply_error(blr, err); + DLIST_REMOVE(blocking_lock_cancelled_queue, blr); + free_blocking_lock_record(blr); +} + +/**************************************************************************** + Send ourselves a blocking lock cancelled message. Handled asynchronously above. +*****************************************************************************/ + +BOOL blocking_lock_cancel(files_struct *fsp, + uint32 lock_pid, + SMB_BIG_UINT offset, + SMB_BIG_UINT count, + enum brl_flavour lock_flav, + unsigned char locktype, + NTSTATUS err) +{ + static BOOL initialized; + char msg[MSG_BLOCKING_LOCK_CANCEL_SIZE]; + blocking_lock_record *blr; + + if (!initialized) { + /* Register our message. */ + message_register(MSG_SMB_BLOCKING_LOCK_CANCEL, + process_blocking_lock_cancel_message); + + initialized = True; + } + + for (blr = blocking_lock_queue; blr; blr = blr->next) { + if (fsp == blr->fsp && + lock_pid == blr->lock_pid && + offset == blr->offset && + count == blr->count && + lock_flav == blr->lock_flav) { + break; + } + } + + if (!blr) { + return False; + } + + /* Check the flags are right. */ + if (blr->com_type == SMBlockingX && + (locktype & LOCKING_ANDX_LARGE_FILES) != + (CVAL(blr->inbuf,smb_vwv3) & LOCKING_ANDX_LARGE_FILES)) { + return False; + } + + /* Move to cancelled queue. */ + DLIST_REMOVE(blocking_lock_queue, blr); + DLIST_ADD(blocking_lock_cancelled_queue, blr); + + /* Create the message. */ + memcpy(msg, &blr, sizeof(blr)); + memcpy(&msg[sizeof(blr)], &err, sizeof(NTSTATUS)); + + message_send_pid(pid_to_procid(sys_getpid()), + MSG_SMB_BLOCKING_LOCK_CANCEL, + &msg, sizeof(msg), True); + + return True; +} diff --git a/source/smbd/close.c b/source/smbd/close.c index 8a63d3b227b..a3ddcae11d0 100644 --- a/source/smbd/close.c +++ b/source/smbd/close.c @@ -134,10 +134,8 @@ static void notify_deferred_opens(struct share_mode_lock *lck) share_mode_entry_to_message(msg, e); - become_root(); message_send_pid(e->pid, MSG_SMB_OPEN_RETRY, msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); - unbecome_root(); } } } @@ -268,8 +266,6 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type) int err = 0; int err1 = 0; - remove_pending_lock_requests_by_fid(fsp); - if (fsp->aio_write_behind) { /* * If we're finishing write behind on a close we can get a write diff --git a/source/smbd/conn.c b/source/smbd/conn.c index db9e759bb47..0b0da589e4d 100644 --- a/source/smbd/conn.c +++ b/source/smbd/conn.c @@ -107,7 +107,7 @@ find_again: int newsz = bmap->n + BITMAP_BLOCK_SZ; struct bitmap * nbmap; - if (newsz <= 0) { + if (newsz <= oldsz) { /* Integer wrap. */ DEBUG(0,("ERROR! Out of connection structures\n")); return NULL; @@ -131,13 +131,25 @@ find_again: goto find_again; } + /* The bitmap position is used below as the connection number + * conn->cnum). This ends up as the TID field in the SMB header, + * which is limited to 16 bits (we skip 0xffff which is the + * NULL TID). + */ + if (i > 65534) { + DEBUG(0, ("Maximum connection limit reached\n")); + return NULL; + } + if ((mem_ctx=talloc_init("connection_struct"))==NULL) { DEBUG(0,("talloc_init(connection_struct) failed!\n")); return NULL; } - if ((conn=TALLOC_ZERO_P(mem_ctx, connection_struct))==NULL) { + if (!(conn=TALLOC_ZERO_P(mem_ctx, connection_struct)) || + !(conn->params = TALLOC_P(mem_ctx, struct share_params))) { DEBUG(0,("talloc_zero() failed!\n")); + TALLOC_FREE(mem_ctx); return NULL; } conn->mem_ctx = mem_ctx; diff --git a/source/smbd/dir.c b/source/smbd/dir.c index e34a81ca0d2..1c77630ee72 100644 --- a/source/smbd/dir.c +++ b/source/smbd/dir.c @@ -869,17 +869,17 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S /* Pseudo-open the file (note - no fd's created). */ if(S_ISDIR(pst->st_mode)) { - fsp = open_directory(conn, name, pst, + status = open_directory(conn, name, pst, READ_CONTROL_ACCESS, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, /* no create options. */ - NULL); + NULL, &fsp); } else { - fsp = open_file_stat(conn, name, pst); + status = open_file_stat(conn, name, pst, &fsp); } - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { return False; } @@ -932,17 +932,17 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ if(S_ISDIR(pst->st_mode)) { return True; } else { - fsp = open_file_ntcreate(conn, name, pst, + status = open_file_ntcreate(conn, name, pst, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - &info); + &info, &fsp); } - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { return False; } diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c index 61145fde2f0..260a8dadbd6 100644 --- a/source/smbd/dosmode.c +++ b/source/smbd/dosmode.c @@ -300,8 +300,7 @@ static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_ * are not violating security in doing the setxattr. */ - fsp = open_file_fchmod(conn,path,sbuf); - if (!fsp) + if (!NT_STATUS_IS_OK(open_file_fchmod(conn,path,sbuf,&fsp))) return ret; become_root(); if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == 0) { @@ -518,8 +517,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, * holding. We need to review this.... may need to * break batch oplocks open by others. JRA. */ - files_struct *fsp = open_file_fchmod(conn,fname,st); - if (!fsp) + files_struct *fsp; + if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,st,&fsp))) return -1; become_root(); ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode); diff --git a/source/smbd/error.c b/source/smbd/error.c index fa236f0de05..0860b7d1d91 100644 --- a/source/smbd/error.c +++ b/source/smbd/error.c @@ -24,40 +24,6 @@ extern struct unix_error_map unix_dos_nt_errmap[]; extern uint32 global_client_caps; -/* these can be set by some functions to override the error codes */ -static int override_ERR_class; -static uint32 override_ERR_code; -static NTSTATUS override_ERR_ntstatus; - -/**************************************************************************** - Setting eclass and ecode only and status to NT_STATUS_INVALID forces DOS errors. - Setting status only and eclass and ecode to -1 forces NT errors. -****************************************************************************/ - -void set_saved_error_triple(int eclass, int ecode, NTSTATUS status) -{ - override_ERR_class = eclass; - override_ERR_code = ecode; - override_ERR_ntstatus = status; -} - -void set_saved_ntstatus(NTSTATUS status) -{ - uint8 tmp_eclass; /* Hmmm. override_ERR_class is not uint8... */ - override_ERR_ntstatus = status; - ntstatus_to_dos(status, &tmp_eclass, &override_ERR_code); - override_ERR_class = tmp_eclass; - -} - -/**************************************************************************** - Return the current settings of the error triple. Return True if any are set. -****************************************************************************/ - -NTSTATUS get_saved_ntstatus(void) -{ - return override_ERR_ntstatus; -} /**************************************************************************** Create an error packet from a cached error. @@ -103,6 +69,10 @@ int unix_error_packet(char *outbuf,int def_class,uint32 def_code, NTSTATUS def_s return error_packet(outbuf,eclass,ecode,ntstatus,line,file); } +BOOL use_nt_status(void) +{ + return lp_nt_status_support() && (global_client_caps & CAP_STATUS32); +} /**************************************************************************** Create an error packet. Normally called using the ERROR() macro. @@ -111,24 +81,14 @@ int unix_error_packet(char *outbuf,int def_class,uint32 def_code, NTSTATUS def_s If the override errors are set they take precedence over any passed in values. ****************************************************************************/ -int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file) +void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file) { - int outsize = set_message(outbuf,0,0,True); BOOL force_nt_status = False; BOOL force_dos_status = False; - if (override_ERR_class != SMB_SUCCESS || !NT_STATUS_IS_OK(override_ERR_ntstatus)) { - eclass = override_ERR_class; - ecode = override_ERR_code; - ntstatus = override_ERR_ntstatus; - override_ERR_class = SMB_SUCCESS; - override_ERR_code = 0; - override_ERR_ntstatus = NT_STATUS_OK; - } - if (eclass == (uint8)-1) { force_nt_status = True; - } else if (NT_STATUS_IS_INVALID(ntstatus)) { + } else if (NT_STATUS_IS_DOS(ntstatus)) { force_dos_status = True; } @@ -146,7 +106,10 @@ int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, in nt_errstr(ntstatus))); } else { /* We're returning a DOS error only. */ - if (eclass == 0 && NT_STATUS_V(ntstatus)) { + if (NT_STATUS_IS_DOS(ntstatus)) { + eclass = NT_STATUS_DOS_CLASS(ntstatus); + ecode = NT_STATUS_DOS_CODE(ntstatus); + } else if (eclass == 0 && NT_STATUS_V(ntstatus)) { ntstatus_to_dos(ntstatus, &eclass, &ecode); } @@ -161,6 +124,11 @@ int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, in eclass, ecode)); } +} +int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file) +{ + int outsize = set_message(outbuf,0,0,True); + error_packet_set(outbuf, eclass, ecode, ntstatus, line, file); return outsize; } diff --git a/source/smbd/fake_file.c b/source/smbd/fake_file.c index b4f1f02b724..7c5eeae5c7d 100644 --- a/source/smbd/fake_file.c +++ b/source/smbd/fake_file.c @@ -101,24 +101,26 @@ enum FAKE_FILE_TYPE is_fake_file(const char *fname) Open a fake quota file with a share mode. ****************************************************************************/ -files_struct *open_fake_file(connection_struct *conn, +NTSTATUS open_fake_file(connection_struct *conn, enum FAKE_FILE_TYPE fake_file_type, const char *fname, - uint32 access_mask) + uint32 access_mask, + files_struct **result) { files_struct *fsp = NULL; + NTSTATUS status; /* access check */ if (current_user.ut.uid != 0) { DEBUG(1,("open_fake_file_shared: access_denied to service[%s] file[%s] user[%s]\n", lp_servicename(SNUM(conn)),fname,conn->user)); - errno = EACCES; - return NULL; + return NT_STATUS_ACCESS_DENIED; + } - fsp = file_new(conn); - if(!fsp) { - return NULL; + status = file_new(conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + return status; } DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n", @@ -128,7 +130,7 @@ files_struct *open_fake_file(connection_struct *conn, fsp->fh->fd = -1; fsp->vuid = current_user.vuid; fsp->fh->pos = -1; - fsp->can_lock = True; /* Should this be true ? */ + fsp->can_lock = False; /* Should this be true ? - No, JRA */ fsp->access_mask = access_mask; string_set(&fsp->fsp_name,fname); @@ -136,11 +138,12 @@ files_struct *open_fake_file(connection_struct *conn, if (fsp->fake_file_handle==NULL) { file_free(fsp); - return NULL; + return NT_STATUS_NO_MEMORY; } conn->num_files_open++; - return fsp; + *result = fsp; + return NT_STATUS_OK; } void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh) diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c index 375bfbe7cf3..e0945be8893 100644 --- a/source/smbd/fileio.c +++ b/source/smbd/fileio.c @@ -214,7 +214,7 @@ ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n) if (!fsp->can_write) { errno = EPERM; - return(0); + return -1; } if (!fsp->modified) { diff --git a/source/smbd/files.c b/source/smbd/files.c index e020d8e13a6..7069818dee4 100644 --- a/source/smbd/files.c +++ b/source/smbd/files.c @@ -59,7 +59,7 @@ static unsigned long get_gen_count(void) Find first available file slot. ****************************************************************************/ -files_struct *file_new(connection_struct *conn) +NTSTATUS file_new(connection_struct *conn, files_struct **result) { int i; static int first_file; @@ -82,14 +82,12 @@ files_struct *file_new(connection_struct *conn) /* TODO: We have to unconditionally return a DOS error here, * W2k3 even returns ERRDOS/ERRnofids for ntcreate&x with * NTSTATUS negotiated */ - set_saved_ntstatus(NT_STATUS_TOO_MANY_OPENED_FILES); - return NULL; + return NT_STATUS_TOO_MANY_OPENED_FILES; } fsp = SMB_MALLOC_P(files_struct); if (!fsp) { - set_saved_ntstatus(NT_STATUS_NO_MEMORY); - return NULL; + return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(fsp); @@ -97,8 +95,7 @@ files_struct *file_new(connection_struct *conn) fsp->fh = SMB_MALLOC_P(struct fd_handle); if (!fsp->fh) { SAFE_FREE(fsp); - set_saved_ntstatus(NT_STATUS_NO_MEMORY); - return NULL; + return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(fsp->fh); @@ -131,8 +128,9 @@ files_struct *file_new(connection_struct *conn) if (fsp_fi_cache.fsp == NULL) { ZERO_STRUCT(fsp_fi_cache); } - - return fsp; + + *result = fsp; + return NT_STATUS_OK; } /**************************************************************************** @@ -464,24 +462,16 @@ void file_free(files_struct *fsp) } /**************************************************************************** - Get a fsp from a packet given the offset of a 16 bit fnum. + Get an fsp from a 16 bit fnum. ****************************************************************************/ -files_struct *file_fsp(char *buf, int where) +files_struct *file_fnum(uint16 fnum) { - int fnum, count=0; files_struct *fsp; - - if (chain_fsp) - return chain_fsp; - - if (!buf) - return NULL; - fnum = SVAL(buf, where); + int count=0; for (fsp=Files;fsp;fsp=fsp->next, count++) { if (fsp->fnum == fnum) { - chain_fsp = fsp; if (count > 10) { DLIST_PROMOTE(Files, fsp); } @@ -492,6 +482,29 @@ files_struct *file_fsp(char *buf, int where) } /**************************************************************************** + Get an fsp from a packet given the offset of a 16 bit fnum. +****************************************************************************/ + +files_struct *file_fsp(char *buf, int where) +{ + files_struct *fsp; + + if (chain_fsp) { + return chain_fsp; + } + + if (!buf) { + return NULL; + } + + fsp = file_fnum(SVAL(buf, where)); + if (fsp) { + chain_fsp = fsp; + } + return fsp; +} + +/**************************************************************************** Reset the chained fsp - done at the start of a packet reply. ****************************************************************************/ @@ -504,15 +517,19 @@ void file_chain_reset(void) Duplicate the file handle part for a DOS or FCB open. ****************************************************************************/ -files_struct *dup_file_fsp(files_struct *fsp, +NTSTATUS dup_file_fsp(files_struct *fsp, uint32 access_mask, uint32 share_access, - uint32 create_options) + uint32 create_options, + files_struct **result) { - files_struct *dup_fsp = file_new(fsp->conn); + NTSTATUS status; + files_struct *dup_fsp; - if (!dup_fsp) { - return NULL; + status = file_new(fsp->conn, &dup_fsp); + + if (!NT_STATUS_IS_OK(status)) { + return status; } SAFE_FREE(dup_fsp->fh); @@ -547,5 +564,6 @@ files_struct *dup_file_fsp(files_struct *fsp, dup_fsp->aio_write_behind = fsp->aio_write_behind; string_set(&dup_fsp->fsp_name,fsp->fsp_name); - return dup_fsp; + *result = dup_fsp; + return NT_STATUS_OK; } diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c index 9e7e19080ec..8ecc965c0d3 100644 --- a/source/smbd/lanman.c +++ b/source/smbd/lanman.c @@ -72,7 +72,11 @@ static int CopyExpanded(connection_struct *conn, StrnCpy(buf,src,sizeof(buf)/2); pstring_sub(buf,"%S",lp_servicename(snum)); - standard_sub_conn(conn,buf,sizeof(buf)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + buf, sizeof(buf)); l = push_ascii(*dst,buf,*n, STR_TERMINATE); (*dst) += l; (*n) -= l; @@ -99,7 +103,11 @@ static int StrlenExpanded(connection_struct *conn, int snum, char *s) } StrnCpy(buf,s,sizeof(buf)/2); pstring_sub(buf,"%S",lp_servicename(snum)); - standard_sub_conn(conn,buf,sizeof(buf)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + buf, sizeof(buf)); return strlen(buf) + 1; } @@ -111,7 +119,11 @@ static char *Expand(connection_struct *conn, int snum, char *s) } StrnCpy(buf,s,sizeof(buf)/2); pstring_sub(buf,"%S",lp_servicename(snum)); - standard_sub_conn(conn,buf,sizeof(buf)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + buf, sizeof(buf)); return &buf[0]; } @@ -593,7 +605,7 @@ static void fill_printq_info_52(connection_struct *conn, int snum, PACKS(desc, "z", driver.info_3->monitorname); /* language monitor */ fstrcpy(location, "\\\\%L\\print$\\WIN40\\0"); - standard_sub_basic( "", location, sizeof(location)-1 ); + standard_sub_basic( "", "", location, sizeof(location)-1 ); PACKS(desc,"z", location); /* share to retrieve files */ PACKS(desc,"z", driver.info_3->defaultdatatype); /* default data type */ @@ -2530,7 +2542,6 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha char *str2 = skip_string(str1,1); char *p = skip_string(str2,1); uint32 jobid; - int snum; fstring sharename; int uLevel = SVAL(p,2); int function = SVAL(p,4); @@ -2544,9 +2555,9 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha return False; } - if ( (snum = lp_servicenumber(sharename)) == -1 ) { - DEBUG(0,("api_PrintJobInfo: unable to get service number from sharename [%s]\n", - sharename)); + if (!share_defined(sharename)) { + DEBUG(0,("api_PrintJobInfo: sharen [%s] not defined\n", + sharename)); return False; } @@ -2569,14 +2580,14 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha /* change job place in the queue, data gives the new place */ place = SVAL(data,0); - if (print_job_set_place(snum, jobid, place)) { + if (print_job_set_place(sharename, jobid, place)) { errcode=NERR_Success; } break; case 0xb: /* change print job name, data gives the name */ - if (print_job_set_name(snum, jobid, data)) { + if (print_job_set_name(sharename, jobid, data)) { errcode=NERR_Success; } break; @@ -2666,7 +2677,7 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par p = *rdata; p2 = p + struct_len; if (uLevel != 20) { - srvstr_push(NULL, p,get_local_machine_name(),16, + srvstr_push(NULL, p,global_myname(),16, STR_ASCII|STR_UPPER|STR_TERMINATE); } p += 16; @@ -2680,7 +2691,7 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) { for (i=0;i<count;i++) { - if (strequal(servers[i].name,get_local_machine_name())) { + if (strequal(servers[i].name,global_myname())) { servertype = servers[i].type; push_ascii(comment,servers[i].comment,sizeof(pstring),STR_TERMINATE); } @@ -2697,7 +2708,11 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par SIVAL(p,6,0); } else { SIVAL(p,6,PTR_DIFF(p2,*rdata)); - standard_sub_conn(conn,comment,sizeof(comment)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + comment, sizeof(comment)); StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0)); p2 = skip_string(p2,1); } @@ -3122,8 +3137,12 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param SSVALS(p,102,-1); /* bad_pw_count */ SSVALS(p,104,-1); /* num_logons */ SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */ - pstrcpy(p2,"\\\\%L"); - standard_sub_conn(conn, p2,0); + { + pstring tmp; + pstrcpy(tmp, "\\\\%L"); + standard_sub_basic("", "", tmp, sizeof(tmp)); + pstrcpy(p2, tmp); + } p2 = skip_string(p2,1); SSVAL(p,110,49); /* country_code */ SSVAL(p,112,860); /* code page */ diff --git a/source/smbd/message.c b/source/smbd/message.c index 31dab458443..fd53e60c141 100644 --- a/source/smbd/message.c +++ b/source/smbd/message.c @@ -101,7 +101,8 @@ static void msg_deliver(void) pstrcpy(s,lp_msg_command()); pstring_sub(s,"%f",alpha_strcpy(alpha_msgfrom,msgfrom,NULL,sizeof(alpha_msgfrom))); pstring_sub(s,"%t",alpha_strcpy(alpha_msgto,msgto,NULL,sizeof(alpha_msgto))); - standard_sub_basic(current_user_info.smb_name, s, sizeof(s)); + standard_sub_basic(current_user_info.smb_name, + current_user_info.domain, s, sizeof(s)); pstring_sub(s,"%s",name); smbrun(s,NULL); } diff --git a/source/smbd/msdfs.c b/source/smbd/msdfs.c index c6d15ada53a..1f04356b4f3 100644 --- a/source/smbd/msdfs.c +++ b/source/smbd/msdfs.c @@ -30,7 +30,7 @@ extern uint32 global_client_caps; into the dfs_path structure **********************************************************************/ -static BOOL parse_dfs_path(char *pathname, struct dfs_path *pdp) +static BOOL parse_dfs_path(const char *pathname, struct dfs_path *pdp) { pstring pathname_local; char *p, *temp; @@ -73,26 +73,32 @@ static BOOL parse_dfs_path(char *pathname, struct dfs_path *pdp) } /********************************************************************** - Parse the pathname of the form /hostname/service/reqpath - into the dfs_path structure + Parse the pathname of the form /hostname/service/reqpath + into the dfs_path structure + This code is dependent on the fact that check_path_syntax() will + convert '\\' characters to '/'. + When POSIX pathnames have been selected this doesn't happen, so we + must look for the unaltered separator of '\\' instead of the modified '/'. + JRA. **********************************************************************/ static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path *pdp, BOOL allow_wcards) { pstring pathname_local; char *p,*temp; + const char sepchar = lp_posix_pathnames() ? '\\' : '/'; pstrcpy(pathname_local,pathname); p = temp = pathname_local; ZERO_STRUCTP(pdp); - trim_char(temp,'/','/'); + trim_char(temp,sepchar,sepchar); DEBUG(10,("temp in parse_processed_dfs_path: .%s. after trimming \\'s\n",temp)); /* now tokenize */ /* parse out hostname */ - p = strchr_m(temp,'/'); + p = strchr_m(temp,sepchar); if(p == NULL) { return False; } @@ -102,7 +108,7 @@ static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path *pdp, BOOL /* parse out servicename */ temp = p+1; - p = strchr_m(temp,'/'); + p = strchr_m(temp,sepchar); if(p == NULL) { pstrcpy(pdp->servicename,temp); pdp->reqpath[0] = '\0'; @@ -144,7 +150,7 @@ static BOOL create_conn_struct(connection_struct *conn, int snum, char *path) DEBUG(0,("talloc_init(connection_struct) failed!\n")); return False; } - + if (!(conn->params = TALLOC_P(conn->mem_ctx, struct share_params))) { DEBUG(0, ("TALLOC failed\n")); return False; @@ -311,7 +317,8 @@ TALLOC_CTX can be NULL here if struct referral **reflistpp, int *refcntp are also NULL. *****************************************************************/ -static BOOL resolve_dfs_path(TALLOC_CTX *ctx, pstring dfspath, struct dfs_path *dp, +static BOOL resolve_dfs_path(TALLOC_CTX *ctx, const char *dfspath, + struct dfs_path *dp, connection_struct *conn, BOOL search_flag, struct referral **reflistpp, int *refcntp, BOOL *self_referralp, int *consumedcntp) @@ -453,7 +460,7 @@ BOOL dfs_redirect( pstring pathname, connection_struct *conn, BOOL search_wcard_ Return a self referral. **********************************************************************/ -static BOOL self_ref(TALLOC_CTX *ctx, char *pathname, struct junction_map *jucn, +static BOOL self_ref(TALLOC_CTX *ctx, const char *pathname, struct junction_map *jucn, int *consumedcntp, BOOL *self_referralp) { struct referral *ref; @@ -484,7 +491,7 @@ static BOOL self_ref(TALLOC_CTX *ctx, char *pathname, struct junction_map *jucn, junction_map structure. **********************************************************************/ -BOOL get_referred_path(TALLOC_CTX *ctx, char *pathname, struct junction_map *jucn, +BOOL get_referred_path(TALLOC_CTX *ctx, const char *pathname, struct junction_map *jucn, int *consumedcntp, BOOL *self_referralp) { struct dfs_path dp; @@ -646,7 +653,7 @@ static int setup_ver2_dfs_referral(char *pathname, char **ppdata, /* add the unexplained 0x16 bytes */ reply_size += 0x16; - pdata = SMB_REALLOC(pdata,reply_size); + pdata = (char *)SMB_REALLOC(pdata,reply_size); if(pdata == NULL) { DEBUG(0,("malloc failed for Realloc!\n")); return -1; @@ -731,7 +738,7 @@ static int setup_ver3_dfs_referral(char *pathname, char **ppdata, reply_size += (strlen(junction->referral_list[i].alternate_path)+1)*2; } - pdata = SMB_REALLOC(pdata,reply_size); + pdata = (char *)SMB_REALLOC(pdata,reply_size); if(pdata == NULL) { DEBUG(0,("version3 referral setup: malloc failed for Realloc!\n")); return -1; @@ -874,7 +881,7 @@ int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_ref Creates a junction structure from a Dfs pathname **********************************************************************/ -BOOL create_junction(char *pathname, struct junction_map *jucn) +BOOL create_junction(const char *pathname, struct junction_map *jucn) { struct dfs_path dp; @@ -1059,6 +1066,7 @@ static int form_junctions(TALLOC_CTX *ctx, int snum, struct junction_map *jucn, ref->ttl = REFERRAL_TTL; if (*lp_msdfs_proxy(snum) != '\0') { pstrcpy(ref->alternate_path, lp_msdfs_proxy(snum)); + cnt++; goto out; } diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c index 3347008cdf8..bbd10130509 100644 --- a/source/smbd/negprot.c +++ b/source/smbd/negprot.c @@ -33,7 +33,8 @@ static void get_challenge(char buff[8]) NTSTATUS nt_status; const uint8 *cryptkey; - /* We might be called more than once, muliple negprots are premitted */ + /* We might be called more than once, multiple negprots are + * permitted */ if (negprot_global_auth_context) { DEBUG(3, ("get challenge: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n")); (negprot_global_auth_context->free)(&negprot_global_auth_context); @@ -168,7 +169,7 @@ static int reply_lanman2(char *inbuf, char *outbuf) Generate the spnego negprot reply blob. Return the number of bytes used. ****************************************************************************/ -static int negprot_spnego(char *p, uint8 *pkeylen) +static DATA_BLOB negprot_spnego(void) { DATA_BLOB blob; nstring dos_name; @@ -179,7 +180,6 @@ static int negprot_spnego(char *p, uint8 *pkeylen) OID_NTLMSSP, NULL}; const char *OIDs_plain[] = {OID_NTLMSSP, NULL}; - int len; global_spnego_negotiated = True; @@ -190,15 +190,6 @@ static int negprot_spnego(char *p, uint8 *pkeylen) push_ascii_nstring(dos_name, unix_name); safe_strcpy(guid, dos_name, sizeof(guid)-1); -#ifdef DEVELOPER - /* valgrind fixer... */ - { - size_t sl = strlen(guid); - if (sizeof(guid)-sl) - memset(&guid[sl], '\0', sizeof(guid)-sl); - } -#endif - /* strangely enough, NT does not sent the single OID NTLMSSP when not a ADS member, it sends no OIDs at all @@ -230,20 +221,7 @@ static int negprot_spnego(char *p, uint8 *pkeylen) SAFE_FREE(host_princ_s); } - memcpy(p, blob.data, blob.length); - len = blob.length; - if (len > 256) { - DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len)); - len = 255; - } - data_blob_free(&blob); - - if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) { - *pkeylen = 0; - } else { - *pkeylen = len; - } - return len; + return blob; } /**************************************************************************** @@ -349,11 +327,17 @@ static int reply_nt1(char *inbuf, char *outbuf) STR_UNICODE|STR_TERMINATE|STR_NOALIGN); DEBUG(3,("not using SPNEGO\n")); } else { - uint8 keylen; - int len = negprot_spnego(p, &keylen); - - SCVAL(outbuf,smb_vwv16+1,keylen); - p += len; + DATA_BLOB spnego_blob = negprot_spnego(); + + if (spnego_blob.data == NULL) { + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + + memcpy(p, spnego_blob.data, spnego_blob.length); + p += spnego_blob.length; + data_blob_free(&spnego_blob); + + SCVAL(outbuf,smb_vwv16+1, 0); DEBUG(3,("using SPNEGO\n")); } diff --git a/source/smbd/ntquotas.c b/source/smbd/ntquotas.c index a824978ecea..e754583312f 100644 --- a/source/smbd/ntquotas.c +++ b/source/smbd/ntquotas.c @@ -244,7 +244,7 @@ void destroy_quota_handle(void **pqt_handle) if (!pqt_handle||!(*pqt_handle)) return; - qt_handle = (*pqt_handle); + qt_handle = (SMB_NTQUOTA_HANDLE *)(*pqt_handle); if (qt_handle->quota_list) diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index fae46f0ce66..2c37a17cc4a 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -37,6 +37,7 @@ static const char *known_nt_pipes[] = { "\\lsass", "\\lsarpc", "\\winreg", + "\\initshutdown", "\\spoolss", "\\netdfs", "\\rpcecho", @@ -321,7 +322,7 @@ static int nt_open_pipe(char *fname, connection_struct *conn, smb_np_struct *p = NULL; uint16 vuid = SVAL(inbuf, smb_uid); int i; - + DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname)); /* See if it is one we want to handle. */ @@ -418,10 +419,14 @@ int reply_ntcreate_and_X_quota(connection_struct *conn, int result; char *p; uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess); - files_struct *fsp = open_fake_file(conn, fake_file_type, fname, desired_access); + files_struct *fsp; + NTSTATUS status; - if (!fsp) { - return ERROR_NT(NT_STATUS_ACCESS_DENIED); + status = open_fake_file(conn, fake_file_type, fname, desired_access, + &fsp); + + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); } set_message(outbuf,34,0,True); @@ -431,31 +436,6 @@ int reply_ntcreate_and_X_quota(connection_struct *conn, /* SCVAL(p,0,NO_OPLOCK_RETURN); */ p++; SSVAL(p,0,fsp->fnum); -#if 0 - p += 2; - SIVAL(p,0,smb_action); - p += 4; - - /* Create time. */ - put_long_date(p,c_time); - p += 8; - put_long_date(p,sbuf.st_atime); /* access time */ - p += 8; - put_long_date(p,sbuf.st_mtime); /* write time */ - p += 8; - put_long_date(p,sbuf.st_mtime); /* change time */ - p += 8; - SIVAL(p,0,fattr); /* File Attributes. */ - p += 4; - SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf)); - p += 8; - SOFF_T(p,0,file_len); - p += 8; - if (flags & EXTENDED_RESPONSE_REQUIRED) - SSVAL(p,2,0x7); - p += 4; - SCVAL(p,0,fsp->is_directory ? 1 : 0); -#endif DEBUG(5,("reply_ntcreate_and_X_quota: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name)); @@ -489,13 +469,15 @@ int reply_ntcreate_and_X(connection_struct *conn, BOOL bad_path = False; files_struct *fsp=NULL; char *p = NULL; - time_t c_time; + struct timespec c_timespec; + struct timespec a_timespec; + struct timespec m_timespec; BOOL extended_oplock_granted = False; NTSTATUS status; START_PROFILE(SMBntcreateX); - DEBUG(10,("reply_ntcreateX: flags = 0x%x, access_mask = 0x%x \ + DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x \ file_attributes = 0x%x, share_access = 0x%x, create_disposition = 0x%x \ create_options = 0x%x root_dir_fid = 0x%x\n", (unsigned int)flags, @@ -694,18 +676,18 @@ create_options = 0x%x root_dir_fid = 0x%x\n", return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - fsp = open_directory(conn, fname, &sbuf, + status = open_directory(conn, fname, &sbuf, access_mask, share_access, create_disposition, create_options, - &info); + &info, &fsp); restore_case_semantics(conn, file_attributes); - if(!fsp) { + if(!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBntcreateX); - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } else { /* @@ -725,15 +707,15 @@ create_options = 0x%x root_dir_fid = 0x%x\n", * before issuing an oplock break request to * our client. JRA. */ - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, - &info); - if (!fsp) { + &info, &fsp); + if (!NT_STATUS_IS_OK(status)) { /* We cheat here. There are two cases we * care about. One is a directory rename, * where the NT client will attempt to @@ -753,7 +735,8 @@ create_options = 0x%x root_dir_fid = 0x%x\n", * we handle in the open_file_stat case. JRA. */ - if(errno == EISDIR) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_FILE_IS_A_DIRECTORY)) { /* * Fail the open if it was explicitly a non-directory file. @@ -766,17 +749,17 @@ create_options = 0x%x root_dir_fid = 0x%x\n", } oplock_request = 0; - fsp = open_directory(conn, fname, &sbuf, + status = open_directory(conn, fname, &sbuf, access_mask, share_access, create_disposition, create_options, - &info); + &info, &fsp); - if(!fsp) { + if(!NT_STATUS_IS_OK(status)) { restore_case_semantics(conn, file_attributes); END_PROFILE(SMBntcreateX); - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } else { @@ -786,7 +769,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } } @@ -879,22 +862,23 @@ create_options = 0x%x root_dir_fid = 0x%x\n", p += 4; /* Create time. */ - c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + a_timespec = get_atimespec(&sbuf); + m_timespec = get_mtimespec(&sbuf); if (lp_dos_filetime_resolution(SNUM(conn))) { - c_time &= ~1; - sbuf.st_atime &= ~1; - sbuf.st_mtime &= ~1; - sbuf.st_mtime &= ~1; + dos_filetime_timespec(&c_timespec); + dos_filetime_timespec(&a_timespec); + dos_filetime_timespec(&m_timespec); } - put_long_date(p,c_time); + put_long_date_timespec(p, c_timespec); p += 8; - put_long_date(p,sbuf.st_atime); /* access time */ + put_long_date_timespec(p, a_timespec); /* access time */ p += 8; - put_long_date(p,sbuf.st_mtime); /* write time */ + put_long_date_timespec(p, m_timespec); /* write time */ p += 8; - put_long_date(p,sbuf.st_mtime); /* change time */ + put_long_date_timespec(p, m_timespec); /* change time */ p += 8; SIVAL(p,0,fattr); /* File Attributes. */ p += 4; @@ -1026,16 +1010,16 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu return NT_STATUS_NO_MEMORY; } - if (psd->off_owner_sid==0) { + if (psd->owner_sid==0) { security_info_sent &= ~OWNER_SECURITY_INFORMATION; } - if (psd->off_grp_sid==0) { + if (psd->grp_sid==0) { security_info_sent &= ~GROUP_SECURITY_INFORMATION; } - if (psd->off_sacl==0) { + if (psd->sacl==0) { security_info_sent &= ~SACL_SECURITY_INFORMATION; } - if (psd->off_dacl==0) { + if (psd->dacl==0) { security_info_sent &= ~DACL_SECURITY_INFORMATION; } @@ -1113,7 +1097,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o uint32 sd_len; uint32 ea_len; uint16 root_dir_fid; - time_t c_time; + struct timespec c_timespec; + struct timespec a_timespec; + struct timespec m_timespec; struct ea_list *ea_list = NULL; TALLOC_CTX *ctx = NULL; char *pdata = NULL; @@ -1336,16 +1322,16 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o * CreateDirectory() call. */ - fsp = open_directory(conn, fname, &sbuf, + status = open_directory(conn, fname, &sbuf, access_mask, share_access, create_disposition, create_options, - &info); - if(!fsp) { + &info, &fsp); + if(!NT_STATUS_IS_OK(status)) { talloc_destroy(ctx); restore_case_semantics(conn, file_attributes); - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } else { @@ -1354,17 +1340,18 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o * Ordinary file case. */ - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_access, create_disposition, create_options, file_attributes, oplock_request, - &info); + &info, &fsp); - if (!fsp) { - if(errno == EISDIR) { + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_FILE_IS_A_DIRECTORY)) { /* * Fail the open if it was explicitly a non-directory file. @@ -1376,16 +1363,16 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o } oplock_request = 0; - fsp = open_directory(conn, fname, &sbuf, + status = open_directory(conn, fname, &sbuf, access_mask, share_access, create_disposition, create_options, - &info); - if(!fsp) { + &info, &fsp); + if(!NT_STATUS_IS_OK(status)) { talloc_destroy(ctx); restore_case_semantics(conn, file_attributes); - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } else { talloc_destroy(ctx); @@ -1394,7 +1381,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); + return ERROR_NT(status); } } } @@ -1511,22 +1498,23 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o p += 8; /* Create time. */ - c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + a_timespec = get_atimespec(&sbuf); + m_timespec = get_mtimespec(&sbuf); if (lp_dos_filetime_resolution(SNUM(conn))) { - c_time &= ~1; - sbuf.st_atime &= ~1; - sbuf.st_mtime &= ~1; - sbuf.st_mtime &= ~1; + dos_filetime_timespec(&c_timespec); + dos_filetime_timespec(&a_timespec); + dos_filetime_timespec(&m_timespec); } - put_long_date(p,c_time); + put_long_date_timespec(p, c_timespec); /* create time. */ p += 8; - put_long_date(p,sbuf.st_atime); /* access time */ + put_long_date_timespec(p, a_timespec); /* access time */ p += 8; - put_long_date(p,sbuf.st_mtime); /* write time */ + put_long_date_timespec(p, m_timespec); /* write time */ p += 8; - put_long_date(p,sbuf.st_mtime); /* change time */ + put_long_date_timespec(p, m_timespec); /* change time */ p += 8; SIVAL(p,0,fattr); /* File Attributes. */ p += 4; @@ -1660,39 +1648,29 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname)); - fsp1 = open_file_ntcreate(conn,oldname,&sbuf1, + status = open_file_ntcreate(conn,oldname,&sbuf1, FILE_READ_DATA, /* Read-only. */ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, /* No create options. */ FILE_ATTRIBUTE_NORMAL, NO_OPLOCK, - &info); + &info, &fsp1); - if (!fsp1) { - status = get_saved_ntstatus(); - if (NT_STATUS_IS_OK(status)) { - status = NT_STATUS_ACCESS_DENIED; - } - set_saved_ntstatus(NT_STATUS_OK); + if (!NT_STATUS_IS_OK(status)) { return status; } - fsp2 = open_file_ntcreate(conn,newname,&sbuf2, - FILE_WRITE_DATA, /* Write-only. */ + status = open_file_ntcreate(conn,newname,&sbuf2, + FILE_WRITE_DATA, /* Read-only. */ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_CREATE, 0, /* No create options. */ fattr, NO_OPLOCK, - &info); + &info, &fsp2); - if (!fsp2) { - status = get_saved_ntstatus(); - if (NT_STATUS_IS_OK(status)) { - status = NT_STATUS_ACCESS_DENIED; - } - set_saved_ntstatus(NT_STATUS_OK); + if (!NT_STATUS_IS_OK(status)) { close_file(fsp1,ERROR_CLOSE); return status; } diff --git a/source/smbd/open.c b/source/smbd/open.c index e2ca81ccd7d..1899a6fce7c 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -38,24 +38,29 @@ struct deferred_open_record { fd support routines - attempt to do a dos_open. ****************************************************************************/ -static int fd_open(struct connection_struct *conn, - const char *fname, - int flags, - mode_t mode) +static BOOL fd_open(struct connection_struct *conn, + const char *fname, + files_struct *fsp, + int flags, + mode_t mode) { - int fd; + int sav; + #ifdef O_NOFOLLOW if (!lp_symlinks(SNUM(conn))) { flags |= O_NOFOLLOW; } #endif - fd = SMB_VFS_OPEN(conn,fname,flags,mode); + fsp->fh->fd = SMB_VFS_OPEN(conn,fname,fsp,flags,mode); + sav = errno; - DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname, - flags, (int)mode, fd, (fd == -1) ? strerror(errno) : "" )); + DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", + fname, flags, (int)mode, fsp->fh->fd, + (fsp->fh->fd == -1) ? strerror(errno) : "" )); - return fd; + errno = sav; + return fsp->fh->fd != -1; } /**************************************************************************** @@ -63,7 +68,7 @@ static int fd_open(struct connection_struct *conn, ****************************************************************************/ int fd_close(struct connection_struct *conn, - files_struct *fsp) + files_struct *fsp) { if (fsp->fh->fd == -1) { return 0; /* What we used to call a stat open. */ @@ -80,9 +85,9 @@ int fd_close(struct connection_struct *conn, ****************************************************************************/ void change_owner_to_parent(connection_struct *conn, - files_struct *fsp, - const char *fname, - SMB_STRUCT_STAT *psbuf) + files_struct *fsp, + const char *fname, + SMB_STRUCT_STAT *psbuf) { const char *parent_path = parent_dirname(fname); SMB_STRUCT_STAT parent_st; @@ -179,14 +184,14 @@ void change_owner_to_parent(connection_struct *conn, Open a file. ****************************************************************************/ -static BOOL open_file(files_struct *fsp, - connection_struct *conn, - const char *fname, - SMB_STRUCT_STAT *psbuf, - int flags, - mode_t unx_mode, - uint32 access_mask, /* client requested access mask. */ - uint32 open_access_mask) /* what we're actually using in the open. */ +static NTSTATUS open_file(files_struct *fsp, + connection_struct *conn, + const char *fname, + SMB_STRUCT_STAT *psbuf, + int flags, + mode_t unx_mode, + uint32 access_mask, /* client requested access mask. */ + uint32 open_access_mask) /* what we're actually using in the open. */ { int accmode = (flags & O_ACCMODE); int local_flags = flags; @@ -211,7 +216,7 @@ static BOOL open_file(files_struct *fsp, /* It's a read-only share - fail if we wanted to write. */ if(accmode != O_RDONLY) { DEBUG(3,("Permission denied opening %s\n",fname)); - return False; + return NT_STATUS_ACCESS_DENIED; } else if(flags & O_CREAT) { /* We don't want to write - but we must make sure that O_CREAT doesn't create the file if we have write @@ -266,17 +271,15 @@ static BOOL open_file(files_struct *fsp, /* Don't create files with Microsoft wildcard characters. */ if ((local_flags & O_CREAT) && !file_existed && ms_has_wild(fname)) { - set_saved_ntstatus(NT_STATUS_OBJECT_NAME_INVALID); - return False; + return NT_STATUS_OBJECT_NAME_INVALID; } /* Actually do the open */ - fsp->fh->fd = fd_open(conn, fname, local_flags, unx_mode); - if (fsp->fh->fd == -1) { + if (!fd_open(conn, fname, fsp, local_flags, unx_mode)) { DEBUG(3,("Error opening file %s (%s) (local_flags=%d) " "(flags=%d)\n", fname,strerror(errno),local_flags,flags)); - return False; + return map_nt_error_from_unix(errno); } /* Inherit the ACL if the file was created. */ @@ -304,8 +307,9 @@ static BOOL open_file(files_struct *fsp, /* For a non-io open, this stat failing means file not found. JRA */ if (ret == -1) { + NTSTATUS status = map_nt_error_from_unix(errno); fd_close(conn, fsp); - return False; + return status; } } @@ -318,7 +322,7 @@ static BOOL open_file(files_struct *fsp, if(S_ISDIR(psbuf->st_mode)) { fd_close(conn, fsp); errno = EISDIR; - return False; + return NT_STATUS_FILE_IS_A_DIRECTORY; } fsp->mode = psbuf->st_mode; @@ -331,7 +335,8 @@ static BOOL open_file(files_struct *fsp, if (!CAN_WRITE(conn)) { fsp->can_write = False; } else { - fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ? True : False; + fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ? + True : False; } fsp->print_file = False; fsp->modified = False; @@ -347,12 +352,13 @@ static BOOL open_file(files_struct *fsp, fsp->wcp = NULL; /* Write cache pointer. */ DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n", - *current_user_info.smb_name ? current_user_info.smb_name : conn->user,fsp->fsp_name, + *current_user_info.smb_name ? + current_user_info.smb_name : conn->user,fsp->fsp_name, BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write), conn->num_files_open + 1)); errno = 0; - return True; + return NT_STATUS_OK; } /******************************************************************* @@ -469,8 +475,8 @@ static void validate_my_share_entries(int num, if (is_deferred_open_entry(share_entry) && !open_was_deferred(share_entry->op_mid)) { pstring str; - DEBUG(0, ("Got a deferred entry without a request: " - "PANIC: %s\n", share_mode_str(num, share_entry))); + pstr_sprintf(str, "Got a deferred entry without a request: " + "PANIC: %s\n", share_mode_str(num, share_entry)); smb_panic(str); } @@ -610,15 +616,17 @@ static BOOL is_delete_request(files_struct *fsp) { */ static BOOL delay_for_oplocks(struct share_mode_lock *lck, - files_struct *fsp, - int pass_number, - int oplock_request) + files_struct *fsp, + int pass_number, + int oplock_request) { int i; struct share_mode_entry *exclusive = NULL; BOOL valid_entry = False; BOOL delay_it = False; BOOL have_level2 = False; + BOOL ret; + char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; if (oplock_request & INTERNAL_OPEN_ONLY) { fsp->oplock_type = NO_OPLOCK; @@ -682,34 +690,36 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, fsp->oplock_type = FAKE_LEVEL_II_OPLOCK; } - if (delay_it) { - BOOL ret; - char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; + if (!delay_it) { + return False; + } - DEBUG(10, ("Sending break request to PID %s\n", - procid_str_static(&exclusive->pid))); - exclusive->op_mid = get_current_mid(); + /* + * Send a break message to the oplock holder and delay the open for + * our client. + */ - /* Create the message. */ - share_mode_entry_to_message(msg, exclusive); + DEBUG(10, ("Sending break request to PID %s\n", + procid_str_static(&exclusive->pid))); + exclusive->op_mid = get_current_mid(); - /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We don't - want this set in the share mode struct pointed to by lck. */ + /* Create the message. */ + share_mode_entry_to_message(msg, exclusive); - if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) { - SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE); - } + /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We + don't want this set in the share mode struct pointed to by lck. */ - become_root(); - ret = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST, - msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); - unbecome_root(); - if (!ret) { - DEBUG(3, ("Could not send oplock break message\n")); - } + if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) { + SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE); + } + + ret = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST, + msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); + if (!ret) { + DEBUG(3, ("Could not send oplock break message\n")); } - return delay_it; + return True; } static BOOL request_timed_out(struct timeval request_time, @@ -773,17 +783,18 @@ static void defer_open(struct share_mode_lock *lck, srv_defer_sign_response(mid); } + /**************************************************************************** On overwrite open ensure that the attributes match. ****************************************************************************/ static BOOL open_match_attributes(connection_struct *conn, - const char *path, - uint32 old_dos_attr, - uint32 new_dos_attr, - mode_t existing_unx_mode, - mode_t new_unx_mode, - mode_t *returned_unx_mode) + const char *path, + uint32 old_dos_attr, + uint32 new_dos_attr, + mode_t existing_unx_mode, + mode_t new_unx_mode, + mode_t *returned_unx_mode) { uint32 noarch_old_dos_attr, noarch_new_dos_attr; @@ -875,8 +886,8 @@ static files_struct *fcb_or_dos_open(connection_struct *conn, } /* We need to duplicate this fsp. */ - dup_fsp = dup_file_fsp(fsp, access_mask, share_access, create_options); - if (!dup_fsp) { + if (!NT_STATUS_IS_OK(dup_file_fsp(fsp, access_mask, share_access, + create_options, &dup_fsp))) { return NULL; } @@ -888,10 +899,10 @@ static files_struct *fcb_or_dos_open(connection_struct *conn, ****************************************************************************/ BOOL map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func, - uint32 *paccess_mask, - uint32 *pshare_mode, - uint32 *pcreate_disposition, - uint32 *pcreate_options) + uint32 *paccess_mask, + uint32 *pshare_mode, + uint32 *pcreate_disposition, + uint32 *pcreate_options) { uint32 access_mask; uint32 share_mode; @@ -1062,17 +1073,18 @@ static void schedule_defer_open(struct share_mode_lock *lck, struct timeval requ Open a file with a share mode. ****************************************************************************/ -files_struct *open_file_ntcreate(connection_struct *conn, - const char *fname, - SMB_STRUCT_STAT *psbuf, - uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */ - uint32 share_access, /* share constants (FILE_SHARE_READ etc). */ - uint32 create_disposition, /* FILE_OPEN_IF etc. */ - uint32 create_options, /* options such as delete on close. */ - uint32 new_dos_attributes, /* attributes used for new file. */ - int oplock_request, /* internal Samba oplock codes. */ - /* Information (FILE_EXISTS etc.) */ - int *pinfo) +NTSTATUS open_file_ntcreate(connection_struct *conn, + const char *fname, + SMB_STRUCT_STAT *psbuf, + uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */ + uint32 share_access, /* share constants (FILE_SHARE_READ etc) */ + uint32 create_disposition, /* FILE_OPEN_IF etc. */ + uint32 create_options, /* options such as delete on close. */ + uint32 new_dos_attributes, /* attributes used for new file. */ + int oplock_request, /* internal Samba oplock codes. */ + /* Information (FILE_EXISTS etc.) */ + int *pinfo, + files_struct **result) { int flags=0; int flags2=0; @@ -1080,7 +1092,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, BOOL def_acl = False; SMB_DEV_T dev = 0; SMB_INO_T inode = 0; - BOOL fsp_open = False; + NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED; files_struct *fsp = NULL; mode_t new_unx_mode = (mode_t)0; mode_t unx_mode = (mode_t)0; @@ -1093,7 +1105,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, uint32 open_access_mask = access_mask; NTSTATUS status; int ret_flock; - + if (conn->printer) { /* @@ -1107,7 +1119,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n", fname)); - return print_fsp_open(conn, fname); + return print_fsp_open(conn, fname, result); } /* We add aARCH to this as this mode is only used if the file is @@ -1146,7 +1158,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, } if (!check_name(fname,conn)) { - return NULL; + return map_nt_error_from_unix(errno); } new_dos_attributes &= SAMBA_ATTRIBUTES_MASK; @@ -1165,11 +1177,12 @@ files_struct *open_file_ntcreate(connection_struct *conn, if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) { /* OS/2 Workplace shell fix may be main code stream in a later * release. */ - set_saved_error_triple(ERRDOS, ERRcannotopen, - NT_STATUS_OBJECT_NAME_NOT_FOUND); DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not " "supported.\n")); - return NULL; + if (use_nt_status()) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + return NT_STATUS_DOS(ERRDOS, ERRcannotopen); } switch( create_disposition ) { @@ -1197,9 +1210,8 @@ files_struct *open_file_ntcreate(connection_struct *conn, DEBUG(5,("open_file_ntcreate: FILE_OPEN " "requested for file %s and file " "doesn't exist.\n", fname )); - set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND); errno = ENOENT; - return NULL; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } break; @@ -1210,9 +1222,8 @@ files_struct *open_file_ntcreate(connection_struct *conn, DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE " "requested for file %s and file " "doesn't exist.\n", fname )); - set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND); errno = ENOENT; - return NULL; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } flags2 |= O_TRUNC; break; @@ -1229,7 +1240,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, } else { errno = EEXIST; } - return NULL; + return map_nt_error_from_unix(errno); } flags2 |= (O_CREAT|O_EXCL); break; @@ -1241,8 +1252,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, break; default: - set_saved_ntstatus(NT_STATUS_INVALID_PARAMETER); - return NULL; + return NT_STATUS_INVALID_PARAMETER; } /* We only care about matching attributes on file exists and @@ -1261,7 +1271,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, (unsigned int)psbuf->st_mode, (unsigned int)unx_mode )); errno = EACCES; - return NULL; + return NT_STATUS_ACCESS_DENIED; } } @@ -1323,21 +1333,22 @@ files_struct *open_file_ntcreate(connection_struct *conn, DEBUG(5,("open_file_ntcreate: write access requested for " "file %s on read only %s\n", fname, !CAN_WRITE(conn) ? "share" : "file" )); - set_saved_ntstatus(NT_STATUS_ACCESS_DENIED); errno = EACCES; - return NULL; + return NT_STATUS_ACCESS_DENIED; } - fsp = file_new(conn); - if(!fsp) { - return NULL; + status = file_new(conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + return status; } fsp->dev = psbuf->st_dev; fsp->inode = psbuf->st_ino; fsp->share_access = share_access; fsp->fh->private_options = create_options; - fsp->access_mask = open_access_mask; /* We change this to the requested access_mask after the open is done. */ + fsp->access_mask = open_access_mask; /* We change this to the + * requested access_mask after + * the open is done. */ /* Ensure no SAMBA_PRIVATE bits can be set. */ fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK); @@ -1350,14 +1361,13 @@ files_struct *open_file_ntcreate(connection_struct *conn, inode = psbuf->st_ino; lck = get_share_mode_lock(NULL, dev, inode, - conn->connectpath, - fname); + conn->connectpath, + fname); if (lck == NULL) { file_free(fsp); DEBUG(0, ("Could not get share mode lock\n")); - set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION); - return NULL; + return NT_STATUS_SHARING_VIOLATION; } /* First pass - send break only on batch oplocks. */ @@ -1365,31 +1375,33 @@ files_struct *open_file_ntcreate(connection_struct *conn, schedule_defer_open(lck, request_time); TALLOC_FREE(lck); file_free(fsp); - return NULL; + return NT_STATUS_SHARING_VIOLATION; } - /* Use the client requested access mask here, not the one we open with. */ + /* Use the client requested access mask here, not the one we + * open with. */ status = open_mode_check(conn, fname, lck, access_mask, share_access, create_options, &file_existed); if (NT_STATUS_IS_OK(status)) { - /* We might be going to allow this open. Check oplock status again. */ - /* Second pass - send break for both batch or exclusive oplocks. */ + /* We might be going to allow this open. Check oplock + * status again. */ + /* Second pass - send break for both batch or + * exclusive oplocks. */ if (delay_for_oplocks(lck, fsp, 2, oplock_request)) { schedule_defer_open(lck, request_time); TALLOC_FREE(lck); file_free(fsp); - return NULL; + return NT_STATUS_SHARING_VIOLATION; } } if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) { /* DELETE_PENDING is not deferred for a second */ - set_saved_ntstatus(status); TALLOC_FREE(lck); file_free(fsp); - return NULL; + return status; } if (!NT_STATUS_IS_OK(status)) { @@ -1405,7 +1417,8 @@ files_struct *open_file_ntcreate(connection_struct *conn, NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) { files_struct *fsp_dup; - /* Use the client requested access mask here, not the one we open with. */ + /* Use the client requested access mask here, + * not the one we open with. */ fsp_dup = fcb_or_dos_open(conn, fname, dev, inode, access_mask, share_access, @@ -1418,7 +1431,8 @@ files_struct *open_file_ntcreate(connection_struct *conn, *pinfo = FILE_WAS_OPENED; } conn->num_files_open++; - return fsp_dup; + *result = fsp_dup; + return NT_STATUS_OK; } } @@ -1439,10 +1453,10 @@ files_struct *open_file_ntcreate(connection_struct *conn, } if (((flags & O_RDWR) && !CAN_WRITE(conn)) || - !can_access_file(conn,fname,psbuf,can_access_mask)) { + !can_access_file(conn,fname,psbuf,can_access_mask)) { can_access = False; } - + /* * If we're returning a share violation, ensure we * cope with the braindead 1 second delay. @@ -1487,17 +1501,17 @@ files_struct *open_file_ntcreate(connection_struct *conn, } TALLOC_FREE(lck); - if (!can_access) { - set_saved_ntstatus(NT_STATUS_ACCESS_DENIED); - } else { + if (can_access) { /* * We have detected a sharing violation here * so return the correct error code */ - set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION); + status = NT_STATUS_SHARING_VIOLATION; + } else { + status = NT_STATUS_ACCESS_DENIED; } file_free(fsp); - return NULL; + return status; } /* @@ -1528,14 +1542,14 @@ files_struct *open_file_ntcreate(connection_struct *conn, */ fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,unx_mode, - access_mask, open_access_mask); + access_mask, open_access_mask); - if (!fsp_open) { + if (!NT_STATUS_IS_OK(fsp_open)) { if (lck != NULL) { TALLOC_FREE(lck); } file_free(fsp); - return NULL; + return fsp_open; } if (!file_existed) { @@ -1559,15 +1573,15 @@ files_struct *open_file_ntcreate(connection_struct *conn, inode = fsp->inode; lck = get_share_mode_lock(NULL, dev, inode, - conn->connectpath, - fname); + conn->connectpath, + fname); if (lck == NULL) { - DEBUG(0, ("open_file_ntcreate: Could not get share mode lock for %s\n", fname)); + DEBUG(0, ("open_file_ntcreate: Could not get share " + "mode lock for %s\n", fname)); fd_close(conn, fsp); file_free(fsp); - set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION); - return NULL; + return NT_STATUS_SHARING_VIOLATION; } status = open_mode_check(conn, fname, lck, @@ -1594,7 +1608,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, defer_open(lck, request_time, timeval_zero(), &state); TALLOC_FREE(lck); - return NULL; + return status; } /* @@ -1620,11 +1634,9 @@ files_struct *open_file_ntcreate(connection_struct *conn, fd_close(conn, fsp); file_free(fsp); - set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION); - return NULL; + return NT_STATUS_SHARING_VIOLATION; } - /* * At this point onwards, we can guarentee that the share entry * is locked, whether we created the file or not, and that the @@ -1642,10 +1654,11 @@ files_struct *open_file_ntcreate(connection_struct *conn, */ if ((SMB_VFS_FTRUNCATE(fsp,fsp->fh->fd,0) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fh->fd,psbuf)==-1)) { + status = map_nt_error_from_unix(errno); TALLOC_FREE(lck); fd_close(conn,fsp); file_free(fsp); - return NULL; + return status; } } @@ -1693,20 +1706,19 @@ files_struct *open_file_ntcreate(connection_struct *conn, set_share_mode(lck, fsp, current_user.ut.uid, 0, fsp->oplock_type); if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || - info == FILE_WAS_SUPERSEDED) { + info == FILE_WAS_SUPERSEDED) { /* Handle strange delete on close create semantics. */ if (create_options & FILE_DELETE_ON_CLOSE) { - NTSTATUS result = can_set_delete_on_close(fsp, True, new_dos_attributes); + status = can_set_delete_on_close(fsp, True, new_dos_attributes); - if (!NT_STATUS_IS_OK(result)) { + if (!NT_STATUS_IS_OK(status)) { /* Remember to delete the mode we just added. */ del_share_mode(lck, fsp); TALLOC_FREE(lck); fd_close(conn,fsp); file_free(fsp); - set_saved_ntstatus(result); - return NULL; + return status; } /* Note that here we set the *inital* delete on close flag, not the regular one. */ @@ -1734,8 +1746,8 @@ files_struct *open_file_ntcreate(connection_struct *conn, int saved_errno = errno; /* We might get ENOSYS in the next * call.. */ - if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fh->fd, unx_mode) == -1 - && errno == ENOSYS) { + if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fh->fd, unx_mode) == -1 && + errno == ENOSYS) { errno = saved_errno; /* Ignore ENOSYS */ } @@ -1756,7 +1768,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, } else { DEBUG(5, ("open_file_ntcreate: reset " "attributes of file %s to 0%o\n", - fname, (unsigned int)new_unx_mode)); + fname, (unsigned int)new_unx_mode)); ret = 0; /* Don't do the fchmod below. */ } } @@ -1765,7 +1777,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, (SMB_VFS_FCHMOD(fsp, fsp->fh->fd, new_unx_mode) == -1)) DEBUG(5, ("open_file_ntcreate: failed to reset " "attributes of file %s to 0%o\n", - fname, (unsigned int)new_unx_mode)); + fname, (unsigned int)new_unx_mode)); } /* If this is a successful open, we must remove any deferred open @@ -1775,31 +1787,32 @@ files_struct *open_file_ntcreate(connection_struct *conn, conn->num_files_open++; - return fsp; + *result = fsp; + return NT_STATUS_OK; } /**************************************************************************** Open a file for for write to ensure that we can fchmod it. ****************************************************************************/ -files_struct *open_file_fchmod(connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf) +NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf, files_struct **result) { files_struct *fsp = NULL; - BOOL fsp_open; + NTSTATUS status; if (!VALID_STAT(*psbuf)) { - return NULL; + return NT_STATUS_INVALID_PARAMETER; } - fsp = file_new(conn); - if(!fsp) { - return NULL; + status = file_new(conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + return status; } /* note! we must use a non-zero desired access or we don't get a real file descriptor. Oh what a twisted web we weave. */ - fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA,FILE_WRITE_DATA); + status = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA,FILE_WRITE_DATA); /* * This is not a user visible file open. @@ -1807,12 +1820,13 @@ files_struct *open_file_fchmod(connection_struct *conn, const char *fname, * the conn->num_files_open. */ - if (!fsp_open) { + if (!NT_STATUS_IS_OK(status)) { file_free(fsp); - return NULL; + return status; } - return fsp; + *result = fsp; + return NT_STATUS_OK; } /**************************************************************************** @@ -1830,14 +1844,15 @@ int close_file_fchmod(files_struct *fsp) Open a directory from an NT SMB call. ****************************************************************************/ -files_struct *open_directory(connection_struct *conn, - const char *fname, - SMB_STRUCT_STAT *psbuf, - uint32 access_mask, - uint32 share_access, - uint32 create_disposition, - uint32 create_options, - int *pinfo) +NTSTATUS open_directory(connection_struct *conn, + const char *fname, + SMB_STRUCT_STAT *psbuf, + uint32 access_mask, + uint32 share_access, + uint32 create_disposition, + uint32 create_options, + int *pinfo, + files_struct **result) { files_struct *fsp = NULL; BOOL dir_existed = VALID_STAT(*psbuf) ? True : False; @@ -1857,8 +1872,7 @@ files_struct *open_directory(connection_struct *conn, if (is_ntfs_stream_name(fname)) { DEBUG(0,("open_directory: %s is a stream name!\n", fname )); - set_saved_ntstatus(NT_STATUS_NOT_A_DIRECTORY); - return NULL; + return NT_STATUS_NOT_A_DIRECTORY; } switch( create_disposition ) { @@ -1869,8 +1883,7 @@ files_struct *open_directory(connection_struct *conn, DEBUG(5,("open_directory: FILE_OPEN requested " "for directory %s and it doesn't " "exist.\n", fname )); - set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND); - return NULL; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } info = FILE_WAS_OPENED; break; @@ -1882,9 +1895,12 @@ files_struct *open_directory(connection_struct *conn, DEBUG(5,("open_directory: FILE_CREATE " "requested for directory %s and it " "already exists.\n", fname )); - set_saved_error_triple(ERRDOS, ERRfilexists, - NT_STATUS_OBJECT_NAME_COLLISION); - return NULL; + if (use_nt_status()) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } else { + return NT_STATUS_DOS(ERRDOS, + ERRfilexists); + } } create_dir = True; info = FILE_WAS_CREATED; @@ -1908,8 +1924,7 @@ files_struct *open_directory(connection_struct *conn, DEBUG(5,("open_directory: invalid create_disposition " "0x%x for directory %s\n", (unsigned int)create_disposition, fname)); - set_saved_ntstatus(NT_STATUS_INVALID_PARAMETER); - return NULL; + return NT_STATUS_INVALID_PARAMETER; } if (create_dir) { @@ -1926,27 +1941,26 @@ files_struct *open_directory(connection_struct *conn, "Error was %s\n", fname, strerror(errno) )); /* Ensure we return the correct NT status to the * client. */ - set_saved_error_triple(0, 0, status); - return NULL; + return status; } /* Ensure we're checking for a symlink here.... */ /* We don't want to get caught by a symlink racer. */ if(SMB_VFS_LSTAT(conn,fname, psbuf) != 0) { - return NULL; + return map_nt_error_from_unix(errno); } if(!S_ISDIR(psbuf->st_mode)) { DEBUG(0,("open_directory: %s is not a directory !\n", fname )); - return NULL; + return NT_STATUS_NOT_A_DIRECTORY; } } - fsp = file_new(conn); - if(!fsp) { - return NULL; + status = file_new(conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + return status; } /* @@ -1958,7 +1972,7 @@ files_struct *open_directory(connection_struct *conn, fsp->dev = psbuf->st_dev; fsp->vuid = current_user.vuid; fsp->file_pid = global_smbpid; - fsp->can_lock = True; + fsp->can_lock = False; fsp->can_read = False; fsp->can_write = False; @@ -1975,14 +1989,13 @@ files_struct *open_directory(connection_struct *conn, string_set(&fsp->fsp_name,fname); lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, - conn->connectpath, - fname); + conn->connectpath, + fname); if (lck == NULL) { DEBUG(0, ("open_directory: Could not get share mode lock for %s\n", fname)); file_free(fsp); - set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION); - return NULL; + return NT_STATUS_SHARING_VIOLATION; } status = open_mode_check(conn, fname, lck, @@ -1990,10 +2003,9 @@ files_struct *open_directory(connection_struct *conn, create_options, &dir_existed); if (!NT_STATUS_IS_OK(status)) { - set_saved_ntstatus(status); TALLOC_FREE(lck); file_free(fsp); - return NULL; + return status; } set_share_mode(lck, fsp, current_user.ut.uid, 0, NO_OPLOCK); @@ -2003,10 +2015,9 @@ files_struct *open_directory(connection_struct *conn, if (create_options & FILE_DELETE_ON_CLOSE) { status = can_set_delete_on_close(fsp, True, 0); if (!NT_STATUS_IS_OK(status)) { - set_saved_ntstatus(status); TALLOC_FREE(lck); file_free(fsp); - return NULL; + return status; } set_delete_on_close_token(lck, ¤t_user.ut); @@ -2027,28 +2038,33 @@ files_struct *open_directory(connection_struct *conn, conn->num_files_open++; - return fsp; + *result = fsp; + return NT_STATUS_OK; } /**************************************************************************** Open a pseudo-file (no locking checks - a 'stat' open). ****************************************************************************/ -files_struct *open_file_stat(connection_struct *conn, char *fname, - SMB_STRUCT_STAT *psbuf) +NTSTATUS open_file_stat(connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf, files_struct **result) { files_struct *fsp = NULL; + NTSTATUS status; - if (!VALID_STAT(*psbuf)) - return NULL; + if (!VALID_STAT(*psbuf)) { + return NT_STATUS_INVALID_PARAMETER; + } /* Can't 'stat' open directories. */ - if(S_ISDIR(psbuf->st_mode)) - return NULL; + if(S_ISDIR(psbuf->st_mode)) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } - fsp = file_new(conn); - if(!fsp) - return NULL; + status = file_new(conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + return status; + } DEBUG(5,("open_file_stat: 'opening' file %s\n", fname)); @@ -2074,7 +2090,8 @@ files_struct *open_file_stat(connection_struct *conn, char *fname, conn->num_files_open++; - return fsp; + *result = fsp; + return NT_STATUS_OK; } /**************************************************************************** diff --git a/source/smbd/oplock_linux.c b/source/smbd/oplock_linux.c index f186c13ebdd..518283c587e 100644 --- a/source/smbd/oplock_linux.c +++ b/source/smbd/oplock_linux.c @@ -89,7 +89,8 @@ static void set_capability(unsigned capability) header.pid = 0; if (capget(&header, &data) == -1) { - DEBUG(3,("Unable to get kernel capabilities (%s)\n", strerror(errno))); + DEBUG(3,("Unable to get kernel capabilities (%s)\n", + strerror(errno))); return; } @@ -156,15 +157,18 @@ static files_struct *linux_oplock_receive_message(fd_set *fds) static BOOL linux_set_kernel_oplock(files_struct *fsp, int oplock_type) { if (linux_setlease(fsp->fh->fd, F_WRLCK) == -1) { - DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, fd = %d, dev = %x, \ -inode = %.0f. (%s)\n", + DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, " + "fd = %d, dev = %x, inode = %.0f. (%s)\n", fsp->fsp_name, fsp->fh->fd, - (unsigned int)fsp->dev, (double)fsp->inode, strerror(errno))); + (unsigned int)fsp->dev, (double)fsp->inode, + strerror(errno))); return False; } - DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f, file_id = %lu\n", - fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->fh->file_id)); + DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, " + "dev = %x, inode = %.0f, file_id = %lu\n", + fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, + fsp->fh->file_id)); return True; } @@ -181,8 +185,9 @@ static void linux_release_kernel_oplock(files_struct *fsp) * oplock state of this file. */ int state = fcntl(fsp->fh->fd, F_GETLEASE, 0); - dbgtext("linux_release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %lu has kernel \ -oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, + dbgtext("linux_release_kernel_oplock: file %s, dev = %x, " + "inode = %.0f file_id = %lu has kernel oplock state " + "of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->fh->file_id, state ); } @@ -191,10 +196,12 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, */ if (linux_setlease(fsp->fh->fd, F_UNLCK) == -1) { if (DEBUGLVL(0)) { - dbgtext("linux_release_kernel_oplock: Error when removing kernel oplock on file " ); - dbgtext("%s, dev = %x, inode = %.0f, file_id = %lu. Error was %s\n", - fsp->fsp_name, (unsigned int)fsp->dev, - (double)fsp->inode, fsp->fh->file_id, strerror(errno) ); + dbgtext("linux_release_kernel_oplock: Error when " + "removing kernel oplock on file " ); + dbgtext("%s, dev = %x, inode = %.0f, file_id = %lu. " + "Error was %s\n", fsp->fsp_name, + (unsigned int)fsp->dev, (double)fsp->inode, + fsp->fh->file_id, strerror(errno) ); } } } diff --git a/source/smbd/password.c b/source/smbd/password.c index 814065dd34a..38000e93f4b 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -29,9 +29,6 @@ static user_struct *validated_users; static int next_vuid = VUID_OFFSET; static int num_validated_vuids; -extern userdom_struct current_user_info; - - /**************************************************************************** Check if a uid has been validated, and return an pointer to the user_struct if it has. NULL if not. vuid is biased by an offset. This allows us to @@ -549,9 +546,11 @@ static BOOL user_ok(const char *user, int snum) str_list_copy(&invalid, lp_invalid_users(snum)); if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { - if ( invalid && - str_list_sub_basic(invalid, - current_user_info.smb_name) ) { + + /* This is used in sec=share only, so no current user + * around to pass to str_list_sub_basic() */ + + if ( invalid && str_list_sub_basic(invalid, "", "") ) { ret = !user_in_list(user, (const char **)invalid); } @@ -564,9 +563,11 @@ static BOOL user_ok(const char *user, int snum) str_list_copy(&valid, lp_valid_users(snum)); if ( valid && str_list_substitute(valid, "%S", lp_servicename(snum)) ) { - if ( valid && - str_list_sub_basic(valid, - current_user_info.smb_name) ) { + + /* This is used in sec=share only, so no current user + * around to pass to str_list_sub_basic() */ + + if ( valid && str_list_sub_basic(valid, "", "") ) { ret = user_in_list(user, (const char **)valid); } } diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c index 2d90383706b..52660da2ffe 100644 --- a/source/smbd/pipes.c +++ b/source/smbd/pipes.c @@ -31,6 +31,21 @@ #define PIPE "\\PIPE\\" #define PIPELEN strlen(PIPE) +#define MAX_PIPE_NAME_LEN 24 + +/* PIPE/<name>/<pid>/<pnum> */ +#define PIPEDB_KEY_FORMAT "PIPE/%s/%u/%d" + +struct pipe_dbrec { + struct process_id pid; + int pnum; + uid_t uid; + + char name[MAX_PIPE_NAME_LEN]; + fstring user; +}; + + extern struct pipe_id_info pipe_names[]; /**************************************************************************** @@ -284,6 +299,8 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) if (!close_rpc_pipe_hnd(p)) { return ERROR_DOS(ERRDOS,ERRbadfid); } + + /* TODO: REMOVE PIPE FROM DB */ return(outsize); } diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c index 1c2cf3091fe..4cdb0908ce8 100644 --- a/source/smbd/posix_acls.c +++ b/source/smbd/posix_acls.c @@ -169,7 +169,7 @@ static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, B *store_size = PAI_ENTRIES_BASE + ((num_entries + num_def_entries)*PAI_ENTRY_LENGTH); - pai_buf = SMB_MALLOC(*store_size); + pai_buf = (char *)SMB_MALLOC(*store_size); if (!pai_buf) { return NULL; } @@ -441,7 +441,7 @@ static struct pai_val *load_inherited_info(files_struct *fsp) if (!lp_map_acl_inherit(SNUM(fsp->conn))) return NULL; - if ((pai_buf = SMB_MALLOC(pai_buf_size)) == NULL) + if ((pai_buf = (char *)SMB_MALLOC(pai_buf_size)) == NULL) return NULL; do { @@ -462,7 +462,7 @@ static struct pai_val *load_inherited_info(files_struct *fsp) if (pai_buf_size > 1024*1024) { return NULL; /* Limit malloc to 1mb. */ } - if ((pai_buf = SMB_MALLOC(pai_buf_size)) == NULL) + if ((pai_buf = (char *)SMB_MALLOC(pai_buf_size)) == NULL) return NULL; } } while (ret == -1); @@ -860,36 +860,36 @@ static SEC_ACCESS map_canon_ace_perms(int snum, int *pacl_type, DOM_SID *powner_ #define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA|FILE_WRITE_ATTRIBUTES) #define FILE_SPECIFIC_EXECUTE_BITS (FILE_EXECUTE) -static mode_t map_nt_perms( SEC_ACCESS sec_access, int type) +static mode_t map_nt_perms( uint32 *mask, int type) { mode_t mode = 0; switch(type) { case S_IRUSR: - if(sec_access.mask & GENERIC_ALL_ACCESS) + if((*mask) & GENERIC_ALL_ACCESS) mode = S_IRUSR|S_IWUSR|S_IXUSR; else { - mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRUSR : 0; - mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWUSR : 0; - mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXUSR : 0; + mode |= ((*mask) & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRUSR : 0; + mode |= ((*mask) & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWUSR : 0; + mode |= ((*mask) & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXUSR : 0; } break; case S_IRGRP: - if(sec_access.mask & GENERIC_ALL_ACCESS) + if((*mask) & GENERIC_ALL_ACCESS) mode = S_IRGRP|S_IWGRP|S_IXGRP; else { - mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRGRP : 0; - mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWGRP : 0; - mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXGRP : 0; + mode |= ((*mask) & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRGRP : 0; + mode |= ((*mask) & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWGRP : 0; + mode |= ((*mask) & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXGRP : 0; } break; case S_IROTH: - if(sec_access.mask & GENERIC_ALL_ACCESS) + if((*mask) & GENERIC_ALL_ACCESS) mode = S_IROTH|S_IWOTH|S_IXOTH; else { - mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IROTH : 0; - mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWOTH : 0; - mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXOTH : 0; + mode |= ((*mask) & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IROTH : 0; + mode |= ((*mask) & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWOTH : 0; + mode |= ((*mask) & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXOTH : 0; } break; } @@ -1408,7 +1408,7 @@ static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst, * S_I(R|W|X)USR bits. */ - current_ace->perms |= map_nt_perms( psa->info, S_IRUSR); + current_ace->perms |= map_nt_perms( &psa->info.mask, S_IRUSR); current_ace->attr = (psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED) ? ALLOW_ACE : DENY_ACE; current_ace->inherited = ((psa->flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False); @@ -3031,8 +3031,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) return -1; } - fsp = open_file_fchmod(conn,fname,&st); - if (!fsp) { + if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,&st,&fsp))) { return -1; } @@ -4351,7 +4350,7 @@ SEC_DESC* get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname) DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n")); return NULL; } - + if (!(conn.params = TALLOC_P(conn.mem_ctx, struct share_params))) { DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n")); TALLOC_FREE(conn.mem_ctx); diff --git a/source/smbd/process.c b/source/smbd/process.c index c5485defc9b..cf61e16a157 100644 --- a/source/smbd/process.c +++ b/source/smbd/process.c @@ -21,7 +21,7 @@ #include "includes.h" -extern uint16 global_smbpid; +uint16 global_smbpid; extern int keepalive; extern struct auth_context *negprot_global_auth_context; extern int smb_echo_count; @@ -171,7 +171,6 @@ BOOL open_was_deferred(uint16 mid) for (pml = deferred_open_queue; pml; pml = pml->next) { if (SVAL(pml->buf.data,smb_mid) == mid) { - set_saved_ntstatus(NT_STATUS_OK); return True; } } @@ -462,11 +461,11 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout) int sav; START_PROFILE(smbd_idle); - maxfd = select_on_fd(smbd_server_fd(), maxfd, &fds); - maxfd = select_on_fd(change_notify_fd(), maxfd, &fds); - maxfd = select_on_fd(oplock_notify_fd(), maxfd, &fds); + maxfd = select_on_fd(smbd_server_fd(), maxfd, &fds); + maxfd = select_on_fd(change_notify_fd(), maxfd, &fds); + maxfd = select_on_fd(oplock_notify_fd(), maxfd, &fds); - selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to); + selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to); sav = errno; END_PROFILE(smbd_idle); @@ -893,7 +892,6 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize pid = sys_getpid(); errno = 0; - set_saved_ntstatus(NT_STATUS_OK); last_message = type; @@ -962,7 +960,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize } if (!change_to_user(conn,session_tag)) { - return(ERROR_FORCE_DOS(ERRSRV,ERRbaduid)); + return(ERROR_NT(NT_STATUS_DOS(ERRSRV,ERRbaduid))); } /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */ @@ -1033,60 +1031,6 @@ static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize) } /**************************************************************************** - Keep track of the number of running smbd's. This functionality is used to - 'hard' limit Samba overhead on resource constrained systems. -****************************************************************************/ - -static BOOL process_count_update_successful = False; - -static int32 increment_smbd_process_count(void) -{ - int32 total_smbds; - - if (lp_max_smbd_processes()) { - total_smbds = 0; - if (tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, 1) == -1) - return 1; - process_count_update_successful = True; - return total_smbds + 1; - } - return 1; -} - -void decrement_smbd_process_count(void) -{ - int32 total_smbds; - - if (lp_max_smbd_processes() && process_count_update_successful) { - total_smbds = 1; - tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, -1); - } -} - -static BOOL smbd_process_limit(void) -{ - int32 total_smbds; - - if (lp_max_smbd_processes()) { - - /* Always add one to the smbd process count, as exit_server() always - * subtracts one. - */ - - if (!conn_tdb_ctx()) { - DEBUG(0,("smbd_process_limit: max smbd processes parameter set with status parameter not \ -set. Ignoring max smbd restriction.\n")); - return False; - } - - total_smbds = increment_smbd_process_count(); - return total_smbds > lp_max_smbd_processes(); - } - else - return False; -} - -/**************************************************************************** Process an smb from the client ****************************************************************************/ @@ -1104,8 +1048,8 @@ static void process_smb(char *inbuf, char *outbuf) deny parameters before doing any parsing of the packet passed to us by the client. This prevents attacks on our parsing code from hosts not in the hosts allow list */ - if (smbd_process_limit() || - !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) { + if (!check_access(smbd_server_fd(), lp_hostsallow(-1), + lp_hostsdeny(-1))) { /* send a negative session response "not listening on calling name" */ static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; DEBUG( 1, ( "Connection denied from %s\n", client_addr() ) ); @@ -1277,7 +1221,7 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize) } /**************************************************************************** - Setup the needed select timeout. + Setup the needed select timeout in milliseconds. ****************************************************************************/ static int setup_select_timeout(void) @@ -1285,16 +1229,17 @@ static int setup_select_timeout(void) int select_timeout; int t; - select_timeout = blocking_locks_timeout(SMBD_SELECT_TIMEOUT); - select_timeout *= 1000; + select_timeout = blocking_locks_timeout_ms(SMBD_SELECT_TIMEOUT*1000); t = change_notify_timeout(); DEBUG(10, ("change_notify_timeout: %d\n", t)); - if (t != -1) + if (t != -1) { select_timeout = MIN(select_timeout, t*1000); + } - if (print_notify_messages_pending()) + if (print_notify_messages_pending()) { select_timeout = MIN(select_timeout, 1000); + } return select_timeout; } @@ -1483,7 +1428,7 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup())); * Check to see if we have any blocking locks * outstanding on the queue. */ - process_blocking_lock_queue(t); + process_blocking_lock_queue(); /* update printer queue caches if necessary */ diff --git a/source/smbd/reply.c b/source/smbd/reply.c index bbca95b0d30..a0596643f81 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -448,6 +448,7 @@ size_t srvstr_get_path_wcard(char *inbuf, char *dest, const char *src, size_t de } else { *err = check_path_syntax_wcard(dest, tmppath, contains_wcard); } + return ret; } @@ -474,6 +475,7 @@ size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len } else { *err = check_path_syntax(dest, tmppath); } + return ret; } @@ -830,6 +832,14 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBchkpth); + + /* Strange DOS error code semantics only for chkpth... */ + if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) { + if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) { + /* We need to map to ERRbadpath */ + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + } return ERROR_NT(status); } @@ -1391,25 +1401,25 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask, &share_mode, &create_disposition, &create_options)) { END_PROFILE(SMBopen); - return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess); + return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess)); } - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_mode, create_disposition, create_options, dos_attr, oplock_request, - &info); + &info, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBopen); if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess); + return ERROR_NT(status); } size = sbuf.st_size; @@ -1514,25 +1524,25 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt &create_disposition, &create_options)) { END_PROFILE(SMBopenX); - return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess); + return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess)); } - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_mode, create_disposition, create_options, smb_attr, oplock_request, - &smb_action); + &smb_action, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBopenX); if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess); + return ERROR_NT(status); } size = sbuf.st_size; @@ -1693,22 +1703,22 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, } /* Open file using ntcreate. */ - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_mode, create_disposition, create_options, fattr, oplock_request, - NULL); + NULL, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBcreate); if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess); + return ERROR_NT(status); } outsize = set_message(outbuf,1,0,True); @@ -1777,25 +1787,25 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, SMB_VFS_STAT(conn,fname,&sbuf); /* We should fail if file does not exist. */ - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, FILE_GENERIC_READ | FILE_GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, fattr, oplock_request, - NULL); + NULL, &fsp); /* close fd from smb_mkstemp() */ close(tmpfd); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBctemp); if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; } - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess); + return ERROR_NT(status); } outsize = set_message(outbuf,1,0,True); @@ -1843,6 +1853,7 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype, { files_struct *fsp; uint32 fmode; + NTSTATUS status; if (!CAN_WRITE(conn)) { return NT_STATUS_MEDIA_WRITE_PROTECTED; @@ -1857,25 +1868,16 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype, return NT_STATUS_OK; } - /* We need a better way to return NT status codes from open... */ - set_saved_ntstatus(NT_STATUS_OK); - - fsp = open_file_ntcreate(conn, fname, pst, + status = open_file_ntcreate(conn, fname, pst, DELETE_ACCESS, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, 0, - NULL); + NULL, &fsp); - if (!fsp) { - NTSTATUS ret = get_saved_ntstatus(); - if (!NT_STATUS_IS_OK(ret)) { - set_saved_ntstatus(NT_STATUS_OK); - return ret; - } - set_saved_ntstatus(NT_STATUS_OK); + if (!NT_STATUS_IS_OK(status)) { return NT_STATUS_ACCESS_DENIED; } close_file(fsp,NORMAL_CLOSE); @@ -1891,6 +1893,7 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b SMB_STRUCT_STAT sbuf; uint32 fattr; files_struct *fsp; + NTSTATUS status; DEBUG(10,("can_delete: %s, dirtype = %d\n", fname, dirtype )); @@ -1950,26 +1953,17 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b /* On open checks the open itself will check the share mode, so don't do it here as we'll get it wrong. */ - /* We need a better way to return NT status codes from open... */ - set_saved_ntstatus(NT_STATUS_OK); - - fsp = open_file_ntcreate(conn, fname, &sbuf, + status = open_file_ntcreate(conn, fname, &sbuf, DELETE_ACCESS, FILE_SHARE_NONE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, 0, - NULL); + NULL, &fsp); - if (!fsp) { - NTSTATUS ret = get_saved_ntstatus(); - if (!NT_STATUS_IS_OK(ret)) { - set_saved_ntstatus(NT_STATUS_OK); - return ret; - } - set_saved_ntstatus(NT_STATUS_OK); - return NT_STATUS_ACCESS_DENIED; + if (!NT_STATUS_IS_OK(status)) { + return status; } close_file(fsp,NORMAL_CLOSE); } @@ -2352,7 +2346,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s /* ensure we don't overrun the packet size */ maxcount = MIN(65535,maxcount); - if (!is_locked(fsp,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (!is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) { SMB_STRUCT_STAT st; SMB_OFF_T size = 0; @@ -2398,7 +2392,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length size_t numtoread; NTSTATUS status; files_struct *fsp = file_fsp(inbuf,smb_vwv0); - BOOL my_lock_ctx = False; + struct byte_range_lock *br_lck = NULL; START_PROFILE(SMBlockread); CHECK_FSP(fsp,conn); @@ -2423,42 +2417,17 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length * Note that the requested lock size is unaffected by max_recv. */ - status = do_lock_spin(fsp, - SVAL(inbuf,smb_pid), - (SMB_BIG_UINT)numtoread, - (SMB_BIG_UINT)startpos, - WRITE_LOCK, - WINDOWS_LOCK, - &my_lock_ctx); + br_lck = do_lock(fsp, + (uint32)SVAL(inbuf,smb_pid), + (SMB_BIG_UINT)numtoread, + (SMB_BIG_UINT)startpos, + WRITE_LOCK, + WINDOWS_LOCK, + False, /* Non-blocking lock. */ + &status); + TALLOC_FREE(br_lck); if (NT_STATUS_V(status)) { -#if 0 - /* - * We used to make lockread a blocking lock. It turns out - * that this isn't on W2k. Found by the Samba 4 RAW-READ torture - * tester. JRA. - */ - - if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) { - /* - * A blocking lock was requested. Package up - * this smb into a queued request and push it - * onto the blocking lock queue. - */ - if(push_blocking_lock_request(inbuf, length, - fsp, - -1, - 0, - SVAL(inbuf,smb_pid), - WRITE_LOCK, - WINDOWS_LOCK, - (SMB_BIG_UINT)startpos, - (SMB_BIG_UINT)numtoread)) { - END_PROFILE(SMBlockread); - return -1; - } - } -#endif END_PROFILE(SMBlockread); return ERROR_NT(status); } @@ -2531,7 +2500,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", data = smb_buf(outbuf) + 3; - if (is_locked(fsp,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) { END_PROFILE(SMBread); return ERROR_DOS(ERRDOS,ERRlock); } @@ -2738,7 +2707,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt } - if (is_locked(fsp,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) { END_PROFILE(SMBreadX); return ERROR_DOS(ERRDOS,ERRlock); } @@ -2801,7 +2770,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, SCVAL(inbuf,smb_com,SMBwritec); SCVAL(outbuf,smb_com,SMBwritec); - if (is_locked(fsp,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { END_PROFILE(SMBwritebraw); return(ERROR_DOS(ERRDOS,ERRlock)); } @@ -2859,6 +2828,10 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, } nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite); + if (nwritten == -1) { + END_PROFILE(SMBwritebraw); + return(UNIXERROR(ERRHRD,ERRdiskfull)); + } if (nwritten < (ssize_t)numtowrite) { SCVAL(outbuf,smb_rcls,ERRHRD); @@ -2922,7 +2895,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); data = smb_buf(inbuf) + 3; - if (numtowrite && is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { END_PROFILE(SMBwriteunlock); return ERROR_DOS(ERRDOS,ERRlock); } @@ -2945,7 +2918,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, if (numtowrite) { status = do_unlock(fsp, - SVAL(inbuf,smb_pid), + (uint32)SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite, (SMB_BIG_UINT)startpos, WINDOWS_LOCK); @@ -2999,7 +2972,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); data = smb_buf(inbuf) + 3; - if (is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { END_PROFILE(SMBwrite); return ERROR_DOS(ERRDOS,ERRlock); } @@ -3114,7 +3087,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng #endif /* LARGE_SMB_OFF_T */ } - if (is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { END_PROFILE(SMBwriteX); return ERROR_DOS(ERRDOS,ERRlock); } @@ -3389,7 +3362,7 @@ int reply_writeclose(connection_struct *conn, mtime = srv_make_unix_date3(inbuf+smb_vwv4); data = smb_buf(inbuf) + 1; - if (numtowrite && is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { END_PROFILE(SMBwriteclose); return ERROR_DOS(ERRDOS,ERRlock); } @@ -3445,7 +3418,7 @@ int reply_lock(connection_struct *conn, SMB_BIG_UINT count,offset; NTSTATUS status; files_struct *fsp = file_fsp(inbuf,smb_vwv0); - BOOL my_lock_ctx = False; + struct byte_range_lock *br_lck = NULL; START_PROFILE(SMBlock); @@ -3459,35 +3432,18 @@ int reply_lock(connection_struct *conn, DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n", fsp->fh->fd, fsp->fnum, (double)offset, (double)count)); - status = do_lock_spin(fsp, - SVAL(inbuf,smb_pid), - count, - offset, - WRITE_LOCK, - WINDOWS_LOCK, - &my_lock_ctx); + br_lck = do_lock(fsp, + (uint32)SVAL(inbuf,smb_pid), + count, + offset, + WRITE_LOCK, + WINDOWS_LOCK, + False, /* Non-blocking lock. */ + &status); + + TALLOC_FREE(br_lck); + if (NT_STATUS_V(status)) { -#if 0 - /* Tests using Samba4 against W2K show this call never creates a blocking lock. */ - if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) { - /* - * A blocking lock was requested. Package up - * this smb into a queued request and push it - * onto the blocking lock queue. - */ - if(push_blocking_lock_request(inbuf, length, - fsp, - -1, - 0, - SVAL(inbuf,smb_pid), - WRITE_LOCK, - WINDOWS_LOCK, - offset, count)) { - END_PROFILE(SMBlock); - return -1; - } - } -#endif END_PROFILE(SMBlock); return ERROR_NT(status); } @@ -3515,7 +3471,7 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3); status = do_unlock(fsp, - SVAL(inbuf,smb_pid), + (uint32)SVAL(inbuf,smb_pid), count, offset, WINDOWS_LOCK); @@ -3619,6 +3575,8 @@ int reply_printopen(connection_struct *conn, { int outsize = 0; files_struct *fsp; + NTSTATUS status; + START_PROFILE(SMBsplopen); if (!CAN_PRINT(conn)) { @@ -3627,11 +3585,11 @@ int reply_printopen(connection_struct *conn, } /* Open for exclusive use, write only. */ - fsp = print_fsp_open(conn, NULL); + status = print_fsp_open(conn, NULL, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBsplopen); - return(UNIXERROR(ERRDOS,ERRnoaccess)); + return(ERROR_NT(status)); } outsize = set_message(outbuf,1,0,True); @@ -3859,6 +3817,17 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, status = mkdir_internal(conn, directory,bad_path); if (!NT_STATUS_IS_OK(status)) { + + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION) && + !use_nt_status()) { + /* + * Yes, in the DOS error code case we get a + * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR + * samba4 torture test. + */ + status = NT_STATUS_DOS(ERRDOS, ERRnoaccess); + } + END_PROFILE(SMBmkdir); return ERROR_NT(status); } @@ -4760,6 +4729,7 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, pstring dest; uint32 dosattrs; uint32 new_create_disposition; + NTSTATUS status; *err_ret = 0; @@ -4788,16 +4758,16 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, } } - fsp1 = open_file_ntcreate(conn,src,&src_sbuf, + status = open_file_ntcreate(conn,src,&src_sbuf, FILE_GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - NULL); + NULL, &fsp1); - if (!fsp1) { + if (!NT_STATUS_IS_OK(status)) { return(False); } @@ -4806,16 +4776,16 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, ZERO_STRUCTP(&sbuf2); } - fsp2 = open_file_ntcreate(conn,dest,&sbuf2, + status = open_file_ntcreate(conn,dest,&sbuf2, FILE_GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, new_create_disposition, 0, dosattrs, INTERNAL_OPEN_ONLY, - NULL); + NULL, &fsp2); - if (!fsp2) { + if (!NT_STATUS_IS_OK(status)) { close_file(fsp1,ERROR_CLOSE); return(False); } @@ -5016,8 +4986,12 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, END_PROFILE(SMBcopy); return ERROR_DOS(ERRDOS,error); } else { - if((errno == ENOENT) && (bad_path1 || bad_path2)) { - set_saved_error_triple(ERRDOS, ERRbadpath, NT_STATUS_OK); + if((errno == ENOENT) && (bad_path1 || bad_path2) && + !use_nt_status()) { + /* Samba 3.0.22 has ERRDOS/ERRbadpath in the + * DOS error code case + */ + return ERROR_DOS(ERRDOS, ERRbadpath); } END_PROFILE(SMBcopy); return(UNIXERROR(ERRDOS,error)); @@ -5088,12 +5062,12 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size Get a lock pid, dealing with large count requests. ****************************************************************************/ -uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format) +uint32 get_lock_pid( char *data, int data_offset, BOOL large_file_format) { if(!large_file_format) - return SVAL(data,SMB_LPID_OFFSET(data_offset)); + return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset)); else - return SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset)); + return (uint32)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset)); } /**************************************************************************** @@ -5230,14 +5204,13 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf, uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); SMB_BIG_UINT count = 0, offset = 0; - uint16 lock_pid; + uint32 lock_pid; int32 lock_timeout = IVAL(inbuf,smb_vwv4); int i; char *data; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False; BOOL err; - BOOL my_lock_ctx = False; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; START_PROFILE(SMBlockingX); @@ -5250,12 +5223,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf, /* we don't support these - and CANCEL_LOCK makes w2k and XP reboot so I don't really want to be compatible! (tridge) */ - return ERROR_FORCE_DOS(ERRDOS, ERRnoatomiclocks); - } - - if (locktype & LOCKING_ANDX_CANCEL_LOCK) { - /* Need to make this like a cancel.... JRA. */ - return ERROR_NT(NT_STATUS_UNSUCCESSFUL); + return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks)); } /* Check if this is an oplock break on a file @@ -5369,7 +5337,9 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf, /* Setup the timeout in seconds. */ - lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000); + if (!lp_blocking_locks(SNUM(conn))) { + lock_timeout = 0; + } /* Now do any requested locks */ data += ((large_file_format ? 20 : 10)*num_ulocks); @@ -5378,7 +5348,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf, of smb_lkrng structs */ for(i = 0; i < (int)num_locks; i++) { - enum brl_type lock_type = ((locktype & 1) ? READ_LOCK:WRITE_LOCK); + enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ? + READ_LOCK:WRITE_LOCK); lock_pid = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); @@ -5396,50 +5367,101 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf, (double)count, (unsigned int)lock_pid, fsp->fsp_name, (int)lock_timeout )); - status = do_lock_spin(fsp, + if (locktype & LOCKING_ANDX_CANCEL_LOCK) { + if (lp_blocking_locks(SNUM(conn))) { + + /* Schedule a message to ourselves to + remove the blocking lock record and + return the right error. */ + + if (!blocking_lock_cancel(fsp, + lock_pid, + offset, + count, + WINDOWS_LOCK, + locktype, + NT_STATUS_FILE_LOCK_CONFLICT)) { + END_PROFILE(SMBlockingX); + return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRcancelviolation)); + } + } + /* Remove a matching pending lock. */ + status = do_lock_cancel(fsp, + lock_pid, + count, + offset, + WINDOWS_LOCK); + } else { + BOOL blocking_lock = lock_timeout ? True : False; + BOOL defer_lock = False; + struct byte_range_lock *br_lck; + + br_lck = do_lock(fsp, lock_pid, count, offset, lock_type, WINDOWS_LOCK, - &my_lock_ctx); + blocking_lock, + &status); + + if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) { + /* Windows internal resolution for blocking locks seems + to be about 200ms... Don't wait for less than that. JRA. */ + if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) { + lock_timeout = lp_lock_spin_time(); + } + defer_lock = True; + } - if (NT_STATUS_V(status)) { - /* - * Interesting fact found by IFSTEST /t - * LockOverlappedTest... Even if it's our own lock - * context, we need to wait here as there may be an - * unlock on the way. So I removed a "&& - * !my_lock_ctx" from the following if statement. JRA. - */ - if ((lock_timeout != 0) && - lp_blocking_locks(SNUM(conn)) && - ERROR_WAS_LOCK_DENIED(status)) { + /* This heuristic seems to match W2K3 very well. If a + lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT + it pretends we asked for a timeout of between 150 - 300 milliseconds as + far as I can tell. Replacement for do_lock_spin(). JRA. */ + + if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock && + NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) { + defer_lock = True; + lock_timeout = lp_lock_spin_time(); + } + + if (br_lck && defer_lock) { /* * A blocking lock was requested. Package up * this smb into a queued request and push it * onto the blocking lock queue. */ - if(push_blocking_lock_request(inbuf, length, - fsp, - lock_timeout, - i, - lock_pid, - lock_type, - WINDOWS_LOCK, - offset, - count)) { + if(push_blocking_lock_request(br_lck, + inbuf, length, + fsp, + lock_timeout, + i, + lock_pid, + lock_type, + WINDOWS_LOCK, + offset, + count)) { + TALLOC_FREE(br_lck); END_PROFILE(SMBlockingX); return -1; } } - break; + + TALLOC_FREE(br_lck); + } + + if (NT_STATUS_V(status)) { + END_PROFILE(SMBlockingX); + return ERROR_NT(status); } } /* If any of the above locks failed, then we must unlock all of the previous locks (X/Open spec). */ - if (i != num_locks && num_locks != 0) { + + if (!(locktype & LOCKING_ANDX_CANCEL_LOCK) && + (i != num_locks) && + (num_locks != 0)) { /* * Ensure we don't do a remove on the lock that just failed, * as under POSIX rules, if we have a lock already there, we @@ -5526,7 +5548,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, tcount = maxcount; total_read = 0; - if (is_locked(fsp,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) { END_PROFILE(SMBreadBmpx); return ERROR_DOS(ERRDOS,ERRlock); } @@ -5658,7 +5680,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, not an SMBwritebmpx - set this up now so we don't forget */ SCVAL(outbuf,smb_com,SMBwritec); - if (is_locked(fsp,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) { + if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) { END_PROFILE(SMBwriteBmpx); return(ERROR_DOS(ERRDOS,ERRlock)); } diff --git a/source/smbd/server.c b/source/smbd/server.c index 2bfeae9f541..593e2bfb12d 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -36,6 +36,7 @@ extern struct auth_context *negprot_global_auth_context; extern pstring user_socket_options; extern SIG_ATOMIC_T got_sig_term; extern SIG_ATOMIC_T reload_after_sighup; +static SIG_ATOMIC_T got_sig_cld; #ifdef WITH_DFS extern int dcelogin_atmost_once; @@ -93,6 +94,15 @@ static void sig_hup(int sig) } /**************************************************************************** + Catch a sigcld +****************************************************************************/ +static void sig_cld(int sig) +{ + got_sig_cld = 1; + sys_select_signal(SIGCLD); +} + +/**************************************************************************** Send a SIGTERM to our process group. *****************************************************************************/ @@ -189,6 +199,54 @@ static void msg_inject_fault(int msg_type, struct process_id src, } #endif /* DEVELOPER */ +struct child_pid { + struct child_pid *prev, *next; + pid_t pid; +}; + +static struct child_pid *children; +static int num_children; + +static void add_child_pid(pid_t pid) +{ + struct child_pid *child; + + if (lp_max_smbd_processes() == 0) { + /* Don't bother with the child list if we don't care anyway */ + return; + } + + child = SMB_MALLOC_P(struct child_pid); + if (child == NULL) { + DEBUG(0, ("Could not add child struct -- malloc failed\n")); + return; + } + child->pid = pid; + DLIST_ADD(children, child); + num_children += 1; +} + +static void remove_child_pid(pid_t pid) +{ + struct child_pid *child; + + if (lp_max_smbd_processes() == 0) { + /* Don't bother with the child list if we don't care anyway */ + return; + } + + for (child = children; child != NULL; child = child->next) { + if (child->pid == pid) { + struct child_pid *tmp = child; + DLIST_REMOVE(children, child); + SAFE_FREE(tmp); + num_children -= 1; + return; + } + } + + DEBUG(0, ("Could not find child %d -- ignoring\n", (int)pid)); +} /**************************************************************************** Have we reached the process limit ? @@ -201,27 +259,7 @@ static BOOL allowable_number_of_smbd_processes(void) if (!max_processes) return True; - { - TDB_CONTEXT *tdb = conn_tdb_ctx(); - int32 val; - if (!tdb) { - DEBUG(0,("allowable_number_of_smbd_processes: can't open connection tdb.\n" )); - return False; - } - - val = tdb_fetch_int32(tdb, "INFO/total_smbds"); - if (val == -1 && (tdb_error(tdb) != TDB_ERR_NOEXIST)) { - DEBUG(0,("allowable_number_of_smbd_processes: can't fetch INFO/total_smbds. Error %s\n", - tdb_errorstr(tdb) )); - return False; - } - if (val > max_processes) { - DEBUG(0,("allowable_number_of_smbd_processes: number of processes (%d) is over allowed limit (%d)\n", - val, max_processes )); - return False; - } - } - return True; + return num_children < max_processes; } /**************************************************************************** @@ -255,7 +293,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ #endif /* Stop zombies */ - CatchChild(); + CatchSignal(SIGCLD, sig_cld); FD_ZERO(&listen_set); @@ -392,6 +430,15 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ /* Ensure we respond to PING and DEBUG messages from the main smbd. */ message_dispatch(); + if (got_sig_cld) { + pid_t pid; + got_sig_cld = False; + + while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) { + remove_child_pid(pid); + } + } + memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set)); @@ -421,6 +468,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ for( ; num > 0; num--) { struct sockaddr addr; socklen_t in_addrlen = sizeof(addr); + pid_t child = 0; s = -1; for(i = 0; i < num_sockets; i++) { @@ -450,8 +498,14 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ if (smbd_server_fd() != -1 && interactive) return True; - if (allowable_number_of_smbd_processes() && smbd_server_fd() != -1 && sys_fork()==0) { + if (allowable_number_of_smbd_processes() && + smbd_server_fd() != -1 && + ((child = sys_fork())==0)) { /* Child code ... */ + + /* Stop zombies, the parent explicitly handles + * them, counting worker smbds. */ + CatchChild(); /* close the listening socket(s) */ for(i = 0; i < num_sockets; i++) @@ -467,7 +521,8 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ /* this is needed so that we get decent entries in smbstatus for port 445 connects */ - set_remote_machine_name(get_peer_addr(smbd_server_fd()), False); + set_remote_machine_name(get_peer_addr(smbd_server_fd()), + False); /* Reset the state of the random * number generation system, so @@ -475,7 +530,8 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ * numbers as each other */ set_need_random_reseed(); - /* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */ + /* tdb needs special fork handling - remove + * CLEAR_IF_FIRST flags */ if (tdb_reopen_all(1) == -1) { DEBUG(0,("tdb_reopen_all failed.\n")); smb_panic("tdb_reopen_all failed."); @@ -496,6 +552,10 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ smbd_set_server_fd(-1); + if (child != 0) { + add_child_pid(child); + } + /* Force parent to check log size after * spawning child. Fix from * klausr@ITAP.Physik.Uni-Stuttgart.De. The @@ -637,7 +697,6 @@ static void exit_server_common(enum server_exit_reason how, yield_connection(NULL,""); respond_to_all_remaining_local_messages(); - decrement_smbd_process_count(); #ifdef WITH_DFS if (dcelogin_atmost_once) { @@ -666,9 +725,7 @@ static void exit_server_common(enum server_exit_reason how, } DEBUGLEVEL = oldlevel; -#if DUMP_CORE dump_core(); -#endif } else { DEBUG(3,("Server exit (%s)\n", @@ -912,18 +969,12 @@ void build_options(BOOL screen); if (!message_init()) exit(1); - /* Initialize our global sam sid first -- quite a lot of the other - * initialization routines further down depend on it. - */ - /* Initialise the password backed before the global_sam_sid to ensure that we fetch from ldap before we make a domain sid up */ if(!initialize_password_db(False)) exit(1); - /* Fail gracefully if we can't open secrets.tdb */ - if (!secrets_init()) { DEBUG(0, ("ERROR: smbd can not open secrets.tdb\n")); exit(1); diff --git a/source/smbd/service.c b/source/smbd/service.c index 13f7f7866ad..60ba85ab65e 100644 --- a/source/smbd/service.c +++ b/source/smbd/service.c @@ -380,35 +380,38 @@ static NTSTATUS find_forced_user(int snum, BOOL vuser_is_guest, { TALLOC_CTX *mem_ctx; char *fuser, *found_username; + struct nt_user_token *tmp_token; NTSTATUS result; - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { + if (!(mem_ctx = talloc_new(NULL))) { DEBUG(0, ("talloc_new failed\n")); return NT_STATUS_NO_MEMORY; } - fuser = talloc_string_sub(mem_ctx, lp_force_user(snum), "%S", - lp_servicename(snum)); - if (fuser == NULL) { - result = NT_STATUS_NO_MEMORY; - goto done; + if (!(fuser = talloc_string_sub(mem_ctx, lp_force_user(snum), "%S", + lp_servicename(snum)))) { + TALLOC_FREE(mem_ctx); + return NT_STATUS_NO_MEMORY; + } result = create_token_from_username(mem_ctx, fuser, vuser_is_guest, uid, gid, &found_username, - token); + &tmp_token); if (!NT_STATUS_IS_OK(result)) { - goto done; + TALLOC_FREE(mem_ctx); + return result; + } + + if (!(*token = dup_nt_token(NULL, tmp_token))) { + TALLOC_FREE(mem_ctx); + return NT_STATUS_NO_MEMORY; } - talloc_steal(NULL, *token); fstrcpy(username, found_username); - result = NT_STATUS_OK; - done: TALLOC_FREE(mem_ctx); - return result; + return NT_STATUS_OK; } /* @@ -764,7 +767,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, { pstring s; pstrcpy(s,lp_pathname(snum)); - standard_sub_conn(conn,s,sizeof(s)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + s, sizeof(s)); set_conn_connectpath(conn,s); DEBUG(3,("Connect path is '%s' for service [%s]\n",s, lp_servicename(snum))); @@ -778,11 +785,16 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, */ { - BOOL can_write = share_access_check(conn, snum, vuser, + NT_USER_TOKEN *token = conn->nt_user_token ? + conn->nt_user_token : vuser->nt_user_token; + + BOOL can_write = share_access_check(token, + lp_servicename(snum), FILE_WRITE_DATA); if (!can_write) { - if (!share_access_check(conn, snum, vuser, + if (!share_access_check(token, + lp_servicename(snum), FILE_READ_DATA)) { /* No access, read or write. */ DEBUG(0,("make_connection: connection to %s " @@ -839,7 +851,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, if (*lp_rootpreexec(snum)) { pstring cmd; pstrcpy(cmd,lp_rootpreexec(snum)); - standard_sub_conn(conn,cmd,sizeof(cmd)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + cmd, sizeof(cmd)); DEBUG(5,("cmd=%s\n",cmd)); ret = smbrun(cmd,NULL); if (ret != 0 && lp_rootpreexec_close(snum)) { @@ -872,7 +888,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, if (*lp_preexec(snum)) { pstring cmd; pstrcpy(cmd,lp_preexec(snum)); - standard_sub_conn(conn,cmd,sizeof(cmd)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + cmd, sizeof(cmd)); ret = smbrun(cmd,NULL); if (ret != 0 && lp_preexec_close(snum)) { DEBUG(1,("preexec gave %d - failing connection\n", @@ -1171,7 +1191,11 @@ void close_cnum(connection_struct *conn, uint16 vuid) change_to_user(conn, vuid)) { pstring cmd; pstrcpy(cmd,lp_postexec(SNUM(conn))); - standard_sub_conn(conn,cmd,sizeof(cmd)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + cmd, sizeof(cmd)); smbrun(cmd,NULL); change_to_root_user(); } @@ -1181,7 +1205,11 @@ void close_cnum(connection_struct *conn, uint16 vuid) if (*lp_rootpostexec(SNUM(conn))) { pstring cmd; pstrcpy(cmd,lp_rootpostexec(SNUM(conn))); - standard_sub_conn(conn,cmd,sizeof(cmd)); + standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user, + conn->connectpath, conn->gid, + get_current_username(), + current_user_info.domain, + cmd, sizeof(cmd)); smbrun(cmd,NULL); } diff --git a/source/smbd/share_access.c b/source/smbd/share_access.c index 3bc442f1baf..adb9d169642 100644 --- a/source/smbd/share_access.c +++ b/source/smbd/share_access.c @@ -28,6 +28,8 @@ * + and & may be combined */ +extern userdom_struct current_user_info; + static BOOL do_group_checks(const char **name, const char **pattern) { if ((*name)[0] == '@') { @@ -74,7 +76,8 @@ static BOOL token_contains_name(TALLOC_CTX *mem_ctx, enum lsa_SidType type; if (username != NULL) { - name = talloc_sub_basic(mem_ctx, username, name); + name = talloc_sub_basic(mem_ctx, username, + current_user_info.domain, name); } if (sharename != NULL) { name = talloc_string_sub(mem_ctx, name, "%S", sharename); diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index 068179cd4bb..f2f0150f6f8 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -171,7 +171,7 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str } for (i = 0, ea_namelist = TALLOC_ARRAY(mem_ctx, char, ea_namelist_size); i < 6; - ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) { + ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) { if (!ea_namelist) { return NULL; @@ -571,7 +571,8 @@ int send_trans2_replies(char *outbuf, char *params, int paramsize, char *pdata, - int datasize) + int datasize, + int max_data_bytes) { /* As we are using a protocol > LANMAN1 then the max_send variable must have been set in the sessetupX call. @@ -592,6 +593,18 @@ int send_trans2_replies(char *outbuf, set_message(outbuf,10,0,True); + /* Modify the data_to_send and datasize and set the error if + we're trying to send more than max_data_bytes. We still send + the part of the packet(s) that fit. Strange, but needed + for OS/2. */ + + if (max_data_bytes > 0 && datasize > max_data_bytes) { + DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n", + max_data_bytes, datasize )); + datasize = data_to_send = max_data_bytes; + error_packet_set(outbuf,ERRDOS,ERRbufferoverflow,STATUS_BUFFER_OVERFLOW,__LINE__,__FILE__); + } + /* If there genuinely are no parameters or data to send just send the empty packet */ if(params_to_send == 0 && data_to_send == 0) { @@ -835,16 +848,16 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - fsp = open_file_ntcreate(conn,fname,&sbuf, + status = open_file_ntcreate(conn,fname,&sbuf, access_mask, share_mode, create_disposition, create_options, open_attr, oplock_request, - &smb_action); + &smb_action, &fsp); - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { talloc_destroy(ctx); if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ @@ -930,7 +943,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i } /* Send the required number of replies */ - send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0, max_data_bytes); return -1; } @@ -1041,7 +1054,7 @@ static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *ps ****************************************************************************/ static BOOL get_lanman2_dir_entry(connection_struct *conn, - void *inbuf, void *outbuf, + void *inbuf, char *outbuf, char *path_mask,uint32 dirtype,int info_level, int requires_resume_key, BOOL dont_descend,char **ppdata, @@ -1062,7 +1075,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SMB_OFF_T file_size = 0; SMB_BIG_UINT allocation_size = 0; uint32 len; - time_t mdate=0, adate=0, cdate=0; + struct timespec mdate_ts, adate_ts, create_date_ts; + time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0; char *nameptr; char *last_entry_ptr; BOOL was_8_3; @@ -1074,6 +1088,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, *out_of_space = False; *got_exact_match = False; + ZERO_STRUCT(mdate_ts); + ZERO_STRUCT(adate_ts); + ZERO_STRUCT(create_date_ts); + if (!conn->dirptr) return(False); @@ -1182,17 +1200,21 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, if (!(mode & aDIR)) file_size = get_file_size(sbuf); allocation_size = get_allocation_size(conn,NULL,&sbuf); - mdate = sbuf.st_mtime; - adate = sbuf.st_atime; - cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + + mdate_ts = get_mtimespec(&sbuf); + adate_ts = get_atimespec(&sbuf); + create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn))); if (lp_dos_filetime_resolution(SNUM(conn))) { - cdate &= ~1; - mdate &= ~1; - adate &= ~1; + dos_filetime_timespec(&create_date_ts); + dos_filetime_timespec(&mdate_ts); + dos_filetime_timespec(&adate_ts); } - + create_date = convert_timespec_to_time_t(create_date_ts); + mdate = convert_timespec_to_time_t(mdate_ts); + adate = convert_timespec_to_time_t(adate_ts); + DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname)); found = True; @@ -1215,7 +1237,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SIVAL(p,0,reskey); p += 4; } - srv_put_dos_date2(p,0,cdate); + srv_put_dos_date2(p,0,create_date); srv_put_dos_date2(p,4,adate); srv_put_dos_date2(p,8,mdate); SIVAL(p,12,(uint32)file_size); @@ -1247,7 +1269,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SIVAL(p,0,reskey); p += 4; } - srv_put_dos_date2(p,0,cdate); + srv_put_dos_date2(p,0,create_date); srv_put_dos_date2(p,4,adate); srv_put_dos_date2(p,8,mdate); SIVAL(p,12,(uint32)file_size); @@ -1291,7 +1313,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SIVAL(p,0,reskey); p += 4; } - srv_put_dos_date2(p,0,cdate); + srv_put_dos_date2(p,0,create_date); srv_put_dos_date2(p,4,adate); srv_put_dos_date2(p,8,mdate); SIVAL(p,12,(uint32)file_size); @@ -1340,10 +1362,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, was_8_3 = mangle_is_8_3(fname, True, conn->params); p += 4; SIVAL(p,0,reskey); p += 4; - put_long_date(p,cdate); p += 8; - put_long_date(p,adate); p += 8; - put_long_date(p,mdate); p += 8; - put_long_date(p,mdate); p += 8; + put_long_date_timespec(p,create_date_ts); p += 8; + put_long_date_timespec(p,adate_ts); p += 8; + put_long_date_timespec(p,mdate_ts); p += 8; + put_long_date_timespec(p,mdate_ts); p += 8; SOFF_T(p,0,file_size); p += 8; SOFF_T(p,0,allocation_size); p += 8; SIVAL(p,0,nt_extmode); p += 4; @@ -1386,10 +1408,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n")); p += 4; SIVAL(p,0,reskey); p += 4; - put_long_date(p,cdate); p += 8; - put_long_date(p,adate); p += 8; - put_long_date(p,mdate); p += 8; - put_long_date(p,mdate); p += 8; + put_long_date_timespec(p,create_date_ts); p += 8; + put_long_date_timespec(p,adate_ts); p += 8; + put_long_date_timespec(p,mdate_ts); p += 8; + put_long_date_timespec(p,mdate_ts); p += 8; SOFF_T(p,0,file_size); p += 8; SOFF_T(p,0,allocation_size); p += 8; SIVAL(p,0,nt_extmode); p += 4; @@ -1407,10 +1429,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n")); p += 4; SIVAL(p,0,reskey); p += 4; - put_long_date(p,cdate); p += 8; - put_long_date(p,adate); p += 8; - put_long_date(p,mdate); p += 8; - put_long_date(p,mdate); p += 8; + put_long_date_timespec(p,create_date_ts); p += 8; + put_long_date_timespec(p,adate_ts); p += 8; + put_long_date_timespec(p,mdate_ts); p += 8; + put_long_date_timespec(p,mdate_ts); p += 8; SOFF_T(p,0,file_size); p += 8; SOFF_T(p,0,allocation_size); p += 8; SIVAL(p,0,nt_extmode); p += 4; @@ -1452,10 +1474,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n")); p += 4; SIVAL(p,0,reskey); p += 4; - put_long_date(p,cdate); p += 8; - put_long_date(p,adate); p += 8; - put_long_date(p,mdate); p += 8; - put_long_date(p,mdate); p += 8; + put_long_date_timespec(p,create_date_ts); p += 8; + put_long_date_timespec(p,adate_ts); p += 8; + put_long_date_timespec(p,mdate_ts); p += 8; + put_long_date_timespec(p,mdate_ts); p += 8; SOFF_T(p,0,file_size); p += 8; SOFF_T(p,0,allocation_size); p += 8; SIVAL(p,0,nt_extmode); p += 4; @@ -1483,10 +1505,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, was_8_3 = mangle_is_8_3(fname, True, conn->params); p += 4; SIVAL(p,0,reskey); p += 4; - put_long_date(p,cdate); p += 8; - put_long_date(p,adate); p += 8; - put_long_date(p,mdate); p += 8; - put_long_date(p,mdate); p += 8; + put_long_date_timespec(p,create_date_ts); p += 8; + put_long_date_timespec(p,adate_ts); p += 8; + put_long_date_timespec(p,mdate_ts); p += 8; + put_long_date_timespec(p,mdate_ts); p += 8; SOFF_T(p,0,file_size); p += 8; SOFF_T(p,0,allocation_size); p += 8; SIVAL(p,0,nt_extmode); p += 4; @@ -1543,9 +1565,9 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */ p+= 8; - put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */ - put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */ - put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */ + put_long_date_timespec(p,get_ctimespec(&sbuf)); /* Inode change Time 64 Bit */ + put_long_date_timespec(p+8,get_atimespec(&sbuf)); /* Last access time 64 Bit */ + put_long_date_timespec(p+16,get_mtimespec(&sbuf)); /* Last modification time 64 Bit */ p+= 24; SIVAL(p,0,sbuf.st_uid); /* user id for the owner */ @@ -1749,7 +1771,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } } - *ppdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); + *ppdata = (char *)SMB_REALLOC( + *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); if(*ppdata == NULL ) { talloc_destroy(ea_ctx); return ERROR_NT(NT_STATUS_NO_MEMORY); @@ -1757,7 +1780,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd pdata = *ppdata; /* Realloc the params space */ - *pparams = SMB_REALLOC(*pparams, 10); + *pparams = (char *)SMB_REALLOC(*pparams, 10); if (*pparams == NULL) { talloc_destroy(ea_ctx); return ERROR_NT(NT_STATUS_NO_MEMORY); @@ -1855,7 +1878,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd SSVAL(params,6,0); /* Never an EA error */ SSVAL(params,8,last_entry_off); - send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata)); + send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata), max_data_bytes); if ((! *directory) && dptr_path(dptr_num)) slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num)); @@ -2000,7 +2023,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } } - *ppdata = SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); + *ppdata = (char *)SMB_REALLOC( + *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); if(*ppdata == NULL) { talloc_destroy(ea_ctx); return ERROR_NT(NT_STATUS_NO_MEMORY); @@ -2009,7 +2033,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd pdata = *ppdata; /* Realloc the params space */ - *pparams = SMB_REALLOC(*pparams, 6*SIZEOFWORD); + *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD); if(*pparams == NULL ) { talloc_destroy(ea_ctx); return ERROR_NT(NT_STATUS_NO_MEMORY); @@ -2136,7 +2160,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd SSVAL(params,4,0); /* Never an EA error */ SSVAL(params,6,last_entry_off); - send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata)); + send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata), max_data_bytes); if ((! *directory) && dptr_path(dptr_num)) slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num)); @@ -2173,7 +2197,8 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf return ERROR_DOS(ERRSRV,ERRinvdevice); } - *ppdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); + *ppdata = (char *)SMB_REALLOC( + *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); if (*ppdata == NULL ) { return ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -2443,17 +2468,10 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION); SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION); /* We have POSIX ACLs, pathname and locking capability. */ -#if defined(DEVELOPER) /* Not quite finished yet... */ SBIG_UINT(pdata,4,((SMB_BIG_UINT)( CIFS_UNIX_POSIX_ACLS_CAP| CIFS_UNIX_POSIX_PATHNAMES_CAP| CIFS_UNIX_FCNTL_LOCKS_CAP))); -#else - SBIG_UINT(pdata,4,((SMB_BIG_UINT)( - CIFS_UNIX_POSIX_ACLS_CAP| - CIFS_UNIX_POSIX_PATHNAMES_CAP| - 0))); -#endif break; case SMB_QUERY_POSIX_FS_INFO: @@ -2505,7 +2523,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned } - send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len); + send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len, max_data_bytes); DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) ); @@ -2569,11 +2587,10 @@ cap_low = 0x%x, cap_high = 0x%x\n", lp_set_posix_pathnames(); mangle_change_to_posix(); } -#if defined(DEVELOPER) + if (client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) { lp_set_posix_cifsx_locktype(POSIX_LOCK); } -#endif break; } case SMB_FS_QUOTA_INFORMATION: @@ -2829,14 +2846,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char * BOOL bad_path = False; BOOL delete_pending = False; int len; - time_t c_time; + time_t create_time, mtime, atime; + struct timespec create_time_ts, mtime_ts, atime_ts; files_struct *fsp = NULL; TALLOC_CTX *data_ctx = NULL; struct ea_list *ea_list = NULL; uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */ -#if defined(DEVELOPER) char *lock_data = NULL; -#endif if (!params) return ERROR_NT(NT_STATUS_INVALID_PARAMETER); @@ -3008,7 +3024,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } break; } -#if defined(DEVELOPER) + case SMB_QUERY_POSIX_LOCK: { if (fsp == NULL || fsp->fh->fd == -1) { @@ -3024,18 +3040,18 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } /* Copy the lock range data. */ - lock_data = talloc_memdup(data_ctx, pdata, total_data); + lock_data = (char *)talloc_memdup( + data_ctx, pdata, total_data); if (!lock_data) { talloc_destroy(data_ctx); return ERROR_NT(NT_STATUS_NO_MEMORY); } } -#endif default: break; } - *pparams = SMB_REALLOC(*pparams,2); + *pparams = (char *)SMB_REALLOC(*pparams,2); if (*pparams == NULL) { talloc_destroy(data_ctx); return ERROR_NT(NT_STATUS_NO_MEMORY); @@ -3043,28 +3059,32 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd params = *pparams; SSVAL(params,0,0); data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN; - *ppdata = SMB_REALLOC(*ppdata, data_size); + *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); if (*ppdata == NULL ) { talloc_destroy(data_ctx); return ERROR_NT(NT_STATUS_NO_MEMORY); } pdata = *ppdata; - c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + mtime_ts = get_mtimespec(&sbuf); + atime_ts = get_atimespec(&sbuf); allocation_size = get_allocation_size(conn,fsp,&sbuf); if (fsp) { if (fsp->pending_modtime) { /* the pending modtime overrides the current modtime */ - sbuf.st_mtime = fsp->pending_modtime; + mtime_ts.tv_sec = fsp->pending_modtime; + mtime_ts.tv_nsec = 0; } } else { /* Do we have this path open ? */ files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino); if (fsp1 && fsp1->pending_modtime) { /* the pending modtime overrides the current modtime */ - sbuf.st_mtime = fsp1->pending_modtime; + mtime_ts.tv_sec = fsp1->pending_modtime; + mtime_ts.tv_nsec = 0; } if (fsp1 && fsp1->initial_allocation_size) { allocation_size = get_allocation_size(conn, fsp1, &sbuf); @@ -3072,12 +3092,15 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } if (lp_dos_filetime_resolution(SNUM(conn))) { - c_time &= ~1; - sbuf.st_atime &= ~1; - sbuf.st_ctime &= ~1; - sbuf.st_mtime &= ~1; + dos_filetime_timespec(&create_time_ts); + dos_filetime_timespec(&mtime_ts); + dos_filetime_timespec(&atime_ts); } + create_time = convert_timespec_to_time_t(create_time_ts); + mtime = convert_timespec_to_time_t(mtime_ts); + atime = convert_timespec_to_time_t(atime_ts); + /* NT expects the name to be in an exact form of the *full* filename. See the trans2 torture test */ if (strequal(base_name,".")) { @@ -3091,9 +3114,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd case SMB_INFO_STANDARD: DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n")); data_size = 22; - srv_put_dos_date2(pdata,l1_fdateCreation,c_time); - srv_put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime); - srv_put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */ + srv_put_dos_date2(pdata,l1_fdateCreation,create_time); + srv_put_dos_date2(pdata,l1_fdateLastAccess,atime); + srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */ SIVAL(pdata,l1_cbFile,(uint32)file_size); SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size); SSVAL(pdata,l1_attrFile,mode); @@ -3104,9 +3127,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd unsigned int ea_size = estimate_ea_size(conn, fsp, fname); DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n")); data_size = 26; - srv_put_dos_date2(pdata,0,c_time); - srv_put_dos_date2(pdata,4,sbuf.st_atime); - srv_put_dos_date2(pdata,8,sbuf.st_mtime); /* write time */ + srv_put_dos_date2(pdata,0,create_time); + srv_put_dos_date2(pdata,4,atime); + srv_put_dos_date2(pdata,8,mtime); /* write time */ SIVAL(pdata,12,(uint32)file_size); SIVAL(pdata,16,(uint32)allocation_size); SSVAL(pdata,20,mode); @@ -3182,20 +3205,17 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd data_size = 40; SIVAL(pdata,36,0); } - put_long_date(pdata,c_time); - put_long_date(pdata+8,sbuf.st_atime); - put_long_date(pdata+16,sbuf.st_mtime); /* write time */ - put_long_date(pdata+24,sbuf.st_mtime); /* change time */ + put_long_date_timespec(pdata,create_time_ts); + put_long_date_timespec(pdata+8,atime_ts); + put_long_date_timespec(pdata+16,mtime_ts); /* write time */ + put_long_date_timespec(pdata+24,mtime_ts); /* change time */ SIVAL(pdata,32,mode); DEBUG(5,("SMB_QFBI - ")); - { - time_t create_time = c_time; - DEBUG(5,("create: %s ", ctime(&create_time))); - } - DEBUG(5,("access: %s ", ctime(&sbuf.st_atime))); - DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime))); - DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime))); + DEBUG(5,("create: %s ", ctime(&create_time))); + DEBUG(5,("access: %s ", ctime(&atime))); + DEBUG(5,("write: %s ", ctime(&mtime))); + DEBUG(5,("change: %s ", ctime(&mtime))); DEBUG(5,("mode: %x\n", mode)); break; @@ -3269,10 +3289,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd { unsigned int ea_size = estimate_ea_size(conn, fsp, fname); DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n")); - put_long_date(pdata,c_time); - put_long_date(pdata+8,sbuf.st_atime); - put_long_date(pdata+16,sbuf.st_mtime); /* write time */ - put_long_date(pdata+24,sbuf.st_mtime); /* change time */ + put_long_date_timespec(pdata,create_time_ts); + put_long_date_timespec(pdata+8,atime_ts); + put_long_date_timespec(pdata+16,mtime_ts); /* write time */ + put_long_date_timespec(pdata+24,mtime_ts); /* change time */ SIVAL(pdata,32,mode); SIVAL(pdata,36,0); /* padding. */ pdata += 40; @@ -3379,10 +3399,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd case SMB_FILE_NETWORK_OPEN_INFORMATION: DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n")); - put_long_date(pdata,c_time); - put_long_date(pdata+8,sbuf.st_atime); - put_long_date(pdata+16,sbuf.st_mtime); /* write time */ - put_long_date(pdata+24,sbuf.st_mtime); /* change time */ + put_long_date_timespec(pdata,create_time_ts); + put_long_date_timespec(pdata+8,atime_ts); + put_long_date_timespec(pdata+16,mtime_ts); /* write time */ + put_long_date_timespec(pdata+24,mtime_ts); /* change time */ SIVAL(pdata,32,allocation_size); SOFF_T(pdata,40,file_size); SIVAL(pdata,48,mode); @@ -3412,9 +3432,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */ pdata += 8; - put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */ - put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */ - put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */ + put_long_date_timespec(pdata,get_ctimespec(&sbuf)); /* Creation Time 64 Bit */ + put_long_date_timespec(pdata+8,get_atimespec(&sbuf)); /* Last access time 64 Bit */ + put_long_date_timespec(pdata+16,get_mtimespec(&sbuf)); /* Last modification time 64 Bit */ pdata += 24; SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */ @@ -3450,7 +3470,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd { int i; - DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC")); + DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC ")); for (i=0; i<100; i++) DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); @@ -3561,13 +3581,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd #endif -#if defined(DEVELOPER) case SMB_QUERY_POSIX_LOCK: { NTSTATUS status = NT_STATUS_INVALID_LEVEL; SMB_BIG_UINT count; SMB_BIG_UINT offset; - uint16 lock_pid; + uint32 lock_pid; enum brl_type lock_type; if (total_data != POSIX_LOCK_DATA_SIZE) { @@ -3588,7 +3607,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - lock_pid = (uint16)IVAL(pdata, POSIX_LOCK_PID_OFFSET); + lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET); #if defined(HAVE_LONGLONG) offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET)); @@ -3634,13 +3653,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } break; } -#endif default: return ERROR_NT(NT_STATUS_INVALID_LEVEL); } - send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size); + send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes); return(-1); } @@ -3789,7 +3807,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name )); SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } else return (UNIXERROR(ERRDOS,ERRbadpath)); @@ -3901,7 +3919,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char if ((total_data == 4) && (IVAL(pdata,0) == 4)) { /* We're done. We only get EA info in this call. */ SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } @@ -3932,7 +3950,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char /* We're done. We only get EA info in this call. */ SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } @@ -4032,16 +4050,16 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char if (fd == -1) { files_struct *new_fsp = NULL; - new_fsp = open_file_ntcreate(conn, fname, &sbuf, + status = open_file_ntcreate(conn, fname, &sbuf, FILE_WRITE_DATA, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, FORCE_OPLOCK_BREAK_TO_NONE, - NULL); + NULL, &new_fsp); - if (new_fsp == NULL) { + if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; @@ -4124,7 +4142,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char } SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } @@ -4153,7 +4171,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char /* We're done. We only get position info in this call. */ SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } @@ -4177,7 +4195,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char /* We're done. We only get mode info in this call. */ SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } @@ -4292,7 +4310,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", inherit_access_acl(conn, fname, unixmode); SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } @@ -4375,7 +4393,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } @@ -4399,7 +4417,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", } SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } @@ -4453,7 +4471,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", } process_pending_change_notify_queue((time_t)0); SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } @@ -4504,20 +4522,18 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", } SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } #endif -#if defined(DEVELOPER) case SMB_SET_POSIX_LOCK: { SMB_BIG_UINT count; SMB_BIG_UINT offset; - uint16 lock_pid; - BOOL lock_blocking; + uint32 lock_pid; + BOOL blocking_lock = False; enum brl_type lock_type; - BOOL my_lock_ctx; if (fsp == NULL || fsp->fh->fd == -1) { return ERROR_NT(NT_STATUS_INVALID_HANDLE); @@ -4546,14 +4562,18 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", } if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) { - lock_blocking = False; + blocking_lock = False; } else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) { - lock_blocking = True; + blocking_lock = True; } else { return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - lock_pid = (uint16)IVAL(pdata, POSIX_LOCK_PID_OFFSET); + if (!lp_blocking_locks(SNUM(conn))) { + blocking_lock = False; + } + + lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET); #if defined(HAVE_LONGLONG) offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET)); @@ -4571,21 +4591,23 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", offset, POSIX_LOCK); } else { - status = do_lock(fsp, - lock_pid, - count, - offset, - lock_type, - POSIX_LOCK, - &my_lock_ctx); - - if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) { + struct byte_range_lock *br_lck = do_lock(fsp, + lock_pid, + count, + offset, + lock_type, + POSIX_LOCK, + blocking_lock, + &status); + + if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) { /* * A blocking lock was requested. Package up * this smb into a queued request and push it * onto the blocking lock queue. */ - if(push_blocking_lock_request(inbuf, length, + if(push_blocking_lock_request(br_lck, + inbuf, length, fsp, -1, /* infinite timeout. */ 0, @@ -4594,9 +4616,11 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", POSIX_LOCK, offset, count)) { + TALLOC_FREE(br_lck); return -1; } } + TALLOC_FREE(br_lck); } if (!NT_STATUS_IS_OK(status)) { @@ -4604,10 +4628,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", } SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } -#endif default: return ERROR_NT(NT_STATUS_INVALID_LEVEL); @@ -4675,16 +4698,16 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if (fd == -1) { files_struct *new_fsp = NULL; - new_fsp = open_file_ntcreate(conn, fname, &sbuf, + status = open_file_ntcreate(conn, fname, &sbuf, FILE_WRITE_DATA, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, FORCE_OPLOCK_BREAK_TO_NONE, - NULL); + NULL, &new_fsp); - if (new_fsp == NULL) { + if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(SVAL(inbuf,smb_mid))) { /* We have re-scheduled this call. */ return -1; @@ -4731,7 +4754,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", } SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } @@ -4836,7 +4859,7 @@ static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); return(-1); } @@ -4885,7 +4908,7 @@ static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char if(fnf_handle == 0) fnf_handle = 257; - send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0, max_data_bytes); return(-1); } @@ -4913,7 +4936,7 @@ static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char SSVAL(params,0,0); /* No changes */ SSVAL(params,2,0); /* No EA errors */ - send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0); + send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0, max_data_bytes); return(-1); } @@ -4947,7 +4970,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* return UNIXERROR(ERRDOS,ERRbadfile); SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES); - send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size); + send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size, max_data_bytes); return(-1); } @@ -4985,7 +5008,7 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */ srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */ srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */ - send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32); + send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32, max_data_bytes); return(-1); } else { DEBUG(2,("Unknown TRANS2_IOCTL\n")); @@ -5295,7 +5318,7 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, if (state->total_data) { /* Can't use talloc here, the core routines do realloc on the * params and data. */ - state->data = SMB_MALLOC(state->total_data); + state->data = (char *)SMB_MALLOC(state->total_data); if (state->data == NULL) { DEBUG(0,("reply_trans2: data malloc fail for %u " "bytes !\n", (unsigned int)state->total_data)); @@ -5315,7 +5338,7 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, if (state->total_param) { /* Can't use talloc here, the core routines do realloc on the * params and data. */ - state->param = SMB_MALLOC(state->total_param); + state->param = (char *)SMB_MALLOC(state->total_param); if (state->param == NULL) { DEBUG(0,("reply_trans: param malloc fail for %u " "bytes !\n", (unsigned int)state->total_param)); diff --git a/source/smbd/uid.c b/source/smbd/uid.c index c4213ba700f..85885803222 100644 --- a/source/smbd/uid.c +++ b/source/smbd/uid.c @@ -109,7 +109,8 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) conn->nt_user_token : vuser->nt_user_token; if (!readonly_share && - !share_access_check(conn, snum, vuser, FILE_WRITE_DATA)) { + !share_access_check(token, lp_servicename(snum), + FILE_WRITE_DATA)) { /* smb.conf allows r/w, but the security descriptor denies * write. Fall back to looking at readonly. */ readonly_share = True; @@ -117,7 +118,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) "security descriptor\n")); } - if (!share_access_check(conn, snum, vuser, + if (!share_access_check(token, lp_servicename(snum), readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { return False; @@ -419,4 +420,3 @@ BOOL unbecome_user(void) pop_conn_ctx(); return True; } - diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c deleted file mode 100644 index f1c2ad335c1..00000000000 --- a/source/smbd/vfs-wrap.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Wrap disk only vfs functions to sidestep dodgy compilers. - Copyright (C) Tim Potter 1998 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_VFS - - -/* Check for NULL pointer parameters in vfswrap_* functions */ - -/* We don't want to have NULL function pointers lying around. Someone - is sure to try and execute them. These stubs are used to prevent - this possibility. */ - -int vfswrap_dummy_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user) -{ - return 0; /* Return >= 0 for success */ -} - -void vfswrap_dummy_disconnect(vfs_handle_struct *handle, connection_struct *conn) -{ -} - -/* Disk operations */ - -SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, - SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) -{ - SMB_BIG_UINT result; - - result = sys_disk_free(conn, path, small_query, bsize, dfree, dsize); - return result; -} - -int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) -{ -#ifdef HAVE_SYS_QUOTAS - int result; - - START_PROFILE(syscall_get_quota); - result = sys_get_quota(conn->connectpath, qtype, id, qt); - END_PROFILE(syscall_get_quota); - return result; -#else - errno = ENOSYS; - return -1; -#endif -} - -int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) -{ -#ifdef HAVE_SYS_QUOTAS - int result; - - START_PROFILE(syscall_set_quota); - result = sys_set_quota(conn->connectpath, qtype, id, qt); - END_PROFILE(syscall_set_quota); - return result; -#else - errno = ENOSYS; - return -1; -#endif -} - -int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels) -{ - errno = ENOSYS; - return -1; /* Not implemented. */ -} - -int vfswrap_statvfs(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, vfs_statvfs_struct *statbuf) -{ - return sys_statvfs(path, statbuf); -} - -/* Directory operations */ - -SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) -{ - SMB_STRUCT_DIR *result; - - START_PROFILE(syscall_opendir); - result = sys_opendir(fname); - END_PROFILE(syscall_opendir); - return result; -} - -SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp) -{ - SMB_STRUCT_DIRENT *result; - - START_PROFILE(syscall_readdir); - result = sys_readdir(dirp); - END_PROFILE(syscall_readdir); - return result; -} - -void vfswrap_seekdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp, long offset) -{ - START_PROFILE(syscall_seekdir); - sys_seekdir(dirp, offset); - END_PROFILE(syscall_seekdir); -} - -long vfswrap_telldir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp) -{ - long result; - START_PROFILE(syscall_telldir); - result = sys_telldir(dirp); - END_PROFILE(syscall_telldir); - return result; -} - -void vfswrap_rewinddir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp) -{ - START_PROFILE(syscall_rewinddir); - sys_rewinddir(dirp); - END_PROFILE(syscall_rewinddir); -} - -int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) -{ - int result; - BOOL has_dacl = False; - - START_PROFILE(syscall_mkdir); - - if (lp_inherit_acls(SNUM(conn)) && (has_dacl = directory_has_default_acl(conn, parent_dirname(path)))) - mode = 0777; - - result = mkdir(path, mode); - - if (result == 0 && !has_dacl) { - /* - * We need to do this as the default behavior of POSIX ACLs - * is to set the mask to be the requested group permission - * bits, not the group permission bits to be the requested - * group permission bits. This is not what we want, as it will - * mess up any inherited ACL bits that were set. JRA. - */ - int saved_errno = errno; /* We may get ENOSYS */ - if ((SMB_VFS_CHMOD_ACL(conn, path, mode) == -1) && (errno == ENOSYS)) - errno = saved_errno; - } - - END_PROFILE(syscall_mkdir); - return result; -} - -int vfswrap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) -{ - int result; - - START_PROFILE(syscall_rmdir); - result = rmdir(path); - END_PROFILE(syscall_rmdir); - return result; -} - -int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp) -{ - int result; - - START_PROFILE(syscall_closedir); - result = sys_closedir(dirp); - END_PROFILE(syscall_closedir); - return result; -} - -/* File operations */ - -int vfswrap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) -{ - int result; - - START_PROFILE(syscall_open); - result = sys_open(fname, flags, mode); - END_PROFILE(syscall_open); - return result; -} - -int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd) -{ - int result; - - START_PROFILE(syscall_close); - - result = close(fd); - END_PROFILE(syscall_close); - return result; -} - -ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n) -{ - ssize_t result; - - START_PROFILE_BYTES(syscall_read, n); - result = sys_read(fd, data, n); - END_PROFILE(syscall_read); - return result; -} - -ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, - size_t n, SMB_OFF_T offset) -{ - ssize_t result; - -#if defined(HAVE_PREAD) || defined(HAVE_PREAD64) - START_PROFILE_BYTES(syscall_pread, n); - result = sys_pread(fd, data, n, offset); - END_PROFILE(syscall_pread); - - if (result == -1 && errno == ESPIPE) { - /* Maintain the fiction that pipes can be seeked (sought?) on. */ - result = SMB_VFS_READ(fsp, fd, data, n); - fsp->fh->pos = 0; - } - -#else /* HAVE_PREAD */ - SMB_OFF_T curr; - int lerrno; - - curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); - if (curr == -1 && errno == ESPIPE) { - /* Maintain the fiction that pipes can be seeked (sought?) on. */ - result = SMB_VFS_READ(fsp, fd, data, n); - fsp->fh->pos = 0; - return result; - } - - if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) { - return -1; - } - - errno = 0; - result = SMB_VFS_READ(fsp, fd, data, n); - lerrno = errno; - - SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET); - errno = lerrno; - -#endif /* HAVE_PREAD */ - - return result; -} - -ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n) -{ - ssize_t result; - - START_PROFILE_BYTES(syscall_write, n); - result = sys_write(fd, data, n); - END_PROFILE(syscall_write); - return result; -} - -ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, - size_t n, SMB_OFF_T offset) -{ - ssize_t result; - -#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64) - START_PROFILE_BYTES(syscall_pwrite, n); - result = sys_pwrite(fd, data, n, offset); - END_PROFILE(syscall_pwrite); - - if (result == -1 && errno == ESPIPE) { - /* Maintain the fiction that pipes can be sought on. */ - result = SMB_VFS_WRITE(fsp, fd, data, n); - } - -#else /* HAVE_PWRITE */ - SMB_OFF_T curr; - int lerrno; - - curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); - if (curr == -1) { - return -1; - } - - if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) { - return -1; - } - - result = SMB_VFS_WRITE(fsp, fd, data, n); - lerrno = errno; - - SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET); - errno = lerrno; - -#endif /* HAVE_PWRITE */ - - return result; -} - -SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence) -{ - SMB_OFF_T result = 0; - - START_PROFILE(syscall_lseek); - - /* Cope with 'stat' file opens. */ - if (filedes != -1) - result = sys_lseek(filedes, offset, whence); - - /* - * We want to maintain the fiction that we can seek - * on a fifo for file system purposes. This allows - * people to set up UNIX fifo's that feed data to Windows - * applications. JRA. - */ - - if((result == -1) && (errno == ESPIPE)) { - result = 0; - errno = 0; - } - - END_PROFILE(syscall_lseek); - return result; -} - -ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr, - SMB_OFF_T offset, size_t n) -{ - ssize_t result; - - START_PROFILE_BYTES(syscall_sendfile, n); - result = sys_sendfile(tofd, fromfd, hdr, offset, n); - END_PROFILE(syscall_sendfile); - return result; -} - -/********************************************************* - For rename across filesystems Patch from Warren Birnbaum - <warrenb@hpcvscdp.cv.hp.com> -**********************************************************/ - -static int copy_reg(const char *source, const char *dest) -{ - SMB_STRUCT_STAT source_stats; - int saved_errno; - int ifd = -1; - int ofd = -1; - - if (sys_lstat (source, &source_stats) == -1) - return -1; - - if (!S_ISREG (source_stats.st_mode)) - return -1; - - if((ifd = sys_open (source, O_RDONLY, 0)) < 0) - return -1; - - if (unlink (dest) && errno != ENOENT) - return -1; - -#ifdef O_NOFOLLOW - if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 ) -#else - if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 ) -#endif - goto err; - - if (transfer_file(ifd, ofd, (size_t)-1) == -1) - goto err; - - /* - * Try to preserve ownership. For non-root it might fail, but that's ok. - * But root probably wants to know, e.g. if NFS disallows it. - */ - -#ifdef HAVE_FCHOWN - if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) -#else - if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) -#endif - goto err; - - /* - * fchown turns off set[ug]id bits for non-root, - * so do the chmod last. - */ - -#if defined(HAVE_FCHMOD) - if (fchmod (ofd, source_stats.st_mode & 07777)) -#else - if (chmod (dest, source_stats.st_mode & 07777)) -#endif - goto err; - - if (close (ifd) == -1) - goto err; - - if (close (ofd) == -1) - return -1; - - /* Try to copy the old file's modtime and access time. */ - { - struct utimbuf tv; - - tv.actime = source_stats.st_atime; - tv.modtime = source_stats.st_mtime; - utime(dest, &tv); - } - - if (unlink (source) == -1) - return -1; - - return 0; - - err: - - saved_errno = errno; - if (ifd != -1) - close(ifd); - if (ofd != -1) - close(ofd); - errno = saved_errno; - return -1; -} - -int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname) -{ - int result; - - START_PROFILE(syscall_rename); - result = rename(oldname, newname); - if (errno == EXDEV) { - /* Rename across filesystems needed. */ - result = copy_reg(oldname, newname); - } - - END_PROFILE(syscall_rename); - return result; -} - -int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd) -{ -#ifdef HAVE_FSYNC - int result; - - START_PROFILE(syscall_fsync); - result = fsync(fd); - END_PROFILE(syscall_fsync); - return result; -#else - return 0; -#endif -} - -int vfswrap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) -{ - int result; - - START_PROFILE(syscall_stat); - result = sys_stat(fname, sbuf); - END_PROFILE(syscall_stat); - return result; -} - -int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) -{ - int result; - - START_PROFILE(syscall_fstat); - result = sys_fstat(fd, sbuf); - END_PROFILE(syscall_fstat); - return result; -} - -int vfswrap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) -{ - int result; - - START_PROFILE(syscall_lstat); - result = sys_lstat(path, sbuf); - END_PROFILE(syscall_lstat); - return result; -} - -int vfswrap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) -{ - int result; - - START_PROFILE(syscall_unlink); - result = unlink(path); - END_PROFILE(syscall_unlink); - return result; -} - -int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) -{ - int result; - - START_PROFILE(syscall_chmod); - - /* - * We need to do this due to the fact that the default POSIX ACL - * chmod modifies the ACL *mask* for the group owner, not the - * group owner bits directly. JRA. - */ - - - { - int saved_errno = errno; /* We might get ENOSYS */ - if ((result = SMB_VFS_CHMOD_ACL(conn, path, mode)) == 0) { - END_PROFILE(syscall_chmod); - return result; - } - /* Error - return the old errno. */ - errno = saved_errno; - } - - result = chmod(path, mode); - END_PROFILE(syscall_chmod); - return result; -} - -int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) -{ - int result; - - START_PROFILE(syscall_fchmod); - - /* - * We need to do this due to the fact that the default POSIX ACL - * chmod modifies the ACL *mask* for the group owner, not the - * group owner bits directly. JRA. - */ - - { - int saved_errno = errno; /* We might get ENOSYS */ - if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) { - END_PROFILE(syscall_fchmod); - return result; - } - /* Error - return the old errno. */ - errno = saved_errno; - } - -#if defined(HAVE_FCHMOD) - result = fchmod(fd, mode); -#else - result = -1; - errno = ENOSYS; -#endif - - END_PROFILE(syscall_fchmod); - return result; -} - -int vfswrap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid) -{ - int result; - - START_PROFILE(syscall_chown); - result = sys_chown(path, uid, gid); - END_PROFILE(syscall_chown); - return result; -} - -int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid) -{ -#ifdef HAVE_FCHOWN - int result; - - START_PROFILE(syscall_fchown); - result = fchown(fd, uid, gid); - END_PROFILE(syscall_fchown); - return result; -#else - errno = ENOSYS; - return -1; -#endif -} - -int vfswrap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) -{ - int result; - - START_PROFILE(syscall_chdir); - result = chdir(path); - END_PROFILE(syscall_chdir); - return result; -} - -char *vfswrap_getwd(vfs_handle_struct *handle, connection_struct *conn, char *path) -{ - char *result; - - START_PROFILE(syscall_getwd); - result = sys_getwd(path); - END_PROFILE(syscall_getwd); - return result; -} - -int vfswrap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times) -{ - int result; - - START_PROFILE(syscall_utime); - result = utime(path, times); - END_PROFILE(syscall_utime); - return result; -} - -/********************************************************************* - A version of ftruncate that will write the space on disk if strict - allocate is set. -**********************************************************************/ - -static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len) -{ - SMB_STRUCT_STAT st; - SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); - unsigned char zero_space[4096]; - SMB_OFF_T space_to_write; - - if (currpos == -1) - return -1; - - if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) - return -1; - - space_to_write = len - st.st_size; - -#ifdef S_ISFIFO - if (S_ISFIFO(st.st_mode)) - return 0; -#endif - - if (st.st_size == len) - return 0; - - /* Shrink - just ftruncate. */ - if (st.st_size > len) - return sys_ftruncate(fd, len); - - /* Write out the real space on disk. */ - if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size) - return -1; - - space_to_write = len - st.st_size; - - memset(zero_space, '\0', sizeof(zero_space)); - while ( space_to_write > 0) { - SMB_OFF_T retlen; - SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write); - - retlen = SMB_VFS_WRITE(fsp,fsp->fh->fd,(char *)zero_space,current_len_to_write); - if (retlen <= 0) - return -1; - - space_to_write -= retlen; - } - - /* Seek to where we were */ - if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos) - return -1; - - return 0; -} - -int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len) -{ - int result = -1; - SMB_STRUCT_STAT st; - char c = 0; - SMB_OFF_T currpos; - - START_PROFILE(syscall_ftruncate); - - if (lp_strict_allocate(SNUM(fsp->conn))) { - result = strict_allocate_ftruncate(handle, fsp, fd, len); - END_PROFILE(syscall_ftruncate); - return result; - } - - /* we used to just check HAVE_FTRUNCATE_EXTEND and only use - sys_ftruncate if the system supports it. Then I discovered that - you can have some filesystems that support ftruncate - expansion and some that don't! On Linux fat can't do - ftruncate extend but ext2 can. */ - - result = sys_ftruncate(fd, len); - if (result == 0) - goto done; - - /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot - extend a file with ftruncate. Provide alternate implementation - for this */ - currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); - if (currpos == -1) { - goto done; - } - - /* Do an fstat to see if the file is longer than the requested - size in which case the ftruncate above should have - succeeded or shorter, in which case seek to len - 1 and - write 1 byte of zero */ - if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) { - goto done; - } - -#ifdef S_ISFIFO - if (S_ISFIFO(st.st_mode)) { - result = 0; - goto done; - } -#endif - - if (st.st_size == len) { - result = 0; - goto done; - } - - if (st.st_size > len) { - /* the sys_ftruncate should have worked */ - goto done; - } - - if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1) - goto done; - - if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1) - goto done; - - /* Seek to where we were */ - if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos) - goto done; - result = 0; - - done: - - END_PROFILE(syscall_ftruncate); - return result; -} - -BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) -{ - BOOL result; - - START_PROFILE(syscall_fcntl_lock); - result = fcntl_lock(fd, op, offset, count, type); - END_PROFILE(syscall_fcntl_lock); - return result; -} - -int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, - int fd, uint32 share_mode) -{ - START_PROFILE(syscall_kernel_flock); - kernel_flock(fd, share_mode); - END_PROFILE(syscall_kernel_flock); - return 0; -} - -BOOL vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid) -{ - BOOL result; - - START_PROFILE(syscall_fcntl_getlock); - result = fcntl_getlock(fd, poffset, pcount, ptype, ppid); - END_PROFILE(syscall_fcntl_getlock); - return result; -} - -int vfswrap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) -{ - int result; - - START_PROFILE(syscall_symlink); - result = sys_symlink(oldpath, newpath); - END_PROFILE(syscall_symlink); - return result; -} - -int vfswrap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz) -{ - int result; - - START_PROFILE(syscall_readlink); - result = sys_readlink(path, buf, bufsiz); - END_PROFILE(syscall_readlink); - return result; -} - -int vfswrap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) -{ - int result; - - START_PROFILE(syscall_link); - result = sys_link(oldpath, newpath); - END_PROFILE(syscall_link); - return result; -} - -int vfswrap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev) -{ - int result; - - START_PROFILE(syscall_mknod); - result = sys_mknod(pathname, mode, dev); - END_PROFILE(syscall_mknod); - return result; -} - -char *vfswrap_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path) -{ - char *result; - - START_PROFILE(syscall_realpath); - result = sys_realpath(path, resolved_path); - END_PROFILE(syscall_realpath); - return result; -} - -size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc) -{ - size_t result; - - START_PROFILE(fget_nt_acl); - result = get_nt_acl(fsp, security_info, ppdesc); - END_PROFILE(fget_nt_acl); - return result; -} - -size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc) -{ - size_t result; - - START_PROFILE(get_nt_acl); - result = get_nt_acl(fsp, security_info, ppdesc); - END_PROFILE(get_nt_acl); - return result; -} - -BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) -{ - BOOL result; - - START_PROFILE(fset_nt_acl); - result = set_nt_acl(fsp, security_info_sent, psd); - END_PROFILE(fset_nt_acl); - return result; -} - -BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) -{ - BOOL result; - - START_PROFILE(set_nt_acl); - result = set_nt_acl(fsp, security_info_sent, psd); - END_PROFILE(set_nt_acl); - return result; -} - -int vfswrap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode) -{ -#ifdef HAVE_NO_ACL - errno = ENOSYS; - return -1; -#else - int result; - - START_PROFILE(chmod_acl); - result = chmod_acl(conn, name, mode); - END_PROFILE(chmod_acl); - return result; -#endif -} - -int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) -{ -#ifdef HAVE_NO_ACL - errno = ENOSYS; - return -1; -#else - int result; - - START_PROFILE(fchmod_acl); - result = fchmod_acl(fsp, fd, mode); - END_PROFILE(fchmod_acl); - return result; -#endif -} - -int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) -{ - return sys_acl_get_entry(theacl, entry_id, entry_p); -} - -int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) -{ - return sys_acl_get_tag_type(entry_d, tag_type_p); -} - -int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) -{ - return sys_acl_get_permset(entry_d, permset_p); -} - -void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d) -{ - return sys_acl_get_qualifier(entry_d); -} - -SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type) -{ - return sys_acl_get_file(handle, path_p, type); -} - -SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) -{ - return sys_acl_get_fd(handle, fsp, fd); -} - -int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset) -{ - return sys_acl_clear_perms(permset); -} - -int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - return sys_acl_add_perm(permset, perm); -} - -char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen) -{ - return sys_acl_to_text(theacl, plen); -} - -SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, connection_struct *conn, int count) -{ - return sys_acl_init(count); -} - -int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) -{ - return sys_acl_create_entry(pacl, pentry); -} - -int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) -{ - return sys_acl_set_tag_type(entry, tagtype); -} - -int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual) -{ - return sys_acl_set_qualifier(entry, qual); -} - -int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) -{ - return sys_acl_set_permset(entry, permset); -} - -int vfswrap_sys_acl_valid(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl ) -{ - return sys_acl_valid(theacl ); -} - -int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) -{ - return sys_acl_set_file(handle, name, acltype, theacl); -} - -int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl) -{ - return sys_acl_set_fd(handle, fsp, fd, theacl); -} - -int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path) -{ - return sys_acl_delete_def_file(handle, path); -} - -int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - return sys_acl_get_perm(permset, perm); -} - -int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, connection_struct *conn, char *text) -{ - return sys_acl_free_text(text); -} - -int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T posix_acl) -{ - return sys_acl_free_acl(posix_acl); -} - -int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype) -{ - return sys_acl_free_qualifier(qualifier, tagtype); -} - -/**************************************************************** - Extended attribute operations. -*****************************************************************/ - -ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size) -{ - return sys_getxattr(path, name, value, size); -} - -ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size) -{ - return sys_lgetxattr(path, name, value, size); -} - -ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size) -{ - return sys_fgetxattr(fd, name, value, size); -} - -ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size) -{ - return sys_listxattr(path, list, size); -} - -ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size) -{ - return sys_llistxattr(path, list, size); -} - -ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size) -{ - return sys_flistxattr(fd, list, size); -} - -int vfswrap_removexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name) -{ - return sys_removexattr(path, name); -} - -int vfswrap_lremovexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name) -{ - return sys_lremovexattr(path, name); -} - -int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name) -{ - return sys_fremovexattr(fd, name); -} - -int vfswrap_setxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags) -{ - return sys_setxattr(path, name, value, size, flags); -} - -int vfswrap_lsetxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags) -{ - return sys_lsetxattr(path, name, value, size, flags); -} - -int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags) -{ - return sys_fsetxattr(fd, name, value, size, flags); -} - -int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_read(aiocb); -} - -int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_write(aiocb); -} - -ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_return(aiocb); -} - -int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_cancel(fd, aiocb); -} - -int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_error(aiocb); -} - -int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb) -{ - return sys_aio_fsync(op, aiocb); -} - -int vfswrap_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *timeout) -{ - return sys_aio_suspend(aiocb, n, timeout); -} diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c index 0e8e6babc40..3ed56d3bf6f 100644 --- a/source/smbd/vfs.c +++ b/source/smbd/vfs.c @@ -4,6 +4,7 @@ VFS initialisation and support functions Copyright (C) Tim Potter 1999 Copyright (C) Alexander Bokovoy 2002 + Copyright (C) James Peach 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,132 +38,6 @@ struct vfs_init_function_entry { static struct vfs_init_function_entry *backends = NULL; -/* Some structures to help us initialise the vfs operations table */ - -struct vfs_syminfo { - char *name; - void *fptr; -}; - -/* Default vfs hooks. WARNING: The order of these initialisers is - very important. They must be in the same order as defined in - vfs.h. Change at your own peril. */ - -static struct vfs_ops default_vfs = { - - { - /* Disk operations */ - - vfswrap_dummy_connect, - vfswrap_dummy_disconnect, - vfswrap_disk_free, - vfswrap_get_quota, - vfswrap_set_quota, - vfswrap_get_shadow_copy_data, - vfswrap_statvfs, - - /* Directory operations */ - - vfswrap_opendir, - vfswrap_readdir, - vfswrap_seekdir, - vfswrap_telldir, - vfswrap_rewinddir, - vfswrap_mkdir, - vfswrap_rmdir, - vfswrap_closedir, - - /* File operations */ - - vfswrap_open, - vfswrap_close, - vfswrap_read, - vfswrap_pread, - vfswrap_write, - vfswrap_pwrite, - vfswrap_lseek, - vfswrap_sendfile, - vfswrap_rename, - vfswrap_fsync, - vfswrap_stat, - vfswrap_fstat, - vfswrap_lstat, - vfswrap_unlink, - vfswrap_chmod, - vfswrap_fchmod, - vfswrap_chown, - vfswrap_fchown, - vfswrap_chdir, - vfswrap_getwd, - vfswrap_utime, - vfswrap_ftruncate, - vfswrap_lock, - vfswrap_kernel_flock, - vfswrap_getlock, - vfswrap_symlink, - vfswrap_readlink, - vfswrap_link, - vfswrap_mknod, - vfswrap_realpath, - - /* Windows ACL operations. */ - vfswrap_fget_nt_acl, - vfswrap_get_nt_acl, - vfswrap_fset_nt_acl, - vfswrap_set_nt_acl, - - /* POSIX ACL operations. */ - vfswrap_chmod_acl, - vfswrap_fchmod_acl, - - vfswrap_sys_acl_get_entry, - vfswrap_sys_acl_get_tag_type, - vfswrap_sys_acl_get_permset, - vfswrap_sys_acl_get_qualifier, - vfswrap_sys_acl_get_file, - vfswrap_sys_acl_get_fd, - vfswrap_sys_acl_clear_perms, - vfswrap_sys_acl_add_perm, - vfswrap_sys_acl_to_text, - vfswrap_sys_acl_init, - vfswrap_sys_acl_create_entry, - vfswrap_sys_acl_set_tag_type, - vfswrap_sys_acl_set_qualifier, - vfswrap_sys_acl_set_permset, - vfswrap_sys_acl_valid, - vfswrap_sys_acl_set_file, - vfswrap_sys_acl_set_fd, - vfswrap_sys_acl_delete_def_file, - vfswrap_sys_acl_get_perm, - vfswrap_sys_acl_free_text, - vfswrap_sys_acl_free_acl, - vfswrap_sys_acl_free_qualifier, - - /* EA operations. */ - vfswrap_getxattr, - vfswrap_lgetxattr, - vfswrap_fgetxattr, - vfswrap_listxattr, - vfswrap_llistxattr, - vfswrap_flistxattr, - vfswrap_removexattr, - vfswrap_lremovexattr, - vfswrap_fremovexattr, - vfswrap_setxattr, - vfswrap_lsetxattr, - vfswrap_fsetxattr, - - /* AIO operations. */ - vfswrap_aio_read, - vfswrap_aio_write, - vfswrap_aio_return, - vfswrap_aio_cancel, - vfswrap_aio_error, - vfswrap_aio_fsync, - vfswrap_aio_suspend - } -}; - /**************************************************************************** maintain the list of available backends ****************************************************************************/ @@ -218,15 +93,20 @@ NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *vfs_op_tu static void vfs_init_default(connection_struct *conn) { DEBUG(3, ("Initialising default vfs hooks\n")); - - memcpy(&conn->vfs.ops, &default_vfs.ops, sizeof(default_vfs.ops)); - memcpy(&conn->vfs_opaque.ops, &default_vfs.ops, sizeof(default_vfs.ops)); + vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME); } /**************************************************************************** initialise custom vfs hooks ****************************************************************************/ +static inline void vfs_set_operation(struct vfs_ops * vfs, vfs_op_type which, + struct vfs_handle_struct * handle, void * op) +{ + ((struct vfs_handle_struct **)&vfs->handles)[which] = handle; + ((void **)(void *)&vfs->ops)[which] = op; +} + BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) { vfs_op_tuple *ops; @@ -293,18 +173,15 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) for(i=0; ops[i].op != NULL; i++) { DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer)); if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) { - /* Check whether this operation was already made opaque by different module */ - if(((void**)&conn->vfs_opaque.ops)[ops[i].type] == ((void**)&default_vfs.ops)[ops[i].type]) { - /* No, it isn't overloaded yet. Overload. */ - DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object)); - ((void**)&conn->vfs_opaque.ops)[ops[i].type] = ops[i].op; - ((vfs_handle_struct **)&conn->vfs_opaque.handles)[ops[i].type] = handle; - } + /* If this operation was already made opaque by different module, it + * will be overridded here. + */ + DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object)); + vfs_set_operation(&conn->vfs_opaque, ops[i].type, handle, ops[i].op); } /* Change current VFS disposition*/ DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object)); - ((void**)&conn->vfs.ops)[ops[i].type] = ops[i].op; - ((vfs_handle_struct **)&conn->vfs.handles)[ops[i].type] = handle; + vfs_set_operation(&conn->vfs, ops[i].type, handle, ops[i].op); } SAFE_FREE(module_name); @@ -312,6 +189,71 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) } /***************************************************************** + Allow VFS modules to extend files_struct with VFS-specific state. + This will be ok for small numbers of extensions, but might need to + be refactored if it becomes more widely used. +******************************************************************/ + +#define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data)) + +void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle, files_struct *fsp, size_t ext_size) +{ + struct vfs_fsp_data *ext; + void * ext_data; + + /* Prevent VFS modules adding multiple extensions. */ + if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) { + return ext_data; + } + + ext = (struct vfs_fsp_data *)TALLOC_ZERO( + handle->conn->mem_ctx, sizeof(struct vfs_fsp_data) + ext_size); + if (ext == NULL) { + return NULL; + } + + ext->owner = handle; + ext->next = fsp->vfs_extension; + fsp->vfs_extension = ext; + return EXT_DATA_AREA(ext); +} + +void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp) +{ + struct vfs_fsp_data *curr; + struct vfs_fsp_data *prev; + + for (curr = fsp->vfs_extension, prev = NULL; + curr; + prev = curr, curr = curr->next) { + if (curr->owner == handle) { + if (prev) { + prev->next = curr->next; + } else { + fsp->vfs_extension = curr->next; + } + TALLOC_FREE(curr); + return; + } + } +} + +void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp) +{ + struct vfs_fsp_data *head; + + for (head = fsp->vfs_extension; head; head = head->next) { + if (head->owner == handle) { + return EXT_DATA_AREA(head); + } + } + + return NULL; +} + +#undef EXT_DATA_AREA + +/***************************************************************** Generic VFS init. ******************************************************************/ @@ -705,7 +647,7 @@ char *vfs_readdirname(connection_struct *conn, void *p) if (!p) return(NULL); - ptr = SMB_VFS_READDIR(conn,p); + ptr = SMB_VFS_READDIR(conn, (DIR *)p); if (!ptr) return(NULL); diff --git a/source/torture/cmd_vfs.c b/source/torture/cmd_vfs.c index ad75a2a71f1..6cecd693f83 100644 --- a/source/torture/cmd_vfs.c +++ b/source/torture/cmd_vfs.c @@ -200,9 +200,10 @@ static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - int flags, fd; + int flags; mode_t mode; const char *flagstr; + files_struct *fsp; mode = 00400; @@ -278,18 +279,21 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c } } - fd = SMB_VFS_OPEN(vfs->conn, argv[1], flags, mode); - if (fd == -1) { + fsp = SMB_MALLOC_P(struct files_struct); + fsp->fsp_name = SMB_STRDUP(argv[1]); + fsp->fh = SMB_MALLOC_P(struct fd_handle); + fsp->conn = vfs->conn; + + fsp->fh->fd = SMB_VFS_OPEN(vfs->conn, argv[1], fsp, flags, mode); + if (fsp->fh->fd == -1) { printf("open: error=%d (%s)\n", errno, strerror(errno)); + SAFE_FREE(fsp->fh); + SAFE_FREE(fsp); return NT_STATUS_UNSUCCESSFUL; } - vfs->files[fd] = SMB_MALLOC_P(struct files_struct); - vfs->files[fd]->fsp_name = SMB_STRDUP(argv[1]); - vfs->files[fd]->fh = SMB_MALLOC_P(struct fd_handle); - vfs->files[fd]->fh->fd = fd; - vfs->files[fd]->conn = vfs->conn; - printf("open: fd=%d\n", fd); + vfs->files[fsp->fh->fd] = fsp; + printf("open: fd=%d\n", fsp->fh->fd); return NT_STATUS_OK; } diff --git a/source/torture/denytest.c b/source/torture/denytest.c index 291a4035af7..2dc5c2b634f 100644 --- a/source/torture/denytest.c +++ b/source/torture/denytest.c @@ -1412,7 +1412,7 @@ BOOL torture_denytest1(int dummy) BOOL correct = True; const char *fnames[2] = {"\\denytest1.dat", "\\denytest1.exe"}; - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli1, 0)) { return False; } @@ -1447,10 +1447,10 @@ BOOL torture_denytest1(int dummy) } else { char x = 1; res = A_0; - if (cli_read(cli1, fnum2, (void *)&x, 0, 1) == 1) { + if (cli_read(cli1, fnum2, (char *)&x, 0, 1) == 1) { res += A_R; } - if (cli_write(cli1, fnum2, 0, (void *)&x, 0, 1) == 1) { + if (cli_write(cli1, fnum2, 0, (char *)&x, 0, 1) == 1) { res += A_W; } } @@ -1498,7 +1498,7 @@ BOOL torture_denytest2(int dummy) BOOL correct = True; const char *fnames[2] = {"\\denytest2.dat", "\\denytest2.exe"}; - if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { + if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) { return False; } @@ -1531,10 +1531,10 @@ BOOL torture_denytest2(int dummy) } else { char x = 1; res = A_0; - if (cli_read(cli2, fnum2, (void *)&x, 0, 1) == 1) { + if (cli_read(cli2, fnum2, (char *)&x, 0, 1) == 1) { res += A_R; } - if (cli_write(cli2, fnum2, 0, (void *)&x, 0, 1) == 1) { + if (cli_write(cli2, fnum2, 0, (char *)&x, 0, 1) == 1) { res += A_W; } } diff --git a/source/torture/locktest.c b/source/torture/locktest.c index b946e48666e..c3200ca038c 100644 --- a/source/torture/locktest.c +++ b/source/torture/locktest.c @@ -113,9 +113,13 @@ static struct record preset[] = { static struct record *recorded; -static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, - enum brl_type lock_type, - br_off start, br_off size) +static void print_brl(SMB_DEV_T dev, + SMB_INO_T ino, + struct process_id pid, + enum brl_type lock_type, + enum brl_flavour lock_flav, + br_off start, + br_off size) { #if NASTY_POSIX_LOCK_HACK { @@ -178,7 +182,7 @@ static struct cli_state *connect_one(char *share, int snum) zero_ip(&ip); /* have to open a new connection */ - if (!(c=cli_initialise(NULL)) || !cli_connect(c, server_n, &ip)) { + if (!(c=cli_initialise()) || !cli_connect(c, server_n, &ip)) { DEBUG(0,("Connection to %s failed\n", server_n)); return NULL; } @@ -216,10 +220,12 @@ static struct cli_state *connect_one(char *share, int snum) fstrcpy(username[1], username[0]); } - if (!cli_session_setup(c, username[snum], - password[snum], strlen(password[snum]), - password[snum], strlen(password[snum]), - lp_workgroup())) { + if (!NT_STATUS_IS_OK(cli_session_setup(c, username[snum], + password[snum], + strlen(password[snum]), + password[snum], + strlen(password[snum]), + lp_workgroup()))) { DEBUG(0,("session setup failed: %s\n", cli_errstr(c))); return NULL; } diff --git a/source/torture/locktest2.c b/source/torture/locktest2.c index 519acebe8e8..5f2f2499acd 100644 --- a/source/torture/locktest2.c +++ b/source/torture/locktest2.c @@ -135,6 +135,7 @@ static BOOL try_unlock(struct cli_state *c, int fstype, static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, enum brl_type lock_type, + enum brl_flavour lock_flav, br_off start, br_off size) { printf("%6d %05x:%05x %s %.0f:%.0f(%.0f)\n", diff --git a/source/torture/mangle_test.c b/source/torture/mangle_test.c index 9ce6afa038f..1c9fba355a6 100644 --- a/source/torture/mangle_test.c +++ b/source/torture/mangle_test.c @@ -167,7 +167,7 @@ BOOL torture_mangle(int dummy) printf("starting mangle test\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } diff --git a/source/torture/masktest.c b/source/torture/masktest.c index ffc9a20e71c..2ce59c86e65 100644 --- a/source/torture/masktest.c +++ b/source/torture/masktest.c @@ -184,7 +184,7 @@ struct cli_state *connect_one(char *share) zero_ip(&ip); /* have to open a new connection */ - if (!(c=cli_initialise(NULL)) || !cli_connect(c, server_n, &ip)) { + if (!(c=cli_initialise()) || !cli_connect(c, server_n, &ip)) { DEBUG(0,("Connection to %s failed\n", server_n)); return NULL; } @@ -216,10 +216,10 @@ struct cli_state *connect_one(char *share) } } - if (!cli_session_setup(c, username, - password, strlen(password), - password, strlen(password), - lp_workgroup())) { + if (!NT_STATUS_IS_OK(cli_session_setup(c, username, + password, strlen(password), + password, strlen(password), + lp_workgroup()))) { DEBUG(0,("session setup failed: %s\n", cli_errstr(c))); return NULL; } diff --git a/source/torture/nbio.c b/source/torture/nbio.c index 795392ae5cb..9b2d58c86ee 100644 --- a/source/torture/nbio.c +++ b/source/torture/nbio.c @@ -34,7 +34,7 @@ static struct { int handle; } ftable[MAX_FILES]; -static struct { +static struct children { double bytes_in, bytes_out; int line; int done; @@ -70,7 +70,7 @@ void nb_alarm(int ignore) void nbio_shmem(int n) { nprocs = n; - children = shm_setup(sizeof(*children) * nprocs); + children = (struct children *)shm_setup(sizeof(*children) * nprocs); if (!children) { printf("Failed to setup shared memory!\n"); exit(1); diff --git a/source/torture/nsstest.c b/source/torture/nsstest.c index d2b17f0f635..7673f922090 100644 --- a/source/torture/nsstest.c +++ b/source/torture/nsstest.c @@ -62,7 +62,9 @@ static void report_nss_error(const char *who, NSS_STATUS status) static struct passwd *nss_getpwent(void) { NSS_STATUS (*_nss_getpwent_r)(struct passwd *, char *, - size_t , int *) = find_fn("getpwent_r"); + size_t , int *) = + (NSS_STATUS (*)(struct passwd *, char *, + size_t, int *))find_fn("getpwent_r"); static struct passwd pwd; static char buf[1000]; NSS_STATUS status; @@ -84,7 +86,9 @@ static struct passwd *nss_getpwent(void) static struct passwd *nss_getpwnam(const char *name) { NSS_STATUS (*_nss_getpwnam_r)(const char *, struct passwd *, char *, - size_t , int *) = find_fn("getpwnam_r"); + size_t , int *) = + (NSS_STATUS (*)(const char *, struct passwd *, char *, + size_t, int *))find_fn("getpwnam_r"); static struct passwd pwd; static char buf[1000]; NSS_STATUS status; @@ -106,7 +110,9 @@ static struct passwd *nss_getpwnam(const char *name) static struct passwd *nss_getpwuid(uid_t uid) { NSS_STATUS (*_nss_getpwuid_r)(uid_t , struct passwd *, char *, - size_t , int *) = find_fn("getpwuid_r"); + size_t , int *) = + (NSS_STATUS (*)(uid_t, struct passwd *, char *, + size_t, int *))find_fn("getpwuid_r"); static struct passwd pwd; static char buf[1000]; NSS_STATUS status; @@ -127,7 +133,8 @@ static struct passwd *nss_getpwuid(uid_t uid) static void nss_setpwent(void) { - NSS_STATUS (*_nss_setpwent)(void) = find_fn("setpwent"); + NSS_STATUS (*_nss_setpwent)(void) = + (NSS_STATUS(*)(void))find_fn("setpwent"); NSS_STATUS status; if (!_nss_setpwent) @@ -141,7 +148,8 @@ static void nss_setpwent(void) static void nss_endpwent(void) { - NSS_STATUS (*_nss_endpwent)(void) = find_fn("endpwent"); + NSS_STATUS (*_nss_endpwent)(void) = + (NSS_STATUS (*)(void))find_fn("endpwent"); NSS_STATUS status; if (!_nss_endpwent) @@ -157,7 +165,9 @@ static void nss_endpwent(void) static struct group *nss_getgrent(void) { NSS_STATUS (*_nss_getgrent_r)(struct group *, char *, - size_t , int *) = find_fn("getgrent_r"); + size_t , int *) = + (NSS_STATUS (*)(struct group *, char *, + size_t, int *))find_fn("getgrent_r"); static struct group grp; static char *buf; static int buflen = 1024; @@ -167,13 +177,13 @@ static struct group *nss_getgrent(void) return NULL; if (!buf) - buf = SMB_MALLOC(buflen); + buf = SMB_MALLOC_ARRAY(char, buflen); again: status = _nss_getgrent_r(&grp, buf, buflen, &nss_errno); if (status == NSS_STATUS_TRYAGAIN) { buflen *= 2; - buf = SMB_REALLOC(buf, buflen); + buf = SMB_REALLOC_ARRAY(buf, char, buflen); if (!buf) { return NULL; } @@ -192,7 +202,9 @@ again: static struct group *nss_getgrnam(const char *name) { NSS_STATUS (*_nss_getgrnam_r)(const char *, struct group *, char *, - size_t , int *) = find_fn("getgrnam_r"); + size_t , int *) = + (NSS_STATUS (*)(const char *, struct group *, char *, + size_t, int *))find_fn("getgrnam_r"); static struct group grp; static char *buf; static int buflen = 1000; @@ -202,12 +214,12 @@ static struct group *nss_getgrnam(const char *name) return NULL; if (!buf) - buf = SMB_MALLOC(buflen); + buf = SMB_MALLOC_ARRAY(char, buflen); again: status = _nss_getgrnam_r(name, &grp, buf, buflen, &nss_errno); if (status == NSS_STATUS_TRYAGAIN) { buflen *= 2; - buf = SMB_REALLOC(buf, buflen); + buf = SMB_REALLOC_ARRAY(buf, char, buflen); if (!buf) { return NULL; } @@ -226,7 +238,9 @@ again: static struct group *nss_getgrgid(gid_t gid) { NSS_STATUS (*_nss_getgrgid_r)(gid_t , struct group *, char *, - size_t , int *) = find_fn("getgrgid_r"); + size_t , int *) = + (NSS_STATUS (*)(gid_t, struct group *, char *, + size_t, int *))find_fn("getgrgid_r"); static struct group grp; static char *buf; static int buflen = 1000; @@ -236,13 +250,13 @@ static struct group *nss_getgrgid(gid_t gid) return NULL; if (!buf) - buf = SMB_MALLOC(buflen); + buf = SMB_MALLOC_ARRAY(char, buflen); again: status = _nss_getgrgid_r(gid, &grp, buf, buflen, &nss_errno); if (status == NSS_STATUS_TRYAGAIN) { buflen *= 2; - buf = SMB_REALLOC(buf, buflen); + buf = SMB_REALLOC_ARRAY(buf, char, buflen); if (!buf) { return NULL; } @@ -260,7 +274,8 @@ again: static void nss_setgrent(void) { - NSS_STATUS (*_nss_setgrent)(void) = find_fn("setgrent"); + NSS_STATUS (*_nss_setgrent)(void) = + (NSS_STATUS (*)(void))find_fn("setgrent"); NSS_STATUS status; if (!_nss_setgrent) @@ -274,7 +289,8 @@ static void nss_setgrent(void) static void nss_endgrent(void) { - NSS_STATUS (*_nss_endgrent)(void) = find_fn("endgrent"); + NSS_STATUS (*_nss_endgrent)(void) = + (NSS_STATUS (*)(void))find_fn("endgrent"); NSS_STATUS status; if (!_nss_endgrent) @@ -290,7 +306,9 @@ static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *sta { NSS_STATUS (*_nss_initgroups)(char *, gid_t , long int *, long int *, gid_t **, long int , int *) = - find_fn("initgroups_dyn"); + (NSS_STATUS (*)(char *, gid_t, long int *, + long int *, gid_t **, + long int, int *))find_fn("initgroups_dyn"); NSS_STATUS status; if (!_nss_initgroups) diff --git a/source/torture/rpctorture.c b/source/torture/rpctorture.c index d69cc8eb8df..98f2dc105fa 100644 --- a/source/torture/rpctorture.c +++ b/source/torture/rpctorture.c @@ -493,7 +493,7 @@ enum client_action strupper_m(global_myname); fstrcpy(cli_info.myhostname, global_myname); - DEBUG(3,("%s client started (version %s)\n",timestring(False),SAMBA_VERSION_STRING)); + DEBUG(3,("%s client started (version %s)\n",current_timestring(False),SAMBA_VERSION_STRING)); if (*smb_cli->domain == 0) { diff --git a/source/torture/scanner.c b/source/torture/scanner.c index 1893be83699..87c82f8a737 100644 --- a/source/torture/scanner.c +++ b/source/torture/scanner.c @@ -49,7 +49,7 @@ static NTSTATUS try_trans2(struct cli_state *cli, int op, char *param, char *data, int param_len, int data_len, - int *rparam_len, int *rdata_len) + unsigned int *rparam_len, unsigned int *rdata_len) { uint16 setup = op; char *rparam=NULL, *rdata=NULL; @@ -80,7 +80,7 @@ static NTSTATUS try_trans2_len(struct cli_state *cli, int op, int level, char *param, char *data, int param_len, int *data_len, - int *rparam_len, int *rdata_len) + unsigned int *rparam_len, unsigned int *rdata_len) { NTSTATUS ret=NT_STATUS_OK; @@ -115,7 +115,7 @@ static BOOL scan_trans2(struct cli_state *cli, int op, int level, { int data_len = 0; int param_len = 0; - int rparam_len, rdata_len; + unsigned int rparam_len, rdata_len; pstring param, data; NTSTATUS status; @@ -196,7 +196,7 @@ BOOL torture_trans2_scan(int dummy) printf("starting trans2 scan test\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -253,7 +253,7 @@ static NTSTATUS try_nttrans(struct cli_state *cli, int op, char *param, char *data, int param_len, int data_len, - int *rparam_len, int *rdata_len) + unsigned int *rparam_len, unsigned int *rdata_len) { char *rparam=NULL, *rdata=NULL; @@ -282,7 +282,7 @@ static NTSTATUS try_nttrans_len(struct cli_state *cli, int op, int level, char *param, char *data, int param_len, int *data_len, - int *rparam_len, int *rdata_len) + unsigned int *rparam_len, unsigned int *rdata_len) { NTSTATUS ret=NT_STATUS_OK; @@ -317,7 +317,7 @@ static BOOL scan_nttrans(struct cli_state *cli, int op, int level, { int data_len = 0; int param_len = 0; - int rparam_len, rdata_len; + unsigned int rparam_len, rdata_len; pstring param, data; NTSTATUS status; @@ -398,7 +398,7 @@ BOOL torture_nttrans_scan(int dummy) printf("starting nttrans scan test\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } diff --git a/source/torture/torture.c b/source/torture/torture.c index a8a8e847fbb..79444946122 100644 --- a/source/torture/torture.c +++ b/source/torture/torture.c @@ -36,6 +36,8 @@ static BOOL use_oplocks; static BOOL use_level_II_oplocks; static const char *client_txt = "client_oplocks.txt"; static BOOL use_kerberos; +static fstring multishare_conn_fname; +static BOOL use_multishare_conn = False; BOOL torture_showall = False; @@ -44,6 +46,7 @@ static double create_procs(BOOL (*fn)(int), BOOL *result); static struct timeval tp1,tp2; + void start_timer(void) { GetTimeOfDay(&tp1); @@ -94,28 +97,27 @@ void *shm_setup(int size) } -static BOOL open_nbt_connection(struct cli_state *c) +static struct cli_state *open_nbt_connection(void) { struct nmb_name called, calling; struct in_addr ip; - - ZERO_STRUCTP(c); + struct cli_state *c; make_nmb_name(&calling, myname, 0x0); make_nmb_name(&called , host, 0x20); zero_ip(&ip); - if (!cli_initialise(c)) { + if (!(c = cli_initialise())) { printf("Failed initialize cli_struct to connect with %s\n", host); - return False; + return NULL; } c->port = port_to_use; if (!cli_connect(c, host, &ip)) { printf("Failed to connect with %s\n", host); - return False; + return NULL; } c->use_kerberos = use_kerberos; @@ -131,7 +133,7 @@ static BOOL open_nbt_connection(struct cli_state *c) */ if (!cli_connect(c, host, &ip)) { printf("Failed to connect with %s\n", host); - return False; + return NULL; } make_nmb_name(&called, "*SMBSERVER", 0x20); @@ -140,14 +142,74 @@ static BOOL open_nbt_connection(struct cli_state *c) printf("We tried with a called name of %s & %s\n", host, "*SMBSERVER"); cli_shutdown(c); - return False; + return NULL; } } - return True; + return c; +} + +/* Insert a NULL at the first separator of the given path and return a pointer + * to the remainder of the string. + */ +static char * +terminate_path_at_separator(char * path) +{ + char * p; + + if (!path) { + return NULL; + } + + if ((p = strchr_m(path, '/'))) { + *p = '\0'; + return p + 1; + } + + if ((p = strchr_m(path, '\\'))) { + *p = '\0'; + return p + 1; + } + + /* No separator. */ + return NULL; +} + +/* + parse a //server/share type UNC name +*/ +BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, + char **hostname, char **sharename) +{ + char *p; + + *hostname = *sharename = NULL; + + if (strncmp(unc_name, "\\\\", 2) && + strncmp(unc_name, "//", 2)) { + return False; + } + + *hostname = talloc_strdup(mem_ctx, &unc_name[2]); + p = terminate_path_at_separator(*hostname); + + if (p && *p) { + *sharename = talloc_strdup(mem_ctx, p); + terminate_path_at_separator(*sharename); + } + + if (*hostname && *sharename) { + return True; + } + + TALLOC_FREE(*hostname); + TALLOC_FREE(*sharename); + return False; } -BOOL torture_open_connection(struct cli_state **c) +static BOOL torture_open_connection_share(struct cli_state **c, + const char *hostname, + const char *sharename) { BOOL retry; int flags = 0; @@ -155,13 +217,15 @@ BOOL torture_open_connection(struct cli_state **c) if (use_kerberos) flags |= CLI_FULL_CONNECTION_USE_KERBEROS; - + status = cli_full_connection(c, myname, - host, NULL, port_to_use, - share, "?????", + hostname, NULL, port_to_use, + sharename, "?????", username, workgroup, password, flags, Undefined, &retry); if (!NT_STATUS_IS_OK(status)) { + printf("failed to open share connection: //%s/%s port:%d - %s\n", + hostname, sharename, port_to_use, nt_errstr(status)); return False; } @@ -172,6 +236,47 @@ BOOL torture_open_connection(struct cli_state **c) return True; } +void torture_open_connection_free_unclist(char **unc_list) +{ + if (unc_list!=NULL) + { + SAFE_FREE(unc_list[0]); + SAFE_FREE(unc_list); + } +} + +BOOL torture_open_connection(struct cli_state **c, int conn_index) +{ + char **unc_list = NULL; + int num_unc_names = 0; + BOOL result; + + if (use_multishare_conn==True) { + char *h, *s; + unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0); + if (!unc_list || num_unc_names <= 0) { + printf("Failed to load unc names list from '%s'\n", multishare_conn_fname); + exit(1); + } + + if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names], + NULL, &h, &s)) { + printf("Failed to parse UNC name %s\n", + unc_list[conn_index % num_unc_names]); + torture_open_connection_free_unclist(unc_list); + exit(1); + } + + result = torture_open_connection_share(c, h, s); + + /* h, s were copied earlier */ + torture_open_connection_free_unclist(unc_list); + return result; + } + + return torture_open_connection_share(c, host, share); +} + BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid) { uint16 old_vuid = cli->vuid; @@ -181,7 +286,10 @@ BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid) fstrcpy(old_user_name, cli->user_name); cli->vuid = 0; - ret = cli_session_setup(cli, username, password, passlen, password, passlen, workgroup); + ret = NT_STATUS_IS_OK(cli_session_setup(cli, username, + password, passlen, + password, passlen, + workgroup)); *new_vuid = cli->vuid; cli->vuid = old_vuid; fstrcpy(cli->user_name, old_user_name); @@ -462,8 +570,8 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2) int fnum1; int fnum2; int i; - uchar buf[131072]; - uchar buf_rd[131072]; + char buf[131072]; + char buf_rd[131072]; BOOL correct = True; ssize_t bytes_read; @@ -494,7 +602,7 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2) printf("%d\r", i); fflush(stdout); } - generate_random_buffer(buf, buf_size); + generate_random_buffer((unsigned char *)buf, buf_size); if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) { printf("write failed (%s)\n", cli_errstr(c1)); @@ -504,7 +612,7 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2) if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) { printf("read failed (%s)\n", cli_errstr(c2)); - printf("read %d, expected %ld\n", bytes_read, + printf("read %d, expected %ld\n", (int)bytes_read, (unsigned long)buf_size); correct = False; break; @@ -540,7 +648,7 @@ static BOOL run_readwritetest(int dummy) static struct cli_state *cli1, *cli2; BOOL test1, test2 = False; - if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { + if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) { return False; } cli_sockopt(cli1, sockops); @@ -595,7 +703,7 @@ static BOOL run_readwritelarge(int dummy) char buf[126*1024]; BOOL correct = True; - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli1, 0)) { return False; } cli_sockopt(cli1, sockops); @@ -826,7 +934,7 @@ static BOOL run_locktest1(int dummy) time_t t1, t2; unsigned lock_timeout; - if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { + if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) { return False; } cli_sockopt(cli1, sockops); @@ -941,7 +1049,7 @@ static BOOL run_tcon_test(int dummy) char buf[4]; BOOL ret = True; - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } cli_sockopt(cli, sockops); @@ -1043,7 +1151,7 @@ static BOOL run_tcon2_test(int dummy) char *service; NTSTATUS status; - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } cli_sockopt(cli, sockops); @@ -1196,7 +1304,7 @@ static BOOL run_locktest2(int dummy) int fnum1, fnum2, fnum3; BOOL correct = True; - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -1335,7 +1443,7 @@ static BOOL run_locktest3(int dummy) #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops - if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { + if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) { return False; } cli_sockopt(cli1, sockops); @@ -1459,7 +1567,7 @@ static BOOL run_locktest4(int dummy) char buf[1000]; BOOL correct = True; - if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { + if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) { return False; } @@ -1630,7 +1738,7 @@ static BOOL run_locktest5(int dummy) char buf[1000]; BOOL correct = True; - if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { + if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) { return False; } @@ -1753,7 +1861,7 @@ static BOOL run_locktest6(int dummy) int fnum; NTSTATUS status; - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -1793,7 +1901,7 @@ static BOOL run_locktest7(int dummy) char buf[200]; BOOL correct = False; - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli1, 0)) { return False; } @@ -1929,7 +2037,7 @@ static BOOL run_fdpasstest(int dummy) int fnum1; pstring buf; - if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) { + if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) { return False; } cli_sockopt(cli1, sockops); @@ -1984,7 +2092,7 @@ static BOOL run_fdsesstest(int dummy) pstring buf; BOOL ret = True; - if (!torture_open_connection(&cli)) + if (!torture_open_connection(&cli, 0)) return False; cli_sockopt(cli, sockops); @@ -2066,7 +2174,7 @@ static BOOL run_unlinktest(int dummy) int fnum; BOOL correct = True; - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -2174,20 +2282,20 @@ static void rand_buf(char *buf, int len) static BOOL run_negprot_nowait(int dummy) { int i; - static struct cli_state cli; + static struct cli_state *cli; BOOL correct = True; printf("starting negprot nowait test\n"); - if (!open_nbt_connection(&cli)) { + if (!(cli = open_nbt_connection())) { return False; } for (i=0;i<50000;i++) { - cli_negprot_send(&cli); + cli_negprot_send(cli); } - if (!torture_close_connection(&cli)) { + if (!torture_close_connection(cli)) { correct = False; } @@ -2202,7 +2310,7 @@ static BOOL run_randomipc(int dummy) { char *rparam = NULL; char *rdata = NULL; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; pstring param; int api, param_len, i; struct cli_state *cli; @@ -2211,7 +2319,7 @@ static BOOL run_randomipc(int dummy) printf("starting random ipc test\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -2264,7 +2372,7 @@ static BOOL run_browsetest(int dummy) printf("starting browse test\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -2302,7 +2410,7 @@ static BOOL run_attrtest(int dummy) printf("starting attrib test\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -2361,7 +2469,8 @@ static BOOL run_trans2test(int dummy) struct cli_state *cli; int fnum; SMB_OFF_T size; - time_t c_time, a_time, m_time, w_time, m_time2; + time_t c_time, a_time, m_time; + struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts; const char *fname = "\\trans2.tst"; const char *dname = "\\trans2"; const char *fname2 = "\\trans2\\trans2.tst"; @@ -2370,15 +2479,15 @@ static BOOL run_trans2test(int dummy) printf("starting trans2 test\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } cli_unlink(cli, fname); fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE); - if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time, &a_time, &m_time, - NULL, NULL)) { + if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts, + &m_time_ts, NULL)) { printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli)); correct = False; } @@ -2433,13 +2542,13 @@ static BOOL run_trans2test(int dummy) fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE); cli_close(cli, fnum); - if (!cli_qpathinfo2(cli, fname, &c_time, &a_time, &w_time, - &m_time, &size, NULL, NULL)) { + if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts, + &m_time_ts, &size, NULL, NULL)) { printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli)); correct = False; } else { - if (w_time < 60*60*24*2) { - printf("write time=%s", ctime(&w_time)); + if (w_time_ts.tv_sec < 60*60*24*2) { + printf("write time=%s", ctime(&w_time_ts.tv_sec)); printf("This system appears to set a initial 0 write time\n"); correct = False; } @@ -2455,8 +2564,8 @@ static BOOL run_trans2test(int dummy) correct = False; } sleep(3); - if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &w_time, - &m_time, &size, NULL, NULL)) { + if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, + &m_time_ts, &size, NULL, NULL)) { printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli)); correct = False; } @@ -2465,12 +2574,13 @@ static BOOL run_trans2test(int dummy) O_RDWR | O_CREAT | O_TRUNC, DENY_NONE); cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum)); cli_close(cli, fnum); - if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &w_time, - &m_time2, &size, NULL, NULL)) { + if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, + &m_time2_ts, &size, NULL, NULL)) { printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli)); correct = False; } else { - if (m_time2 == m_time) { + if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec)) + == 0) { printf("This system does not update directory modification times\n"); correct = False; } @@ -2519,7 +2629,7 @@ static BOOL run_w2ktest(int dummy) printf("starting w2k test\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -2554,7 +2664,7 @@ static BOOL run_oplock1(int dummy) printf("starting oplock test 1\n"); - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli1, 0)) { return False; } @@ -2612,7 +2722,7 @@ static BOOL run_oplock2(int dummy) printf("starting oplock test 2\n"); - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli1, 0)) { use_level_II_oplocks = False; use_oplocks = saved_use_oplocks; return False; @@ -2621,7 +2731,7 @@ static BOOL run_oplock2(int dummy) cli1->use_oplocks = True; cli1->use_level_II_oplocks = True; - if (!torture_open_connection(&cli2)) { + if (!torture_open_connection(&cli2, 1)) { use_level_II_oplocks = False; use_oplocks = saved_use_oplocks; return False; @@ -2755,7 +2865,7 @@ static BOOL run_oplock3(int dummy) /* Child code */ use_oplocks = True; use_level_II_oplocks = True; - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { *shared_correct = False; exit(0); } @@ -2769,7 +2879,7 @@ static BOOL run_oplock3(int dummy) /* parent code */ use_oplocks = True; use_level_II_oplocks = True; - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 1)) { /* other is forked */ return False; } cli_oplock_handler(cli, oplock3_handler); @@ -2802,7 +2912,7 @@ static BOOL run_deletetest(int dummy) printf("starting delete test\n"); - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli1, 0)) { return False; } @@ -3116,7 +3226,7 @@ static BOOL run_deletetest(int dummy) cli_setatr(cli1, fname, 0, 0); cli_unlink(cli1, fname); - if (!torture_open_connection(&cli2)) { + if (!torture_open_connection(&cli2, 1)) { printf("[8] failed to open second connection.\n"); correct = False; goto fail; @@ -3283,7 +3393,7 @@ static BOOL run_properties(int dummy) ZERO_STRUCT(cli); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -3331,7 +3441,7 @@ static BOOL run_xcopy(int dummy) printf("starting xcopy test\n"); - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli1, 0)) { return False; } @@ -3374,7 +3484,7 @@ static BOOL run_rename(int dummy) printf("starting rename test\n"); - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli1, 0)) { return False; } @@ -3560,7 +3670,7 @@ static BOOL run_pipe_number(int dummy) int num_pipes = 0; printf("starting pipenumber test\n"); - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli1, 0)) { return False; } @@ -3574,6 +3684,7 @@ static BOOL run_pipe_number(int dummy) break; } num_pipes++; + printf("\r%6d", num_pipes); } printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name ); @@ -3597,7 +3708,7 @@ static BOOL run_opentest(int dummy) printf("starting open test\n"); - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli1, 0)) { return False; } @@ -3744,7 +3855,7 @@ static BOOL run_opentest(int dummy) /* Test the non-io opens... */ - if (!torture_open_connection(&cli2)) { + if (!torture_open_connection(&cli2, 1)) { return False; } @@ -4045,7 +4156,7 @@ static BOOL run_openattrtest(int dummy) printf("starting open attr test\n"); - if (!torture_open_connection(&cli1)) { + if (!torture_open_connection(&cli1, 0)) { return False; } @@ -4157,7 +4268,7 @@ static BOOL run_dirtest(int dummy) printf("starting directory test\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -4230,7 +4341,7 @@ BOOL torture_ioctl_test(int dummy) DATA_BLOB blob; NTSTATUS status; - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -4258,7 +4369,8 @@ BOOL torture_ioctl_test(int dummy) status = cli_raw_ioctl(cli, fnum, code, &blob); if (NT_STATUS_IS_OK(status)) { - printf("ioctl 0x%x OK : %d bytes\n", code, blob.length); + printf("ioctl 0x%x OK : %d bytes\n", (int)code, + (int)blob.length); data_blob_free(&blob); } } @@ -4281,7 +4393,7 @@ BOOL torture_chkpath_test(int dummy) int fnum; BOOL ret; - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -4366,7 +4478,7 @@ static BOOL run_eatest(int dummy) printf("starting eatest\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -4409,7 +4521,7 @@ static BOOL run_eatest(int dummy) correct = False; } - printf("num_eas = %d\n", num_eas); + printf("num_eas = %d\n", (int)num_eas); if (num_eas != 20) { printf("Should be 20 EA's stored... failing.\n"); @@ -4418,7 +4530,8 @@ static BOOL run_eatest(int dummy) for (i = 0; i < num_eas; i++) { printf("%d: ea_name = %s. Val = ", i, ea_list[i].name); - dump_data(0, ea_list[i].value.data, ea_list[i].value.length); + dump_data(0, (char *)ea_list[i].value.data, + ea_list[i].value.length); } /* Setting EA's to zero length deletes them. Test this */ @@ -4442,10 +4555,11 @@ static BOOL run_eatest(int dummy) correct = False; } - printf("num_eas = %d\n", num_eas); + printf("num_eas = %d\n", (int)num_eas); for (i = 0; i < num_eas; i++) { printf("%d: ea_name = %s. Val = ", i, ea_list[i].name); - dump_data(0, ea_list[i].value.data, ea_list[i].value.length); + dump_data(0, (char *)ea_list[i].value.data, + ea_list[i].value.length); } if (num_eas != 0) { @@ -4476,7 +4590,7 @@ static BOOL run_dirtest1(int dummy) printf("starting directory test\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -4550,8 +4664,8 @@ static BOOL run_dirtest1(int dummy) static BOOL run_error_map_extract(int dummy) { - static struct cli_state c_dos; - static struct cli_state c_nt; + static struct cli_state *c_dos; + static struct cli_state *c_nt; uint32 error; @@ -4564,81 +4678,81 @@ static BOOL run_error_map_extract(int dummy) { /* NT-Error connection */ - if (!open_nbt_connection(&c_nt)) { + if (!(c_nt = open_nbt_connection())) { return False; } - c_nt.use_spnego = False; + c_nt->use_spnego = False; - if (!cli_negprot(&c_nt)) { - printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt)); - cli_shutdown(&c_nt); + if (!cli_negprot(c_nt)) { + printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(c_nt)); + cli_shutdown(c_nt); return False; } - if (!cli_session_setup(&c_nt, "", "", 0, "", 0, - workgroup)) { - printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt)); + if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0, + workgroup))) { + printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt)); return False; } /* DOS-Error connection */ - if (!open_nbt_connection(&c_dos)) { + if (!(c_dos = open_nbt_connection())) { return False; } - c_dos.use_spnego = False; - c_dos.force_dos_errors = True; + c_dos->use_spnego = False; + c_dos->force_dos_errors = True; - if (!cli_negprot(&c_dos)) { - printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos)); - cli_shutdown(&c_dos); + if (!cli_negprot(c_dos)) { + printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(c_dos)); + cli_shutdown(c_dos); return False; } - if (!cli_session_setup(&c_dos, "", "", 0, "", 0, - workgroup)) { - printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos)); + if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0, + workgroup))) { + printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos)); return False; } for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) { fstr_sprintf(user, "%X", error); - if (cli_session_setup(&c_nt, user, - password, strlen(password), - password, strlen(password), - workgroup)) { + if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user, + password, strlen(password), + password, strlen(password), + workgroup))) { printf("/** Session setup succeeded. This shouldn't happen...*/\n"); } - flgs2 = SVAL(c_nt.inbuf,smb_flg2); + flgs2 = SVAL(c_nt->inbuf,smb_flg2); /* Case #1: 32-bit NT errors */ if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls)); + nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls)); } else { printf("/** Dos error on NT connection! (%s) */\n", - cli_errstr(&c_nt)); + cli_errstr(c_nt)); nt_status = NT_STATUS(0xc0000000); } - if (cli_session_setup(&c_dos, user, - password, strlen(password), - password, strlen(password), - workgroup)) { + if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user, + password, strlen(password), + password, strlen(password), + workgroup))) { printf("/** Session setup succeeded. This shouldn't happen...*/\n"); } - flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum; + flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum; /* Case #1: 32-bit NT errors */ if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { printf("/** NT error on DOS connection! (%s) */\n", - cli_errstr(&c_nt)); + cli_errstr(c_nt)); errnum = errclass = 0; } else { - cli_dos_error(&c_dos, &errclass, &errnum); + cli_dos_error(c_dos, &errclass, &errnum); } if (NT_STATUS_V(nt_status) != error) { @@ -4655,6 +4769,101 @@ static BOOL run_error_map_extract(int dummy) { return True; } +static BOOL run_local_substitute(int dummy) +{ + TALLOC_CTX *mem_ctx; + int diff = 0; + + if ((mem_ctx = talloc_init("run_local_subst")) == NULL) { + printf("talloc_init failed\n"); + return False; + } + + diff |= strcmp(talloc_sub_specified(mem_ctx, "%U", "bla", "", -1, -1), + "bla"); + diff |= strcmp(talloc_sub_specified(mem_ctx, "%u%U", "bla", "", -1, -1), + "blabla"); + diff |= strcmp(talloc_sub_specified(mem_ctx, "%g", "", "", -1, -1), + "NO_GROUP"); + diff |= strcmp(talloc_sub_specified(mem_ctx, "%G", "", "", -1, -1), + "NO_GROUP"); + diff |= strcmp(talloc_sub_specified(mem_ctx, "%g", "", "", -1, 0), + gidtoname(0)); + diff |= strcmp(talloc_sub_specified(mem_ctx, "%G", "", "", -1, 0), + gidtoname(0)); + diff |= strcmp(talloc_sub_specified(mem_ctx, "%D%u", "u", "dom", -1, 0), + "domu"); + diff |= strcmp(talloc_sub_specified(mem_ctx, "%i %I", "", "", -1, -1), + "0.0.0.0 0.0.0.0"); + + /* Different captialization rules in sub_basic... */ + + diff |= strcmp(talloc_sub_basic(mem_ctx, "BLA", "dom", "%U%D"), + "blaDOM"); + + TALLOC_FREE(mem_ctx); + return (diff == 0); +} + +static BOOL run_local_gencache(int dummy) +{ + char *val; + time_t tm; + + if (!gencache_init()) { + d_printf("%s: gencache_init() failed\n", __location__); + return False; + } + + if (!gencache_set("foo", "bar", time(NULL) + 1000)) { + d_printf("%s: gencache_set() failed\n", __location__); + return False; + } + + if (!gencache_get("foo", &val, &tm)) { + d_printf("%s: gencache_get() failed\n", __location__); + return False; + } + + if (strcmp(val, "bar") != 0) { + d_printf("%s: gencache_get() returned %s, expected %s\n", + __location__, val, "bar"); + SAFE_FREE(val); + return False; + } + + SAFE_FREE(val); + + if (!gencache_del("foo")) { + d_printf("%s: gencache_del() failed\n", __location__); + return False; + } + if (gencache_del("foo")) { + d_printf("%s: second gencache_del() succeeded\n", + __location__); + return False; + } + + if (gencache_get("foo", &val, &tm)) { + d_printf("%s: gencache_get() on deleted entry " + "succeeded\n", __location__); + return False; + } + + if (!gencache_shutdown()) { + d_printf("%s: gencache_shutdown() failed\n", __location__); + return False; + } + + if (gencache_shutdown()) { + d_printf("%s: second gencache_shutdown() succeeded\n", + __location__); + return False; + } + + return True; +} + static double create_procs(BOOL (*fn)(int), BOOL *result) { int i, status; @@ -4693,7 +4902,7 @@ static double create_procs(BOOL (*fn)(int), BOOL *result) slprintf(myname,sizeof(myname),"CLIENT%d", i); while (1) { - if (torture_open_connection(¤t_cli)) break; + if (torture_open_connection(¤t_cli, i)) break; if (tries-- == 0) { printf("pid %d failed to start\n", (int)getpid()); _exit(1); @@ -4805,6 +5014,8 @@ static struct { {"CHKPATH", torture_chkpath_test, 0}, {"FDSESS", run_fdsesstest, 0}, { "EATEST", run_eatest, 0}, + { "LOCAL-SUBSTITUTE", run_local_substitute, 0}, + { "LOCAL-GENCACHE", run_local_gencache, 0}, {NULL, NULL, 0}}; @@ -4884,6 +5095,7 @@ static void usage(void) printf("\t-A showall\n"); printf("\t-p port\n"); printf("\t-s seed\n"); + printf("\t-b unclist_filename specify multiple shares for multiple connections\n"); printf("\n\n"); printf("tests are:"); @@ -4952,7 +5164,7 @@ static void usage(void) fstrcpy(workgroup, lp_workgroup()); - while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) { + while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:b:")) != EOF) { switch (opt) { case 'p': port_to_use = atoi(optarg); @@ -5008,6 +5220,10 @@ static void usage(void) gotpass = 1; } break; + case 'b': + fstrcpy(multishare_conn_fname, optarg); + use_multishare_conn = True; + break; default: printf("Unknown option %c (%d)\n", (char)opt, opt); usage(); diff --git a/source/torture/utable.c b/source/torture/utable.c index afc3b749a54..e5126da91d3 100644 --- a/source/torture/utable.c +++ b/source/torture/utable.c @@ -32,7 +32,7 @@ BOOL torture_utable(int dummy) printf("starting utable\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } @@ -121,7 +121,7 @@ BOOL torture_casetable(int dummy) smb_ucs2_t equiv[0x10000][MAX_EQUIVALENCE]; printf("starting casetable\n"); - if (!torture_open_connection(&cli)) { + if (!torture_open_connection(&cli, 0)) { return False; } diff --git a/source/torture/vfstest.c b/source/torture/vfstest.c index 61bb4b0bf65..fa0545988e9 100644 --- a/source/torture/vfstest.c +++ b/source/torture/vfstest.c @@ -575,6 +575,6 @@ int main(int argc, char *argv[]) process_cmd(&vfs, line); } - free(vfs.conn); + conn_free(vfs.conn); return 0; } diff --git a/source/utils/net_sam.c b/source/utils/net_sam.c index 9edbc7b8cf4..03e0ff0a9c3 100644 --- a/source/utils/net_sam.c +++ b/source/utils/net_sam.c @@ -206,23 +206,20 @@ static int net_sam_set_pwnoexp(int argc, const char **argv) } /* - * Set a user's time field + * Set pass last change time, based on force pass change now */ -static int net_sam_set_time(int argc, const char **argv, const char *field, - BOOL (*fn)(struct samu *, time_t, - enum pdb_value_state)) +static int net_sam_set_pwdmustchangenow(int argc, const char **argv) { struct samu *sam_acct = NULL; DOM_SID sid; enum lsa_SidType type; const char *dom, *name; NTSTATUS status; - time_t new_time; - if (argc != 2) { - d_fprintf(stderr, "usage: net sam set %s <user> " - "[now|YYYY-MM-DD HH:MM]\n", field); + if ((argc != 2) || (!strequal(argv[1], "yes") && + !strequal(argv[1], "no"))) { + d_fprintf(stderr, "usage: net sam set pwdmustchangenow <user> [yes|no]\n"); return -1; } @@ -238,22 +235,6 @@ static int net_sam_set_time(int argc, const char **argv, const char *field, return -1; } - if (strequal(argv[1], "now")) { - new_time = time(NULL); - } else { - struct tm tm; - char *end; - ZERO_STRUCT(tm); - end = strptime(argv[1], "%Y-%m-%d %H:%M", &tm); - new_time = mktime(&tm); - if ((end == NULL) || (*end != '\0') || (new_time == -1)) { - d_fprintf(stderr, "Could not parse time string %s\n", - argv[1]); - return -1; - } - } - - if ( !(sam_acct = samu_new( NULL )) ) { d_fprintf(stderr, "Internal error\n"); return -1; @@ -264,9 +245,10 @@ static int net_sam_set_time(int argc, const char **argv, const char *field, return -1; } - if (!fn(sam_acct, new_time, PDB_CHANGED)) { - d_fprintf(stderr, "Internal error\n"); - return -1; + if (strequal(argv[1], "yes")) { + pdb_set_pass_last_set_time(sam_acct, 0, PDB_CHANGED); + } else { + pdb_set_pass_last_set_time(sam_acct, time(NULL), PDB_CHANGED); } status = pdb_update_sam_account(sam_acct); @@ -278,21 +260,11 @@ static int net_sam_set_time(int argc, const char **argv, const char *field, TALLOC_FREE(sam_acct); - d_printf("Updated %s for %s\\%s to %s\n", field, dom, name, argv[1]); + d_fprintf(stderr, "Updated 'user must change password at next logon' for %s\\%s to %s\n", dom, + name, argv[1]); return 0; } -static int net_sam_set_pwdmustchange(int argc, const char **argv) -{ - return net_sam_set_time(argc, argv, "pwdmustchange", - pdb_set_pass_must_change_time); -} - -static int net_sam_set_pwdcanchange(int argc, const char **argv) -{ - return net_sam_set_time(argc, argv, "pwdcanchange", - pdb_set_pass_can_change_time); -} /* * Set a user's or a group's comment @@ -376,10 +348,8 @@ static int net_sam_set(int argc, const char **argv) "Disable/Enable a user's lockout flag" }, { "pwnoexp", net_sam_set_pwnoexp, "Disable/Enable whether a user's pw does not expire" }, - { "pwdmustchange", net_sam_set_pwdmustchange, - "Set a users password must change time" }, - { "pwdcanchange", net_sam_set_pwdcanchange, - "Set a users password can change time" }, + { "pwdmustchangenow", net_sam_set_pwdmustchangenow, + "Force users password must change at next logon" }, {NULL, NULL} }; @@ -387,6 +357,80 @@ static int net_sam_set(int argc, const char **argv) } /* + * Change account policies + */ + +static int net_sam_policy(int argc, const char **argv) +{ + + const char *account_policy = NULL; + uint32 value, old_value; + int field; + + if ((argc < 1) || (argc > 2)) { + d_fprintf(stderr, "usage: net sam policy \"<account policy>\" " + "-> show current value\n"); + d_fprintf(stderr, "usage: net sam policy \"<account policy>\" " + "<value> -> set a new value\n"); + return -1; + } + + account_policy = argv[0]; + field = account_policy_name_to_fieldnum(account_policy); + + if (field == 0) { + char *apn = account_policy_names_list(); + d_fprintf(stderr, "No account policy by that name!\n"); + if (apn) { + d_fprintf(stderr, "Valid account policies " + "are:\n%s\n", apn); + } + SAFE_FREE(apn); + return -1; + } + + if (!pdb_get_account_policy(field, &old_value)) { + fprintf(stderr, "Valid account policy, but unable to " + "fetch value!\n"); + return -1; + } + + if (argc == 1) { + /* + * Just read the value + */ + + printf("Account policy \"%s\" description: %s\n", + account_policy, account_policy_get_desc(field)); + printf("Account policy \"%s\" value is: %d\n", account_policy, + old_value); + return 0; + } + + /* + * Here we know we have 2 args, so set it + */ + + value = strtoul(argv[1], NULL, 10); + + printf("Account policy \"%s\" description: %s\n", account_policy, + account_policy_get_desc(field)); + printf("Account policy \"%s\" value was: %d\n", account_policy, + old_value); + + if (!pdb_set_account_policy(field, value)) { + d_fprintf(stderr, "Setting account policy %s to %u failed \n", + account_policy, value); + } + + printf("Account policy \"%s\" value is now: %d\n", account_policy, + value); + + return 0; +} + + +/* * Map a unix group to a domain group */ @@ -1232,6 +1276,8 @@ int net_sam(int argc, const char **argv) "Show details of a SAM entry" }, { "set", net_sam_set, "Set details of a SAM account" }, + { "policy", net_sam_policy, + "Set account policies" }, #ifdef HAVE_LDAP { "provision", net_sam_provision, "Provision a clean User Database" }, diff --git a/source/utils/net_time.c b/source/utils/net_time.c index f6486286a65..f6269627dab 100644 --- a/source/utils/net_time.c +++ b/source/utils/net_time.c @@ -30,8 +30,10 @@ static time_t cli_servertime(const char *host, struct in_addr *ip, int *zone) time_t ret = 0; struct cli_state *cli = NULL; - cli = cli_initialise(NULL); - if (!cli) goto done; + cli = cli_initialise(); + if (!cli) { + goto done; + } if (!cli_connect(cli, host, ip)) { fprintf(stderr,"Can't contact server\n"); @@ -58,7 +60,9 @@ static time_t cli_servertime(const char *host, struct in_addr *ip, int *zone) if (zone) *zone = cli->serverzone; done: - if (cli) cli_shutdown(cli); + if (cli) { + cli_shutdown(cli); + } return ret; } diff --git a/source/utils/status.c b/source/utils/status.c index 163d99a2f69..4f66501511b 100644 --- a/source/utils/status.c +++ b/source/utils/status.c @@ -48,6 +48,9 @@ static BOOL numeric_only = False; const char *username = NULL; +extern BOOL status_profile_dump(BOOL be_verbose); +extern BOOL status_profile_rates(BOOL be_verbose); + /* added by OH */ static void Ucrit_addUid(uid_t uid) { @@ -98,7 +101,10 @@ static BOOL Ucrit_addPid( pid_t pid ) return True; } -static void print_share_mode(const struct share_mode_entry *e, const char *sharepath, const char *fname) +static void print_share_mode(const struct share_mode_entry *e, + const char *sharepath, + const char *fname, + void *dummy) { static int count; @@ -182,368 +188,6 @@ static void print_brl(SMB_DEV_T dev, (double)start, (double)size); } - -/******************************************************************* - dump the elements of the profile structure - ******************************************************************/ -static int profile_dump(void) -{ -#ifdef WITH_PROFILE - if (!profile_setup(True)) { - fprintf(stderr,"Failed to initialise profile memory\n"); - return -1; - } - - d_printf("smb_count: %u\n", profile_p->smb_count); - d_printf("uid_changes: %u\n", profile_p->uid_changes); - d_printf("************************ System Calls ****************************\n"); - d_printf("opendir_count: %u\n", profile_p->syscall_opendir_count); - d_printf("opendir_time: %u\n", profile_p->syscall_opendir_time); - d_printf("readdir_count: %u\n", profile_p->syscall_readdir_count); - d_printf("readdir_time: %u\n", profile_p->syscall_readdir_time); - d_printf("mkdir_count: %u\n", profile_p->syscall_mkdir_count); - d_printf("mkdir_time: %u\n", profile_p->syscall_mkdir_time); - d_printf("rmdir_count: %u\n", profile_p->syscall_rmdir_count); - d_printf("rmdir_time: %u\n", profile_p->syscall_rmdir_time); - d_printf("closedir_count: %u\n", profile_p->syscall_closedir_count); - d_printf("closedir_time: %u\n", profile_p->syscall_closedir_time); - d_printf("open_count: %u\n", profile_p->syscall_open_count); - d_printf("open_time: %u\n", profile_p->syscall_open_time); - d_printf("close_count: %u\n", profile_p->syscall_close_count); - d_printf("close_time: %u\n", profile_p->syscall_close_time); - d_printf("read_count: %u\n", profile_p->syscall_read_count); - d_printf("read_time: %u\n", profile_p->syscall_read_time); - d_printf("read_bytes: %u\n", profile_p->syscall_read_bytes); - d_printf("write_count: %u\n", profile_p->syscall_write_count); - d_printf("write_time: %u\n", profile_p->syscall_write_time); - d_printf("write_bytes: %u\n", profile_p->syscall_write_bytes); - d_printf("pread_count: %u\n", profile_p->syscall_pread_count); - d_printf("pread_time: %u\n", profile_p->syscall_pread_time); - d_printf("pread_bytes: %u\n", profile_p->syscall_pread_bytes); - d_printf("pwrite_count: %u\n", profile_p->syscall_pwrite_count); - d_printf("pwrite_time: %u\n", profile_p->syscall_pwrite_time); - d_printf("pwrite_bytes: %u\n", profile_p->syscall_pwrite_bytes); -#ifdef WITH_SENDFILE - d_printf("sendfile_count: %u\n", profile_p->syscall_sendfile_count); - d_printf("sendfile_time: %u\n", profile_p->syscall_sendfile_time); - d_printf("sendfile_bytes: %u\n", profile_p->syscall_sendfile_bytes); -#endif - d_printf("lseek_count: %u\n", profile_p->syscall_lseek_count); - d_printf("lseek_time: %u\n", profile_p->syscall_lseek_time); - d_printf("rename_count: %u\n", profile_p->syscall_rename_count); - d_printf("rename_time: %u\n", profile_p->syscall_rename_time); - d_printf("fsync_count: %u\n", profile_p->syscall_fsync_count); - d_printf("fsync_time: %u\n", profile_p->syscall_fsync_time); - d_printf("stat_count: %u\n", profile_p->syscall_stat_count); - d_printf("stat_time: %u\n", profile_p->syscall_stat_time); - d_printf("fstat_count: %u\n", profile_p->syscall_fstat_count); - d_printf("fstat_time: %u\n", profile_p->syscall_fstat_time); - d_printf("lstat_count: %u\n", profile_p->syscall_lstat_count); - d_printf("lstat_time: %u\n", profile_p->syscall_lstat_time); - d_printf("unlink_count: %u\n", profile_p->syscall_unlink_count); - d_printf("unlink_time: %u\n", profile_p->syscall_unlink_time); - d_printf("chmod_count: %u\n", profile_p->syscall_chmod_count); - d_printf("chmod_time: %u\n", profile_p->syscall_chmod_time); - d_printf("fchmod_count: %u\n", profile_p->syscall_fchmod_count); - d_printf("fchmod_time: %u\n", profile_p->syscall_fchmod_time); - d_printf("chown_count: %u\n", profile_p->syscall_chown_count); - d_printf("chown_time: %u\n", profile_p->syscall_chown_time); - d_printf("fchown_count: %u\n", profile_p->syscall_fchown_count); - d_printf("fchown_time: %u\n", profile_p->syscall_fchown_time); - d_printf("chdir_count: %u\n", profile_p->syscall_chdir_count); - d_printf("chdir_time: %u\n", profile_p->syscall_chdir_time); - d_printf("getwd_count: %u\n", profile_p->syscall_getwd_count); - d_printf("getwd_time: %u\n", profile_p->syscall_getwd_time); - d_printf("utime_count: %u\n", profile_p->syscall_utime_count); - d_printf("utime_time: %u\n", profile_p->syscall_utime_time); - d_printf("ftruncate_count: %u\n", profile_p->syscall_ftruncate_count); - d_printf("ftruncate_time: %u\n", profile_p->syscall_ftruncate_time); - d_printf("fcntl_lock_count: %u\n", profile_p->syscall_fcntl_lock_count); - d_printf("fcntl_lock_time: %u\n", profile_p->syscall_fcntl_lock_time); - d_printf("readlink_count: %u\n", profile_p->syscall_readlink_count); - d_printf("readlink_time: %u\n", profile_p->syscall_readlink_time); - d_printf("symlink_count: %u\n", profile_p->syscall_symlink_count); - d_printf("symlink_time: %u\n", profile_p->syscall_symlink_time); - d_printf("************************ Statcache *******************************\n"); - d_printf("lookups: %u\n", profile_p->statcache_lookups); - d_printf("misses: %u\n", profile_p->statcache_misses); - d_printf("hits: %u\n", profile_p->statcache_hits); - d_printf("************************ Writecache ******************************\n"); - d_printf("read_hits: %u\n", profile_p->writecache_read_hits); - d_printf("abutted_writes: %u\n", profile_p->writecache_abutted_writes); - d_printf("total_writes: %u\n", profile_p->writecache_total_writes); - d_printf("non_oplock_writes: %u\n", profile_p->writecache_non_oplock_writes); - d_printf("direct_writes: %u\n", profile_p->writecache_direct_writes); - d_printf("init_writes: %u\n", profile_p->writecache_init_writes); - d_printf("flushed_writes[SEEK]: %u\n", profile_p->writecache_flushed_writes[SEEK_FLUSH]); - d_printf("flushed_writes[READ]: %u\n", profile_p->writecache_flushed_writes[READ_FLUSH]); - d_printf("flushed_writes[WRITE]: %u\n", profile_p->writecache_flushed_writes[WRITE_FLUSH]); - d_printf("flushed_writes[READRAW]: %u\n", profile_p->writecache_flushed_writes[READRAW_FLUSH]); - d_printf("flushed_writes[OPLOCK_RELEASE]: %u\n", profile_p->writecache_flushed_writes[OPLOCK_RELEASE_FLUSH]); - d_printf("flushed_writes[CLOSE]: %u\n", profile_p->writecache_flushed_writes[CLOSE_FLUSH]); - d_printf("flushed_writes[SYNC]: %u\n", profile_p->writecache_flushed_writes[SYNC_FLUSH]); - d_printf("flushed_writes[SIZECHANGE]: %u\n", profile_p->writecache_flushed_writes[SIZECHANGE_FLUSH]); - d_printf("num_perfect_writes: %u\n", profile_p->writecache_num_perfect_writes); - d_printf("num_write_caches: %u\n", profile_p->writecache_num_write_caches); - d_printf("allocated_write_caches: %u\n", profile_p->writecache_allocated_write_caches); - d_printf("************************ SMB Calls *******************************\n"); - d_printf("mkdir_count: %u\n", profile_p->SMBmkdir_count); - d_printf("mkdir_time: %u\n", profile_p->SMBmkdir_time); - d_printf("rmdir_count: %u\n", profile_p->SMBrmdir_count); - d_printf("rmdir_time: %u\n", profile_p->SMBrmdir_time); - d_printf("open_count: %u\n", profile_p->SMBopen_count); - d_printf("open_time: %u\n", profile_p->SMBopen_time); - d_printf("create_count: %u\n", profile_p->SMBcreate_count); - d_printf("create_time: %u\n", profile_p->SMBcreate_time); - d_printf("close_count: %u\n", profile_p->SMBclose_count); - d_printf("close_time: %u\n", profile_p->SMBclose_time); - d_printf("flush_count: %u\n", profile_p->SMBflush_count); - d_printf("flush_time: %u\n", profile_p->SMBflush_time); - d_printf("unlink_count: %u\n", profile_p->SMBunlink_count); - d_printf("unlink_time: %u\n", profile_p->SMBunlink_time); - d_printf("mv_count: %u\n", profile_p->SMBmv_count); - d_printf("mv_time: %u\n", profile_p->SMBmv_time); - d_printf("getatr_count: %u\n", profile_p->SMBgetatr_count); - d_printf("getatr_time: %u\n", profile_p->SMBgetatr_time); - d_printf("setatr_count: %u\n", profile_p->SMBsetatr_count); - d_printf("setatr_time: %u\n", profile_p->SMBsetatr_time); - d_printf("read_count: %u\n", profile_p->SMBread_count); - d_printf("read_time: %u\n", profile_p->SMBread_time); - d_printf("write_count: %u\n", profile_p->SMBwrite_count); - d_printf("write_time: %u\n", profile_p->SMBwrite_time); - d_printf("lock_count: %u\n", profile_p->SMBlock_count); - d_printf("lock_time: %u\n", profile_p->SMBlock_time); - d_printf("unlock_count: %u\n", profile_p->SMBunlock_count); - d_printf("unlock_time: %u\n", profile_p->SMBunlock_time); - d_printf("ctemp_count: %u\n", profile_p->SMBctemp_count); - d_printf("ctemp_time: %u\n", profile_p->SMBctemp_time); - d_printf("mknew_count: %u\n", profile_p->SMBmknew_count); - d_printf("mknew_time: %u\n", profile_p->SMBmknew_time); - d_printf("chkpth_count: %u\n", profile_p->SMBchkpth_count); - d_printf("chkpth_time: %u\n", profile_p->SMBchkpth_time); - d_printf("exit_count: %u\n", profile_p->SMBexit_count); - d_printf("exit_time: %u\n", profile_p->SMBexit_time); - d_printf("lseek_count: %u\n", profile_p->SMBlseek_count); - d_printf("lseek_time: %u\n", profile_p->SMBlseek_time); - d_printf("lockread_count: %u\n", profile_p->SMBlockread_count); - d_printf("lockread_time: %u\n", profile_p->SMBlockread_time); - d_printf("writeunlock_count: %u\n", profile_p->SMBwriteunlock_count); - d_printf("writeunlock_time: %u\n", profile_p->SMBwriteunlock_time); - d_printf("readbraw_count: %u\n", profile_p->SMBreadbraw_count); - d_printf("readbraw_time: %u\n", profile_p->SMBreadbraw_time); - d_printf("readBmpx_count: %u\n", profile_p->SMBreadBmpx_count); - d_printf("readBmpx_time: %u\n", profile_p->SMBreadBmpx_time); - d_printf("readBs_count: %u\n", profile_p->SMBreadBs_count); - d_printf("readBs_time: %u\n", profile_p->SMBreadBs_time); - d_printf("writebraw_count: %u\n", profile_p->SMBwritebraw_count); - d_printf("writebraw_time: %u\n", profile_p->SMBwritebraw_time); - d_printf("writeBmpx_count: %u\n", profile_p->SMBwriteBmpx_count); - d_printf("writeBmpx_time: %u\n", profile_p->SMBwriteBmpx_time); - d_printf("writeBs_count: %u\n", profile_p->SMBwriteBs_count); - d_printf("writeBs_time: %u\n", profile_p->SMBwriteBs_time); - d_printf("writec_count: %u\n", profile_p->SMBwritec_count); - d_printf("writec_time: %u\n", profile_p->SMBwritec_time); - d_printf("setattrE_count: %u\n", profile_p->SMBsetattrE_count); - d_printf("setattrE_time: %u\n", profile_p->SMBsetattrE_time); - d_printf("getattrE_count: %u\n", profile_p->SMBgetattrE_count); - d_printf("getattrE_time: %u\n", profile_p->SMBgetattrE_time); - d_printf("lockingX_count: %u\n", profile_p->SMBlockingX_count); - d_printf("lockingX_time: %u\n", profile_p->SMBlockingX_time); - d_printf("trans_count: %u\n", profile_p->SMBtrans_count); - d_printf("trans_time: %u\n", profile_p->SMBtrans_time); - d_printf("transs_count: %u\n", profile_p->SMBtranss_count); - d_printf("transs_time: %u\n", profile_p->SMBtranss_time); - d_printf("ioctl_count: %u\n", profile_p->SMBioctl_count); - d_printf("ioctl_time: %u\n", profile_p->SMBioctl_time); - d_printf("ioctls_count: %u\n", profile_p->SMBioctls_count); - d_printf("ioctls_time: %u\n", profile_p->SMBioctls_time); - d_printf("copy_count: %u\n", profile_p->SMBcopy_count); - d_printf("copy_time: %u\n", profile_p->SMBcopy_time); - d_printf("move_count: %u\n", profile_p->SMBmove_count); - d_printf("move_time: %u\n", profile_p->SMBmove_time); - d_printf("echo_count: %u\n", profile_p->SMBecho_count); - d_printf("echo_time: %u\n", profile_p->SMBecho_time); - d_printf("writeclose_count: %u\n", profile_p->SMBwriteclose_count); - d_printf("writeclose_time: %u\n", profile_p->SMBwriteclose_time); - d_printf("openX_count: %u\n", profile_p->SMBopenX_count); - d_printf("openX_time: %u\n", profile_p->SMBopenX_time); - d_printf("readX_count: %u\n", profile_p->SMBreadX_count); - d_printf("readX_time: %u\n", profile_p->SMBreadX_time); - d_printf("writeX_count: %u\n", profile_p->SMBwriteX_count); - d_printf("writeX_time: %u\n", profile_p->SMBwriteX_time); - d_printf("trans2_count: %u\n", profile_p->SMBtrans2_count); - d_printf("trans2_time: %u\n", profile_p->SMBtrans2_time); - d_printf("transs2_count: %u\n", profile_p->SMBtranss2_count); - d_printf("transs2_time: %u\n", profile_p->SMBtranss2_time); - d_printf("findclose_count: %u\n", profile_p->SMBfindclose_count); - d_printf("findclose_time: %u\n", profile_p->SMBfindclose_time); - d_printf("findnclose_count: %u\n", profile_p->SMBfindnclose_count); - d_printf("findnclose_time: %u\n", profile_p->SMBfindnclose_time); - d_printf("tcon_count: %u\n", profile_p->SMBtcon_count); - d_printf("tcon_time: %u\n", profile_p->SMBtcon_time); - d_printf("tdis_count: %u\n", profile_p->SMBtdis_count); - d_printf("tdis_time: %u\n", profile_p->SMBtdis_time); - d_printf("negprot_count: %u\n", profile_p->SMBnegprot_count); - d_printf("negprot_time: %u\n", profile_p->SMBnegprot_time); - d_printf("sesssetupX_count: %u\n", profile_p->SMBsesssetupX_count); - d_printf("sesssetupX_time: %u\n", profile_p->SMBsesssetupX_time); - d_printf("ulogoffX_count: %u\n", profile_p->SMBulogoffX_count); - d_printf("ulogoffX_time: %u\n", profile_p->SMBulogoffX_time); - d_printf("tconX_count: %u\n", profile_p->SMBtconX_count); - d_printf("tconX_time: %u\n", profile_p->SMBtconX_time); - d_printf("dskattr_count: %u\n", profile_p->SMBdskattr_count); - d_printf("dskattr_time: %u\n", profile_p->SMBdskattr_time); - d_printf("search_count: %u\n", profile_p->SMBsearch_count); - d_printf("search_time: %u\n", profile_p->SMBsearch_time); - d_printf("ffirst_count: %u\n", profile_p->SMBffirst_count); - d_printf("ffirst_time: %u\n", profile_p->SMBffirst_time); - d_printf("funique_count: %u\n", profile_p->SMBfunique_count); - d_printf("funique_time: %u\n", profile_p->SMBfunique_time); - d_printf("fclose_count: %u\n", profile_p->SMBfclose_count); - d_printf("fclose_time: %u\n", profile_p->SMBfclose_time); - d_printf("nttrans_count: %u\n", profile_p->SMBnttrans_count); - d_printf("nttrans_time: %u\n", profile_p->SMBnttrans_time); - d_printf("nttranss_count: %u\n", profile_p->SMBnttranss_count); - d_printf("nttranss_time: %u\n", profile_p->SMBnttranss_time); - d_printf("ntcreateX_count: %u\n", profile_p->SMBntcreateX_count); - d_printf("ntcreateX_time: %u\n", profile_p->SMBntcreateX_time); - d_printf("ntcancel_count: %u\n", profile_p->SMBntcancel_count); - d_printf("ntcancel_time: %u\n", profile_p->SMBntcancel_time); - d_printf("splopen_count: %u\n", profile_p->SMBsplopen_count); - d_printf("splopen_time: %u\n", profile_p->SMBsplopen_time); - d_printf("splwr_count: %u\n", profile_p->SMBsplwr_count); - d_printf("splwr_time: %u\n", profile_p->SMBsplwr_time); - d_printf("splclose_count: %u\n", profile_p->SMBsplclose_count); - d_printf("splclose_time: %u\n", profile_p->SMBsplclose_time); - d_printf("splretq_count: %u\n", profile_p->SMBsplretq_count); - d_printf("splretq_time: %u\n", profile_p->SMBsplretq_time); - d_printf("sends_count: %u\n", profile_p->SMBsends_count); - d_printf("sends_time: %u\n", profile_p->SMBsends_time); - d_printf("sendb_count: %u\n", profile_p->SMBsendb_count); - d_printf("sendb_time: %u\n", profile_p->SMBsendb_time); - d_printf("fwdname_count: %u\n", profile_p->SMBfwdname_count); - d_printf("fwdname_time: %u\n", profile_p->SMBfwdname_time); - d_printf("cancelf_count: %u\n", profile_p->SMBcancelf_count); - d_printf("cancelf_time: %u\n", profile_p->SMBcancelf_time); - d_printf("getmac_count: %u\n", profile_p->SMBgetmac_count); - d_printf("getmac_time: %u\n", profile_p->SMBgetmac_time); - d_printf("sendstrt_count: %u\n", profile_p->SMBsendstrt_count); - d_printf("sendstrt_time: %u\n", profile_p->SMBsendstrt_time); - d_printf("sendend_count: %u\n", profile_p->SMBsendend_count); - d_printf("sendend_time: %u\n", profile_p->SMBsendend_time); - d_printf("sendtxt_count: %u\n", profile_p->SMBsendtxt_count); - d_printf("sendtxt_time: %u\n", profile_p->SMBsendtxt_time); - d_printf("invalid_count: %u\n", profile_p->SMBinvalid_count); - d_printf("invalid_time: %u\n", profile_p->SMBinvalid_time); - d_printf("************************ Pathworks Calls *************************\n"); - d_printf("setdir_count: %u\n", profile_p->pathworks_setdir_count); - d_printf("setdir_time: %u\n", profile_p->pathworks_setdir_time); - d_printf("************************ Trans2 Calls ****************************\n"); - d_printf("open_count: %u\n", profile_p->Trans2_open_count); - d_printf("open_time: %u\n", profile_p->Trans2_open_time); - d_printf("findfirst_count: %u\n", profile_p->Trans2_findfirst_count); - d_printf("findfirst_time: %u\n", profile_p->Trans2_findfirst_time); - d_printf("findnext_count: %u\n", profile_p->Trans2_findnext_count); - d_printf("findnext_time: %u\n", profile_p->Trans2_findnext_time); - d_printf("qfsinfo_count: %u\n", profile_p->Trans2_qfsinfo_count); - d_printf("qfsinfo_time: %u\n", profile_p->Trans2_qfsinfo_time); - d_printf("setfsinfo_count: %u\n", profile_p->Trans2_setfsinfo_count); - d_printf("setfsinfo_time: %u\n", profile_p->Trans2_setfsinfo_time); - d_printf("qpathinfo_count: %u\n", profile_p->Trans2_qpathinfo_count); - d_printf("qpathinfo_time: %u\n", profile_p->Trans2_qpathinfo_time); - d_printf("setpathinfo_count: %u\n", profile_p->Trans2_setpathinfo_count); - d_printf("setpathinfo_time: %u\n", profile_p->Trans2_setpathinfo_time); - d_printf("qfileinfo_count: %u\n", profile_p->Trans2_qfileinfo_count); - d_printf("qfileinfo_time: %u\n", profile_p->Trans2_qfileinfo_time); - d_printf("setfileinfo_count: %u\n", profile_p->Trans2_setfileinfo_count); - d_printf("setfileinfo_time: %u\n", profile_p->Trans2_setfileinfo_time); - d_printf("fsctl_count: %u\n", profile_p->Trans2_fsctl_count); - d_printf("fsctl_time: %u\n", profile_p->Trans2_fsctl_time); - d_printf("ioctl_count: %u\n", profile_p->Trans2_ioctl_count); - d_printf("ioctl_time: %u\n", profile_p->Trans2_ioctl_time); - d_printf("findnotifyfirst_count: %u\n", profile_p->Trans2_findnotifyfirst_count); - d_printf("findnotifyfirst_time: %u\n", profile_p->Trans2_findnotifyfirst_time); - d_printf("findnotifynext_count: %u\n", profile_p->Trans2_findnotifynext_count); - d_printf("findnotifynext_time: %u\n", profile_p->Trans2_findnotifynext_time); - d_printf("mkdir_count: %u\n", profile_p->Trans2_mkdir_count); - d_printf("mkdir_time: %u\n", profile_p->Trans2_mkdir_time); - d_printf("session_setup_count: %u\n", profile_p->Trans2_session_setup_count); - d_printf("session_setup_time: %u\n", profile_p->Trans2_session_setup_time); - d_printf("get_dfs_referral_count: %u\n", profile_p->Trans2_get_dfs_referral_count); - d_printf("get_dfs_referral_time: %u\n", profile_p->Trans2_get_dfs_referral_time); - d_printf("report_dfs_inconsistancy_count: %u\n", profile_p->Trans2_report_dfs_inconsistancy_count); - d_printf("report_dfs_inconsistancy_time: %u\n", profile_p->Trans2_report_dfs_inconsistancy_time); - d_printf("************************ NT Transact Calls ***********************\n"); - d_printf("create_count: %u\n", profile_p->NT_transact_create_count); - d_printf("create_time: %u\n", profile_p->NT_transact_create_time); - d_printf("ioctl_count: %u\n", profile_p->NT_transact_ioctl_count); - d_printf("ioctl_time: %u\n", profile_p->NT_transact_ioctl_time); - d_printf("set_security_desc_count: %u\n", profile_p->NT_transact_set_security_desc_count); - d_printf("set_security_desc_time: %u\n", profile_p->NT_transact_set_security_desc_time); - d_printf("notify_change_count: %u\n", profile_p->NT_transact_notify_change_count); - d_printf("notify_change_time: %u\n", profile_p->NT_transact_notify_change_time); - d_printf("rename_count: %u\n", profile_p->NT_transact_rename_count); - d_printf("rename_time: %u\n", profile_p->NT_transact_rename_time); - d_printf("query_security_desc_count: %u\n", profile_p->NT_transact_query_security_desc_count); - d_printf("query_security_desc_time: %u\n", profile_p->NT_transact_query_security_desc_time); - d_printf("************************ ACL Calls *******************************\n"); - d_printf("get_nt_acl_count: %u\n", profile_p->get_nt_acl_count); - d_printf("get_nt_acl_time: %u\n", profile_p->get_nt_acl_time); - d_printf("fget_nt_acl_count: %u\n", profile_p->fget_nt_acl_count); - d_printf("fget_nt_acl_time: %u\n", profile_p->fget_nt_acl_time); - d_printf("set_nt_acl_count: %u\n", profile_p->set_nt_acl_count); - d_printf("set_nt_acl_time: %u\n", profile_p->set_nt_acl_time); - d_printf("fset_nt_acl_count: %u\n", profile_p->fset_nt_acl_count); - d_printf("fset_nt_acl_time: %u\n", profile_p->fset_nt_acl_time); - d_printf("chmod_acl_count: %u\n", profile_p->chmod_acl_count); - d_printf("chmod_acl_time: %u\n", profile_p->chmod_acl_time); - d_printf("fchmod_acl_count: %u\n", profile_p->fchmod_acl_count); - d_printf("fchmod_acl_time: %u\n", profile_p->fchmod_acl_time); - d_printf("************************ NMBD Calls ****************************\n"); - d_printf("name_release_count: %u\n", profile_p->name_release_count); - d_printf("name_release_time: %u\n", profile_p->name_release_time); - d_printf("name_refresh_count: %u\n", profile_p->name_refresh_count); - d_printf("name_refresh_time: %u\n", profile_p->name_refresh_time); - d_printf("name_registration_count: %u\n", profile_p->name_registration_count); - d_printf("name_registration_time: %u\n", profile_p->name_registration_time); - d_printf("node_status_count: %u\n", profile_p->node_status_count); - d_printf("node_status_time: %u\n", profile_p->node_status_time); - d_printf("name_query_count: %u\n", profile_p->name_query_count); - d_printf("name_query_time: %u\n", profile_p->name_query_time); - d_printf("host_announce_count: %u\n", profile_p->host_announce_count); - d_printf("host_announce_time: %u\n", profile_p->host_announce_time); - d_printf("workgroup_announce_count: %u\n", profile_p->workgroup_announce_count); - d_printf("workgroup_announce_time: %u\n", profile_p->workgroup_announce_time); - d_printf("local_master_announce_count: %u\n", profile_p->local_master_announce_count); - d_printf("local_master_announce_time: %u\n", profile_p->local_master_announce_time); - d_printf("master_browser_announce_count: %u\n", profile_p->master_browser_announce_count); - d_printf("master_browser_announce_time: %u\n", profile_p->master_browser_announce_time); - d_printf("lm_host_announce_count: %u\n", profile_p->lm_host_announce_count); - d_printf("lm_host_announce_time: %u\n", profile_p->lm_host_announce_time); - d_printf("get_backup_list_count: %u\n", profile_p->get_backup_list_count); - d_printf("get_backup_list_time: %u\n", profile_p->get_backup_list_time); - d_printf("reset_browser_count: %u\n", profile_p->reset_browser_count); - d_printf("reset_browser_time: %u\n", profile_p->reset_browser_time); - d_printf("announce_request_count: %u\n", profile_p->announce_request_count); - d_printf("announce_request_time: %u\n", profile_p->announce_request_time); - d_printf("lm_announce_request_count: %u\n", profile_p->lm_announce_request_count); - d_printf("lm_announce_request_time: %u\n", profile_p->lm_announce_request_time); - d_printf("domain_logon_count: %u\n", profile_p->domain_logon_count); - d_printf("domain_logon_time: %u\n", profile_p->domain_logon_time); - d_printf("sync_browse_lists_count: %u\n", profile_p->sync_browse_lists_count); - d_printf("sync_browse_lists_time: %u\n", profile_p->sync_browse_lists_time); - d_printf("run_elections_count: %u\n", profile_p->run_elections_count); - d_printf("run_elections_time: %u\n", profile_p->run_elections_time); - d_printf("election_count: %u\n", profile_p->election_count); - d_printf("election_time: %u\n", profile_p->election_time); -#else /* WITH_PROFILE */ - fprintf(stderr, "Profile data unavailable\n"); -#endif /* WITH_PROFILE */ - - return 0; -} - - static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { struct connections_data crec; @@ -602,7 +246,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo int main(int argc, char *argv[]) { int c; - static int profile_only = 0; + int profile_only = 0; TDB_CONTEXT *tdb; BOOL show_processes, show_locks, show_shares; poptContext pc; @@ -614,9 +258,8 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo {"shares", 'S', POPT_ARG_NONE, &shares_only, 'S', "Show shares only" }, {"user", 'u', POPT_ARG_STRING, &username, 'u', "Switch to user" }, {"brief", 'b', POPT_ARG_NONE, &brief, 'b', "Be brief" }, -#ifdef WITH_PROFILE - {"profile", 'P', POPT_ARG_NONE, &profile_only, 'P', "Do profiling" }, -#endif /* WITH_PROFILE */ + {"profile", 'P', POPT_ARG_NONE, NULL, 'P', "Do profiling" }, + {"profile-rates", 'R', POPT_ARG_NONE, NULL, 'R', "Show call rates" }, {"byterange", 'B', POPT_ARG_NONE, &show_brl, 'B', "Include byte range locks"}, {"numeric", 'n', POPT_ARG_NONE, &numeric_only, 'n', "Numeric uid/gid"}, POPT_COMMON_SAMBA @@ -643,6 +286,9 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo case 'u': Ucrit_addUid(nametouid(poptGetOptArg(pc))); break; + case 'P': + case 'R': + profile_only = c; } } @@ -663,11 +309,18 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); return (-1); } - - if (profile_only) { - return profile_dump(); + + switch (profile_only) { + case 'P': + /* Dump profile data */ + return status_profile_dump(verbose); + case 'R': + /* Continuously display rate-converted data */ + return status_profile_rates(verbose); + default: + break; } - + if ( show_processes ) { tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0); if (!tdb) { @@ -719,7 +372,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo exit(1); } - ret = share_mode_forall(print_share_mode); + ret = share_mode_forall(print_share_mode, NULL); if (ret == 0) { d_printf("No locked files\n"); diff --git a/source/web/diagnose.c b/source/web/diagnose.c index d259717da0b..b53e139ca94 100644 --- a/source/web/diagnose.c +++ b/source/web/diagnose.c @@ -60,16 +60,16 @@ BOOL nmbd_running(void) then closing it */ BOOL smbd_running(void) { - static struct cli_state cli; + struct cli_state *cli; - if (!cli_initialise(&cli)) + if ((cli = cli_initialise()) == NULL) return False; - if (!cli_connect(&cli, global_myname(), &loopback_ip)) { - cli_shutdown(&cli); + if (!cli_connect(cli, global_myname(), &loopback_ip)) { + cli_shutdown(cli); return False; } - cli_shutdown(&cli); + cli_shutdown(cli); return True; } diff --git a/source/web/neg_lang.c b/source/web/neg_lang.c index fb79f41f13c..207614655db 100644 --- a/source/web/neg_lang.c +++ b/source/web/neg_lang.c @@ -57,8 +57,8 @@ static int qsort_cmp_list(const void *x, const void *y) { struct pri_list *a = (struct pri_list *)x; struct pri_list *b = (struct pri_list *)y; if (a->pri > b->pri) return -1; - if (a->pri == b->pri) return 0; - return 1; + if (a->pri < b->pri) return 1; + return 0; } /* diff --git a/source/web/statuspage.c b/source/web/statuspage.c index cb6fa911711..459b679d817 100644 --- a/source/web/statuspage.c +++ b/source/web/statuspage.c @@ -106,7 +106,10 @@ static char *tstring(time_t t) return buf; } -static void print_share_mode(const struct share_mode_entry *e, const char *sharepath, const char *fname) +static void print_share_mode(const struct share_mode_entry *e, + const char *sharepath, + const char *fname, + void *dummy) { char *utf8_fname; int deny_mode; @@ -434,7 +437,7 @@ void status_page(void) printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n", _("PID"), _("Sharing"), _("R/W"), _("Oplock"), _("File"), _("Date")); locking_init(1); - share_mode_forall(print_share_mode); + share_mode_forall(print_share_mode, NULL); locking_end(); printf("</table>\n"); |