}
}
+static int gpfs_getacl_with_capability(const char *fname, int flags, void *buf)
+{
+ int ret, saved_errno;
+
+ set_effective_capability(DAC_OVERRIDE_CAPABILITY);
+
+ ret = gpfswrap_getacl(discard_const_p(char, fname), flags, buf);
+ saved_errno = errno;
+
+ drop_effective_capability(DAC_OVERRIDE_CAPABILITY);
+
+ errno = saved_errno;
+ return ret;
+}
+
/*
* get the ACL from GPFS, allocated on the specified mem_ctx
* internally retries when initial buffer was too small
int ret, flags;
unsigned int *len;
size_t struct_size;
+ bool use_capability = false;
again:
/* set the length of the buffer as input value */
*len = size;
- errno = 0;
- ret = gpfswrap_getacl(discard_const_p(char, fname), flags, aclbuf);
+ if (use_capability) {
+ ret = gpfs_getacl_with_capability(fname, flags, aclbuf);
+ } else {
+ ret = gpfswrap_getacl(discard_const_p(char, fname),
+ flags, aclbuf);
+ if ((ret != 0) && (errno == EACCES)) {
+ DBG_DEBUG("Retry with DAC capability for %s\n", fname);
+ use_capability = true;
+ ret = gpfs_getacl_with_capability(fname, flags, aclbuf);
+ }
+ }
+
if ((ret != 0) && (errno == ENOSPC)) {
/*
* get the size needed to accommodate the complete buffer