diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/close.c | 66 | ||||
-rw-r--r-- | source3/smbd/dir.c | 4 | ||||
-rw-r--r-- | source3/smbd/fake_file.c | 2 | ||||
-rw-r--r-- | source3/smbd/files.c | 6 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 26 | ||||
-rw-r--r-- | source3/smbd/open.c | 2 | ||||
-rw-r--r-- | source3/smbd/posix_acls.c | 30 | ||||
-rw-r--r-- | source3/smbd/reply.c | 26 | ||||
-rw-r--r-- | source3/smbd/sec_ctx.c | 83 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 14 | ||||
-rw-r--r-- | source3/smbd/uid.c | 30 |
11 files changed, 162 insertions, 127 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c index d284c82f44..059b88ecc8 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -145,13 +145,12 @@ static void notify_deferred_opens(struct share_mode_lock *lck) /**************************************************************************** Close a file. - If normal_close is 1 then this came from a normal SMBclose (or equivalent) - operation otherwise it came as the result of some other operation such as - the closing of the connection. In the latter case printing and - magic scripts are not run. + close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE. + printing and magic scripts are only run on normal close. + delete on close is done on normal and shutdown close. ****************************************************************************/ -static int close_normal_file(files_struct *fsp, BOOL normal_close) +static int close_normal_file(files_struct *fsp, enum file_close_type close_type) { BOOL delete_file = False; connection_struct *conn = fsp->conn; @@ -187,7 +186,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) } if (fsp->print_file) { - print_fsp_end(fsp, normal_close); + print_fsp_end(fsp, close_type); file_free(fsp); return 0; } @@ -232,12 +231,26 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) * reference to a file. */ - if (normal_close && delete_file) { + if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) && + delete_file && + lck->delete_token) { SMB_STRUCT_STAT sbuf; DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n", fsp->fsp_name)); + /* Become the user who requested the delete. */ + + if (!push_sec_ctx()) { + smb_panic("close_file: file %s. failed to push sec_ctx.\n"); + } + + set_sec_ctx(lck->delete_token->uid, + lck->delete_token->gid, + lck->delete_token->ngroups, + lck->delete_token->groups, + NULL); + /* We can only delete the file if the name we have is still valid and hasn't been renamed. */ @@ -268,8 +281,11 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) "and unlink failed with error %s\n", fsp->fsp_name, strerror(errno) )); } - process_pending_change_notify_queue((time_t)0); } + /* unbecome user. */ + pop_sec_ctx(); + + process_pending_change_notify_queue((time_t)0); } talloc_free(lck); @@ -288,7 +304,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) } /* check for magic scripts */ - if (normal_close) { + if (close_type == NORMAL_CLOSE) { check_magic(fsp,conn); } @@ -324,7 +340,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) Close a directory opened by an NT SMB call. ****************************************************************************/ -static int close_directory(files_struct *fsp, BOOL normal_close) +static int close_directory(files_struct *fsp, enum file_close_type close_type) { struct share_mode_lock *lck = 0; BOOL delete_dir = False; @@ -349,11 +365,31 @@ static int close_directory(files_struct *fsp, BOOL normal_close) talloc_free(lck); - if (normal_close && delete_dir) { - BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name); + if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) && + delete_dir && + lck->delete_token) { + BOOL ok; + + /* Become the user who requested the delete. */ + + if (!push_sec_ctx()) { + smb_panic("close_directory: failed to push sec_ctx.\n"); + } + + set_sec_ctx(lck->delete_token->uid, + lck->delete_token->gid, + lck->delete_token->ngroups, + lck->delete_token->groups, + NULL); + + ok = rmdir_internals(fsp->conn, fsp->fsp_name); + DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n", fsp->fsp_name, ok ? "succeeded" : "failed" )); + /* unbecome user. */ + pop_sec_ctx(); + /* * Ensure we remove any change notify requests that would * now fail as the directory has been deleted. @@ -404,12 +440,12 @@ static int close_stat(files_struct *fsp) Close a files_struct. ****************************************************************************/ -int close_file(files_struct *fsp, BOOL normal_close) +int close_file(files_struct *fsp, enum file_close_type close_type) { if(fsp->is_directory) - return close_directory(fsp, normal_close); + return close_directory(fsp, close_type); else if (fsp->is_stat) return close_stat(fsp); else - return close_normal_file(fsp, normal_close); + return close_normal_file(fsp, close_type); } diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 0635db22db..81fe7c4021 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -866,7 +866,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); - close_file(fsp, True); + close_file(fsp, NORMAL_CLOSE); /* No access if SD get failed. */ if (!sd_size) { @@ -929,7 +929,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); - close_file(fsp, False); + close_file(fsp, NORMAL_CLOSE); /* No access if SD get failed. */ if (!sd_size) diff --git a/source3/smbd/fake_file.c b/source3/smbd/fake_file.c index 799725a782..1356baf1a8 100644 --- a/source3/smbd/fake_file.c +++ b/source3/smbd/fake_file.c @@ -109,7 +109,7 @@ files_struct *open_fake_file(connection_struct *conn, files_struct *fsp = NULL; /* access check */ - if (current_user.uid != 0) { + 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; diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 181e17b11f..5a545c236e 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -148,7 +148,7 @@ void file_close_conn(connection_struct *conn) for (fsp=Files;fsp;fsp=next) { next = fsp->next; if (fsp->conn == conn) { - close_file(fsp,False); + close_file(fsp,SHUTDOWN_CLOSE); } } } @@ -164,7 +164,7 @@ void file_close_pid(uint16 smbpid) for (fsp=Files;fsp;fsp=next) { next = fsp->next; if (fsp->file_pid == smbpid) { - close_file(fsp,False); + close_file(fsp,SHUTDOWN_CLOSE); } } } @@ -222,7 +222,7 @@ void file_close_user(int vuid) for (fsp=Files;fsp;fsp=next) { next=fsp->next; if (fsp->vuid == vuid) { - close_file(fsp,False); + close_file(fsp,SHUTDOWN_CLOSE); } } } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 72288e2c24..e12a24968b 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -798,7 +798,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", fattr = FILE_ATTRIBUTE_NORMAL; } if (!fsp->is_directory && (fattr & aDIR)) { - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); END_PROFILE(SMBntcreateX); return ERROR_DOS(ERRDOS,ERRnoaccess); } @@ -812,13 +812,13 @@ create_options = 0x%x root_dir_fid = 0x%x\n", if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) { fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size); if (fsp->is_directory) { - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); END_PROFILE(SMBntcreateX); /* Can't set allocation size on a directory. */ return ERROR_NT(NT_STATUS_ACCESS_DENIED); } if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); END_PROFILE(SMBntcreateX); return ERROR_NT(NT_STATUS_DISK_FULL); } @@ -1416,7 +1416,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(ctx); - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); restore_case_semantics(conn, file_attributes); return ERROR_NT(status); } @@ -1427,7 +1427,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o status = set_ea(conn, fsp, fname, ea_list); talloc_destroy(ctx); if (!NT_STATUS_IS_OK(status)) { - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); restore_case_semantics(conn, file_attributes); return ERROR_NT(status); } @@ -1441,7 +1441,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o fattr = FILE_ATTRIBUTE_NORMAL; } if (!fsp->is_directory && (fattr & aDIR)) { - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); return ERROR_DOS(ERRDOS,ERRnoaccess); } @@ -1454,12 +1454,12 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o if (allocation_size && (allocation_size > file_len)) { fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size); if (fsp->is_directory) { - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); /* Can't set allocation size on a directory. */ return ERROR_NT(NT_STATUS_ACCESS_DENIED); } if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); return ERROR_NT(NT_STATUS_DISK_FULL); } } else { @@ -1688,7 +1688,7 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new status = NT_STATUS_ACCESS_DENIED; } set_saved_ntstatus(NT_STATUS_OK); - close_file(fsp1,False); + close_file(fsp1,ERROR_CLOSE); return status; } @@ -1702,12 +1702,12 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new * Thus we don't look at the error return from the * close of fsp1. */ - close_file(fsp1,False); + close_file(fsp1,NORMAL_CLOSE); /* Ensure the modtime is set correctly on the destination file. */ fsp_set_pending_modtime(fsp2, sbuf1.st_mtime); - close_ret = close_file(fsp2,False); + close_ret = close_file(fsp2,NORMAL_CLOSE); /* Grrr. We have to do this as open_file_shared1 adds aARCH when it creates the file. This isn't the correct thing to do in the copy case. JRA */ @@ -2379,7 +2379,7 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, ZERO_STRUCT(qt); /* access check */ - if (current_user.uid != 0) { + if (current_user.ut.uid != 0) { DEBUG(1,("get_user_quota: access_denied service [%s] user [%s]\n", lp_servicename(SNUM(conn)),conn->user)); return ERROR_DOS(ERRDOS,ERRnoaccess); @@ -2626,7 +2626,7 @@ static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, ZERO_STRUCT(qt); /* access check */ - if (current_user.uid != 0) { + if (current_user.ut.uid != 0) { DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n", lp_servicename(SNUM(conn)),conn->user)); return ERROR_DOS(ERRDOS,ERRnoaccess); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index dd2731c897..15e814aae3 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1678,6 +1678,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, } /* Note that here we set the *inital* delete on close flag, not the regular one. */ + set_delete_on_close_token(lck, ¤t_user.ut); lck->initial_delete_on_close = True; lck->modified = True; } @@ -1983,6 +1984,7 @@ files_struct *open_directory(connection_struct *conn, return NULL; } + set_delete_on_close_token(lck, ¤t_user.ut); lck->initial_delete_on_close = True; lck->modified = True; } diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 34497f0280..5db245ac0c 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -929,7 +929,7 @@ static BOOL unpack_nt_owners(int snum, SMB_STRUCT_STAT *psbuf, uid_t *puser, gid if (lp_force_unknown_acl_user(snum)) { /* this allows take ownership to work * reasonably */ - *puser = current_user.uid; + *puser = current_user.ut.uid; } else { DEBUG(3,("unpack_nt_owners: unable to validate" " owner sid for %s\n", @@ -950,7 +950,7 @@ static BOOL unpack_nt_owners(int snum, SMB_STRUCT_STAT *psbuf, uid_t *puser, gid if (lp_force_unknown_acl_user(snum)) { /* this allows take group ownership to work * reasonably */ - *pgrp = current_user.gid; + *pgrp = current_user.ut.gid; } else { DEBUG(3,("unpack_nt_owners: unable to validate" " group sid.\n")); @@ -1024,7 +1024,7 @@ static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace ) /* Assume that the current user is in the current group (force group) */ - if (uid_ace->unix_ug.uid == current_user.uid && group_ace->unix_ug.gid == current_user.gid) + if (uid_ace->unix_ug.uid == current_user.ut.uid && group_ace->unix_ug.gid == current_user.ut.gid) return True; fstrcpy(u_name, uidtoname(uid_ace->unix_ug.uid)); @@ -2246,8 +2246,8 @@ static BOOL current_user_in_group(gid_t gid) { int i; - for (i = 0; i < current_user.ngroups; i++) { - if (current_user.groups[i] == gid) { + for (i = 0; i < current_user.ut.ngroups; i++) { + if (current_user.ut.groups[i] == gid) { return True; } } @@ -3026,7 +3026,7 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_ &se_restore); /* Case (2) */ - if ( ( has_take_ownership_priv && ( uid == current_user.uid ) ) || + if ( ( has_take_ownership_priv && ( uid == current_user.ut.uid ) ) || /* Case (3) */ ( has_restore_priv ) ) { @@ -3056,7 +3056,7 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_ and also copes with the case where the SID in a take ownership ACL is a local SID on the users workstation */ - uid = current_user.uid; + uid = current_user.ut.uid; become_root(); /* Keep the current file gid the same. */ @@ -3136,7 +3136,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) * the file. */ - if (need_chown && (user == (uid_t)-1 || user == current_user.uid)) { + if (need_chown && (user == (uid_t)-1 || user == current_user.ut.uid)) { DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); @@ -3960,12 +3960,12 @@ refusing write due to mask.\n", fname)); break; case SMB_ACL_USER: { - /* Check against current_user.uid. */ + /* Check against current_user.ut.uid. */ uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry); if (puid == NULL) { goto check_stat; } - if (current_user.uid == *puid) { + if (current_user.ut.uid == *puid) { /* We have a uid match but we must ensure we have seen the acl mask. */ ret = have_write; DEBUG(10,("check_posix_acl_group_write: file %s \ @@ -4130,13 +4130,13 @@ BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname) if (!S_ISDIR(sbuf.st_mode)) { return False; } - if (current_user.uid == 0 || conn->admin_user) { + if (current_user.ut.uid == 0 || conn->admin_user) { /* I'm sorry sir, I didn't know you were root... */ return True; } /* Check primary owner write access. */ - if (current_user.uid == sbuf.st_uid) { + if (current_user.ut.uid == sbuf.st_uid) { return (sbuf.st_mode & S_IWUSR) ? True : False; } @@ -4152,7 +4152,7 @@ BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname) * for bug #3348. Don't assume owning sticky bit * directory means write access allowed. */ - if (current_user.uid != sbuf_file.st_uid) { + if (current_user.ut.uid != sbuf_file.st_uid) { return False; } } @@ -4178,7 +4178,7 @@ BOOL can_write_to_file(connection_struct *conn, const char *fname, SMB_STRUCT_ST { int ret; - if (current_user.uid == 0 || conn->admin_user) { + if (current_user.ut.uid == 0 || conn->admin_user) { /* I'm sorry sir, I didn't know you were root... */ return True; } @@ -4191,7 +4191,7 @@ BOOL can_write_to_file(connection_struct *conn, const char *fname, SMB_STRUCT_ST } /* Check primary owner write access. */ - if (current_user.uid == psbuf->st_uid) { + if (current_user.ut.uid == psbuf->st_uid) { return (psbuf->st_mode & S_IWUSR) ? True : False; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 69c71c74b5..89b98be1e7 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1386,7 +1386,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, if (fattr & aDIR) { DEBUG(3,("attempt to open a directory %s\n",fname)); - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); END_PROFILE(SMBopen); return ERROR_DOS(ERRDOS,ERRnoaccess); } @@ -1510,13 +1510,13 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) { fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size); if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); END_PROFILE(SMBntcreateX); return ERROR_NT(NT_STATUS_DISK_FULL); } retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size); if (retval < 0) { - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); END_PROFILE(SMBwrite); return ERROR_NT(NT_STATUS_DISK_FULL); } @@ -1526,7 +1526,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt fattr = dos_mode(conn,fname,&sbuf); mtime = sbuf.st_mtime; if (fattr & aDIR) { - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); END_PROFILE(SMBopenX); return ERROR_DOS(ERRDOS,ERRnoaccess); } @@ -1845,7 +1845,7 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype, set_saved_ntstatus(NT_STATUS_OK); return NT_STATUS_ACCESS_DENIED; } - close_file(fsp,False); + close_file(fsp,NORMAL_CLOSE); return NT_STATUS_OK; } @@ -1938,7 +1938,7 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b set_saved_ntstatus(NT_STATUS_OK); return NT_STATUS_ACCESS_DENIED; } - close_file(fsp,False); + close_file(fsp,NORMAL_CLOSE); } return NT_STATUS_OK; } @@ -3267,7 +3267,7 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size, * Special case - close NT SMB directory handle. */ DEBUG(3,("close %s fnum=%d\n", fsp->is_directory ? "directory" : "stat file open", fsp->fnum)); - close_file(fsp,True); + close_file(fsp,NORMAL_CLOSE); } else { /* * Close ordinary file. @@ -3295,7 +3295,7 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size, * a disk full error. If not then it was probably an I/O error. */ - if((close_err = close_file(fsp,True)) != 0) { + if((close_err = close_file(fsp,NORMAL_CLOSE)) != 0) { errno = close_err; END_PROFILE(SMBclose); return (UNIXERROR(ERRHRD,ERRgeneral)); @@ -3356,7 +3356,7 @@ int reply_writeclose(connection_struct *conn, if (numtowrite) { DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n", fsp->fsp_name )); - close_err = close_file(fsp,True); + close_err = close_file(fsp,NORMAL_CLOSE); } DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n", @@ -3596,7 +3596,7 @@ int reply_printclose(connection_struct *conn, DEBUG(3,("printclose fd=%d fnum=%d\n", fsp->fh->fd,fsp->fnum)); - close_err = close_file(fsp,True); + close_err = close_file(fsp,NORMAL_CLOSE); if(close_err != 0) { errno = close_err; @@ -4746,7 +4746,7 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, NULL); if (!fsp2) { - close_file(fsp1,False); + close_file(fsp1,ERROR_CLOSE); return(False); } @@ -4765,7 +4765,7 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size); } - close_file(fsp1,False); + close_file(fsp1,NORMAL_CLOSE); /* Ensure the modtime is set correctly on the destination file. */ fsp_set_pending_modtime( fsp2, src_sbuf.st_mtime); @@ -4776,7 +4776,7 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, * Thus we don't look at the error return from the * close of fsp1. */ - *err_ret = close_file(fsp2,False); + *err_ret = close_file(fsp2,NORMAL_CLOSE); return(ret == (SMB_OFF_T)src_sbuf.st_size); } diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c index a5411b94a1..fc6a858974 100644 --- a/source3/smbd/sec_ctx.c +++ b/source3/smbd/sec_ctx.c @@ -23,10 +23,7 @@ extern struct current_user current_user; struct sec_ctx { - uid_t uid; - uid_t gid; - int ngroups; - gid_t *groups; + UNIX_USER_TOKEN ut; NT_USER_TOKEN *token; }; @@ -216,10 +213,10 @@ BOOL initialise_groups(char *user, uid_t uid, gid_t gid) prev_ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx - 1]; - SAFE_FREE(prev_ctx_p->groups); - prev_ctx_p->ngroups = 0; + SAFE_FREE(prev_ctx_p->ut.groups); + prev_ctx_p->ut.ngroups = 0; - get_current_groups(gid, &prev_ctx_p->ngroups, &prev_ctx_p->groups); + get_current_groups(gid, &prev_ctx_p->ut.ngroups, &prev_ctx_p->ut.groups); done: unbecome_root(); @@ -249,26 +246,26 @@ BOOL push_sec_ctx(void) ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx]; - ctx_p->uid = geteuid(); - ctx_p->gid = getegid(); + ctx_p->ut.uid = geteuid(); + ctx_p->ut.gid = getegid(); DEBUG(3, ("push_sec_ctx(%u, %u) : sec_ctx_stack_ndx = %d\n", - (unsigned int)ctx_p->uid, (unsigned int)ctx_p->gid, sec_ctx_stack_ndx )); + (unsigned int)ctx_p->ut.uid, (unsigned int)ctx_p->ut.gid, sec_ctx_stack_ndx )); ctx_p->token = dup_nt_token(sec_ctx_stack[sec_ctx_stack_ndx-1].token); - ctx_p->ngroups = sys_getgroups(0, NULL); + ctx_p->ut.ngroups = sys_getgroups(0, NULL); - if (ctx_p->ngroups != 0) { - if (!(ctx_p->groups = SMB_MALLOC_ARRAY(gid_t, ctx_p->ngroups))) { + if (ctx_p->ut.ngroups != 0) { + if (!(ctx_p->ut.groups = SMB_MALLOC_ARRAY(gid_t, ctx_p->ut.ngroups))) { DEBUG(0, ("Out of memory in push_sec_ctx()\n")); delete_nt_token(&ctx_p->token); return False; } - sys_getgroups(ctx_p->ngroups, ctx_p->groups); + sys_getgroups(ctx_p->ut.ngroups, ctx_p->ut.groups); } else { - ctx_p->groups = NULL; + ctx_p->ut.groups = NULL; } return True; @@ -296,28 +293,28 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN sys_setgroups(ngroups, groups); #endif - ctx_p->ngroups = ngroups; + ctx_p->ut.ngroups = ngroups; - SAFE_FREE(ctx_p->groups); + SAFE_FREE(ctx_p->ut.groups); if (token && (token == ctx_p->token)) smb_panic("DUPLICATE_TOKEN"); delete_nt_token(&ctx_p->token); - ctx_p->groups = memdup(groups, sizeof(gid_t) * ngroups); + ctx_p->ut.groups = memdup(groups, sizeof(gid_t) * ngroups); ctx_p->token = dup_nt_token(token); become_id(uid, gid); - ctx_p->uid = uid; - ctx_p->gid = gid; + ctx_p->ut.uid = uid; + ctx_p->ut.gid = gid; /* Update current_user stuff */ - current_user.uid = uid; - current_user.gid = gid; - current_user.ngroups = ngroups; - current_user.groups = groups; + current_user.ut.uid = uid; + current_user.ut.gid = gid; + current_user.ut.ngroups = ngroups; + current_user.ut.groups = groups; current_user.nt_user_token = ctx_p->token; } @@ -352,11 +349,11 @@ BOOL pop_sec_ctx(void) /* Clear previous user info */ - ctx_p->uid = (uid_t)-1; - ctx_p->gid = (gid_t)-1; + ctx_p->ut.uid = (uid_t)-1; + ctx_p->ut.gid = (gid_t)-1; - SAFE_FREE(ctx_p->groups); - ctx_p->ngroups = 0; + SAFE_FREE(ctx_p->ut.groups); + ctx_p->ut.ngroups = 0; delete_nt_token(&ctx_p->token); @@ -369,17 +366,17 @@ BOOL pop_sec_ctx(void) prev_ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx]; #ifdef HAVE_SETGROUPS - sys_setgroups(prev_ctx_p->ngroups, prev_ctx_p->groups); + sys_setgroups(prev_ctx_p->ut.ngroups, prev_ctx_p->ut.groups); #endif - become_id(prev_ctx_p->uid, prev_ctx_p->gid); + become_id(prev_ctx_p->ut.uid, prev_ctx_p->ut.gid); /* Update current_user stuff */ - current_user.uid = prev_ctx_p->uid; - current_user.gid = prev_ctx_p->gid; - current_user.ngroups = prev_ctx_p->ngroups; - current_user.groups = prev_ctx_p->groups; + current_user.ut.uid = prev_ctx_p->ut.uid; + current_user.ut.gid = prev_ctx_p->ut.gid; + current_user.ut.ngroups = prev_ctx_p->ut.ngroups; + current_user.ut.groups = prev_ctx_p->ut.groups; current_user.nt_user_token = prev_ctx_p->token; DEBUG(3, ("pop_sec_ctx (%u, %u) - sec_ctx_stack_ndx = %d\n", @@ -400,26 +397,26 @@ void init_sec_ctx(void) memset(sec_ctx_stack, 0, sizeof(struct sec_ctx) * MAX_SEC_CTX_DEPTH); for (i = 0; i < MAX_SEC_CTX_DEPTH; i++) { - sec_ctx_stack[i].uid = (uid_t)-1; - sec_ctx_stack[i].gid = (gid_t)-1; + sec_ctx_stack[i].ut.uid = (uid_t)-1; + sec_ctx_stack[i].ut.gid = (gid_t)-1; } /* Initialise first level of stack. It is the current context */ ctx_p = &sec_ctx_stack[0]; - ctx_p->uid = geteuid(); - ctx_p->gid = getegid(); + ctx_p->ut.uid = geteuid(); + ctx_p->ut.gid = getegid(); - get_current_groups(ctx_p->gid, &ctx_p->ngroups, &ctx_p->groups); + get_current_groups(ctx_p->ut.gid, &ctx_p->ut.ngroups, &ctx_p->ut.groups); ctx_p->token = NULL; /* Maps to guest user. */ /* Initialise current_user global */ - current_user.uid = ctx_p->uid; - current_user.gid = ctx_p->gid; - current_user.ngroups = ctx_p->ngroups; - current_user.groups = ctx_p->groups; + current_user.ut.uid = ctx_p->ut.uid; + current_user.ut.gid = ctx_p->ut.gid; + current_user.ut.ngroups = ctx_p->ut.ngroups; + current_user.ut.groups = ctx_p->ut.groups; /* The conn and vuid are usually taken care of by other modules. We initialise them here. */ diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 8ff219b468..b8fc2b5b8f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -856,7 +856,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i inode = sbuf.st_ino; if (fattr & aDIR) { talloc_destroy(ctx); - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); return(ERROR_DOS(ERRDOS,ERRnoaccess)); } @@ -864,7 +864,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i status = set_ea(conn, fsp, fname, ea_list); talloc_destroy(ctx); if (!NT_STATUS_IS_OK(status)) { - close_file(fsp,False); + close_file(fsp,ERROR_CLOSE); return ERROR_NT(status); } } @@ -2355,7 +2355,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned fsp.fnum = -1; /* access check */ - if (current_user.uid != 0) { + if (current_user.ut.uid != 0) { DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", lp_servicename(SNUM(conn)),conn->user)); return ERROR_DOS(ERRDOS,ERRnoaccess); @@ -2530,7 +2530,7 @@ cap_low = 0x%x, cap_high = 0x%x\n", ZERO_STRUCT(quotas); /* access check */ - if ((current_user.uid != 0)||!CAN_WRITE(conn)) { + if ((current_user.ut.uid != 0)||!CAN_WRITE(conn)) { DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", lp_servicename(SNUM(conn)),conn->user)); return ERROR_DOS(ERRSRV,ERRaccess); @@ -3888,7 +3888,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char new_fsp->fnum, strerror(errno))); ret = -1; } - close_file(new_fsp,True); + close_file(new_fsp,NORMAL_CLOSE); } else { ret = vfs_allocate_file_space(fsp, allocation_size); if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) { @@ -3951,7 +3951,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char } /* The set is across all open files on this dev/inode pair. */ - if (!set_delete_on_close(fsp, delete_on_close)) { + if (!set_delete_on_close(fsp, delete_on_close, ¤t_user.ut)) { return ERROR_NT(NT_STATUS_ACCESS_DENIED); } @@ -4416,7 +4416,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", return(UNIXERROR(ERRDOS,ERRbadpath)); } ret = vfs_set_filelen(new_fsp, size); - close_file(new_fsp,True); + close_file(new_fsp,NORMAL_CLOSE); } else { ret = vfs_set_filelen(fsp, size); } diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 9db3d97ab2..d419720c33 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -30,18 +30,18 @@ extern struct current_user current_user; gid_t get_current_user_gid_first(int *piterator) { *piterator = 0; - return current_user.gid; + return current_user.ut.gid; } gid_t get_current_user_gid_next(int *piterator) { gid_t ret; - if (!current_user.groups || *piterator >= current_user.ngroups) { + if (!current_user.ut.groups || *piterator >= current_user.ut.ngroups) { return (gid_t)-1; } - ret = current_user.groups[*piterator]; + ret = current_user.ut.groups[*piterator]; (*piterator) += 1; return ret; } @@ -216,12 +216,12 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) */ if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && - (current_user.uid == conn->uid)) { + (current_user.ut.uid == conn->uid)) { DEBUG(4,("change_to_user: Skipping user change - already user\n")); return(True); } else if ((current_user.conn == conn) && (vuser != 0) && (current_user.vuid == vuid) && - (current_user.uid == vuser->uid)) { + (current_user.ut.uid == vuser->uid)) { DEBUG(4,("change_to_user: Skipping user change - already user\n")); return(True); } @@ -237,14 +237,14 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if (conn->force_user) /* security = share sets this too */ { uid = conn->uid; gid = conn->gid; - current_user.groups = conn->groups; - current_user.ngroups = conn->ngroups; + current_user.ut.groups = conn->groups; + current_user.ut.ngroups = conn->ngroups; token = conn->nt_user_token; } else if (vuser) { uid = conn->admin_user ? 0 : vuser->uid; gid = vuser->gid; - current_user.ngroups = vuser->n_groups; - current_user.groups = vuser->groups; + current_user.ut.ngroups = vuser->n_groups; + current_user.ut.groups = vuser->groups; token = vuser->nt_user_token; } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing share %s.\n",vuid, lp_servicename(snum) )); @@ -270,8 +270,8 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) */ int i; - for (i = 0; i < current_user.ngroups; i++) { - if (current_user.groups[i] == conn->gid) { + for (i = 0; i < current_user.ut.ngroups; i++) { + if (current_user.ut.groups[i] == conn->gid) { gid = conn->gid; break; } @@ -288,7 +288,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if (vuser && vuser->guest) is_guest = True; - token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest); + token = create_nt_token(uid, gid, current_user.ut.ngroups, current_user.ut.groups, is_guest); if (!token) { DEBUG(1, ("change_to_user: create_nt_token failed!\n")); return False; @@ -296,7 +296,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) must_free_token = True; } - set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token); + set_sec_ctx(uid, gid, current_user.ut.ngroups, current_user.ut.groups, token); /* * Free the new token (as set_sec_ctx copies it). @@ -343,8 +343,8 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) if (!push_sec_ctx()) return False; - set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid, - p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token); + set_sec_ctx(p->pipe_user.ut.uid, p->pipe_user.ut.gid, + p->pipe_user.ut.ngroups, p->pipe_user.ut.groups, p->pipe_user.nt_user_token); return True; } |