/** * e2k_security_descriptor_new: * @xml_form: the XML form of the folder's security descriptor * (The "http://schemas.microsoft.com/exchange/security/descriptor" * property, aka %E2K_PR_EXCHANGE_SD_XML) * @binary_form: the binary form of the folder's security descriptor * (The "http://schemas.microsoft.com/exchange/ntsecuritydescriptor" * property, aka %E2K_PR_EXCHANGE_SD_BINARY) * * Constructs an #E2kSecurityDescriptor from the data in @xml_form and * @binary_form. * * Return value: the security descriptor, or %NULL if the data could * not be parsed. **/ E2kSecurityDescriptor * e2k_security_descriptor_new (xmlNodePtr xml_form, GByteArray *binary_form) { E2kSecurityDescriptor *sd; E2k_SECURITY_DESCRIPTOR_RELATIVE sdbuf; guint16 off, header_len; g_return_val_if_fail (xml_form != NULL, NULL); g_return_val_if_fail (binary_form != NULL, NULL); if (binary_form->len < 2) return NULL; memcpy (&header_len, binary_form->data, 2); header_len = GUINT16_FROM_LE (header_len); if (header_len + sizeof (sdbuf) > binary_form->len) return NULL; memcpy (&sdbuf, binary_form->data + header_len, sizeof (sdbuf)); if (sdbuf.Revision != E2K_SECURITY_DESCRIPTOR_REVISION) return NULL; if ((sdbuf.Control & (E2K_SE_DACL_PRESENT | E2K_SE_SACL_PRESENT)) != E2K_SE_DACL_PRESENT) return NULL; sd = g_object_new (E2K_TYPE_SECURITY_DESCRIPTOR, NULL); sd->priv->header = g_byte_array_new (); g_byte_array_append (sd->priv->header, binary_form->data, header_len); sd->priv->control_flags = sdbuf.Control; /* Create a SID for "Default" then extract remaining SIDs from * the XML form since they have display names associated with * them. */ sd->priv->default_sid = e2k_sid_new_from_string_sid (E2K_SID_TYPE_WELL_KNOWN_GROUP, E2K_SID_WKS_EVERYONE, NULL); g_hash_table_insert (sd->priv->sids, (char *)e2k_sid_get_binary_sid (sd->priv->default_sid), sd->priv->default_sid); extract_sids (sd, xml_form); off = GUINT32_FROM_LE (sdbuf.Owner) + sd->priv->header->len; if (!parse_sid (sd, binary_form, &off, &sd->priv->owner)) goto lose; off = GUINT32_FROM_LE (sdbuf.Group) + sd->priv->header->len; if (!parse_sid (sd, binary_form, &off, &sd->priv->group)) goto lose; off = GUINT32_FROM_LE (sdbuf.Dacl) + sd->priv->header->len; if (!parse_acl (sd, binary_form, &off)) goto lose; return sd; lose: g_object_unref (sd); return NULL; }
/* Convert CIFS ACL to POSIX form */ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr) { int rc = 0; struct cifs_sid *owner_sid_ptr, *group_sid_ptr; struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ char *end_of_acl = ((char *)pntsd) + acl_len; __u32 dacloffset; if (pntsd == NULL) return -EIO; owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->osidoffset)); group_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->gsidoffset)); dacloffset = le32_to_cpu(pntsd->dacloffset); dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n", pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), le32_to_cpu(pntsd->gsidoffset), le32_to_cpu(pntsd->sacloffset), dacloffset); /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */ rc = parse_sid(owner_sid_ptr, end_of_acl); if (rc) { cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc); return rc; } rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER); if (rc) { cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n", __func__, rc); return rc; } rc = parse_sid(group_sid_ptr, end_of_acl); if (rc) { cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n", __func__, rc); return rc; } rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP); if (rc) { cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n", __func__, rc); return rc; } if (dacloffset) parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr, fattr); else cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */ return rc; }
static int parse_sec_desc(struct cifs_sb_info *cifs_sb, struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr) { int rc = 0; struct cifs_sid *owner_sid_ptr, *group_sid_ptr; struct cifs_acl *dacl_ptr; /* */ char *end_of_acl = ((char *)pntsd) + acl_len; __u32 dacloffset; if (pntsd == NULL) return -EIO; owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->osidoffset)); group_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->gsidoffset)); dacloffset = le32_to_cpu(pntsd->dacloffset); dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x " "sacloffset 0x%x dacloffset 0x%x", pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), le32_to_cpu(pntsd->gsidoffset), le32_to_cpu(pntsd->sacloffset), dacloffset); /* */ rc = parse_sid(owner_sid_ptr, end_of_acl); if (rc) { cFYI(1, "%s: Error %d parsing Owner SID", __func__, rc); return rc; } rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER); if (rc) { cFYI(1, "%s: Error %d mapping Owner SID to uid", __func__, rc); return rc; } rc = parse_sid(group_sid_ptr, end_of_acl); if (rc) { cFYI(1, "%s: Error %d mapping Owner SID to gid", __func__, rc); return rc; } rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP); if (rc) { cFYI(1, "%s: Error %d mapping Group SID to gid", __func__, rc); return rc; } if (dacloffset) parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr, fattr); else cFYI(1, "no ACL"); /* */ return rc; }
/* Convert CIFS ACL to POSIX form */ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, struct inode *inode) { int rc; struct cifs_sid *owner_sid_ptr, *group_sid_ptr; struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ char *end_of_acl = ((char *)pntsd) + acl_len; __u32 dacloffset; if ((inode == NULL) || (pntsd == NULL)) return -EIO; owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->osidoffset)); group_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->gsidoffset)); dacloffset = le32_to_cpu(pntsd->dacloffset); dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); cFYI(DBG2, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " "sacloffset 0x%x dacloffset 0x%x", pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), le32_to_cpu(pntsd->gsidoffset), le32_to_cpu(pntsd->sacloffset), dacloffset)); /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */ rc = parse_sid(owner_sid_ptr, end_of_acl); if (rc) return rc; rc = parse_sid(group_sid_ptr, end_of_acl); if (rc) return rc; if (dacloffset) parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr, inode); else cFYI(1, ("no ACL")); /* BB grant all or default perms? */ /* cifscred->uid = owner_sid_ptr->rid; cifscred->gid = group_sid_ptr->rid; memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, sizeof(struct cifs_sid)); memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, sizeof(struct cifs_sid)); */ return 0; }
/* Convert CIFS ACL to POSIX form */ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr) { int rc; struct cifs_sid *owner_sid_ptr, *group_sid_ptr; struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ char *end_of_acl = ((char *)pntsd) + acl_len; __u32 dacloffset; if (pntsd == NULL) return -EIO; owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->osidoffset)); group_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->gsidoffset)); dacloffset = le32_to_cpu(pntsd->dacloffset); dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x " "sacloffset 0x%x dacloffset 0x%x", pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), le32_to_cpu(pntsd->gsidoffset), le32_to_cpu(pntsd->sacloffset), dacloffset); /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */ rc = parse_sid(owner_sid_ptr, end_of_acl); if (rc) return rc; rc = parse_sid(group_sid_ptr, end_of_acl); if (rc) return rc; if (dacloffset) parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr, fattr); else cFYI(1, "no ACL"); /* BB grant all or default perms? */ return 0; }
static gboolean parse_acl (E2kSecurityDescriptor *sd, GByteArray *binsd, guint16 *off) { E2k_ACL aclbuf; E2k_ACE acebuf; int ace_count, i; if (binsd->len - *off < sizeof (E2k_ACL)) return FALSE; memcpy (&aclbuf, binsd->data + *off, sizeof (aclbuf)); if (*off + GUINT16_FROM_LE (aclbuf.AclSize) > binsd->len) return FALSE; if (aclbuf.AclRevision != E2K_ACL_REVISION) return FALSE; ace_count = GUINT16_FROM_LE (aclbuf.AceCount); *off += sizeof (aclbuf); for (i = 0; i < ace_count; i++) { if (binsd->len - *off < sizeof (E2k_ACE)) return FALSE; memcpy (&acebuf, binsd->data + *off, sizeof (acebuf.Header) + sizeof (acebuf.Mask)); *off += sizeof (acebuf.Header) + sizeof (acebuf.Mask); /* If either of OBJECT_INHERIT_ACE or INHERIT_ONLY_ACE * is set, both must be. */ if (acebuf.Header.AceFlags & E2K_OBJECT_INHERIT_ACE) { if (!(acebuf.Header.AceFlags & E2K_INHERIT_ONLY_ACE)) return FALSE; } else { if (acebuf.Header.AceFlags & E2K_INHERIT_ONLY_ACE) return FALSE; } if (!parse_sid (sd, binsd, off, &acebuf.Sid)) return FALSE; if (!g_hash_table_lookup (sd->priv->sid_order, acebuf.Sid)) { int size = g_hash_table_size (sd->priv->sid_order); g_hash_table_insert (sd->priv->sid_order, acebuf.Sid, GUINT_TO_POINTER (size + 1)); } g_array_append_val (sd->priv->aces, acebuf); } return TRUE; }
static int parse_sec_desc(struct cifs_ntsd *pntsd, ssize_t acl_len, int raw) { int rc; uint32_t dacloffset; char *end_of_acl = ((char *)pntsd) + acl_len; struct wbcDomainSid *owner_sid_ptr, *group_sid_ptr; struct cifs_ctrl_acl *dacl_ptr; /* no need for SACL ptr */ if (pntsd == NULL) return -EIO; owner_sid_ptr = (struct wbcDomainSid *)((char *)pntsd + le32toh(pntsd->osidoffset)); group_sid_ptr = (struct wbcDomainSid *)((char *)pntsd + le32toh(pntsd->gsidoffset)); dacloffset = le32toh(pntsd->dacloffset); dacl_ptr = (struct cifs_ctrl_acl *)((char *)pntsd + dacloffset); printf("REVISION:0x%x\n", pntsd->revision); printf("CONTROL:0x%x\n", pntsd->type); rc = parse_sid(owner_sid_ptr, end_of_acl, "OWNER", raw); if (rc) return rc; rc = parse_sid(group_sid_ptr, end_of_acl, "GROUP", raw); if (rc) return rc; if (dacloffset) parse_dacl(dacl_ptr, end_of_acl, raw); else printf("No ACL\n"); /* BB grant all or default perms? */ return 0; }