static int acl_allowedAttributes(struct ldb_module *module, struct ldb_message *sd_msg, struct ldb_message *msg, struct acl_context *ac) { struct ldb_message_element *oc_el; struct ldb_context *ldb = ldb_module_get_ctx(module); const struct dsdb_schema *schema = dsdb_get_schema(ldb); TALLOC_CTX *mem_ctx; const char **attr_list; int i, ret; /* If we don't have a schema yet, we can't do anything... */ if (schema == NULL) { return LDB_SUCCESS; } /* Must remove any existing attribute */ if (ac->allowedAttributes) { ldb_msg_remove_attr(msg, "allowedAttributes"); } mem_ctx = talloc_new(msg); if (!mem_ctx) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } oc_el = ldb_msg_find_element(sd_msg, "objectClass"); attr_list = dsdb_full_attribute_list(mem_ctx, schema, oc_el, DSDB_SCHEMA_ALL); if (!attr_list) { ldb_asprintf_errstring(ldb, "acl: Failed to get list of attributes"); talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } if (ac->allowedAttributes) { for (i=0; attr_list && attr_list[i]; i++) { ldb_msg_add_string(msg, "allowedAttributes", attr_list[i]); } } if (ac->allowedAttributesEffective) { struct security_descriptor *sd; struct dom_sid *sid = NULL; ldb_msg_remove_attr(msg, "allowedAttributesEffective"); if (ac->user_type == SECURITY_SYSTEM) { for (i=0; attr_list && attr_list[i]; i++) { ldb_msg_add_string(msg, "allowedAttributesEffective", attr_list[i]); } return LDB_SUCCESS; } ret = get_sd_from_ldb_message(mem_ctx, sd_msg, &sd); if (ret != LDB_SUCCESS) { return ret; } ret = get_dom_sid_from_ldb_message(mem_ctx, sd_msg, &sid); if (ret != LDB_SUCCESS) { return ret; } for (i=0; attr_list && attr_list[i]; i++) { struct dsdb_attribute *attr = dsdb_attribute_by_lDAPDisplayName(schema, attr_list[i]); if (!attr) { return LDB_ERR_OPERATIONS_ERROR; } /* remove constructed attributes */ if (attr->systemFlags & DS_FLAG_ATTR_IS_CONSTRUCTED || attr->systemOnly || (attr->linkID != 0 && attr->linkID % 2 != 0 )) { continue; } ret = acl_check_access_on_attribute(module, msg, sd, sid, SEC_ADS_WRITE_PROP, attr); if (ret == LDB_SUCCESS) { ldb_msg_add_string(msg, "allowedAttributesEffective", attr_list[i]); } } } return LDB_SUCCESS; }
static char *print_schema_recursive(char *append_to_string, struct dsdb_schema *schema, const char *print_class, enum dsdb_schema_convert_target target, const char **attrs_skip, const struct attr_map *attr_map, const struct oid_map *oid_map) { char *out = append_to_string; const struct dsdb_class *objectclass; objectclass = dsdb_class_by_lDAPDisplayName(schema, print_class); if (!objectclass) { DEBUG(0, ("Cannot find class %s in schema\n", print_class)); return NULL; } do { TALLOC_CTX *mem_ctx = talloc_new(append_to_string); const char *name = objectclass->lDAPDisplayName; const char *oid = objectclass->governsID_oid; const char *subClassOf = objectclass->subClassOf; int objectClassCategory = objectclass->objectClassCategory; const char **must; const char **may; char *schema_entry = NULL; const char *objectclass_name_as_list[] = { objectclass->lDAPDisplayName, NULL }; int j; int attr_idx; if (!mem_ctx) { DEBUG(0, ("Failed to create new talloc context\n")); return NULL; } /* We have been asked to skip some attributes/objectClasses */ if (attrs_skip && str_list_check_ci(attrs_skip, name)) { continue; } /* We might have been asked to remap this oid, due to a conflict */ for (j=0; oid_map && oid_map[j].old_oid; j++) { if (strcasecmp(oid, oid_map[j].old_oid) == 0) { oid = oid_map[j].new_oid; break; } } /* We might have been asked to remap this name, due to a conflict */ for (j=0; name && attr_map && attr_map[j].old_attr; j++) { if (strcasecmp(name, attr_map[j].old_attr) == 0) { name = attr_map[j].new_attr; break; } } may = dsdb_full_attribute_list(mem_ctx, schema, objectclass_name_as_list, DSDB_SCHEMA_ALL_MAY); for (j=0; may && may[j]; j++) { /* We might have been asked to remap this name, due to a conflict */ for (attr_idx=0; attr_map && attr_map[attr_idx].old_attr; attr_idx++) { if (strcasecmp(may[j], attr_map[attr_idx].old_attr) == 0) { may[j] = attr_map[attr_idx].new_attr; break; } } } must = dsdb_full_attribute_list(mem_ctx, schema, objectclass_name_as_list, DSDB_SCHEMA_ALL_MUST); for (j=0; must && must[j]; j++) { /* We might have been asked to remap this name, due to a conflict */ for (attr_idx=0; attr_map && attr_map[attr_idx].old_attr; attr_idx++) { if (strcasecmp(must[j], attr_map[attr_idx].old_attr) == 0) { must[j] = attr_map[attr_idx].new_attr; break; } } } schema_entry = schema_class_description(mem_ctx, target, SEPERATOR, oid, name, NULL, subClassOf, objectClassCategory, must, may, NULL); if (schema_entry == NULL) { DEBUG(0, ("failed to generate schema description for %s\n", name)); return NULL; } switch (target) { case TARGET_OPENLDAP: out = talloc_asprintf_append(out, "objectclass %s\n\n", schema_entry); break; case TARGET_FEDORA_DS: out = talloc_asprintf_append(out, "objectClasses: %s\n", schema_entry); break; } talloc_free(mem_ctx); } while (0); for (objectclass=schema->classes; objectclass; objectclass = objectclass->next) { if (ldb_attr_cmp(objectclass->subClassOf, print_class) == 0 && ldb_attr_cmp(objectclass->lDAPDisplayName, print_class) != 0) { out = print_schema_recursive(out, schema, objectclass->lDAPDisplayName, target, attrs_skip, attr_map, oid_map); } } return out; }