diff options
author | Christian Ambach <ambi@samba.org> | 2012-11-05 19:26:57 +0100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2013-02-04 12:19:30 +0100 |
commit | f1ff845720604fc32788a59ec9a1a128135efe35 (patch) | |
tree | 547bc422a2278fbfc7a2587d056624dcceb4ce0b /source3/modules/vfs_gpfs.c | |
parent | d9075e19ca8c788824208ee1d77ad5861fe778ed (diff) | |
download | samba-f1ff845720604fc32788a59ec9a1a128135efe35.tar.gz samba-f1ff845720604fc32788a59ec9a1a128135efe35.tar.xz samba-f1ff845720604fc32788a59ec9a1a128135efe35.zip |
s3:vfs_gpfs add a generic vfs_gpfs_getacl function
in contrast to gpfs_getacl_alloc which always puts the
ACL on talloc_tos(), this one allows to specify the memory
context and if the caller is interested in the raw ACL blob
or a structured version
Signed-off-by: Christian Ambach <ambi@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source3/modules/vfs_gpfs.c')
-rw-r--r-- | source3/modules/vfs_gpfs.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index e2058e1832..c0d6fb2046 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -219,6 +219,79 @@ static void gpfs_dumpacl(int level, struct gpfs_acl *gacl) } } +/* + * get the ACL from GPFS, allocated on the specified mem_ctx + * internally retries when initial buffer was too small + * + * caller needs to cast result to either + * raw = yes: struct gpfs_opaque_acl + * raw = no: struct gpfs_acl + * + */ +static void *vfs_gpfs_getacl(TALLOC_CTX *mem_ctx, + const char *fname, + const bool raw, + const gpfs_aclType_t type) +{ + + void *aclbuf; + size_t size = 512; + int ret, flags; + unsigned int *len; + size_t struct_size; + +again: + + aclbuf = talloc_zero_size(mem_ctx, size); + if (aclbuf == NULL) { + errno = ENOMEM; + return NULL; + } + + if (raw) { + struct gpfs_opaque_acl *buf = (struct gpfs_opaque_acl *) aclbuf; + buf->acl_type = type; + flags = GPFS_GETACL_NATIVE; + len = (unsigned int *) &(buf->acl_buffer_len); + struct_size = sizeof(struct gpfs_opaque_acl); + } else { + struct gpfs_acl *buf = (struct gpfs_acl *) aclbuf; + buf->acl_type = type; + flags = GPFS_GETACL_STRUCT; + len = &(buf->acl_len); + struct_size = sizeof(struct gpfs_acl); + } + + /* set the length of the buffer as input value */ + *len = size; + + errno = 0; + ret = smbd_gpfs_getacl((char *)fname, flags, aclbuf); + if ((ret != 0) && (errno == ENOSPC)) { + /* + * get the size needed to accommodate the complete buffer + * + * the value returned only applies to the ACL blob in the + * struct so make sure to also have headroom for the first + * struct members by adding room for the complete struct + * (might be a few bytes too much then) + */ + size = *len + struct_size; + talloc_free(aclbuf); + DEBUG(10, ("Increasing ACL buffer size to %zu\n", size)); + goto again; + } + + if (ret != 0) { + DEBUG(5, ("smbd_gpfs_getacl failed with %s\n", + strerror(errno))); + talloc_free(aclbuf); + return NULL; + } + + return aclbuf; +} + static struct gpfs_acl *gpfs_getacl_alloc(const char *fname, gpfs_aclType_t type) { struct gpfs_acl *acl; |