mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
vfs: Store ACL control flags in gpfs vfs module.
Use literals to allow a compile and execution on gpfs 3.4. Signed-off-by: Alexander Werth <alexander.werth@de.ibm.com> Reviewed-by: Christof Schmitt <cs@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
a5d5bdc36b
commit
69b7631ca7
@ -52,6 +52,24 @@ struct gpfs_config_data {
|
||||
bool recalls;
|
||||
};
|
||||
|
||||
static inline unsigned int gpfs_acl_flags(gpfs_acl_t *gacl)
|
||||
{
|
||||
if (gacl->acl_level == 1) { /* GPFS_ACL_LEVEL_V4FLAGS */
|
||||
/* gacl->v4Level1.acl_flags requires gpfs 3.5 */
|
||||
return *(unsigned int *)&gacl->ace_v4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline gpfs_ace_v4_t *gpfs_ace_ptr(gpfs_acl_t *gacl, unsigned int i)
|
||||
{
|
||||
if (gacl->acl_level == 1) { /* GPFS_ACL_LEVEL_V4FLAGS */
|
||||
/* &gacl->v4Level1.ace_v4[i] requires gpfs 3.5 */
|
||||
char *ptr = (char *)&gacl->ace_v4[i] + sizeof(unsigned int);
|
||||
return (gpfs_ace_v4_t *)ptr;
|
||||
}
|
||||
return &gacl->ace_v4[i];
|
||||
}
|
||||
|
||||
static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
|
||||
uint32 share_mode, uint32 access_mask)
|
||||
@ -208,6 +226,34 @@ static int vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sd2gpfs_control(uint16_t control, struct gpfs_acl *gacl)
|
||||
{
|
||||
unsigned int gpfs_aclflags = 0;
|
||||
control &= SEC_DESC_DACL_PROTECTED | SEC_DESC_SACL_PROTECTED |
|
||||
SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_SACL_AUTO_INHERITED |
|
||||
SEC_DESC_DACL_DEFAULTED | SEC_DESC_SACL_DEFAULTED |
|
||||
SEC_DESC_DACL_PRESENT | SEC_DESC_SACL_PRESENT;
|
||||
gpfs_aclflags = control << 8;
|
||||
if (!(control & SEC_DESC_DACL_PRESENT))
|
||||
gpfs_aclflags |= 0x00800000; /* ACL4_FLAG_NULL_DACL; */
|
||||
if (!(control & SEC_DESC_SACL_PRESENT))
|
||||
gpfs_aclflags |= 0x01000000; /* ACL4_FLAG_NULL_SACL; */
|
||||
gacl->acl_level = 1; /* GPFS_ACL_LEVEL_V4FLAGS*/
|
||||
/* gacl->v4Level1.acl_flags requires gpfs 3.5 */
|
||||
*(unsigned int *)&gacl->ace_v4 = gpfs_aclflags;
|
||||
}
|
||||
|
||||
static uint16_t gpfs2sd_control(unsigned int gpfs_aclflags)
|
||||
{
|
||||
uint16_t control = gpfs_aclflags >> 8;
|
||||
control &= SEC_DESC_DACL_PROTECTED | SEC_DESC_SACL_PROTECTED |
|
||||
SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_SACL_AUTO_INHERITED |
|
||||
SEC_DESC_DACL_DEFAULTED | SEC_DESC_SACL_DEFAULTED |
|
||||
SEC_DESC_DACL_PRESENT | SEC_DESC_SACL_PRESENT;
|
||||
control |= SEC_DESC_SELF_RELATIVE;
|
||||
return control;
|
||||
}
|
||||
|
||||
static void gpfs_dumpacl(int level, struct gpfs_acl *gacl)
|
||||
{
|
||||
gpfs_aclCount_t i;
|
||||
@ -217,14 +263,18 @@ static void gpfs_dumpacl(int level, struct gpfs_acl *gacl)
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(level, ("gpfs acl: nace: %d, type:%d, version:%d, level:%d, len:%d\n",
|
||||
gacl->acl_nace, gacl->acl_type, gacl->acl_version, gacl->acl_level, gacl->acl_len));
|
||||
DEBUG(level, ("len: %d, level: %d, version: %d, nace: %d, "
|
||||
"control: %x\n",
|
||||
gacl->acl_len, gacl->acl_level, gacl->acl_version,
|
||||
gacl->acl_nace, gpfs_acl_flags(gacl)));
|
||||
|
||||
for(i=0; i<gacl->acl_nace; i++)
|
||||
{
|
||||
struct gpfs_ace_v4 *gace = gacl->ace_v4 + i;
|
||||
DEBUG(level, ("\tace[%d]: type:%d, flags:0x%x, mask:0x%x, iflags:0x%x, who:%u\n",
|
||||
i, gace->aceType, gace->aceFlags, gace->aceMask,
|
||||
gace->aceIFlags, gace->aceWho));
|
||||
struct gpfs_ace_v4 *gace = gpfs_ace_ptr(gacl, i);
|
||||
DEBUG(level, ("\tace[%d]: type:%d, flags:0x%x, mask:0x%x, "
|
||||
"iflags:0x%x, who:%u\n",
|
||||
i, gace->aceType, gace->aceFlags, gace->aceMask,
|
||||
gace->aceIFlags, gace->aceWho));
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,9 +316,11 @@ again:
|
||||
} else {
|
||||
struct gpfs_acl *buf = (struct gpfs_acl *) aclbuf;
|
||||
buf->acl_type = type;
|
||||
buf->acl_level = 1; /* GPFS_ACL_LEVEL_V4FLAGS */
|
||||
flags = GPFS_GETACL_STRUCT;
|
||||
len = &(buf->acl_len);
|
||||
struct_size = sizeof(struct gpfs_acl);
|
||||
/* reserve space for control flags in gpfs 3.5 and beyond */
|
||||
struct_size = sizeof(struct gpfs_acl) + sizeof(unsigned int);
|
||||
}
|
||||
|
||||
/* set the length of the buffer as input value */
|
||||
@ -331,12 +383,17 @@ static int gpfs_get_nfs4_acl(TALLOC_CTX *mem_ctx, const char *fname, SMB4ACL_T *
|
||||
|
||||
*ppacl = smb_create_smb4acl(mem_ctx);
|
||||
|
||||
DEBUG(10, ("len: %d, level: %d, version: %d, nace: %d\n",
|
||||
if (gacl->acl_level == 1) { /* GPFS_ACL_LEVEL_V4FLAGS */
|
||||
uint16_t control = gpfs2sd_control(gpfs_acl_flags(gacl));
|
||||
smbacl4_set_controlflags(*ppacl, control);
|
||||
}
|
||||
|
||||
DEBUG(10, ("len: %d, level: %d, version: %d, nace: %d, control: %x\n",
|
||||
gacl->acl_len, gacl->acl_level, gacl->acl_version,
|
||||
gacl->acl_nace));
|
||||
gacl->acl_nace, gpfs_acl_flags(gacl)));
|
||||
|
||||
for (i=0; i<gacl->acl_nace; i++) {
|
||||
struct gpfs_ace_v4 *gace = &gacl->ace_v4[i];
|
||||
struct gpfs_ace_v4 *gace = gpfs_ace_ptr(gacl, i);
|
||||
SMB_ACE4PROP_T smbace;
|
||||
DEBUG(10, ("type: %d, iflags: %x, flags: %x, mask: %x, "
|
||||
"who: %d\n", gace->aceType, gace->aceIFlags,
|
||||
@ -369,7 +426,7 @@ static int gpfs_get_nfs4_acl(TALLOC_CTX *mem_ctx, const char *fname, SMB4ACL_T *
|
||||
|
||||
/* remove redundant deny entries */
|
||||
if (i > 0 && gace->aceType == SMB_ACE4_ACCESS_DENIED_ACE_TYPE) {
|
||||
struct gpfs_ace_v4 *prev = &gacl->ace_v4[i-1];
|
||||
struct gpfs_ace_v4 *prev = gpfs_ace_ptr(gacl, i - 1);
|
||||
if (prev->aceType == SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE &&
|
||||
prev->aceFlags == gace->aceFlags &&
|
||||
prev->aceIFlags == gace->aceIFlags &&
|
||||
@ -377,7 +434,7 @@ static int gpfs_get_nfs4_acl(TALLOC_CTX *mem_ctx, const char *fname, SMB4ACL_T *
|
||||
gace->aceWho == prev->aceWho) {
|
||||
/* it's redundant - skip it */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
smbace.aceType = gace->aceType;
|
||||
@ -484,32 +541,37 @@ static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle,
|
||||
return map_nt_error_from_unix(errno);
|
||||
}
|
||||
|
||||
static bool gpfsacl_process_smbacl(vfs_handle_struct *handle, files_struct *fsp, SMB4ACL_T *smbacl)
|
||||
static struct gpfs_acl *vfs_gpfs_smbacl2gpfsacl(TALLOC_CTX *mem_ctx,
|
||||
files_struct *fsp,
|
||||
SMB4ACL_T *smbacl,
|
||||
bool controlflags)
|
||||
{
|
||||
int ret;
|
||||
gpfs_aclLen_t gacl_len;
|
||||
SMB4ACE_T *smbace;
|
||||
struct gpfs_acl *gacl;
|
||||
TALLOC_CTX *mem_ctx = talloc_tos();
|
||||
gpfs_aclLen_t gacl_len;
|
||||
SMB4ACE_T *smbace;
|
||||
|
||||
gacl_len = offsetof(gpfs_acl_t, ace_v4) + smb_get_naces(smbacl) *
|
||||
sizeof(gpfs_ace_v4_t);
|
||||
gacl_len = offsetof(gpfs_acl_t, ace_v4) + sizeof(unsigned int)
|
||||
+ smb_get_naces(smbacl) * sizeof(gpfs_ace_v4_t);
|
||||
|
||||
gacl = (struct gpfs_acl *)TALLOC_SIZE(mem_ctx, gacl_len);
|
||||
if (gacl == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
errno = ENOMEM;
|
||||
return False;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gacl->acl_len = gacl_len;
|
||||
gacl->acl_level = 0;
|
||||
gacl->acl_level = 0; /* GPFS_ACL_LEVEL_BASE */
|
||||
gacl->acl_version = GPFS_ACL_VERSION_NFS4;
|
||||
gacl->acl_type = GPFS_ACL_TYPE_NFS4;
|
||||
gacl->acl_nace = 0; /* change later... */
|
||||
|
||||
if (controlflags) {
|
||||
gacl->acl_level = 1; /* GPFS_ACL_LEVEL_V4FLAGS */
|
||||
sd2gpfs_control(smbacl4_get_controlflags(smbacl), gacl);
|
||||
}
|
||||
|
||||
for (smbace=smb_first_ace4(smbacl); smbace!=NULL; smbace = smb_next_ace4(smbace)) {
|
||||
struct gpfs_ace_v4 *gace = &gacl->ace_v4[gacl->acl_nace];
|
||||
struct gpfs_ace_v4 *gace = gpfs_ace_ptr(gacl, gacl->acl_nace);
|
||||
SMB_ACE4PROP_T *aceprop = smb_get_ace4(smbace);
|
||||
|
||||
gace->aceType = aceprop->aceType;
|
||||
@ -567,9 +629,38 @@ static bool gpfsacl_process_smbacl(vfs_handle_struct *handle, files_struct *fsp,
|
||||
|
||||
gacl->acl_nace++;
|
||||
}
|
||||
gacl->acl_len = (char *)gpfs_ace_ptr(gacl, gacl->acl_nace)
|
||||
- (char *)gacl;
|
||||
return gacl;
|
||||
}
|
||||
|
||||
static bool gpfsacl_process_smbacl(vfs_handle_struct *handle,
|
||||
files_struct *fsp,
|
||||
SMB4ACL_T *smbacl)
|
||||
{
|
||||
int ret;
|
||||
struct gpfs_acl *gacl;
|
||||
TALLOC_CTX *mem_ctx = talloc_tos();
|
||||
|
||||
gacl = vfs_gpfs_smbacl2gpfsacl(mem_ctx, fsp, smbacl, true);
|
||||
if (gacl == NULL) { /* out of memory */
|
||||
return False;
|
||||
}
|
||||
ret = smbd_gpfs_putacl(fsp->fsp_name->base_name,
|
||||
GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl);
|
||||
|
||||
if ((ret != 0) && (errno == EINVAL)) {
|
||||
DEBUG(10, ("Retry without nfs41 control flags\n"));
|
||||
talloc_free(gacl);
|
||||
gacl = vfs_gpfs_smbacl2gpfsacl(mem_ctx, fsp, smbacl, false);
|
||||
if (gacl == NULL) { /* out of memory */
|
||||
return False;
|
||||
}
|
||||
ret = smbd_gpfs_putacl(fsp->fsp_name->base_name,
|
||||
GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA,
|
||||
gacl);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
DEBUG(8, ("gpfs_putacl failed with %s\n", strerror(errno)));
|
||||
gpfs_dumpacl(8, gacl);
|
||||
|
Loading…
Reference in New Issue
Block a user