summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/close.c66
-rw-r--r--source3/smbd/dir.c4
-rw-r--r--source3/smbd/fake_file.c2
-rw-r--r--source3/smbd/files.c6
-rw-r--r--source3/smbd/nttrans.c26
-rw-r--r--source3/smbd/open.c2
-rw-r--r--source3/smbd/posix_acls.c30
-rw-r--r--source3/smbd/reply.c26
-rw-r--r--source3/smbd/sec_ctx.c83
-rw-r--r--source3/smbd/trans2.c14
-rw-r--r--source3/smbd/uid.c30
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, &current_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, &current_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, &current_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;
}