static struct cifs_sid_id * id_rb_search(struct rb_root *root, struct cifs_sid *sidptr) { int rc; struct rb_node *node = root->rb_node; struct cifs_sid_id *lsidid; while (node) { lsidid = rb_entry(node, struct cifs_sid_id, rbnode); rc = compare_sids(sidptr, &((lsidid)->sid)); if (rc > 0) { node = node->rb_left; } else if (rc < 0) { node = node->rb_right; } else return lsidid; } return NULL; }
static void id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, struct cifs_sid_id **psidid, char *typestr) { int rc; char *strptr; struct rb_node *node = root->rb_node; struct rb_node *parent = NULL; struct rb_node **linkto = &(root->rb_node); struct cifs_sid_id *lsidid; while (node) { lsidid = rb_entry(node, struct cifs_sid_id, rbnode); parent = node; rc = compare_sids(sidptr, &((lsidid)->sid)); if (rc > 0) { linkto = &(node->rb_left); node = node->rb_left; } else if (rc < 0) { linkto = &(node->rb_right); node = node->rb_right; } } memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid)); (*psidid)->time = jiffies - (SID_MAP_RETRY + 1); (*psidid)->refcount = 0; sprintf((*psidid)->sidstr, "%s", typestr); strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr); sid_to_str(&(*psidid)->sid, strptr); clear_bit(SID_ID_PENDING, &(*psidid)->state); clear_bit(SID_ID_MAPPED, &(*psidid)->state); rb_link_node(&(*psidid)->rbnode, parent, linkto); rb_insert_color(&(*psidid)->rbnode, root); }
static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, struct cifs_fattr *fattr) { int i; int num_aces = 0; int acl_size; char *acl_base; struct cifs_ace **ppace; /* BB need to add parm so we can store the SID BB */ if (!pdacl) { /* no DACL in the security descriptor, set all the permissions for user/group/other */ fattr->cf_mode |= S_IRWXUGO; return; } /* validate that we do not go past end of acl */ if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) { cERROR(1, "ACL too small to parse DACL"); return; } cFYI(DBG2, "DACL revision %d size %d num aces %d", le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), le32_to_cpu(pdacl->num_aces)); /* reset rwx permissions for user/group/other. Also, if num_aces is 0 i.e. DACL has no ACEs, user/group/other have no permissions */ fattr->cf_mode &= ~(S_IRWXUGO); acl_base = (char *)pdacl; acl_size = sizeof(struct cifs_acl); num_aces = le32_to_cpu(pdacl->num_aces); if (num_aces > 0) { umode_t user_mask = S_IRWXU; umode_t group_mask = S_IRWXG; umode_t other_mask = S_IRWXO; ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), GFP_KERNEL); for (i = 0; i < num_aces; ++i) { ppace[i] = (struct cifs_ace *) (acl_base + acl_size); #ifdef CONFIG_CIFS_DEBUG2 dump_ace(ppace[i], end_of_acl); #endif if (compare_sids(&(ppace[i]->sid), pownersid)) access_flags_to_mode(ppace[i]->access_req, ppace[i]->type, &fattr->cf_mode, &user_mask); if (compare_sids(&(ppace[i]->sid), pgrpsid)) access_flags_to_mode(ppace[i]->access_req, ppace[i]->type, &fattr->cf_mode, &group_mask); if (compare_sids(&(ppace[i]->sid), &sid_everyone)) access_flags_to_mode(ppace[i]->access_req, ppace[i]->type, &fattr->cf_mode, &other_mask); acl_base = (char *)ppace[i]; acl_size = le16_to_cpu(ppace[i]->size); } kfree(ppace); } return; }
static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, struct cifs_fattr *fattr) { int i; int num_aces = 0; int acl_size; char *acl_base; struct cifs_ace **ppace; if (!pdacl) { fattr->cf_mode |= S_IRWXUGO; return; } if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) { cERROR(1, "ACL too small to parse DACL"); return; } cFYI(DBG2, "DACL revision %d size %d num aces %d", le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), le32_to_cpu(pdacl->num_aces)); fattr->cf_mode &= ~(S_IRWXUGO); acl_base = (char *)pdacl; acl_size = sizeof(struct cifs_acl); num_aces = le32_to_cpu(pdacl->num_aces); if (num_aces > 0) { umode_t user_mask = S_IRWXU; umode_t group_mask = S_IRWXG; umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO; if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *)) return; ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), GFP_KERNEL); if (!ppace) { cERROR(1, "DACL memory allocation error"); return; } for (i = 0; i < num_aces; ++i) { ppace[i] = (struct cifs_ace *) (acl_base + acl_size); #ifdef CONFIG_CIFS_DEBUG2 dump_ace(ppace[i], end_of_acl); #endif if (compare_sids(&(ppace[i]->sid), pownersid) == 0) access_flags_to_mode(ppace[i]->access_req, ppace[i]->type, &fattr->cf_mode, &user_mask); if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) access_flags_to_mode(ppace[i]->access_req, ppace[i]->type, &fattr->cf_mode, &group_mask); if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) access_flags_to_mode(ppace[i]->access_req, ppace[i]->type, &fattr->cf_mode, &other_mask); if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0) access_flags_to_mode(ppace[i]->access_req, ppace[i]->type, &fattr->cf_mode, &other_mask); acl_base = (char *)ppace[i]; acl_size = le16_to_cpu(ppace[i]->size); } kfree(ppace); } return; }