/* Covert GPFS NFS4 ACLs to FSAL ACLs, and set the ACL * pointer of attribute. */ static int gpfs_acl_2_fsal_acl(struct attrlist * p_object_attributes, gpfs_acl_t *p_gpfsacl) { fsal_acl_status_t status; fsal_acl_data_t acldata; fsal_ace_t *pace; fsal_acl_t *pacl; gpfs_ace_v4_t *pace_gpfs; /* sanity checks */ if(!p_object_attributes || !p_gpfsacl) return ERR_FSAL_FAULT; /* Create fsal acl data. */ acldata.naces = p_gpfsacl->acl_nace; acldata.aces = (fsal_ace_t *)nfs4_ace_alloc(acldata.naces); /* Fill fsal acl data from gpfs acl. */ for(pace = acldata.aces, pace_gpfs = p_gpfsacl->ace_v4; pace < acldata.aces + acldata.naces; pace++, pace_gpfs++) { pace->type = pace_gpfs->aceType; pace->flag = pace_gpfs->aceFlags; pace->iflag = pace_gpfs->aceIFlags; pace->perm = pace_gpfs->aceMask; if(IS_FSAL_ACE_SPECIAL_ID(*pace)) /* Record special user. */ { pace->who.uid = pace_gpfs->aceWho; } else { if(IS_FSAL_ACE_GROUP_ID(*pace)) /* Record group. */ pace->who.gid = pace_gpfs->aceWho; else /* Record user. */ pace->who.uid = pace_gpfs->aceWho; } LogDebug(COMPONENT_FSAL, "gpfs_acl_2_fsal_acl: fsal ace: type = 0x%x, flag = 0x%x, perm = 0x%x, special = %d, %s = 0x%x", pace->type, pace->flag, pace->perm, IS_FSAL_ACE_SPECIAL_ID(*pace), GET_FSAL_ACE_WHO_TYPE(*pace), GET_FSAL_ACE_WHO(*pace)); } /* Create a new hash table entry for fsal acl. */ pacl = nfs4_acl_new_entry(&acldata, &status); LogDebug(COMPONENT_FSAL, "fsal acl = %p, fsal_acl_status = %u", pacl, status); if(pacl == NULL) { LogCrit(COMPONENT_FSAL, "gpfs_acl_2_fsal_acl: failed to create a new acl entry"); return ERR_FSAL_FAULT; } /* Add fsal acl to attribute. */ p_object_attributes->acl = pacl; return ERR_FSAL_NO_ERROR; }
fsal_acl_t *lzfs_int_convert_lzfs_acl(const liz_acl_t *lzfs_acl) { fsal_acl_data_t acl_data; fsal_acl_status_t acl_status; fsal_acl_t *fsal_acl = NULL; if (!lzfs_acl) { return NULL; } acl_data.naces = liz_get_acl_size(lzfs_acl); acl_data.aces = (fsal_ace_t *)nfs4_ace_alloc(acl_data.naces); if (!acl_data.aces) { return NULL; } for (unsigned i = 0; i < acl_data.naces; ++i) { fsal_ace_t *fsal_ace = acl_data.aces + i; liz_acl_ace_t lzfs_ace; int rc = liz_get_acl_entry(lzfs_acl, i, &lzfs_ace); (void)rc; assert(rc == 0); fsal_ace->type = lzfs_ace.type; fsal_ace->flag = lzfs_ace.flags & 0xFF; fsal_ace->iflag = (lzfs_ace.flags & LIZ_ACL_SPECIAL_WHO) ? FSAL_ACE_IFLAG_SPECIAL_ID : 0; if (IS_FSAL_ACE_GROUP_ID(*fsal_ace)) { fsal_ace->who.gid = lzfs_ace.id; } else { fsal_ace->who.uid = lzfs_ace.id; } if (IS_FSAL_ACE_SPECIAL_ID(*fsal_ace)) { switch (lzfs_ace.id) { case LIZ_ACL_OWNER_SPECIAL_ID: fsal_ace->who.uid = FSAL_ACE_SPECIAL_OWNER; break; case LIZ_ACL_GROUP_SPECIAL_ID: fsal_ace->who.uid = FSAL_ACE_SPECIAL_GROUP; break; case LIZ_ACL_EVERYONE_SPECIAL_ID: fsal_ace->who.uid = FSAL_ACE_SPECIAL_EVERYONE; break; default: fsal_ace->who.uid = FSAL_ACE_NORMAL_WHO; LogWarn(COMPONENT_FSAL, "Invalid LizardFS ACE special id type (%u)", (unsigned)lzfs_ace.id); } } } fsal_acl = nfs4_acl_new_entry(&acl_data, &acl_status); LogDebug(COMPONENT_FSAL, "fsal acl = %p, fsal_acl_status = %u", fsal_acl, acl_status); return fsal_acl; }
liz_acl_t *lzfs_int_convert_fsal_acl(const fsal_acl_t *fsal_acl) { liz_acl_t *lzfs_acl = NULL; if (!fsal_acl || (!fsal_acl->aces && fsal_acl->naces > 0)) { return NULL; } int count = 0; for (unsigned i = 0; i < fsal_acl->naces; ++i) { fsal_ace_t *fsal_ace = fsal_acl->aces + i; count += (IS_FSAL_ACE_ALLOW(*fsal_ace) || IS_FSAL_ACE_DENY(*fsal_ace)) ? 1 : 0; } lzfs_acl = liz_create_acl(); if (!lzfs_acl) { return NULL; } for (unsigned i = 0; i < fsal_acl->naces; ++i) { fsal_ace_t *fsal_ace = fsal_acl->aces + i; if (!(IS_FSAL_ACE_ALLOW(*fsal_ace) || IS_FSAL_ACE_DENY(*fsal_ace))) { continue; } liz_acl_ace_t ace; ace.flags = fsal_ace->flag & 0xFF; ace.mask = fsal_ace->perm; ace.type = fsal_ace->type; if (IS_FSAL_ACE_GROUP_ID(*fsal_ace)) { ace.id = GET_FSAL_ACE_GROUP(*fsal_ace); } else { ace.id = GET_FSAL_ACE_USER(*fsal_ace); } if (IS_FSAL_ACE_SPECIAL_ID(*fsal_ace)) { ace.flags |= LIZ_ACL_SPECIAL_WHO; switch (GET_FSAL_ACE_USER(*fsal_ace)) { case FSAL_ACE_SPECIAL_OWNER: ace.id = LIZ_ACL_OWNER_SPECIAL_ID; break; case FSAL_ACE_SPECIAL_GROUP: ace.id = LIZ_ACL_GROUP_SPECIAL_ID; break; case FSAL_ACE_SPECIAL_EVERYONE: ace.id = LIZ_ACL_EVERYONE_SPECIAL_ID; break; default: LogFullDebug(COMPONENT_FSAL, "Invalid FSAL ACE special id type (%d)", (int)GET_FSAL_ACE_USER(*fsal_ace)); continue; } } liz_add_acl_entry(lzfs_acl, &ace); } return lzfs_acl; }
/* Covert FSAL ACLs to PTFS NFS4 ACLs. */ fsal_status_t fsal_acl_2_ptfs_acl(fsal_acl_t * p_fsalacl, ptfsal_xstat_t * p_buffxstat) { int i; fsal_ace_t *pace; gpfs_acl_t *p_ptfsacl; p_ptfsacl = (gpfs_acl_t *) p_buffxstat->buffacl; p_ptfsacl->acl_level = 0; p_ptfsacl->acl_version = PTFS_ACL_VERSION_NFS4; p_ptfsacl->acl_type = PTFS_ACL_TYPE_NFS4; p_ptfsacl->acl_nace = p_fsalacl->naces; p_ptfsacl->acl_len = ((int)(signed long)&(((gpfs_acl_t *) 0)->ace_v1)) + p_ptfsacl->acl_nace * sizeof(ptfs_ace_v4_t); for(pace = p_fsalacl->aces, i = 0; pace < p_fsalacl->aces + p_fsalacl->naces; pace++, i++) { p_ptfsacl->ace_v4[i].aceType = pace->type; p_ptfsacl->ace_v4[i].aceFlags = pace->flag; p_ptfsacl->ace_v4[i].aceIFlags = pace->iflag; p_ptfsacl->ace_v4[i].aceMask = pace->perm; if(IS_FSAL_ACE_SPECIAL_ID(*pace)) p_ptfsacl->ace_v4[i].aceWho = pace->who.uid; else { if(IS_FSAL_ACE_GROUP_ID(*pace)) p_ptfsacl->ace_v4[i].aceWho = pace->who.gid; else p_ptfsacl->ace_v4[i].aceWho = pace->who.uid; } LogDebug(COMPONENT_FSAL, "fsal_acl_2_ptfs_acl: ptfs ace: " "type = 0x%x, flag = 0x%x, perm = 0x%x, special = %d, %s = 0x%x", p_ptfsacl->ace_v4[i].aceType, p_ptfsacl->ace_v4[i].aceFlags, p_ptfsacl->ace_v4[i].aceMask, (p_ptfsacl->ace_v4[i].aceIFlags & FSAL_ACE_IFLAG_SPECIAL_ID) ? 1 : 0, (p_ptfsacl->ace_v4[i].aceFlags & FSAL_ACE_FLAG_GROUP_ID) ? "gid" : "uid", p_ptfsacl->ace_v4[i].aceWho); } ReturnCode(ERR_FSAL_NO_ERROR, 0); }
static bool fsal_check_ace_matches(fsal_ace_t *pace, struct user_cred *creds, bool is_owner, bool is_group) { bool result = false; char *cause = ""; if (IS_FSAL_ACE_SPECIAL_ID(*pace)) switch (pace->who.uid) { case FSAL_ACE_SPECIAL_OWNER: if (is_owner) { result = true; cause = "special owner"; } break; case FSAL_ACE_SPECIAL_GROUP: if (is_group) { result = true; cause = "special group"; } break; case FSAL_ACE_SPECIAL_EVERYONE: result = true; cause = "special everyone"; break; default: break; } else if (IS_FSAL_ACE_GROUP_ID(*pace)) { if (fsal_check_ace_group(pace->who.gid, creds)) { result = true; cause = "group"; } } else { if (fsal_check_ace_owner(pace->who.uid, creds)) { result = true; cause = "owner"; } } LogFullDebug(COMPONENT_NFS_V4_ACL, "result: %d, cause: %s, flag: 0x%X, who: %d", result, cause, pace->flag, GET_FSAL_ACE_WHO(*pace)); return result; }
static void fsal_print_ace(int ace_number, fsal_ace_t *pace, char *p_acebuf) { char inherit_flags[ACL_DEBUG_BUF_SIZE]; if(!pace || !p_acebuf) return; memset(p_acebuf, 0, ACL_DEBUG_BUF_SIZE); memset(inherit_flags, 0, ACL_DEBUG_BUF_SIZE); /* Get inherit flags if any. */ fsal_print_inherit_flags(pace, inherit_flags); /* Print the entire ACE. */ sprintf(p_acebuf, "ACE %d %s %s %d %c%c%c%c%c%c%c%c%c%c%c%c%c%c %s", ace_number, /* ACE type. */ IS_FSAL_ACE_ALLOW(*pace)? "allow": IS_FSAL_ACE_DENY(*pace) ? "deny": IS_FSAL_ACE_AUDIT(*pace)? "audit": "?", /* ACE who and its type. */ (IS_FSAL_ACE_SPECIAL_ID(*pace) && IS_FSAL_ACE_SPECIAL_OWNER(*pace)) ? "owner@": (IS_FSAL_ACE_SPECIAL_ID(*pace) && IS_FSAL_ACE_SPECIAL_GROUP(*pace)) ? "group@": (IS_FSAL_ACE_SPECIAL_ID(*pace) && IS_FSAL_ACE_SPECIAL_EVERYONE(*pace)) ? "everyone@": IS_FSAL_ACE_SPECIAL_ID(*pace) ? "specialid": IS_FSAL_ACE_GROUP_ID(*pace) ? "gid": "uid", GET_FSAL_ACE_WHO(*pace), /* ACE mask. */ IS_FSAL_ACE_READ_DATA(*pace) ? 'r':'-', IS_FSAL_ACE_WRITE_DATA(*pace) ? 'w':'-', IS_FSAL_ACE_EXECUTE(*pace) ? 'x':'-', IS_FSAL_ACE_ADD_SUBDIRECTORY(*pace) ? 'm':'-', IS_FSAL_ACE_READ_NAMED_ATTR(*pace) ? 'n':'-', IS_FSAL_ACE_WRITE_NAMED_ATTR(*pace) ? 'N':'-', IS_FSAL_ACE_DELETE_CHILD(*pace) ? 'p':'-', IS_FSAL_ACE_READ_ATTR(*pace) ? 't':'-', IS_FSAL_ACE_WRITE_ATTR(*pace) ? 'T':'-', IS_FSAL_ACE_DELETE(*pace) ? 'd':'-', IS_FSAL_ACE_READ_ACL(*pace) ? 'c':'-', IS_FSAL_ACE_WRITE_ACL(*pace) ? 'C':'-', IS_FSAL_ACE_WRITE_OWNER(*pace) ? 'o':'-', IS_FSAL_ACE_SYNCHRONIZE(*pace) ? 'z':'-', /* ACE Inherit flags. */ IS_FSAL_ACE_INHERIT(*pace)? inherit_flags: ""); }
static fsal_boolean_t fsal_check_ace_matches(fsal_ace_t *pace, fsal_op_context_t *p_context, fsal_boolean_t is_owner, fsal_boolean_t is_group) { int matches = 0; if (IS_FSAL_ACE_SPECIAL_ID(*pace)) switch(pace->who.uid) { case FSAL_ACE_SPECIAL_OWNER: if(is_owner) matches = 1; break; case FSAL_ACE_SPECIAL_GROUP: if(is_group) matches = 2; break; case FSAL_ACE_SPECIAL_EVERYONE: matches = 3; break; default: break; } else if (IS_FSAL_ACE_GROUP_ID(*pace)) { if(fsal_check_ace_group(pace->who.gid, p_context)) matches = 4; } else { if(fsal_check_ace_owner(pace->who.uid, p_context)) matches = 5; } LogDebug(COMPONENT_FSAL, "fsal_check_ace_matches: matches %d flag 0x%X who %d", matches, pace->flag, GET_FSAL_ACE_WHO(*pace)); return (matches != 0); }
/* XXX dang - This will lose PANFS specific types (PAN_IDENTITY_PAN_* and * PAN_IDENTITY_WIN_*), since those were consolidated into the FSAL types */ void fsal_id_to_panace_id(fsal_ace_t *ace, pan_identity_t *pan_id) { if (IS_FSAL_ACE_SPECIAL_ID(*ace)) { if (IS_FSAL_ACE_SPECIAL_EVERYONE(*ace)) { pan_id->type = PAN_IDENTITY_PAN_GROUP; pan_id->u.pan_gid = PAN_IDENTITY_EVERYONE_GROUP_ID; } else { pan_id->type = PAN_IDENTITY_UNKNOWN; pan_id->u.uid = ace->who.uid; } } else { if (IS_FSAL_ACE_GROUP_ID(*ace)) { pan_id->type = PAN_IDENTITY_UNIX_GROUP; pan_id->u.gid = ace->who.gid; } else { pan_id->type = PAN_IDENTITY_UNIX_USER; pan_id->u.uid = ace->who.uid; } } }
/* Covert FSAL ACLs to GPFS NFS4 ACLs. */ fsal_status_t fsal_acl_2_gpfs_acl(struct fsal_obj_handle *dir_hdl, fsal_acl_t *p_fsalacl, gpfsfsal_xstat_t *p_buffxstat) { int i; fsal_ace_t *pace; gpfs_acl_t *p_gpfsacl; p_gpfsacl = (gpfs_acl_t *) p_buffxstat->buffacl; p_gpfsacl->acl_level = 0; p_gpfsacl->acl_version = GPFS_ACL_VERSION_NFS4; p_gpfsacl->acl_type = GPFS_ACL_TYPE_NFS4; p_gpfsacl->acl_nace = p_fsalacl->naces; p_gpfsacl->acl_len = ((int)(signed long)&(((gpfs_acl_t *) 0)->ace_v1)) + p_gpfsacl->acl_nace * sizeof(gpfs_ace_v4_t); for (pace = p_fsalacl->aces, i = 0; pace < p_fsalacl->aces + p_fsalacl->naces; pace++, i++) { p_gpfsacl->ace_v4[i].aceType = pace->type; p_gpfsacl->ace_v4[i].aceFlags = pace->flag; p_gpfsacl->ace_v4[i].aceIFlags = pace->iflag; p_gpfsacl->ace_v4[i].aceMask = pace->perm; if (IS_FSAL_ACE_SPECIAL_ID(*pace)) p_gpfsacl->ace_v4[i].aceWho = pace->who.uid; else { if (IS_FSAL_ACE_GROUP_ID(*pace)) p_gpfsacl->ace_v4[i].aceWho = pace->who.gid; else p_gpfsacl->ace_v4[i].aceWho = pace->who.uid; } LogMidDebug(COMPONENT_FSAL, "fsal_acl_2_gpfs_acl: gpfs ace: type = 0x%x, flag = 0x%x, perm = 0x%x, special = %d, %s = 0x%x", p_gpfsacl->ace_v4[i].aceType, p_gpfsacl->ace_v4[i].aceFlags, p_gpfsacl->ace_v4[i].aceMask, (p_gpfsacl->ace_v4[i]. aceIFlags & FSAL_ACE_IFLAG_SPECIAL_ID) ? 1 : 0, (p_gpfsacl->ace_v4[i]. aceFlags & FSAL_ACE_FLAG_GROUP_ID) ? "gid" : "uid", p_gpfsacl->ace_v4[i].aceWho); /* It is invalid to set inherit flags on non dir objects */ if (dir_hdl->type != DIRECTORY && (p_gpfsacl->ace_v4[i].aceFlags & FSAL_ACE_FLAG_INHERIT) != 0) { LogMidDebug(COMPONENT_FSAL, "attempt to set inherit flag to non dir object"); return fsalstat(ERR_FSAL_INVAL, 0); } /* It is invalid to set inherit only with * out an actual inherit flag */ if ((p_gpfsacl->ace_v4[i].aceFlags & FSAL_ACE_FLAG_INHERIT) == FSAL_ACE_FLAG_INHERIT_ONLY) { LogMidDebug(COMPONENT_FSAL, "attempt to set inherit only without an inherit flag"); return fsalstat(ERR_FSAL_INVAL, 0); } } return fsalstat(ERR_FSAL_NO_ERROR, 0); }