diff options
author | Jeremy Allison <jra@samba.org> | 2006-02-02 20:44:50 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2006-02-02 20:44:50 +0000 |
commit | 130b5e80f1917a3eb52568ce114af465ad068c52 (patch) | |
tree | 5f5186f7190610b4697292e7674c8b9529f7261f /source | |
parent | d13e343dc7bfa1e30d7b54b59ab202b3f52ea954 (diff) | |
download | samba-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.h | 138 | ||||
-rw-r--r-- | source/lib/smbrun.c | 8 | ||||
-rw-r--r-- | source/lib/substitute.c | 8 | ||||
-rw-r--r-- | source/locking/locking.c | 157 | ||||
-rw-r--r-- | source/modules/vfs_fake_perms.c | 8 | ||||
-rw-r--r-- | source/printing/nt_printing.c | 14 | ||||
-rw-r--r-- | source/printing/printfsp.c | 4 | ||||
-rw-r--r-- | source/printing/printing.c | 15 | ||||
-rw-r--r-- | source/rpc_server/srv_dfs_nt.c | 4 | ||||
-rw-r--r-- | source/rpc_server/srv_lsa_nt.c | 9 | ||||
-rw-r--r-- | source/rpc_server/srv_pipe.c | 15 | ||||
-rw-r--r-- | source/rpc_server/srv_pipe_hnd.c | 6 | ||||
-rw-r--r-- | source/rpc_server/srv_spoolss_nt.c | 12 | ||||
-rw-r--r-- | source/rpc_server/srv_srvsvc_nt.c | 18 | ||||
-rw-r--r-- | source/smbd/close.c | 66 | ||||
-rw-r--r-- | source/smbd/dir.c | 4 | ||||
-rw-r--r-- | source/smbd/fake_file.c | 2 | ||||
-rw-r--r-- | source/smbd/files.c | 6 | ||||
-rw-r--r-- | source/smbd/nttrans.c | 26 | ||||
-rw-r--r-- | source/smbd/open.c | 2 | ||||
-rw-r--r-- | source/smbd/posix_acls.c | 30 | ||||
-rw-r--r-- | source/smbd/reply.c | 26 | ||||
-rw-r--r-- | source/smbd/sec_ctx.c | 83 | ||||
-rw-r--r-- | source/smbd/trans2.c | 14 | ||||
-rw-r--r-- | source/smbd/uid.c | 30 |
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, ¤t_user.ut); lck->initial_delete_on_close = True; lck->modified = True; } @@ -1983,6 +1984,7 @@ files_struct *open_directory(connection_struct *conn, return NULL; } + set_delete_on_close_token(lck, ¤t_user.ut); lck->initial_delete_on_close = True; lck->modified = True; } diff --git a/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, ¤t_user.ut)) { return ERROR_NT(NT_STATUS_ACCESS_DENIED); } @@ -4416,7 +4416,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", return(UNIXERROR(ERRDOS,ERRbadpath)); } ret = vfs_set_filelen(new_fsp, size); - close_file(new_fsp,True); + close_file(new_fsp,NORMAL_CLOSE); } else { ret = vfs_set_filelen(fsp, size); } diff --git a/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; } |