summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-02-02 20:44:50 +0000
committerJeremy Allison <jra@samba.org>2006-02-02 20:44:50 +0000
commit130b5e80f1917a3eb52568ce114af465ad068c52 (patch)
tree5f5186f7190610b4697292e7674c8b9529f7261f /source
parentd13e343dc7bfa1e30d7b54b59ab202b3f52ea954 (diff)
downloadsamba-130b5e80f1917a3eb52568ce114af465ad068c52.tar.gz
samba-130b5e80f1917a3eb52568ce114af465ad068c52.tar.xz
samba-130b5e80f1917a3eb52568ce114af465ad068c52.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.
Diffstat (limited to 'source')
-rw-r--r--source/include/smb.h138
-rw-r--r--source/lib/smbrun.c8
-rw-r--r--source/lib/substitute.c8
-rw-r--r--source/locking/locking.c157
-rw-r--r--source/modules/vfs_fake_perms.c8
-rw-r--r--source/printing/nt_printing.c14
-rw-r--r--source/printing/printfsp.c4
-rw-r--r--source/printing/printing.c15
-rw-r--r--source/rpc_server/srv_dfs_nt.c4
-rw-r--r--source/rpc_server/srv_lsa_nt.c9
-rw-r--r--source/rpc_server/srv_pipe.c15
-rw-r--r--source/rpc_server/srv_pipe_hnd.c6
-rw-r--r--source/rpc_server/srv_spoolss_nt.c12
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c18
-rw-r--r--source/smbd/close.c66
-rw-r--r--source/smbd/dir.c4
-rw-r--r--source/smbd/fake_file.c2
-rw-r--r--source/smbd/files.c6
-rw-r--r--source/smbd/nttrans.c26
-rw-r--r--source/smbd/open.c2
-rw-r--r--source/smbd/posix_acls.c30
-rw-r--r--source/smbd/reply.c26
-rw-r--r--source/smbd/sec_ctx.c83
-rw-r--r--source/smbd/trans2.c14
-rw-r--r--source/smbd/uid.c30
25 files changed, 427 insertions, 278 deletions
diff --git a/source/include/smb.h b/source/include/smb.h
index ac268ea763f..b8211aac45c 100644
--- a/source/include/smb.h
+++ b/source/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/source/lib/smbrun.c b/source/lib/smbrun.c
index 6d6d7817f1a..4f5525039f5 100644
--- a/source/lib/smbrun.c
+++ b/source/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/source/lib/substitute.c b/source/lib/substitute.c
index 344f6e06fdf..30e1d97ca9b 100644
--- a/source/lib/substitute.c
+++ b/source/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/source/locking/locking.c b/source/locking/locking.c
index e8309582fd9..e558c6d74ff 100644
--- a/source/locking/locking.c
+++ b/source/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/source/modules/vfs_fake_perms.c b/source/modules/vfs_fake_perms.c
index 4d10ea5f337..decbe01d3ca 100644
--- a/source/modules/vfs_fake_perms.c
+++ b/source/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/source/printing/nt_printing.c b/source/printing/nt_printing.c
index 3649da1ac05..a91c2a5c70b 100644
--- a/source/printing/nt_printing.c
+++ b/source/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/source/printing/printfsp.c b/source/printing/printfsp.c
index eb81dc4536f..c248851822b 100644
--- a/source/printing/printfsp.c
+++ b/source/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/source/printing/printing.c b/source/printing/printing.c
index 6e74095f719..82b9a7f74e3 100644
--- a/source/printing/printing.c
+++ b/source/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/source/rpc_server/srv_dfs_nt.c b/source/rpc_server/srv_dfs_nt.c
index f61348ee05d..63e4d4e9b7c 100644
--- a/source/rpc_server/srv_dfs_nt.c
+++ b/source/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/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index 6cd673550ec..f48f3e863a8 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/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/source/rpc_server/srv_pipe.c b/source/rpc_server/srv_pipe.c
index ecf79d0c1f3..381adbe6358 100644
--- a/source/rpc_server/srv_pipe.c
+++ b/source/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/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c
index 5fb84115cc3..37d3ef64c0b 100644
--- a/source/rpc_server/srv_pipe_hnd.c
+++ b/source/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/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 334158bbbd2..a22d6db266c 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/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/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index 65e0504e678..8150a8bf698 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/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/source/smbd/close.c b/source/smbd/close.c
index d284c82f442..059b88ecc89 100644
--- a/source/smbd/close.c
+++ b/source/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/source/smbd/dir.c b/source/smbd/dir.c
index 0635db22dbd..81fe7c40218 100644
--- a/source/smbd/dir.c
+++ b/source/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/source/smbd/fake_file.c b/source/smbd/fake_file.c
index 799725a7820..1356baf1a81 100644
--- a/source/smbd/fake_file.c
+++ b/source/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/source/smbd/files.c b/source/smbd/files.c
index 181e17b11fb..5a545c236e6 100644
--- a/source/smbd/files.c
+++ b/source/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/source/smbd/nttrans.c b/source/smbd/nttrans.c
index 72288e2c244..e12a24968b0 100644
--- a/source/smbd/nttrans.c
+++ b/source/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/source/smbd/open.c b/source/smbd/open.c
index dd2731c8973..15e814aae3c 100644
--- a/source/smbd/open.c
+++ b/source/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/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 34497f02809..5db245ac0ce 100644
--- a/source/smbd/posix_acls.c
+++ b/source/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/source/smbd/reply.c b/source/smbd/reply.c
index 69c71c74b59..89b98be1e77 100644
--- a/source/smbd/reply.c
+++ b/source/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/source/smbd/sec_ctx.c b/source/smbd/sec_ctx.c
index a5411b94a17..fc6a8589747 100644
--- a/source/smbd/sec_ctx.c
+++ b/source/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/source/smbd/trans2.c b/source/smbd/trans2.c
index 8ff219b468c..b8fc2b5b8f1 100644
--- a/source/smbd/trans2.c
+++ b/source/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/source/smbd/uid.c b/source/smbd/uid.c
index 9db3d97ab2d..d419720c33e 100644
--- a/source/smbd/uid.c
+++ b/source/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;
}