summaryrefslogtreecommitdiffstats
path: root/source3
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
parent206cbff8b72a2ccc41e52b45097976f4511bfdec (diff)
downloadsamba-d14af63e6ab600eb3ac705f2f425c860e927553a.tar.gz
samba-d14af63e6ab600eb3ac705f2f425c860e927553a.tar.xz
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')
-rw-r--r--source3/include/smb.h138
-rw-r--r--source3/lib/smbrun.c8
-rw-r--r--source3/lib/substitute.c8
-rw-r--r--source3/locking/locking.c157
-rw-r--r--source3/modules/vfs_fake_perms.c8
-rw-r--r--source3/printing/nt_printing.c14
-rw-r--r--source3/printing/printfsp.c4
-rw-r--r--source3/printing/printing.c15
-rw-r--r--source3/rpc_server/srv_dfs_nt.c4
-rw-r--r--source3/rpc_server/srv_lsa_nt.c9
-rw-r--r--source3/rpc_server/srv_pipe.c15
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c6
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c12
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c18
-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
25 files changed, 427 insertions, 278 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h
index ac268ea763..b8211aac45 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -253,8 +253,7 @@ typedef struct nttime_info {
#define SID_MAX_SIZE ((size_t)(8+(MAXSUBAUTHS*4)))
/* SID Types */
-enum SID_NAME_USE
-{
+enum SID_NAME_USE {
SID_NAME_USE_NONE = 0,
SID_NAME_USER = 1, /* user */
SID_NAME_DOM_GRP, /* domain group */
@@ -276,19 +275,17 @@ enum SID_NAME_USE
*
* @sa http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/accctrl_38yn.asp
**/
-typedef struct sid_info
-{
- uint8 sid_rev_num; /**< SID revision number */
- uint8 num_auths; /**< Number of sub-authorities */
- uint8 id_auth[6]; /**< Identifier Authority */
- /*
- * Pointer to sub-authorities.
- *
- * @note The values in these uint32's are in *native* byteorder, not
- * neccessarily little-endian...... JRA.
- */
- uint32 sub_auths[MAXSUBAUTHS];
-
+typedef struct sid_info {
+ uint8 sid_rev_num; /**< SID revision number */
+ uint8 num_auths; /**< Number of sub-authorities */
+ uint8 id_auth[6]; /**< Identifier Authority */
+ /*
+ * Pointer to sub-authorities.
+ *
+ * @note The values in these uint32's are in *native* byteorder, not
+ * neccessarily little-endian...... JRA.
+ */
+ uint32 sub_auths[MAXSUBAUTHS];
} DOM_SID;
/* Some well-known SIDs */
@@ -333,10 +330,16 @@ typedef struct _nt_user_token {
SE_PRIV privileges;
} NT_USER_TOKEN;
+typedef struct _unix_token {
+ uid_t uid;
+ gid_t gid;
+ int ngroups;
+ gid_t *groups;
+} UNIX_USER_TOKEN;
+
/* 32 bit time (sec) since 01jan1970 - cifs6.txt, section 3.5, page 30 */
-typedef struct time_info
-{
- uint32 time;
+typedef struct time_info {
+ uint32 time;
} UTIME;
/* Structure used when SMBwritebmpx is active */
@@ -350,17 +353,15 @@ typedef struct {
BOOL wr_discard; /* discard all further data */
} write_bmpx_struct;
-typedef struct write_cache
-{
- SMB_OFF_T file_size;
- SMB_OFF_T offset;
- size_t alloc_size;
- size_t data_size;
- char *data;
+typedef struct write_cache {
+ SMB_OFF_T file_size;
+ SMB_OFF_T offset;
+ size_t alloc_size;
+ size_t data_size;
+ char *data;
} write_cache;
-typedef struct
-{
+typedef struct {
smb_ucs2_t *origname;
smb_ucs2_t *filename;
SMB_STRUCT_STAT *statinfo;
@@ -442,27 +443,23 @@ typedef struct data_blob_ {
* Used in NT change-notify code.
*/
-typedef struct
-{
+typedef struct {
time_t modify_time;
time_t status_time;
} dir_status_struct;
-struct vuid_cache_entry
-{
+struct vuid_cache_entry {
uint16 vuid;
BOOL read_only;
BOOL admin_user;
};
-struct vuid_cache
-{
+struct vuid_cache {
unsigned int entries;
struct vuid_cache_entry array[VUID_CACHE_SIZE];
};
-typedef struct
-{
+typedef struct {
char *name;
BOOL is_wild;
} name_compare_entry;
@@ -482,8 +479,7 @@ struct dfree_cached_info {
struct dptr_struct;
-typedef struct connection_struct
-{
+typedef struct connection_struct {
struct connection_struct *next, *prev;
TALLOC_CTX *mem_ctx;
unsigned cnum; /* an index passed over the wire */
@@ -534,14 +530,10 @@ typedef struct connection_struct
struct dfree_cached_info *dfree_info;
} connection_struct;
-struct current_user
-{
+struct current_user {
connection_struct *conn;
uint16 vuid;
- uid_t uid;
- gid_t gid;
- int ngroups;
- gid_t *groups;
+ UNIX_USER_TOKEN ut;
NT_USER_TOKEN *nt_user_token;
};
@@ -562,42 +554,37 @@ typedef struct {
enum {LPQ_QUEUED=0,LPQ_PAUSED,LPQ_SPOOLING,LPQ_PRINTING,LPQ_ERROR,LPQ_DELETING,
LPQ_OFFLINE,LPQ_PAPEROUT,LPQ_PRINTED,LPQ_DELETED,LPQ_BLOCKED,LPQ_USER_INTERVENTION};
-typedef struct _print_queue_struct
-{
- int job; /* normally the UNIX jobid -- see note in
- printing.c:traverse_fn_delete() */
- int size;
- int page_count;
- int status;
- int priority;
- time_t time;
- fstring fs_user;
- fstring fs_file;
+typedef struct _print_queue_struct {
+ int job; /* normally the UNIX jobid -- see note in
+ printing.c:traverse_fn_delete() */
+ int size;
+ int page_count;
+ int status;
+ int priority;
+ time_t time;
+ fstring fs_user;
+ fstring fs_file;
} print_queue_struct;
enum {LPSTAT_OK, LPSTAT_STOPPED, LPSTAT_ERROR};
-typedef struct
-{
- fstring message;
- int qcount;
- int status;
+typedef struct {
+ fstring message;
+ int qcount;
+ int status;
} print_status_struct;
/* used for server information: client, nameserv and ipc */
-struct server_info_struct
-{
- fstring name;
- uint32 type;
- fstring comment;
- fstring domain; /* used ONLY in ipc.c NOT namework.c */
- BOOL server_added; /* used ONLY in ipc.c NOT namework.c */
+struct server_info_struct {
+ fstring name;
+ uint32 type;
+ fstring comment;
+ fstring domain; /* used ONLY in ipc.c NOT namework.c */
+ BOOL server_added; /* used ONLY in ipc.c NOT namework.c */
};
-
/* used for network interfaces */
-struct interface
-{
+struct interface {
struct interface *next, *prev;
struct in_addr ip;
struct in_addr bcast;
@@ -656,6 +643,7 @@ struct share_mode_lock {
SMB_INO_T ino;
int num_share_modes;
struct share_mode_entry *share_modes;
+ UNIX_USER_TOKEN *delete_token;
BOOL delete_on_close;
BOOL initial_delete_on_close;
BOOL fresh;
@@ -746,8 +734,7 @@ struct enum_list {
void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \
enum brl_type lock_type, \
br_off start, br_off size)
-struct parm_struct
-{
+struct parm_struct {
const char *label;
parm_type type;
parm_class p_class;
@@ -1374,8 +1361,7 @@ enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANM
enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER,SEC_DOMAIN,SEC_ADS};
/* server roles */
-enum server_types
-{
+enum server_types {
ROLE_STANDALONE,
ROLE_DOMAIN_MEMBER,
ROLE_DOMAIN_BDC,
@@ -1552,8 +1538,6 @@ struct cnotify_fns {
int select_time;
};
-
-
#include "smb_macros.h"
#define MAX_NETBIOSNAME_LEN 16
@@ -1621,7 +1605,6 @@ typedef struct user_struct {
} user_struct;
-
struct unix_error_map {
int unix_error;
int dos_class;
@@ -1744,4 +1727,7 @@ typedef struct uuid_flat {
/* map readonly options */
enum mapreadonly_options {MAP_READONLY_NO, MAP_READONLY_YES, MAP_READONLY_PERMISSIONS};
+/* Different reasons for closing a file. */
+enum file_close_type {NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE};
+
#endif /* _SMB_H */
diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c
index 6d6d7817f1..4f5525039f 100644
--- a/source3/lib/smbrun.c
+++ b/source3/lib/smbrun.c
@@ -58,8 +58,8 @@ outfd (or discard it if outfd is NULL).
int smbrun(const char *cmd, int *outfd)
{
pid_t pid;
- uid_t uid = current_user.uid;
- gid_t gid = current_user.gid;
+ uid_t uid = current_user.ut.uid;
+ gid_t gid = current_user.ut.gid;
/*
* Lose any kernel oplock capabilities we may have.
@@ -189,8 +189,8 @@ sends the provided secret to the child stdin.
int smbrunsecret(const char *cmd, const char *secret)
{
pid_t pid;
- uid_t uid = current_user.uid;
- gid_t gid = current_user.gid;
+ uid_t uid = current_user.ut.uid;
+ gid_t gid = current_user.ut.gid;
int ifd[2];
/*
diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c
index 344f6e06fd..30e1d97ca9 100644
--- a/source3/lib/substitute.c
+++ b/source3/lib/substitute.c
@@ -840,11 +840,11 @@ void standard_sub_snum(int snum, char *str, size_t len)
/* calling uidtoname() on every substitute would be too expensive, so
we cache the result here as nearly every call is for the same uid */
- if (cached_uid != current_user.uid) {
- fstrcpy(cached_user, uidtoname(current_user.uid));
- cached_uid = current_user.uid;
+ if (cached_uid != current_user.ut.uid) {
+ fstrcpy(cached_user, uidtoname(current_user.ut.uid));
+ cached_uid = current_user.ut.uid;
}
- standard_sub_advanced(snum, cached_user, "", current_user.gid,
+ standard_sub_advanced(snum, cached_user, "", current_user.ut.gid,
smb_user_name, str, len);
}
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index e8309582fd..e558c6d74f 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -50,6 +50,9 @@ struct locking_data {
int num_share_mode_entries;
BOOL delete_on_close;
BOOL initial_delete_on_close; /* Only set at NTCreateX if file was created. */
+ uint32 delete_token_size; /* Only valid if either of
+ the two previous fields
+ are True. */
} s;
struct share_mode_entry dummy; /* Needed for alignment. */
} u;
@@ -429,8 +432,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
int i;
if (dbuf.dsize < sizeof(struct locking_data)) {
- DEBUG(0, ("parse_share_modes: buffer too short\n"));
- return False;
+ smb_panic("PANIC: parse_share_modes: buffer too short.\n");
}
data = (struct locking_data *)dbuf.dptr;
@@ -449,18 +451,17 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
DEBUG(0, ("invalid number of share modes: %d\n",
lck->num_share_modes));
- return False;
+ smb_panic("PANIC: invalid number of share modes");
}
lck->share_modes = NULL;
-
+
if (lck->num_share_modes != 0) {
if (dbuf.dsize < (sizeof(struct locking_data) +
(lck->num_share_modes *
sizeof(struct share_mode_entry)))) {
- DEBUG(0, ("parse_share_modes: buffer too short\n"));
- return False;
+ smb_panic("PANIC: parse_share_modes: buffer too short.\n");
}
lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data),
@@ -468,20 +469,67 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
sizeof(struct share_mode_entry));
if (lck->share_modes == NULL) {
- DEBUG(0, ("talloc failed\n"));
- return False;
+ smb_panic("talloc failed\n");
}
}
+ /* Get any delete token. */
+ if (data->u.s.delete_token_size) {
+ /* Each uid/gid is stored as a 4 byte value. */
+ uint32 val;
+ uint32 *p = (uint32 *)(dbuf.dptr + sizeof(*data) +
+ (lck->num_share_modes *
+ sizeof(struct share_mode_entry)));
+
+ if ((data->u.s.delete_token_size < 8) || (data->u.s.delete_token_size % 4) != 0) {
+ DEBUG(0, ("parse_share_modes: invalid token size %d\n",
+ data->u.s.delete_token_size));
+ smb_panic("parse_share_modes: invalid token size\n");
+ }
+
+ lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
+ if (!lck->delete_token) {
+ smb_panic("talloc failed\n");
+ }
+
+ /* Copy out the uid and gid. */
+ memcpy(&val, p++, 4);
+ lck->delete_token->uid = (uid_t)val;
+ memcpy(&val, p++, 4);
+ lck->delete_token->gid = (gid_t)val;
+
+ /* Any supplementary groups ? */
+ lck->delete_token->ngroups = (data->u.s.delete_token_size > 8) ?
+ ((data->u.s.delete_token_size - 8)/4) : 0;
+ if (lck->delete_token->ngroups) {
+ /* Make this a talloc child of lck->delete_token. */
+ lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
+ lck->delete_token->ngroups);
+ if (!lck->delete_token) {
+ smb_panic("talloc failed\n");
+ }
+
+ for (i = 0; i < lck->delete_token->ngroups; i++) {
+ memcpy(&val, p++, 4);
+ lck->delete_token->groups[i] = (gid_t)val;
+ }
+ }
+
+ } else {
+ lck->delete_token = NULL;
+ }
+
/* Save off the associated service path and filename. */
lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
- (lck->num_share_modes *
- sizeof(struct share_mode_entry)));
+ (lck->num_share_modes *
+ sizeof(struct share_mode_entry)) +
+ data->u.s.delete_token_size );
lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
- (lck->num_share_modes *
- sizeof(struct share_mode_entry)) +
- strlen(lck->servicepath) + 1 );
+ (lck->num_share_modes *
+ sizeof(struct share_mode_entry)) +
+ data->u.s.delete_token_size +
+ strlen(lck->servicepath) + 1 );
/*
* Ensure that each entry has a real process attached.
@@ -528,6 +576,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
result.dsize = sizeof(*data) +
lck->num_share_modes * sizeof(struct share_mode_entry) +
+ (lck->delete_token ? (8 + (lck->delete_token->ngroups*4)) : 0) +
sp_len + 1 +
strlen(lck->filename) + 1;
result.dptr = talloc_size(lck, result.dsize);
@@ -549,6 +598,25 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
sizeof(struct share_mode_entry)*lck->num_share_modes);
offset = sizeof(*data) +
sizeof(struct share_mode_entry)*lck->num_share_modes;
+
+ /* Store any delete on close token. */
+ if (lck->delete_token) {
+ uint32 val;
+ uint32 *p = (uint32 *)(result.dptr + offset);
+
+ val = (uint32)lck->delete_token->uid;
+ memcpy(p++, &val, 4);
+
+ val = (uint32)lck->delete_token->uid;
+ memcpy(p++, &val, 4);
+
+ for (i = 0; i < lck->delete_token->ngroups; i++) {
+ val = (uint32)lck->delete_token->groups[i];
+ memcpy(p++, &val, 4);
+ }
+ offset = ((char *)p - result.dptr);
+ }
+
safe_strcpy(result.dptr + offset, lck->servicepath,
result.dsize - offset - 1);
offset += sp_len + 1;
@@ -619,6 +687,7 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
lck->ino = ino;
lck->num_share_modes = 0;
lck->share_modes = NULL;
+ lck->delete_token = NULL;
lck->delete_on_close = False;
lck->initial_delete_on_close = False;
lck->fresh = False;
@@ -1047,6 +1116,55 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
return NT_STATUS_OK;
}
+/*************************************************************************
+ Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
+ (Should this be in locking.c.... ?).
+*************************************************************************/
+
+static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok)
+{
+ UNIX_USER_TOKEN *cpy;
+
+ if (tok == NULL) {
+ return NULL;
+ }
+
+ cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
+ if (!cpy) {
+ return NULL;
+ }
+
+ cpy->uid = tok->uid;
+ cpy->gid = tok->gid;
+ cpy->ngroups = tok->ngroups;
+ if (tok->ngroups) {
+ /* Make this a talloc child of cpy. */
+ cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
+ if (!cpy->groups) {
+ return NULL;
+ }
+ memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
+ }
+ return cpy;
+}
+
+/****************************************************************************
+ Replace the delete on close token.
+****************************************************************************/
+
+void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok)
+{
+ /* Ensure there's no token. */
+ if (lck->delete_token) {
+ talloc_free(lck->delete_token); /* Also deletes groups... */
+ lck->delete_token = NULL;
+ }
+
+ /* Copy the new token (can be NULL). */
+ lck->delete_token = copy_unix_token(lck, tok);
+ lck->modified = True;
+}
+
/****************************************************************************
Sets the delete on close flag over all share modes on this file.
Modify the share mode entry for all files open
@@ -1055,9 +1173,11 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
in the close code, the last closer will delete the file
if flag is set.
Note that setting this to any value clears the initial_delete_on_close flag.
+ If delete_on_close is True this makes a copy of any UNIX_USER_TOKEN into the
+ lck entry.
****************************************************************************/
-BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
+BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
{
struct share_mode_lock *lck;
@@ -1074,8 +1194,13 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
if (lck == NULL) {
return False;
}
+
if (lck->delete_on_close != delete_on_close) {
+ set_delete_on_close_token(lck, tok);
lck->delete_on_close = delete_on_close;
+ if (delete_on_close) {
+ SMB_ASSERT(lck->delete_token != NULL);
+ }
lck->modified = True;
}
@@ -1105,9 +1230,11 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
data = (struct locking_data *)dbuf.dptr;
shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
sharepath = dbuf.dptr + sizeof(*data) +
- data->u.s.num_share_mode_entries*sizeof(*shares);
+ data->u.s.num_share_mode_entries*sizeof(*shares) +
+ data->u.s.delete_token_size;
fname = dbuf.dptr + sizeof(*data) +
data->u.s.num_share_mode_entries*sizeof(*shares) +
+ data->u.s.delete_token_size +
strlen(sharepath) + 1;
for (i=0;i<data->u.s.num_share_mode_entries;i++) {
diff --git a/source3/modules/vfs_fake_perms.c b/source3/modules/vfs_fake_perms.c
index 4d10ea5f33..decbe01d3c 100644
--- a/source3/modules/vfs_fake_perms.c
+++ b/source3/modules/vfs_fake_perms.c
@@ -40,8 +40,8 @@ static int fake_perms_stat(vfs_handle_struct *handle, connection_struct *conn, c
} else {
sbuf->st_mode = S_IRWXU;
}
- sbuf->st_uid = current_user.uid;
- sbuf->st_gid = current_user.gid;
+ sbuf->st_uid = current_user.ut.uid;
+ sbuf->st_gid = current_user.ut.gid;
}
return ret;
@@ -58,8 +58,8 @@ static int fake_perms_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd
} else {
sbuf->st_mode = S_IRWXU;
}
- sbuf->st_uid = current_user.uid;
- sbuf->st_gid = current_user.gid;
+ sbuf->st_uid = current_user.ut.uid;
+ sbuf->st_gid = current_user.ut.gid;
}
return ret;
}
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 3649da1ac0..a91c2a5c70 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1296,7 +1296,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
}
}
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
/* Get file version info (if available) for new file */
pstrcpy(filepath, new_file);
@@ -1332,7 +1332,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
}
}
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
if (use_version && (new_major != old_major || new_minor != old_minor)) {
/* Compare versions and choose the larger version number */
@@ -1361,7 +1361,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
error_exit:
if(fsp)
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
return -1;
}
@@ -1486,7 +1486,7 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
driverpath, cversion));
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
close_cnum(conn, user->vuid);
unbecome_user();
*perr = WERR_OK;
@@ -1496,7 +1496,7 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
error_exit:
if(fsp)
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
close_cnum(conn, user->vuid);
unbecome_user();
@@ -5275,7 +5275,7 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
/* Always allow root or SE_PRINT_OPERATROR to do anything */
- if ( user->uid == 0 || user_has_privileges(user->nt_user_token, &se_printop ) ) {
+ if ( user->ut.uid == 0 || user_has_privileges(user->nt_user_token, &se_printop ) ) {
return True;
}
@@ -5327,7 +5327,7 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
/* see if we need to try the printer admin list */
if ( access_granted == 0 ) {
- if ( user_in_list(uidtoname(user->uid), lp_printer_admin(snum), user->groups, user->ngroups) )
+ if ( user_in_list(uidtoname(user->ut.uid), lp_printer_admin(snum), user->ut.groups, user->ut.ngroups) )
return True;
}
diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c
index eb81dc4536..c248851822 100644
--- a/source3/printing/printfsp.c
+++ b/source3/printing/printfsp.c
@@ -94,7 +94,7 @@ files_struct *print_fsp_open(connection_struct *conn, const char *fname)
Print a file - called on closing the file.
****************************************************************************/
-void print_fsp_end(files_struct *fsp, BOOL normal_close)
+void print_fsp_end(files_struct *fsp, enum file_close_type close_type)
{
uint32 jobid;
fstring sharename;
@@ -117,5 +117,5 @@ void print_fsp_end(files_struct *fsp, BOOL normal_close)
return;
}
- print_job_end(SNUM(fsp->conn),jobid, normal_close);
+ print_job_end(SNUM(fsp->conn),jobid, close_type);
}
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 6e74095f71..82b9a7f74e 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -1932,7 +1932,7 @@ static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
return strequal(pjob->user, vuser->user.smb_name);
} else {
- return strequal(pjob->user, uidtoname(user->uid));
+ return strequal(pjob->user, uidtoname(user->ut.uid));
}
}
@@ -1963,7 +1963,7 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR
sys_adminlog( LOG_ERR,
"Permission denied-- user not allowed to delete, \
pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
+ uidtoname(user->ut.uid), PRINTERNAME(snum) );
/* END_ADMIN_LOG */
return False;
@@ -2030,7 +2030,7 @@ BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *
sys_adminlog( LOG_ERR,
"Permission denied-- user not allowed to delete, \
pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
+ uidtoname(user->ut.uid), PRINTERNAME(snum) );
/* END_ADMIN_LOG */
*errcode = WERR_ACCESS_DENIED;
@@ -2085,7 +2085,7 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR
sys_adminlog( LOG_ERR,
"Permission denied-- user not allowed to delete, \
pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
+ uidtoname(user->ut.uid), PRINTERNAME(snum) );
/* END_ADMIN_LOG */
return False;
}
@@ -2366,7 +2366,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE
if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
fstrcpy(pjob.user, vuser->user.smb_name);
} else {
- fstrcpy(pjob.user, uidtoname(user->uid));
+ fstrcpy(pjob.user, uidtoname(user->ut.uid));
}
fstrcpy(pjob.queuename, lp_const_servicename(snum));
@@ -2437,7 +2437,7 @@ void print_job_endpage(int snum, uint32 jobid)
error.
****************************************************************************/
-BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
+BOOL print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
{
const char* sharename = lp_const_servicename(snum);
struct printjob *pjob;
@@ -2453,7 +2453,8 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
if (pjob->spooled || pjob->pid != sys_getpid())
return False;
- if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
+ if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
+ (sys_fstat(pjob->fd, &sbuf) == 0)) {
pjob->size = sbuf.st_size;
close(pjob->fd);
pjob->fd = -1;
diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c
index f61348ee05..63e4d4e9b7 100644
--- a/source3/rpc_server/srv_dfs_nt.c
+++ b/source3/rpc_server/srv_dfs_nt.c
@@ -52,7 +52,7 @@ WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
get_current_user(&user,p);
- if (user.uid != 0) {
+ if (user.ut.uid != 0) {
DEBUG(10,("_dfs_add: uid != 0. Access denied.\n"));
return WERR_ACCESS_DENIED;
}
@@ -115,7 +115,7 @@ WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u,
get_current_user(&user,p);
- if (user.uid != 0) {
+ if (user.ut.uid != 0) {
DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n"));
return WERR_ACCESS_DENIED;
}
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index 6cd673550e..f48f3e863a 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -1198,7 +1198,7 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u
account_pol.tdb was already opened as root, this is all we have */
get_current_user( &user, p );
- if ( user.uid != sec_initial_uid()
+ if ( user.ut.uid != sec_initial_uid()
&& !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
@@ -1239,7 +1239,7 @@ NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEP
account_pol.tdb was already opened as root, this is all we have */
get_current_user( &user, p );
- if ( user.uid != sec_initial_uid()
+ if ( user.ut.uid != sec_initial_uid()
&& !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
@@ -1401,7 +1401,7 @@ NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R
account_pol.tdb was already opened as root, this is all we have */
get_current_user( &user, p );
- if ( user.uid != sec_initial_uid()
+ if ( user.ut.uid != sec_initial_uid()
&& !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
@@ -1459,7 +1459,7 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u,
account_pol.tdb was already opened as root, this is all we have */
get_current_user( &user, p );
- if ( user.uid != sec_initial_uid()
+ if ( user.ut.uid != sec_initial_uid()
&& !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
@@ -1573,4 +1573,3 @@ NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, L
return NT_STATUS_OK;
}
-
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index ecf79d0c1f..381adbe635 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -617,8 +617,8 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
/* Set up for non-authenticated user. */
delete_nt_token(&p->pipe_user.nt_user_token);
- p->pipe_user.ngroups = 0;
- SAFE_FREE( p->pipe_user.groups);
+ p->pipe_user.ut.ngroups = 0;
+ SAFE_FREE( p->pipe_user.ut.groups);
status = auth_ntlmssp_update(a, *p_resp_blob, &reply);
@@ -641,8 +641,8 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
* Store the UNIX credential data (uid/gid pair) in the pipe structure.
*/
- p->pipe_user.uid = a->server_info->uid;
- p->pipe_user.gid = a->server_info->gid;
+ p->pipe_user.ut.uid = a->server_info->uid;
+ p->pipe_user.ut.gid = a->server_info->gid;
/*
* Copy the session key from the ntlmssp state.
@@ -654,9 +654,10 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
return False;
}
- p->pipe_user.ngroups = a->server_info->n_groups;
- if (p->pipe_user.ngroups) {
- if (!(p->pipe_user.groups = memdup(a->server_info->groups, sizeof(gid_t) * p->pipe_user.ngroups))) {
+ p->pipe_user.ut.ngroups = a->server_info->n_groups;
+ if (p->pipe_user.ut.ngroups) {
+ if (!(p->pipe_user.ut.groups = memdup(a->server_info->groups,
+ sizeof(gid_t) * p->pipe_user.ut.ngroups))) {
DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n"));
return False;
}
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 5fb84115cc..37d3ef64c0 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -343,8 +343,8 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
ZERO_STRUCT(p->pipe_user);
- p->pipe_user.uid = (uid_t)-1;
- p->pipe_user.gid = (gid_t)-1;
+ p->pipe_user.ut.uid = (uid_t)-1;
+ p->pipe_user.ut.gid = (gid_t)-1;
/* Store the session key and NT_TOKEN */
if (vuser) {
@@ -1224,7 +1224,7 @@ static BOOL close_internal_rpc_pipe_hnd(void *np_conn)
delete_nt_token(&p->pipe_user.nt_user_token);
data_blob_free(&p->session_key);
- SAFE_FREE(p->pipe_user.groups);
+ SAFE_FREE(p->pipe_user.ut.groups);
DLIST_REMOVE(InternalPipes, p);
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 334158bbbd..a22d6db266 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -1620,9 +1620,9 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
- if ( user.uid != 0
+ if ( user.ut.uid != 0
&& !user_has_privileges( user.nt_user_token, &se_printop )
- && !user_in_list(uidtoname(user.uid), lp_printer_admin(snum), user.groups, user.ngroups) )
+ && !user_in_list(uidtoname(user.ut.uid), lp_printer_admin(snum), user.ut.groups, user.ut.ngroups) )
{
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
@@ -1676,7 +1676,7 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
return WERR_ACCESS_DENIED;
}
- if (!user_ok(uidtoname(user.uid), snum, user.groups, user.ngroups) || !print_access_check(&user, snum, printer_default->access_required)) {
+ if (!user_ok(uidtoname(user.ut.uid), snum, user.ut.groups, user.ut.ngroups) || !print_access_check(&user, snum, printer_default->access_required)) {
DEBUG(3, ("access DENIED for printer open\n"));
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
@@ -1869,7 +1869,7 @@ static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handl
return WERR_BADFID;
Printer->document_started=False;
- print_job_end(snum, Printer->jobid,True);
+ print_job_end(snum, Printer->jobid,NORMAL_CLOSE);
/* error codes unhandled so far ... */
return WERR_OK;
@@ -7554,12 +7554,12 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
case 3:
fstrcpy(driver_name, driver.info_3->name ? driver.info_3->name : "");
sys_adminlog(LOG_INFO,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.",
- driver_name, get_drv_ver_to_os(driver.info_3->cversion),uidtoname(user.uid));
+ driver_name, get_drv_ver_to_os(driver.info_3->cversion),uidtoname(user.ut.uid));
break;
case 6:
fstrcpy(driver_name, driver.info_6->name ? driver.info_6->name : "");
sys_adminlog(LOG_INFO,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.",
- driver_name, get_drv_ver_to_os(driver.info_6->version),uidtoname(user.uid));
+ driver_name, get_drv_ver_to_os(driver.info_6->version),uidtoname(user.ut.uid));
break;
}
/* END_ADMIN_LOG */
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index 65e0504e67..8150a8bf69 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -1401,7 +1401,7 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES
/* fail out now if you are not root or not a domain admin */
- if ((user.uid != sec_initial_uid()) &&
+ if ((user.ut.uid != sec_initial_uid()) &&
( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
goto done;
@@ -1412,7 +1412,7 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES
if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
strequal(session_list[snum].remote_machine, machine)) {
- if (user.uid != sec_initial_uid()) {
+ if (user.ut.uid != sec_initial_uid()) {
not_root = True;
become_root();
}
@@ -1572,7 +1572,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
/* fail out now if you are not root and not a disk op */
- if ( user.uid != sec_initial_uid() && !is_disk_op )
+ if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
switch (q_u->info_level) {
@@ -1739,7 +1739,7 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
- if (user.uid != sec_initial_uid() && !is_disk_op )
+ if (user.ut.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
@@ -1906,7 +1906,7 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
- if (user.uid != sec_initial_uid() && !is_disk_op )
+ if (user.ut.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
@@ -2098,7 +2098,7 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
psd->dacl->revision = (uint16) NT4_ACL_REVISION;
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
unbecome_user();
close_cnum(conn, user.vuid);
return r_u->status;
@@ -2106,7 +2106,7 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
error_exit:
if(fsp) {
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
}
if (became_user)
@@ -2207,7 +2207,7 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
goto error_exit;
}
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
unbecome_user();
close_cnum(conn, user.vuid);
return r_u->status;
@@ -2215,7 +2215,7 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
error_exit:
if(fsp) {
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
}
if (became_user) {
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;
}