r23620: Convert set_nt_acl to return NTSTATUS. Also fix the chown
authorJeremy Allison <jra@samba.org>
Tue, 26 Jun 2007 22:49:10 +0000 (22:49 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:23:37 +0000 (12:23 -0500)
return to correctly return NT_STATUS_INVALID_OWNER if it
should be disallowed. Matches better what W2K3R3 does.

NFSv4 ACL module owners, please examine these changes.

Jeremy.
(This used to be commit fc6899a5506b272f8cd5f5837ca13300b4e69a5f)

15 files changed:
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/vfs.h
source3/modules/nfs4_acls.c
source3/modules/vfs_afsacl.c
source3/modules/vfs_aixacl2.c
source3/modules/vfs_cap.c
source3/modules/vfs_catia.c
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_gpfs.c
source3/modules/vfs_zfsacl.c
source3/rpc_server/srv_srvsvc_nt.c
source3/smbd/nttrans.c
source3/smbd/posix_acls.c

index 6204ef47f4c9463464c8a192ed4d667e91e991cc..1ba6a9b13bd001e1ac8987405ee30396ba6ca269 100644 (file)
@@ -295,18 +295,18 @@ static size_t skel_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        return 0;
 }
 
-static BOOL skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int
+static NTSTATUS skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int
        fd, uint32 security_info_sent, SEC_DESC *psd)
 {
        errno = ENOSYS;
-       return False;
+       return NT_STATUS_NOT_IMPLEMENTED;
 }
 
-static BOOL skel_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const
+static NTSTATUS skel_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const
        char *name, uint32 security_info_sent, SEC_DESC *psd)
 {
        errno = ENOSYS;
-       return False;
+       return NT_STATUS_NOT_IMPLEMENTED;
 }
 
 static int skel_chmod_acl(vfs_handle_struct *handle,  const char *name, mode_t mode)
index a422b7ce003320d70fb44bc716ba635b7c901f8b..746fa31736b65fcc9fafb50fbfe2cb9ce6d11e25 100644 (file)
@@ -286,13 +286,13 @@ static size_t skel_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        return SMB_VFS_NEXT_GET_NT_ACL(handle, fsp, name, security_info, ppdesc);
 }
 
-static BOOL skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+static NTSTATUS skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        int fd, uint32 security_info_sent, SEC_DESC *psd)
 {
        return SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, fd, security_info_sent, psd);
 }
 
-static BOOL skel_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+static NTSTATUS skel_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        const char *name, uint32 security_info_sent, SEC_DESC *psd)
 {
        return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent, psd);
index eac9eced165991fa0b52dccec2930cebbc65a9a8..d968ba9d82ad6c7ef286a34e29db34ba0f55df79 100644 (file)
@@ -71,6 +71,7 @@
  * timestamp resolition. JRA. */
 /* Changed to version21 to add chflags operation -- jpeach */
 /* Changed to version22 to add lchown operation -- jra */
+/* Leave at 22 - not yet released. But change set_nt_acl to return an NTSTATUS. jra. */
 #define SMB_VFS_INTERFACE_VERSION 22
 
 
@@ -300,8 +301,8 @@ struct vfs_ops {
                
                size_t (*fget_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd,  uint32 security_info, struct security_descriptor **ppdesc);
                size_t (*get_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name,  uint32 security_info, struct security_descriptor **ppdesc);
-               BOOL (*fset_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor *psd);
-               BOOL (*set_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor *psd);
+               NTSTATUS (*fset_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor *psd);
+               NTSTATUS (*set_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor *psd);
                
                /* POSIX ACL operations. */
                
index 1da8d1b7a334e4b421d4952c5bb487f64d935b4a..30c209dd93aca0f2fc3b0ba8c069ce5c17387c4b 100644 (file)
@@ -42,7 +42,7 @@ typedef struct _SMB_ACL4_INT_T
 
 extern struct current_user current_user;
 extern int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid);
-extern BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp,
+extern NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp,
        uint32 security_info_sent, SEC_DESC *psd);
 
 static SMB_ACL4_INT_T *get_validated_aclint(SMB4ACL_T *acl)
@@ -559,7 +559,7 @@ static SMB4ACL_T *smbacl4_win2nfs4(
        return acl;
 }
 
-BOOL smb_set_nt_acl_nfs4(files_struct *fsp,
+NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
        uint32 security_info_sent,
        SEC_DESC *psd,
        set_nfs4acl_native_fn_t set_nfs4_native)
@@ -569,7 +569,6 @@ BOOL smb_set_nt_acl_nfs4(files_struct *fsp,
        BOOL    result;
 
        SMB_STRUCT_STAT sbuf;
-       BOOL need_chown = False;
        uid_t newUID = (uid_t)-1;
        gid_t newGID = (gid_t)-1;
 
@@ -580,43 +579,37 @@ BOOL smb_set_nt_acl_nfs4(files_struct *fsp,
        {
                DEBUG(9, ("security_info_sent (0x%x) ignored\n",
                        security_info_sent));
-               return True; /* won't show error - later to be refined... */
+               return NT_STATUS_OK; /* won't show error - later to be refined... */
        }
 
        /* Special behaviours */
        if (smbacl4_get_vfs_params(SMBACL4_PARAM_TYPE_NAME, fsp, &params))
-               return False;
+               return NT_STATUS_NO_MEMORY;
 
        if (smbacl4_GetFileOwner(fsp, &sbuf))
-               return False;
+               return map_nt_error_from_unix(errno);
 
        if (params.do_chown) {
                /* chown logic is a copy/paste from posix_acl.c:set_nt_acl */
-               if (!unpack_nt_owners(SNUM(fsp->conn), &newUID, &newGID, security_info_sent, psd))
-               {
+               NTSTATUS status = unpack_nt_owners(SNUM(fsp->conn), &newUID, &newGID, security_info_sent, psd);
+               if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(8, ("unpack_nt_owners failed"));
-                       return False;
+                       return status;
                }
                if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) ||
-                       ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) {
-                       need_chown = True;
-               }
-               if (need_chown) {
-                       if ((newUID == (uid_t)-1 || newUID == current_user.ut.uid)) {
-                               if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
-                                       DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
-                                               fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, strerror(errno) ));
-                                       return False;
+                               ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) {
+                       if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
+                               DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
+                                       fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, strerror(errno) ));
+                               if (errno == EPERM) {
+                                       return NT_STATUS_INVALID_OWNER;
                                }
-                               DEBUG(10,("chown %s, %u, %u succeeded.\n",
-                                       fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
-                               if (smbacl4_GetFileOwner(fsp, &sbuf))
-                                       return False;
-                               need_chown = False;
-                       } else { /* chown is needed, but _after_ changing acl */
-                               sbuf.st_uid = newUID; /* OWNER@ in case of e_special */
-                               sbuf.st_gid = newGID; /* GROUP@ in case of e_special */
+                               return map_nt_error_from_unix(errno);
                        }
+                       DEBUG(10,("chown %s, %u, %u succeeded.\n",
+                               fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
+                       if (smbacl4_GetFileOwner(fsp, &sbuf))
+                               return map_nt_error_from_unix(errno);
                }
        }
 
@@ -624,7 +617,7 @@ BOOL smb_set_nt_acl_nfs4(files_struct *fsp,
        {
                acl = smbacl4_win2nfs4(psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
                if (!acl)
-                       return False;
+                       return map_nt_error_from_unix(errno);
 
                smbacl4_dump_nfs4acl(10, acl);
 
@@ -632,25 +625,11 @@ BOOL smb_set_nt_acl_nfs4(files_struct *fsp,
                if (result!=True)
                {
                        DEBUG(10, ("set_nfs4_native failed with %s\n", strerror(errno)));
-                       return False;
+                       return map_nt_error_from_unix(errno);
                }
        } else
                DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n", security_info_sent));
 
-       /* Any chown pending? */
-       if (need_chown) {
-               DEBUG(3,("chown#2 %s. uid = %u, gid = %u.\n",
-                       fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
-               if (try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
-                       DEBUG(2,("chown#2 %s, %u, %u failed. Error = %s.\n",
-                               fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
-                               strerror(errno)));
-                       return False;
-               }
-               DEBUG(10,("chown#2 %s, %u, %u succeeded.\n",
-                       fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
-       }
-
        DEBUG(10, ("smb_set_nt_acl_nfs4 succeeded\n"));
-       return True;
+       return NT_STATUS_OK;
 }
index 47e8ec5aefac54c781f9515ce4efefae05677f54..2f472df28cde281af37e7d5feea2d0845acc5237 100644 (file)
@@ -883,7 +883,7 @@ static void merge_unknown_aces(struct afs_acl *src, struct afs_acl *dst)
        }
 }
 
-static BOOL afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                           uint32 security_info_sent,
                           struct security_descriptor *psd)
 {
@@ -980,7 +980,7 @@ static BOOL afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        free_afs_acl(&old_afs_acl);
        free_afs_acl(&new_afs_acl);
 
-       return (ret == 0);
+       return (ret == 0) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
 }
 
 static size_t afsacl_fget_nt_acl(struct vfs_handle_struct *handle,
@@ -998,7 +998,7 @@ static size_t afsacl_get_nt_acl(struct vfs_handle_struct *handle,
        return afs_get_nt_acl(fsp, security_info, ppdesc);
 }
 
-BOOL afsacl_fset_nt_acl(vfs_handle_struct *handle,
+NTSTATUS afsacl_fset_nt_acl(vfs_handle_struct *handle,
                         files_struct *fsp,
                         int fd, uint32 security_info_sent,
                         SEC_DESC *psd)
@@ -1006,7 +1006,7 @@ BOOL afsacl_fset_nt_acl(vfs_handle_struct *handle,
        return afs_set_nt_acl(handle, fsp, security_info_sent, psd);
 }
 
-BOOL afsacl_set_nt_acl(vfs_handle_struct *handle,
+NTSTATUS afsacl_set_nt_acl(vfs_handle_struct *handle,
                       files_struct *fsp,
                       const char *name, uint32 security_info_sent,
                       SEC_DESC *psd)
index f1e116ec197e1d525c03aeec01b849c4d9e562b6..0ec2e6a5b3e4c23a925431db52cd4696aaec195a 100644 (file)
@@ -366,10 +366,10 @@ static BOOL aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
        return True;
 }
 
-static BOOL aixjfs2_set_nt_acl_common(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
+static NTSTATUS aixjfs2_set_nt_acl_common(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
 {
        acl_type_t      acl_type_info;
-       BOOL    result = False;
+       NTSTATUS        result = NT_STATUS_ACCESS_DENIED;
        int     rc;
 
        rc = aixjfs2_query_acl_support(
@@ -385,17 +385,17 @@ static BOOL aixjfs2_set_nt_acl_common(files_struct *fsp, uint32 security_info_se
        } else if (rc==1) { /* assume POSIX ACL - by default... */
                result = set_nt_acl(fsp, security_info_sent, psd);
        } else
-               result = False; /* query failed */
+               result = map_nt_error_from_unix(errno); /* query failed */
        
        return result;
 }
 
-BOOL aixjfs2_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
+NTSTATUS aixjfs2_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
 {
        return aixjfs2_set_nt_acl_common(fsp, security_info_sent, psd);
 }
 
-BOOL aixjfs2_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
+NTSTATUS aixjfs2_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
 {
        return aixjfs2_set_nt_acl_common(fsp, security_info_sent, psd);
 }
index ab99031e4d638c73935532c4f1d30b061cc65b5c..04dbec95b6b8fe478edb5af902bb653df9377a05 100644 (file)
@@ -184,7 +184,7 @@ static char *cap_realpath(vfs_handle_struct *handle, const char *path, char *res
        return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path);
 }
 
-static BOOL cap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor *psd)
+static NTSTATUS cap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor *psd)
 {
         pstring capname;
        capencode(capname, name);
index a32bd59d5c7f7cd5323f63dde19984c66aa700f2..a4a2f8f7bde8ca0fd10d0e2dfd387372fe293fe3 100644 (file)
@@ -238,7 +238,7 @@ static size_t catia_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                                       ppdesc);
 }
 
-static BOOL catia_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, 
+static NTSTATUS catia_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, 
                             const char *name, uint32 security_info_sent,
                             struct security_descriptor_info *psd)
 {
index 28fe4d4ea7827aef9e40b570d741d1d054dd93f4..930b7c850725986c1ae5482b5fb61e448852d8ce 100644 (file)
@@ -947,9 +947,9 @@ static size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, c
        return result;
 }
 
-static BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
+static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
 {
-       BOOL result;
+       NTSTATUS result;
 
        START_PROFILE(fset_nt_acl);
        result = set_nt_acl(fsp, security_info_sent, psd);
@@ -957,9 +957,9 @@ static BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, in
        return result;
 }
 
-static BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
+static NTSTATUS vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
 {
-       BOOL result;
+       NTSTATUS result;
 
        START_PROFILE(set_nt_acl);
        result = set_nt_acl(fsp, security_info_sent, psd);
index cd434f1951fd72cf1edaa4faeeffcc0001fff136..e76cb9fc23f2495e51192f6459c6c62edd7bb8a0 100644 (file)
@@ -191,10 +191,10 @@ static size_t smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct
 static size_t smb_full_audit_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                               const char *name, uint32 security_info,
                               SEC_DESC **ppdesc);
-static BOOL smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+static NTSTATUS smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                              int fd, uint32 security_info_sent,
                              SEC_DESC *psd);
-static BOOL smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+static NTSTATUS smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                             const char *name, uint32 security_info_sent,
                             SEC_DESC *psd);
 static int smb_full_audit_chmod_acl(vfs_handle_struct *handle,
@@ -1497,30 +1497,30 @@ static size_t smb_full_audit_get_nt_acl(vfs_handle_struct *handle, files_struct
        return result;
 }
 
-static BOOL smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+static NTSTATUS smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                              int fd, uint32 security_info_sent,
                              SEC_DESC *psd)
 {
-       BOOL result;
+       NTSTATUS result;
 
        result = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, fd, security_info_sent,
                                          psd);
 
-       do_log(SMB_VFS_OP_FSET_NT_ACL, result, handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", fsp->fsp_name);
 
        return result;
 }
 
-static BOOL smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+static NTSTATUS smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                             const char *name, uint32 security_info_sent,
                             SEC_DESC *psd)
 {
-       BOOL result;
+       NTSTATUS result;
 
        result = SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent,
                                         psd);
 
-       do_log(SMB_VFS_OP_SET_NT_ACL, result, handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_SET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", fsp->fsp_name);
 
        return result;
 }
index 3795a5d4a6333816eb4ff9f4914a715a5c516787..9c9503e7722312a7b5899398a2e964946c5b16bf 100644 (file)
@@ -334,14 +334,14 @@ static BOOL gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
        return True;
 }
 
-static BOOL gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
+static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
 {
        struct gpfs_acl *acl;
-       BOOL    result = False;
+       NTSTATUS result = NT_STATUS_ACCESS_DENIED;
 
        acl = gpfs_getacl_alloc(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS);
        if (acl == NULL)
-               return False;
+               return result;
 
        if (acl->acl_version&GPFS_ACL_VERSION_NFS4)
        {
@@ -355,12 +355,12 @@ static BOOL gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_info_
        return result;
 }
 
-static BOOL gpfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
+static NTSTATUS gpfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
 {
        return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd);
 }
 
-static BOOL gpfsacl_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, char *name, uint32 security_info_sent, SEC_DESC *psd)
+static NTSTATUS gpfsacl_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, char *name, uint32 security_info_sent, SEC_DESC *psd)
 {
        return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd);
 }
index 79602c2221116e99b19d83c6b97c32f5ecea6121..a68258cfdb968369faea842ca6f4b8549accd34a 100644 (file)
@@ -125,7 +125,7 @@ static BOOL zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
  * set the local file's acls obtaining it in NT form
  * using the NFSv4 format conversion
  */
-static BOOL zfs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+static NTSTATUS zfs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                           uint32 security_info_sent,
                           struct security_descriptor *psd)
 {
@@ -149,7 +149,7 @@ static size_t zfsacl_get_nt_acl(struct vfs_handle_struct *handle,
        return zfs_get_nt_acl(fsp, security_info, ppdesc);
 }
 
-static BOOL zfsacl_fset_nt_acl(vfs_handle_struct *handle,
+static NTSTATUS zfsacl_fset_nt_acl(vfs_handle_struct *handle,
                         files_struct *fsp,
                         int fd, uint32 security_info_sent,
                         SEC_DESC *psd)
@@ -157,7 +157,7 @@ static BOOL zfsacl_fset_nt_acl(vfs_handle_struct *handle,
        return zfs_set_nt_acl(handle, fsp, security_info_sent, psd);
 }
 
-static BOOL zfsacl_set_nt_acl(vfs_handle_struct *handle,
+static NTSTATUS zfsacl_set_nt_acl(vfs_handle_struct *handle,
                       files_struct *fsp,
                       const char *name, uint32 security_info_sent,
                       SEC_DESC *psd)
index 7132f92c9363008d87a58e575b5a1d2bfd7991b8..0573599a81b5416dabff44b632d03bd0839d7f3f 100644 (file)
@@ -2147,7 +2147,6 @@ error_exit:
 
 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r)
 {
-       BOOL ret;
        DATA_BLOB null_pw;
        files_struct *fsp = NULL;
        SMB_STRUCT_STAT st;
@@ -2215,9 +2214,9 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecur
                }
        }
 
-       ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd);
+       nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd);
 
-       if (ret == False) {
+       if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", r->in.file));
                status = WERR_ACCESS_DENIED;
                goto error_exit;
index 965da90a64d37ebde8c6e259a4f314febe38cf75..c13e35698bd89da2a2a48a39bcc3f38a2829afbd 100644 (file)
@@ -1062,7 +1062,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
        prs_struct pd;
        SEC_DESC *psd = NULL;
        TALLOC_CTX *mem_ctx;
-       BOOL ret;
+       NTSTATUS status;
        
        if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) {
                return NT_STATUS_OK;
@@ -1112,16 +1112,10 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
                security_info_sent &= ~DACL_SECURITY_INFORMATION;
        }
        
-       ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd);
-       
-       if (!ret) {
-               talloc_destroy(mem_ctx);
-               return NT_STATUS_ACCESS_DENIED;
-       }
+       status = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd);
        
        talloc_destroy(mem_ctx);
-       
-       return NT_STATUS_OK;
+       return status;
 }
 
 /****************************************************************************
index 7eda998547e650afad450ab250828a256fe81ac1..8db48ea6647c3fd4458bdaa49d34c56e35acb266 100644 (file)
@@ -923,7 +923,7 @@ static mode_t map_nt_perms( uint32 *mask, int type)
  Unpack a SEC_DESC into a UNIX owner and group.
 ****************************************************************************/
 
-BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, SEC_DESC *psd)
+NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, SEC_DESC *psd)
 {
        DOM_SID owner_sid;
        DOM_SID grp_sid;
@@ -933,7 +933,7 @@ BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_
 
        if(security_info_sent == 0) {
                DEBUG(0,("unpack_nt_owners: no security info sent !\n"));
-               return True;
+               return NT_STATUS_OK;
        }
 
        /*
@@ -961,9 +961,11 @@ BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_
                                DEBUG(3,("unpack_nt_owners: unable to validate"
                                         " owner sid for %s\n",
                                         sid_string_static(&owner_sid)));
-                               return False;
+                               return NT_STATUS_INVALID_OWNER;
                        }
                }
+               DEBUG(3,("unpack_nt_owners: owner sid mapped to uid %u\n",
+                        (unsigned int)*puser ));
        }
 
        /*
@@ -981,14 +983,16 @@ BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_
                        } else {
                                DEBUG(3,("unpack_nt_owners: unable to validate"
                                         " group sid.\n"));
-                               return False;
+                               return NT_STATUS_INVALID_OWNER;
                        }
                }
-       }
+               DEBUG(3,("unpack_nt_owners: group sid mapped to gid %u\n",
+                        (unsigned int)*pgrp));
+       }
 
        DEBUG(5,("unpack_nt_owners: owner_sids validated.\n"));
 
-       return True;
+       return NT_STATUS_OK;
 }
 
 /****************************************************************************
@@ -3049,6 +3053,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
 
        /* Case (4). */
        if (!lp_dos_filemode(SNUM(conn))) {
+               errno = EPERM;
                return -1;
        }
 
@@ -3082,7 +3087,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
  This should be the only external function needed for the UNIX style set ACL.
 ****************************************************************************/
 
-BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
+NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
 {
        connection_struct *conn = fsp->conn;
        uid_t user = (uid_t)-1;
@@ -3094,15 +3099,13 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
        canon_ace *dir_ace_list = NULL;
        BOOL acl_perms = False;
        mode_t orig_mode = (mode_t)0;
-       uid_t orig_uid;
-       gid_t orig_gid;
-       BOOL need_chown = False;
+       NTSTATUS status;
 
        DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name ));
 
        if (!CAN_WRITE(conn)) {
                DEBUG(10,("set acl rejected on read-only share\n"));
-               return False;
+               return NT_STATUS_MEDIA_WRITE_PROTECTED;
        }
 
        /*
@@ -3111,40 +3114,29 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
 
        if(fsp->is_directory || fsp->fh->fd == -1) {
                if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0)
-                       return False;
+                       return map_nt_error_from_unix(errno);
        } else {
                if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0)
-                       return False;
+                       return map_nt_error_from_unix(errno);
        }
 
        /* Save the original elements we check against. */
        orig_mode = sbuf.st_mode;
-       orig_uid = sbuf.st_uid;
-       orig_gid = sbuf.st_gid;
 
        /*
         * Unpack the user/group/world id's.
         */
 
-       if (!unpack_nt_owners( SNUM(conn), &user, &grp, security_info_sent, psd)) {
-               return False;
+       status = unpack_nt_owners( SNUM(conn), &user, &grp, security_info_sent, psd);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
        /*
         * Do we need to chown ?
         */
 
-       if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp))) {
-               need_chown = True;
-       }
-
-       /*
-        * Chown before setting ACL only if we don't change the user, or
-        * if we change to the current user, but not if we want to give away
-        * the file.
-        */
-
-       if (need_chown && (user == (uid_t)-1 || user == current_user.ut.uid)) {
+       if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) {
 
                DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
                                fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
@@ -3152,7 +3144,10 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
                if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) {
                        DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n",
                                fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
-                       return False;
+                       if (errno == EPERM) {
+                               return NT_STATUS_INVALID_OWNER;
+                       }
+                       return map_nt_error_from_unix(errno);
                }
 
                /*
@@ -3162,7 +3157,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
 
                if(fsp->is_directory) {
                        if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf) != 0) {
-                               return False;
+                               return map_nt_error_from_unix(errno);
                        }
                } else {
 
@@ -3174,16 +3169,11 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
                                ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf);
   
                        if(ret != 0)
-                               return False;
+                               return map_nt_error_from_unix(errno);
                }
 
                /* Save the original elements we check against. */
                orig_mode = sbuf.st_mode;
-               orig_uid = sbuf.st_uid;
-               orig_gid = sbuf.st_gid;
-
-               /* We did it, don't try again */
-               need_chown = False;
        }
 
        create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
@@ -3198,7 +3188,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
                        DEBUG(3,("set_nt_acl: cannot set permissions\n"));
                        free_canon_ace_list(file_ace_list);
                        free_canon_ace_list(dir_ace_list); 
-                       return False;
+                       return NT_STATUS_ACCESS_DENIED;
                }
 
                /*
@@ -3221,7 +3211,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
                                        DEBUG(3,("set_nt_acl: failed to set file acl on file %s (%s).\n", fsp->fsp_name, strerror(errno) ));
                                        free_canon_ace_list(file_ace_list);
                                        free_canon_ace_list(dir_ace_list); 
-                                       return False;
+                                       return map_nt_error_from_unix(errno);
                                }
                        }
 
@@ -3231,7 +3221,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
                                                DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) ));
                                                free_canon_ace_list(file_ace_list);
                                                free_canon_ace_list(dir_ace_list); 
-                                               return False;
+                                               return map_nt_error_from_unix(errno);
                                        }
                                } else {
 
@@ -3256,7 +3246,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
                                                        DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno)));
                                                        free_canon_ace_list(file_ace_list);
                                                        free_canon_ace_list(dir_ace_list);
-                                                       return False;
+                                                       return map_nt_error_from_unix(errno);
                                                }
                                        }
                                }
@@ -3279,7 +3269,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
                                        free_canon_ace_list(dir_ace_list);
                                        DEBUG(3,("set_nt_acl: failed to convert file acl to posix permissions for file %s.\n",
                                                fsp->fsp_name ));
-                                       return False;
+                                       return NT_STATUS_ACCESS_DENIED;
                                }
 
                                if (orig_mode != posix_perms) {
@@ -3304,7 +3294,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
                                                                fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) ));
                                                        free_canon_ace_list(file_ace_list);
                                                        free_canon_ace_list(dir_ace_list);
-                                                       return False;
+                                                       return map_nt_error_from_unix(errno);
                                                }
                                        }
                                }
@@ -3315,20 +3305,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
                free_canon_ace_list(dir_ace_list); 
        }
 
-       /* Any chown pending? */
-       if (need_chown) {
-
-               DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
-                       fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
-
-               if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) {
-                       DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n",
-                               fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
-                       return False;
-               }
-       }
-
-       return True;
+       return NT_STATUS_OK;
 }
 
 /****************************************************************************