vfs: Allocate SMB4ACL_T on an explict memory context
authorAndrew Bartlett <abartlet@samba.org>
Sun, 14 Apr 2013 08:13:42 +0000 (18:13 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 9 May 2013 04:18:20 +0000 (06:18 +0200)
This ensures the caller knows exactly what the memory lifetime of this
returned object is.  This makes the NFSv4 ACL code consistent with the
POSIX and NT ACL code, to avoid supprising developers who have worked
on those other parts of the ACL code.

Most of this patch is adding a memory context to the callers and passing it in.

Andrew Bartlett
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/nfs4_acls.c
source3/modules/nfs4_acls.h
source3/modules/vfs_aixacl2.c
source3/modules/vfs_gpfs.c
source3/modules/vfs_zfsacl.c

index fa9efc12e9257f1da76091797e9b170ff955d949..fa6b2fe2a00c9696e304cecb734025fc57ded65d 100644 (file)
@@ -142,9 +142,8 @@ static SMB_ACE4_INT_T *get_validated_aceint(SMB4ACE_T *ace)
        return aceint;
 }
 
-SMB4ACL_T *smb_create_smb4acl(void)
+SMB4ACL_T *smb_create_smb4acl(TALLOC_CTX *mem_ctx)
 {
-       TALLOC_CTX *mem_ctx = talloc_tos();
        SMB_ACL4_INT_T  *theacl = (SMB_ACL4_INT_T *)TALLOC_ZERO_SIZE(
                mem_ctx, sizeof(SMB_ACL4_INT_T));
        if (theacl==NULL)
@@ -379,10 +378,12 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
        struct security_acl *psa = NULL;
        TALLOC_CTX *frame = talloc_stackframe();
 
-       if (theacl==NULL || smb_get_naces(theacl)==0)
+       if (theacl==NULL || smb_get_naces(theacl)==0) {
+               TALLOC_FREE(frame);
                return NT_STATUS_ACCESS_DENIED; /* special because we
                                                 * shouldn't alloc 0 for
                                                 * win */
+       }
 
        uid_to_sid(&sid_owner, sbuf->st_ex_uid);
        gid_to_sid(&sid_group, sbuf->st_ex_gid);
@@ -691,6 +692,7 @@ static int smbacl4_MergeIgnoreReject(
 }
 
 static SMB4ACL_T *smbacl4_win2nfs4(
+       TALLOC_CTX *mem_ctx,
        const files_struct *fsp,
        const struct security_acl *dacl,
        smbacl4_vfs_params *pparams,
@@ -704,7 +706,7 @@ static SMB4ACL_T *smbacl4_win2nfs4(
 
        DEBUG(10, ("smbacl4_win2nfs4 invoked\n"));
 
-       theacl = smb_create_smb4acl();
+       theacl = smb_create_smb4acl(mem_ctx);
        if (theacl==NULL)
                return NULL;
 
@@ -748,6 +750,7 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
        uid_t newUID = (uid_t)-1;
        gid_t newGID = (gid_t)-1;
        int saved_errno;
+       TALLOC_CTX *frame = talloc_stackframe();
 
        DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp)));
 
@@ -756,16 +759,21 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
        {
                DEBUG(9, ("security_info_sent (0x%x) ignored\n",
                        security_info_sent));
+               TALLOC_FREE(frame);
                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))
+       if (smbacl4_get_vfs_params(SMBACL4_PARAM_TYPE_NAME, fsp, &params)) {
+               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
+       }
 
-       if (smbacl4_fGetFileOwner(fsp, &sbuf))
+       if (smbacl4_fGetFileOwner(fsp, &sbuf)) {
+               TALLOC_FREE(frame);
                return map_nt_error_from_unix(errno);
+       }
 
        if (params.do_chown) {
                /* chown logic is a copy/paste from posix_acl.c:set_nt_acl */
@@ -773,6 +781,7 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
                                                   security_info_sent, psd);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(8, ("unpack_nt_owners failed"));
+                       TALLOC_FREE(frame);
                        return status;
                }
                if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) ||
@@ -785,6 +794,7 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
                                         (unsigned int)newUID,
                                         (unsigned int)newGID,
                                         nt_errstr(status)));
+                               TALLOC_FREE(frame);
                                return status;
                        }
 
@@ -794,6 +804,7 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
                        if (smbacl4_GetFileOwner(fsp->conn,
                                                 fsp->fsp_name->base_name,
                                                 &sbuf))
+                               TALLOC_FREE(frame);
                                return map_nt_error_from_unix(errno);
 
                        /* If we successfully chowned, we know we must
@@ -806,13 +817,16 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
        if (!(security_info_sent & SECINFO_DACL) || psd->dacl ==NULL) {
                DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n",
                           security_info_sent));
+               TALLOC_FREE(frame);
                return NT_STATUS_OK;
        }
 
-       theacl = smbacl4_win2nfs4(fsp, psd->dacl, &params,
+       theacl = smbacl4_win2nfs4(frame, fsp, psd->dacl, &params,
                                  sbuf.st_ex_uid, sbuf.st_ex_gid);
-       if (!theacl)
+       if (!theacl) {
+               TALLOC_FREE(frame);
                return map_nt_error_from_unix(errno);
+       }
 
        smbacl4_dump_nfs4acl(10, theacl);
 
@@ -824,6 +838,9 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp,
        if (set_acl_as_root) {
                unbecome_root();
        }
+
+       TALLOC_FREE(frame);
+
        if (result!=True) {
                errno = saved_errno;
                DEBUG(10, ("set_nfs4_native failed with %s\n",
index f45039636160cc2b37026bbc200ec5a4ad6c2d10..1bde81baf0dada5105fd4c25b47a842ae04f45df 100644 (file)
@@ -114,7 +114,7 @@ typedef struct _SMB_ACE4PROP_T {
 typedef struct _SMB4ACL_T {char dontuse;} SMB4ACL_T;
 typedef struct _SMB4ACE_T {char dontuse;} SMB4ACE_T;
 
-SMB4ACL_T *smb_create_smb4acl(void);
+SMB4ACL_T *smb_create_smb4acl(TALLOC_CTX *mem_ctx);
 
 /* prop's contents are copied */
 /* it doesn't change the order, appends */
index aca7a652d6613a64194ab9da5032c801a912056b..c97cd577f2cf07a28f83ef8295b55e4f6020aaba 100644 (file)
@@ -93,7 +93,7 @@ static AIXJFS2_ACL_T *aixjfs2_getacl_alloc(const char *fname, acl_type_t *type)
        return acl;
 }
 
-static bool aixjfs2_get_nfs4_acl(const char *name,
+static bool aixjfs2_get_nfs4_acl(TALLOC_CTX *mem_ctx, const char *name
        SMB4ACL_T **ppacl, bool *pretryPosix)
 {
        int32_t i;
@@ -121,7 +121,7 @@ static bool aixjfs2_get_nfs4_acl(const char *name,
        DEBUG(10, ("len: %d, version: %d, nace: %d, type: 0x%x\n",
                        jfs2_acl->aclLength, jfs2_acl->aclVersion, jfs2_acl->aclEntryN, type.u64));
 
-       *ppacl = smb_create_smb4acl();
+       *ppacl = smb_create_smb4acl(mem_ctx);
        if (*ppacl==NULL)
                return False;
 
@@ -158,15 +158,18 @@ static NTSTATUS aixjfs2_fget_nt_acl(vfs_handle_struct *handle,
        TALLOC_CTX *mem_ctx,
        struct security_descriptor **ppdesc)
 {
+       NTSTATUS status;
        SMB4ACL_T *pacl = NULL;
        bool    result;
        bool    retryPosix = False;
+       TALLOC_CTX *frame = talloc_stackframe();
 
        *ppdesc = NULL;
-       result = aixjfs2_get_nfs4_acl(fsp->fsp_name->base_name, &pacl,
+       result = aixjfs2_get_nfs4_acl(frame, fsp->fsp_name->base_name, &pacl,
                                      &retryPosix);
        if (retryPosix)
        {
+               TALLOC_FREE(frame);
                DEBUG(10, ("retrying with posix acl...\n"));
                return posix_fget_nt_acl(fsp, security_info,
                                         mem_ctx, ppdesc);
@@ -174,8 +177,10 @@ static NTSTATUS aixjfs2_fget_nt_acl(vfs_handle_struct *handle,
        if (result==False)
                return NT_STATUS_ACCESS_DENIED;
 
-       return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc,
-                                   mem_ctx, pacl);
+       status = smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc,
+                                     mem_ctx, pacl);
+       TALLOC_FREE(frame);
+       return status;
 }
 
 static NTSTATUS aixjfs2_get_nt_acl(vfs_handle_struct *handle,
index 33a81a026259108ec070375dea1b4c1b8df54a17..39f4bb9437e8c0eb6e02419f981d87931e72b599 100644 (file)
@@ -299,7 +299,7 @@ again:
  * On failure returns -1 if there is system (GPFS) error, check errno.
  * Returns 0 on success
  */
-static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl)
+static int gpfs_get_nfs4_acl(TALLOC_CTX *mem_ctx, const char *fname, SMB4ACL_T **ppacl)
 {
        gpfs_aclCount_t i;
        struct gpfs_acl *gacl = NULL;
@@ -321,7 +321,7 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl)
                return 1;
        }
 
-       *ppacl = smb_create_smb4acl();
+       *ppacl = smb_create_smb4acl(mem_ctx);
 
        DEBUG(10, ("len: %d, level: %d, version: %d, nace: %d\n",
                   gacl->acl_len, gacl->acl_level, gacl->acl_version,
@@ -399,20 +399,30 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle,
                                return NT_STATUS_INTERNAL_ERROR);
 
        if (!config->acl) {
-               return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info,
-                                               mem_ctx, ppdesc);
+               status = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info,
+                                                 mem_ctx, ppdesc);
+               TALLOC_FREE(frame);
+               return status;
        }
 
-       result = gpfs_get_nfs4_acl(fsp->fsp_name->base_name, &pacl);
+       result = gpfs_get_nfs4_acl(frame, fsp->fsp_name->base_name, &pacl);
 
-       if (result == 0)
-               return smb_fget_nt_acl_nfs4(fsp, security_info, mem_ctx, ppdesc, pacl);
+       if (result == 0) {
+               statys = smb_fget_nt_acl_nfs4(fsp, security_info, mem_ctx, ppdesc, pacl);
+               TALLOC_FREE(frame);
+               return status;
+       }
 
        if (result > 0) {
                DEBUG(10, ("retrying with posix acl...\n"));
-               return posix_fget_nt_acl(fsp, security_info, mem_ctx, ppdesc);
+               status = posix_fget_nt_acl(fsp, security_info, mem_ctx, ppdesc);
+               TALLOC_FREE(frame);
+               return status;
+
        }
 
+       TALLOC_FREE(frame);
+
        /* GPFS ACL was not read, something wrong happened, error code is set in errno */
        return map_nt_error_from_unix(errno);
 }
@@ -425,6 +435,8 @@ static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle,
        SMB4ACL_T *pacl = NULL;
        int     result;
        struct gpfs_config_data *config;
+       TALLOC_CTX *frame = talloc_stackframe();
+       NTSTATUS status;
 
        *ppdesc = NULL;
 
index 91e31e9c4e00f10d3428d0bde1c7c484662b9131..743f33b821a9080e095336f8c2acc288bcfe48c3 100644 (file)
  * read the local file's acls and return it in NT form
  * using the NFSv4 format conversion
  */
-static NTSTATUS zfs_get_nt_acl_common(const char *name,
+static NTSTATUS zfs_get_nt_acl_common(TALLOC_CTX *mem_ctx,
+                                     const char *name,
                                      uint32 security_info,
                                      SMB4ACL_T **ppacl)
 {
        int naces, i;
        ace_t *acebuf;
        SMB4ACL_T *pacl;
-       TALLOC_CTX      *mem_ctx;
 
        /* read the number of file aces */
        if((naces = acl(name, ACE_GETACLCNT, 0, NULL)) == -1) {
@@ -74,7 +74,7 @@ static NTSTATUS zfs_get_nt_acl_common(const char *name,
                return map_nt_error_from_unix(errno);
        }
        /* create SMB4ACL data */
-       if((pacl = smb_create_smb4acl()) == NULL) {
+       if((pacl = smb_create_smb4acl(mem_ctx)) == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
        for(i=0; i<naces; i++) {
@@ -199,15 +199,20 @@ static NTSTATUS zfsacl_fget_nt_acl(struct vfs_handle_struct *handle,
 {
        SMB4ACL_T *pacl;
        NTSTATUS status;
+       TALLOC_CTX *frame = talloc_stackframe();
 
-       status = zfs_get_nt_acl_common(fsp->fsp_name->base_name,
+       status = zfs_get_nt_acl_common(frame,
+                                      fsp->fsp_name->base_name,
                                       security_info,
                                       &pacl);
        if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
                return status;
        }
 
-       return smb_fget_nt_acl_nfs4(fsp, security_info, mem_ctx, ppdesc, pacl);
+       status = smb_fget_nt_acl_nfs4(fsp, security_info, mem_ctx, ppdesc, pacl);
+       TALLOC_FREE(frame);
+       return status;
 }
 
 static NTSTATUS zfsacl_get_nt_acl(struct vfs_handle_struct *handle,
@@ -217,15 +222,19 @@ static NTSTATUS zfsacl_get_nt_acl(struct vfs_handle_struct *handle,
 {
        SMB4ACL_T *pacl;
        NTSTATUS status;
+       TALLOC_CTX *frame = talloc_stackframe();
 
-       status = zfs_get_nt_acl_common(name, security_info, &pacl);
+       status = zfs_get_nt_acl_common(frame, name, security_info, &pacl);
        if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
                return status;
        }
 
-       return smb_get_nt_acl_nfs4(handle->conn, name, security_info,
-                                  mem_ctx, ppdesc,
-                                  pacl);
+       status = smb_get_nt_acl_nfs4(handle->conn, name, security_info,
+                                    mem_ctx, ppdesc,
+                                    pacl);
+       TALLOC_FREE(frame);
+       return status;
 }
 
 static NTSTATUS zfsacl_fset_nt_acl(vfs_handle_struct *handle,
@@ -269,13 +278,15 @@ static NTSTATUS zfsacl_fset_nt_acl(vfs_handle_struct *handle,
 
 static SMB_ACL_T zfsacl_fail__sys_acl_get_file(vfs_handle_struct *handle,
                                               const char *path_p,
-                                              SMB_ACL_TYPE_T type)
+                                              SMB_ACL_TYPE_T type,
+                                              TALLOC_CTX *mem_ctx)
 {
        return (SMB_ACL_T)NULL;
 }
 
 static SMB_ACL_T zfsacl_fail__sys_acl_get_fd(vfs_handle_struct *handle,
-                                            files_struct *fsp)
+                                            files_struct *fsp,
+                                            TALLOC_CTX *mem_ctx)
 {
        return (SMB_ACL_T)NULL;
 }