s3-secdesc: remove "typedef struct security_descriptor SEC_DESC".
[samba.git] / source3 / modules / nfs4_acls.c
index ba038479af4b3356f2af92aad06e2a74c98bd8bc..3201fa5482bb642ee439187a1e40b58af4b618c9 100644 (file)
@@ -44,10 +44,10 @@ typedef struct _SMB_ACL4_INT_T
        SMB_ACE4_INT_T  *last;
 } SMB_ACL4_INT_T;
 
-static SMB_ACL4_INT_T *get_validated_aclint(SMB4ACL_T *acl)
+static SMB_ACL4_INT_T *get_validated_aclint(SMB4ACL_T *theacl)
 {
-       SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)acl;
-       if (acl==NULL)
+       SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)theacl;
+       if (theacl==NULL)
        {
                DEBUG(2, ("acl is NULL\n"));
                errno = EINVAL;
@@ -83,21 +83,21 @@ static SMB_ACE4_INT_T *get_validated_aceint(SMB4ACE_T *ace)
 SMB4ACL_T *smb_create_smb4acl(void)
 {
        TALLOC_CTX *mem_ctx = talloc_tos();
-       SMB_ACL4_INT_T  *acl = (SMB_ACL4_INT_T *)TALLOC_ZERO_SIZE(mem_ctx, sizeof(SMB_ACL4_INT_T));
-       if (acl==NULL)
+       SMB_ACL4_INT_T  *theacl = (SMB_ACL4_INT_T *)TALLOC_ZERO_SIZE(mem_ctx, sizeof(SMB_ACL4_INT_T));
+       if (theacl==NULL)
        {
                DEBUG(0, ("TALLOC_SIZE failed\n"));
                errno = ENOMEM;
                return NULL;
        }
-       acl->magic = SMB_ACL4_INT_MAGIC;
-       /* acl->first, last = NULL not needed */
-       return (SMB4ACL_T *)acl;
+       theacl->magic = SMB_ACL4_INT_MAGIC;
+       /* theacl->first, last = NULL not needed */
+       return (SMB4ACL_T *)theacl;
 }
 
-SMB4ACE_T *smb_add_ace4(SMB4ACL_T *acl, SMB_ACE4PROP_T *prop)
+SMB4ACE_T *smb_add_ace4(SMB4ACL_T *theacl, SMB_ACE4PROP_T *prop)
 {
-       SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
+       SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl);
        TALLOC_CTX *mem_ctx = talloc_tos();
        SMB_ACE4_INT_T *ace;
 
@@ -143,18 +143,18 @@ SMB4ACE_T *smb_next_ace4(SMB4ACE_T *ace)
        return (SMB4ACE_T *)aceint->next;
 }
 
-SMB4ACE_T *smb_first_ace4(SMB4ACL_T *acl)
+SMB4ACE_T *smb_first_ace4(SMB4ACL_T *theacl)
 {
-       SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
+       SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl);
        if (aclint==NULL)
                return NULL;
 
        return (SMB4ACE_T *)aclint->first;
 }
 
-uint32 smb_get_naces(SMB4ACL_T *acl)
+uint32 smb_get_naces(SMB4ACL_T *theacl)
 {
-       SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
+       SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl);
        if (aclint==NULL)
                return 0;
 
@@ -168,9 +168,9 @@ static int smbacl4_GetFileOwner(struct connection_struct *conn,
        memset(psbuf, 0, sizeof(SMB_STRUCT_STAT));
 
        /* Get the stat struct for the owner info. */
-       if (SMB_VFS_STAT(conn, filename, psbuf) != 0)
+       if (vfs_stat_smb_fname(conn, filename, psbuf) != 0)
        {
-               DEBUG(8, ("SMB_VFS_STAT failed with error %s\n",
+               DEBUG(8, ("vfs_stat_smb_fname failed with error %s\n",
                        strerror(errno)));
                return -1;
        }
@@ -183,7 +183,8 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf)
        memset(psbuf, 0, sizeof(SMB_STRUCT_STAT));
 
        if (fsp->is_directory || fsp->fh->fd == -1) {
-               return smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, psbuf);
+               return smbacl4_GetFileOwner(fsp->conn,
+                                           fsp->fsp_name->base_name, psbuf);
        }
        if (SMB_VFS_FSTAT(fsp, psbuf) != 0)
        {
@@ -195,25 +196,25 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf)
        return 0;
 }
 
-static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */
+static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *theacl, /* in */
        DOM_SID *psid_owner, /* in */
        DOM_SID *psid_group, /* in */
        bool is_directory, /* in */
-       SEC_ACE **ppnt_ace_list, /* out */
+       struct security_ace **ppnt_ace_list, /* out */
        int *pgood_aces /* out */
 )
 {
-       SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)acl;
+       SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)theacl;
        SMB_ACE4_INT_T *aceint;
-       SEC_ACE *nt_ace_list = NULL;
+       struct security_ace *nt_ace_list = NULL;
        int good_aces = 0;
 
-       DEBUG(10, ("smbacl_nfs42win entered"));
+       DEBUG(10, ("smbacl_nfs42win entered\n"));
 
-       aclint = get_validated_aclint(acl);
-       /* We do not check for naces being 0 or acl being NULL here because it is done upstream */
+       aclint = get_validated_aclint(theacl);
+       /* We do not check for naces being 0 or theacl being NULL here because it is done upstream */
        /* in smb_get_nt_acl_nfs4(). */
-       nt_ace_list = (SEC_ACE *)TALLOC_ZERO_SIZE(mem_ctx, aclint->naces * sizeof(SEC_ACE));
+       nt_ace_list = (struct security_ace *)TALLOC_ZERO_SIZE(mem_ctx, aclint->naces * sizeof(struct security_ace));
        if (nt_ace_list==NULL)
        {
                DEBUG(10, ("talloc error"));
@@ -225,6 +226,7 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */
                uint32_t mask;
                DOM_SID sid;
                SMB_ACE4PROP_T  *ace = &aceint->prop;
+               uint32_t mapped_ace_flags;
 
                DEBUG(10, ("magic: 0x%x, type: %d, iflags: %x, flags: %x, mask: %x, "
                        "who: %d\n", aceint->magic, ace->aceType, ace->flags,
@@ -261,10 +263,23 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */
                        ace->aceMask |= SMB_ACE4_DELETE_CHILD;
                }
 
+               mapped_ace_flags = ace->aceFlags & 0xf;
+               if (!is_directory && (mapped_ace_flags & (SMB_ACE4_FILE_INHERIT_ACE|SMB_ACE4_DIRECTORY_INHERIT_ACE))) {
+                       /*
+                        * GPFS sets inherits dir_inhert and file_inherit flags
+                        * to files, too, which confuses windows, and seems to
+                        * be wrong anyways. ==> Map these bits away for files.
+                        */
+                       DEBUG(10, ("removing inherit flags from nfs4 ace\n"));
+                       mapped_ace_flags &= ~(SMB_ACE4_FILE_INHERIT_ACE|SMB_ACE4_DIRECTORY_INHERIT_ACE);
+               }
+               DEBUG(10, ("mapped ace flags: 0x%x => 0x%x\n",
+                     ace->aceFlags, mapped_ace_flags));
+
                mask = ace->aceMask;
                init_sec_ace(&nt_ace_list[good_aces++], &sid,
                        ace->aceType, mask,
-                       ace->aceFlags & 0xf);
+                       mapped_ace_flags);
        }
 
        *ppnt_ace_list = nt_ace_list;
@@ -275,24 +290,25 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */
 
 static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
        uint32 security_info,
-       SEC_DESC **ppdesc, SMB4ACL_T *acl)
+       struct security_descriptor **ppdesc, SMB4ACL_T *theacl)
 {
        int     good_aces = 0;
        DOM_SID sid_owner, sid_group;
        size_t sd_size = 0;
-       SEC_ACE *nt_ace_list = NULL;
-       SEC_ACL *psa = NULL;
+       struct security_ace *nt_ace_list = NULL;
+       struct security_acl *psa = NULL;
        TALLOC_CTX *mem_ctx = talloc_tos();
 
-       if (acl==NULL || smb_get_naces(acl)==0)
+       if (theacl==NULL || smb_get_naces(theacl)==0)
                return NT_STATUS_ACCESS_DENIED; /* special because we
                                                 * shouldn't alloc 0 for
                                                 * win */
 
-       uid_to_sid(&sid_owner, sbuf->st_uid);
-       gid_to_sid(&sid_group, sbuf->st_gid);
+       uid_to_sid(&sid_owner, sbuf->st_ex_uid);
+       gid_to_sid(&sid_group, sbuf->st_ex_gid);
 
-       if (smbacl4_nfs42win(mem_ctx, acl, &sid_owner, &sid_group, S_ISDIR(sbuf->st_mode),
+       if (smbacl4_nfs42win(mem_ctx, theacl, &sid_owner, &sid_group,
+                            S_ISDIR(sbuf->st_ex_mode),
                                &nt_ace_list, &good_aces)==False) {
                DEBUG(8,("smbacl4_nfs42win failed\n"));
                return map_nt_error_from_unix(errno);
@@ -315,30 +331,30 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
        }
 
        DEBUG(10, ("smb_get_nt_acl_nfs4_common successfully exited with sd_size %d\n",
-                  ndr_size_security_descriptor(*ppdesc, 0)));
+                  (int)ndr_size_security_descriptor(*ppdesc, NULL, 0)));
 
        return NT_STATUS_OK;
 }
 
 NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp,
                               uint32 security_info,
-                              SEC_DESC **ppdesc, SMB4ACL_T *acl)
+                              struct security_descriptor **ppdesc, SMB4ACL_T *theacl)
 {
        SMB_STRUCT_STAT sbuf;
 
-       DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
+       DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp)));
 
        if (smbacl4_fGetFileOwner(fsp, &sbuf)) {
                return map_nt_error_from_unix(errno);
        }
 
-       return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, acl);
+       return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, theacl);
 }
 
 NTSTATUS smb_get_nt_acl_nfs4(struct connection_struct *conn,
                              const char *name,
                              uint32 security_info,
-                             SEC_DESC **ppdesc, SMB4ACL_T *acl)
+                             struct security_descriptor **ppdesc, SMB4ACL_T *theacl)
 {
        SMB_STRUCT_STAT sbuf;
 
@@ -348,7 +364,7 @@ NTSTATUS smb_get_nt_acl_nfs4(struct connection_struct *conn,
                return map_nt_error_from_unix(errno);
        }
 
-       return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, acl);
+       return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, theacl);
 }
 
 enum smbacl4_mode_enum {e_simple=0, e_special=1};
@@ -399,9 +415,9 @@ static int smbacl4_get_vfs_params(
        return 0;
 }
 
-static void smbacl4_dump_nfs4acl(int level, SMB4ACL_T *acl)
+static void smbacl4_dump_nfs4acl(int level, SMB4ACL_T *theacl)
 {
-       SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
+       SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl);
        SMB_ACE4_INT_T *aceint;
 
        DEBUG(level, ("NFS4ACL: size=%d\n", aclint->naces));
@@ -423,17 +439,24 @@ static void smbacl4_dump_nfs4acl(int level, SMB4ACL_T *acl)
  * return ace if found matching; otherwise NULL
  */
 static SMB_ACE4PROP_T *smbacl4_find_equal_special(
-       SMB4ACL_T *acl,
+       SMB4ACL_T *theacl,
        SMB_ACE4PROP_T *aceNew)
 {
-       SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
+       SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl);
        SMB_ACE4_INT_T *aceint;
 
        for(aceint = aclint->first; aceint!=NULL; aceint=(SMB_ACE4_INT_T *)aceint->next) {
                SMB_ACE4PROP_T *ace = &aceint->prop;
 
+                DEBUG(10,("ace type:0x%x flags:0x%x aceFlags:0x%x "
+                         "new type:0x%x flags:0x%x aceFlags:0x%x\n",
+                         ace->aceType, ace->flags, ace->aceFlags,
+                         aceNew->aceType, aceNew->flags,aceNew->aceFlags));
+
                if (ace->flags == aceNew->flags &&
                        ace->aceType==aceNew->aceType &&
+                       ((ace->aceFlags&SMB_ACE4_INHERIT_ONLY_ACE)==
+                        (aceNew->aceFlags&SMB_ACE4_INHERIT_ONLY_ACE)) &&
                        (ace->aceFlags&SMB_ACE4_IDENTIFIER_GROUP)==
                        (aceNew->aceFlags&SMB_ACE4_IDENTIFIER_GROUP)
                ) {
@@ -520,7 +543,7 @@ static bool smbacl4_fill_ace4(
        smbacl4_vfs_params *params,
        uid_t ownerUID,
        gid_t ownerGID,
-       const SEC_ACE *ace_nt, /* input */
+       const struct security_ace *ace_nt, /* input */
        SMB_ACE4PROP_T *ace_v4 /* output */
 )
 {
@@ -618,14 +641,14 @@ static bool smbacl4_fill_ace4(
 
 static int smbacl4_MergeIgnoreReject(
        enum smbacl4_acedup_enum acedup,
-       SMB4ACL_T *acl, /* may modify it */
+       SMB4ACL_T *theacl, /* may modify it */
        SMB_ACE4PROP_T *ace, /* the "new" ACE */
        bool    *paddNewACE,
        int     i
 )
 {
        int     result = 0;
-       SMB_ACE4PROP_T *ace4found = smbacl4_find_equal_special(acl, ace);
+       SMB_ACE4PROP_T *ace4found = smbacl4_find_equal_special(theacl, ace);
        if (ace4found)
        {
                switch(acedup)
@@ -652,20 +675,20 @@ static int smbacl4_MergeIgnoreReject(
 
 static SMB4ACL_T *smbacl4_win2nfs4(
        const char *filename,
-       const SEC_ACL *dacl,
+       const struct security_acl *dacl,
        smbacl4_vfs_params *pparams,
        uid_t ownerUID,
        gid_t ownerGID
 )
 {
-       SMB4ACL_T *acl;
+       SMB4ACL_T *theacl;
        uint32  i;
        TALLOC_CTX *mem_ctx = talloc_tos();
 
        DEBUG(10, ("smbacl4_win2nfs4 invoked\n"));
 
-       acl = smb_create_smb4acl();
-       if (acl==NULL)
+       theacl = smb_create_smb4acl();
+       if (theacl==NULL)
                return NULL;
 
        for(i=0; i<dacl->num_aces; i++) {
@@ -682,25 +705,25 @@ static SMB4ACL_T *smbacl4_win2nfs4(
                }
 
                if (pparams->acedup!=e_dontcare) {
-                       if (smbacl4_MergeIgnoreReject(pparams->acedup, acl,
+                       if (smbacl4_MergeIgnoreReject(pparams->acedup, theacl,
                                &ace_v4, &addNewACE, i))
                                return NULL;
                }
 
                if (addNewACE)
-                       smb_add_ace4(acl, &ace_v4);
+                       smb_add_ace4(theacl, &ace_v4);
        }
 
-       return acl;
+       return theacl;
 }
 
 NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
        uint32 security_info_sent,
-       const SEC_DESC *psd,
+       const struct security_descriptor *psd,
        set_nfs4acl_native_fn_t set_nfs4_native)
 {
        smbacl4_vfs_params params;
-       SMB4ACL_T *acl = NULL;
+       SMB4ACL_T *theacl = NULL;
        bool    result;
 
        SMB_STRUCT_STAT sbuf;
@@ -709,7 +732,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
        gid_t newGID = (gid_t)-1;
        int saved_errno;
 
-       DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
+       DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp)));
 
        if ((security_info_sent & (DACL_SECURITY_INFORMATION |
                GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION)) == 0)
@@ -728,23 +751,30 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
 
        if (params.do_chown) {
                /* chown logic is a copy/paste from posix_acl.c:set_nt_acl */
-               NTSTATUS status = unpack_nt_owners(SNUM(fsp->conn), &newUID, &newGID, security_info_sent, psd);
+               NTSTATUS status = unpack_nt_owners(fsp->conn, &newUID, &newGID, security_info_sent, psd);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(8, ("unpack_nt_owners failed"));
                        return status;
                }
-               if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) ||
-                   ((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, 
+               if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) ||
+                   ((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) {
+
+                       if(try_chown(fsp->conn, fsp->fsp_name, newUID,
+                                    newGID)) {
+                               DEBUG(3,("chown %s, %u, %u failed. Error = "
+                                        "%s.\n", fsp_str_dbg(fsp),
+                                        (unsigned int)newUID,
+                                        (unsigned int)newGID,
                                         strerror(errno)));
                                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->conn, fsp->fsp_name, &sbuf))
+                                 fsp_str_dbg(fsp), (unsigned int)newUID,
+                                 (unsigned int)newGID));
+                       if (smbacl4_GetFileOwner(fsp->conn,
+                                                fsp->fsp_name->base_name,
+                                                &sbuf))
                                return map_nt_error_from_unix(errno);
 
                        /* If we successfully chowned, we know we must
@@ -759,16 +789,17 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
                return NT_STATUS_OK;
        }
 
-       acl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
-       if (!acl)
+       theacl = smbacl4_win2nfs4(fsp->fsp_name->base_name, psd->dacl, &params,
+                                 sbuf.st_ex_uid, sbuf.st_ex_gid);
+       if (!theacl)
                return map_nt_error_from_unix(errno);
 
-       smbacl4_dump_nfs4acl(10, acl);
+       smbacl4_dump_nfs4acl(10, theacl);
 
        if (set_acl_as_root) {
                become_root();
        }
-       result = set_nfs4_native(fsp, acl);
+       result = set_nfs4_native(fsp, theacl);
        saved_errno = errno;
        if (set_acl_as_root) {
                unbecome_root();