summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-02-02 20:44:50 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:06:21 -0500
commitd14af63e6ab600eb3ac705f2f425c860e927553a (patch)
tree9be5b1da9836c61c7b1bf2df72df7014944b8599 /source3/smbd
parent206cbff8b72a2ccc41e52b45097976f4511bfdec (diff)
downloadsamba-d14af63e6ab600eb3ac705f2f425c860e927553a.tar.gz
samba-d14af63e6ab600eb3ac705f2f425c860e927553a.tar.bz2
samba-d14af63e6ab600eb3ac705f2f425c860e927553a.zip
r13293: Rather a big patch I'm afraid, but this should fix bug #3347
by saving the UNIX token used to set a delete on close flag, and using it when doing the delete. libsmbsharemodes.so still needs updating to cope with this change. Samba4 torture tests to follow. Jeremy. (This used to be commit 23f16cbc2e8cde97c486831e26bcafd4ab4a9654)
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;
}