Use common code to fill in allowedAttributes in kludge_acl.
[kai/samba.git] / source4 / dsdb / samdb / ldb_modules / kludge_acl.c
index ea33548b919bcfad154c08296129531d004a8da3..bc30fbc36d14be2a1ea1857f177ca3ff5e2289a8 100644 (file)
  *
  */
 
-enum user_is {
-       ANONYMOUS,
-       USER,
-       ADMINISTRATOR,
-       SYSTEM
-};
-
 struct kludge_private_data {
        const char **password_attrs;
 };
 
-static enum user_is what_is_user(struct ldb_module *module) 
+static enum security_user_level what_is_user(struct ldb_module *module) 
 {
        struct auth_session_info *session_info
                = (struct auth_session_info *)ldb_get_opaque(module->ldb, "sessionInfo");
-       if (!session_info) {
-               return ANONYMOUS;
-       }
-       
-       if (security_token_is_system(session_info->security_token)) {
-               return SYSTEM;
-       }
-
-       if (security_token_is_anonymous(session_info->security_token)) {
-               return ANONYMOUS;
-       }
-
-       if (security_token_has_builtin_administrators(session_info->security_token)) {
-               return ADMINISTRATOR;
-       }
-
-       if (security_token_has_nt_authenticated_users(session_info->security_token)) {
-               return USER;
-       }
-
-       return ANONYMOUS;
+       return security_session_user_level(session_info);
 }
 
 static const char *user_name(TALLOC_CTX *mem_ctx, struct ldb_module *module) 
@@ -104,7 +77,7 @@ struct kludge_acl_context {
        void *up_context;
        int (*up_callback)(struct ldb_context *, void *, struct ldb_reply *);
 
-       enum user_is user_type;
+       enum security_user_level user_type;
        bool allowedAttributes;
        bool allowedAttributesEffective;
        bool allowedChildClasses;
@@ -120,8 +93,9 @@ static int kludge_acl_allowedAttributes(struct ldb_context *ldb, struct ldb_mess
        struct ldb_message_element *oc_el;
        struct ldb_message_element *allowedAttributes;
        const struct dsdb_schema *schema = dsdb_get_schema(ldb);
-       const struct dsdb_class *class;
-       int i, j, ret;
+       TALLOC_CTX *mem_ctx;
+       char **objectclass_list, **attr_list;
+       int i, ret;
 
        /* If we don't have a schema yet, we can't do anything... */
        if (schema == NULL) {
@@ -135,48 +109,39 @@ static int kludge_acl_allowedAttributes(struct ldb_context *ldb, struct ldb_mess
                return ret;
        }
        
+       mem_ctx = talloc_new(msg);
+       if (!mem_ctx) {
+               ldb_oom(ldb);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
        /* To ensure that oc_el is valid, we must look for it after 
           we alter the element array in ldb_msg_add_empty() */
        oc_el = ldb_msg_find_element(msg, "objectClass");
+       
+       objectclass_list = talloc_array(mem_ctx, char *, oc_el->num_values + 1);
+       if (!objectclass_list) {
+               ldb_oom(ldb);
+               talloc_free(mem_ctx);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
 
        for (i=0; oc_el && i < oc_el->num_values; i++) {
-               class = dsdb_class_by_lDAPDisplayName(schema, (const char *)oc_el->values[i].data);
-               if (!class) {
-                       /* We don't know this class?  what is going on? */
-                       continue;
-               }
-
-               for (j=0; class->mayContain && class->mayContain[j]; j++) {
-                       ldb_msg_add_string(msg, attrName, class->mayContain[j]);
-               }
-               for (j=0; class->mustContain && class->mustContain[j]; j++) {
-                       ldb_msg_add_string(msg, attrName, class->mustContain[j]);
-               }
-               for (j=0; class->systemMayContain && class->systemMayContain[j]; j++) {
-                       ldb_msg_add_string(msg, attrName, class->systemMayContain[j]);
-               }
-               for (j=0; class->systemMustContain && class->systemMustContain[j]; j++) {
-                       ldb_msg_add_string(msg, attrName, class->systemMustContain[j]);
-               }
+               objectclass_list[i] = (char *)oc_el->values[i].data;
        }
-               
-       if (allowedAttributes->num_values > 1) {
-               qsort(allowedAttributes->values, 
-                     allowedAttributes->num_values, 
-                     sizeof(*allowedAttributes->values),
-                     (comparison_fn_t)data_blob_cmp);
-       
-               for (i=1 ; i < allowedAttributes->num_values; i++) {
-                       struct ldb_val *val1 = &allowedAttributes->values[i-1];
-                       struct ldb_val *val2 = &allowedAttributes->values[i];
-                       if (data_blob_cmp(val1, val2) == 0) {
-                               memmove(val1, val2, (allowedAttributes->num_values - i) * sizeof( struct ldb_val)); 
-                               allowedAttributes->num_values--;
-                               i--;
-                       }
-               }
+       objectclass_list[i] = NULL;
+
+       attr_list = dsdb_full_attribute_list(mem_ctx, schema, (const char **)objectclass_list, DSDB_SCHEMA_ALL);
+       if (!attr_list) {
+               ldb_asprintf_errstring(ldb, "kludge_acl: Failed to get list of attributes create %s attribute", attrName);
+               talloc_free(mem_ctx);
+               return LDB_ERR_OPERATIONS_ERROR;
        }
 
+       for (i=0; attr_list && attr_list[i]; i++) {
+               ldb_msg_add_string(msg, attrName, attr_list[i]);
+       }
+       talloc_free(mem_ctx);
        return 0;
 
 }
@@ -272,8 +237,8 @@ static int kludge_acl_callback(struct ldb_context *ldb, void *context, struct ld
        if (data && data->password_attrs) /* if we are not initialized just get through */
        {
                switch (ac->user_type) {
-               case SYSTEM:
-               case ADMINISTRATOR:
+               case SECURITY_SYSTEM:
+               case SECURITY_ADMINISTRATOR:
                        if (ac->allowedAttributesEffective) {
                                ret = kludge_acl_allowedAttributes(ldb, ares->message, "allowedAttributesEffective");
                                if (ret != LDB_SUCCESS) {
@@ -359,7 +324,7 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
           so we don't allow a search for 'sambaPassword=penguin',
           just as we would not allow that attribute to be returned */
        switch (ac->user_type) {
-       case SYSTEM:
+       case SECURITY_SYSTEM:
                break;
        default:
                /* remove password attributes */
@@ -391,10 +356,10 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
 /* ANY change type */
 static int kludge_acl_change(struct ldb_module *module, struct ldb_request *req)
 {
-       enum user_is user_type = what_is_user(module);
+       enum security_user_level user_type = what_is_user(module);
        switch (user_type) {
-       case SYSTEM:
-       case ADMINISTRATOR:
+       case SECURITY_SYSTEM:
+       case SECURITY_ADMINISTRATOR:
                return ldb_next_request(module, req);
        default:
                ldb_asprintf_errstring(module->ldb,
@@ -471,7 +436,7 @@ done:
        return ldb_next_init(module);
 }
 
-static const struct ldb_module_ops kludge_acl_ops = {
+_PUBLIC_ const struct ldb_module_ops ldb_kludge_acl_module_ops = {
        .name              = "kludge_acl",
        .search            = kludge_acl_search,
        .add               = kludge_acl_change,
@@ -481,8 +446,3 @@ static const struct ldb_module_ops kludge_acl_ops = {
        .extended          = kludge_acl_change,
        .init_context      = kludge_acl_init
 };
-
-int ldb_kludge_acl_init(void)
-{
-       return ldb_register_module(&kludge_acl_ops);
-}