r13293: Rather a big patch I'm afraid, but this should fix bug #3347
authorJeremy Allison <jra@samba.org>
Thu, 2 Feb 2006 20:44:50 +0000 (20:44 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:06:21 +0000 (11:06 -0500)
by saving the UNIX token used to set a delete on close flag,
and using it when doing the delete. libsmbsharemodes.so still
needs updating to cope with this change.
Samba4 torture tests to follow.
Jeremy.
(This used to be commit 23f16cbc2e8cde97c486831e26bcafd4ab4a9654)

25 files changed:
source3/include/smb.h
source3/lib/smbrun.c
source3/lib/substitute.c
source3/locking/locking.c
source3/modules/vfs_fake_perms.c
source3/printing/nt_printing.c
source3/printing/printfsp.c
source3/printing/printing.c
source3/rpc_server/srv_dfs_nt.c
source3/rpc_server/srv_lsa_nt.c
source3/rpc_server/srv_pipe.c
source3/rpc_server/srv_pipe_hnd.c
source3/rpc_server/srv_spoolss_nt.c
source3/rpc_server/srv_srvsvc_nt.c
source3/smbd/close.c
source3/smbd/dir.c
source3/smbd/fake_file.c
source3/smbd/files.c
source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/posix_acls.c
source3/smbd/reply.c
source3/smbd/sec_ctx.c
source3/smbd/trans2.c
source3/smbd/uid.c

index ac268ea763ff55366b7e9e1aaa1a036b20c680fb..b8211aac45c820f19f23c5fa03050919215a682f 100644 (file)
@@ -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 */
index 6d6d7817f1abbc13b01c25724cb51f3ee7e19f0a..4f5525039f5ab4d538d08678015941e840bb8f84 100644 (file)
@@ -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];
        
        /*
index 344f6e06fdf7d3f096b4bfec4029e42cb5bc7c0f..30e1d97ca9b29e4245fbe3b9e0ef74b42f0b6710 100644 (file)
@@ -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);
 }
index e8309582fd9dff613de1d3415f9448f75bef1036..e558c6d74fff1df468fed809a6e9a0333dc80367 100644 (file)
@@ -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++) {
index 4d10ea5f3378bd7a86ea874c9462137b5230b76f..decbe01d3cacf8de22f421369b87ed0eaaf6196d 100644 (file)
@@ -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;
 }
index 3649da1ac0516e379c251da82e5d43d1f6e30b96..a91c2a5c70b1a26fba2790a10ba7ee767c38fd3a 100644 (file)
@@ -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;
         }
 
index eb81dc4536fb575dc5b617f1925741149f974404..c248851822b8242d83ce98446b79da0f69e85009 100644 (file)
@@ -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);
 }
index 6e74095f719b01f8a6d8c75d2dc9ee08f6e9c949..82b9a7f74e3f4641ed52dfc8b780ec700d17b6ca 100644 (file)
@@ -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;
index f61348ee05d91244a86a77bf66c2296dfb501b24..63e4d4e9b7c175cf1a3f143dd15663ec46dc314c 100644 (file)
@@ -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;
        }
index 6cd673550ec1f3d747f41cbc1e253f01e852b928..f48f3e863a8fc36179dde1f67df9b8108059c045 100644 (file)
@@ -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;
 }
-
index ecf79d0c1f32ba7b0fd7587ec596d33b05ce870b..381adbe635890a31ae9afab76151dbdc6ade7607 100644 (file)
@@ -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;
                }
index 5fb84115cc335894ea2a896ac3d9493be8c7d90d..37d3ef64c0b3f747247ec58310061bc4bdb085ab 100644 (file)
@@ -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);
 
index 334158bbbd2b0ff533ee467b3aaa3d59216571b7..a22d6db266c4a73a783b725b4605c8d7584a9472 100644 (file)
@@ -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 */
index 65e0504e6785861ebceb7656d05bb831b4710446..8150a8bf698b0e6135501e975dd9bf230863c24b 100644 (file)
@@ -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) {
index d284c82f4425ad1bde78d67d9bb36b816e3d6a1d..059b88ecc898cc4a54a3e975003fa0fdb57f97e9 100644 (file)
@@ -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);
 }
index 0635db22dbd13d9901d54bf77824fb4a428fa159..81fe7c40218e3351cee6d8cf611529171a5b56c3 100644 (file)
@@ -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)
index 799725a7820975c2de979bba29c1412d4728ad69..1356baf1a81a20fafcfbc2f2c5d965b7a2f5294e 100644 (file)
@@ -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;
index 181e17b11fb445fcc1a9238cc21045c37c578e77..5a545c236e692406279c5800633370b16c8d5a7b 100644 (file)
@@ -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);
                }
        }
 }
index 72288e2c244dd9b0ecc2ba49e77b7e530ceecf02..e12a24968b04981e73eead80bc0429ebac9fc4ab 100644 (file)
@@ -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);
index dd2731c897305a79e80583bb3c3914a6b5fcaa5e..15e814aae3c9d598a34a1034c92ab2c9fabaeb40 100644 (file)
@@ -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;
        }
index 34497f02809aa4620600a92dd0d034b8dc9a537f..5db245ac0ced3a1878800d18bbb685e2848ed6d3 100644 (file)
@@ -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;
        }
 
index 69c71c74b597bd0ec530d70d954b73e62e35b685..89b98be1e77024738ee8acdce2a16503c8fecaf8 100644 (file)
@@ -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);
 }
index a5411b94a177523aeebdda5984404218f3c3bf3f..fc6a8589747e65f6727422942684222d5b79ca06 100644 (file)
 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. */
index 8ff219b468c0dee081c0694bc2f870d99b0d5182..b8fc2b5b8f1768c6ba4234dbd71a665d3178273e 100644 (file)
@@ -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);
                }
index 9db3d97ab2dcf0ddff1787621a6f2f06e41e7e96..d419720c33e6f91f2c4dae014fd927617f9f5f85 100644 (file)
@@ -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;
 }