r5587: more work around the samldb module
authorSimo Sorce <idra@samba.org>
Sun, 27 Feb 2005 16:35:19 +0000 (16:35 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:10:55 +0000 (13:10 -0500)
fix the provision.ldif the layout of the @MODULES dn has changed since last commit
(This used to be commit acb99e63d40e71fa843c1b7a1719a350a353ed28)

source4/dsdb/config.mk
source4/dsdb/samdb/ldb_modules/samldb.c
source4/provision.ldif

index f636fea3fa301d2f65244a812865208e2433fdca..060fa98c46763ed9829e9fbacc0b783da5603062 100644 (file)
@@ -6,6 +6,7 @@
 SUBSYSTEM = LIBLDB
 INIT_OBJ_FILES = \
                dsdb/samdb/ldb_modules/samldb.o
 SUBSYSTEM = LIBLDB
 INIT_OBJ_FILES = \
                dsdb/samdb/ldb_modules/samldb.o
+#
 # End MODULE libldb_samldb
 ################################################
 
 # End MODULE libldb_samldb
 ################################################
 
index 6b8546e2b83eb8a7809c51a86d547cc2f9f37e6a..1e110afc2ed3026d5ed3ca16738f0bfff91509f5 100644 (file)
@@ -57,6 +57,156 @@ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_search_free\n");
        return ldb_next_search_free(module, res);
 }
 
        return ldb_next_search_free(module, res);
 }
 
+
+/*
+  allocate a new id, attempting to do it atomically
+  return 0 on failure, the id on success
+*/
+static int samldb_allocate_next_rid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
+                                  const char *dn, uint32_t *id)
+{
+       const char * const attrs[2] = { "nextRid", NULL };
+       struct ldb_message **res = NULL;
+       struct ldb_message msg;
+       int ret;
+       const char *str;
+       struct ldb_val vals[2];
+       struct ldb_message_element els[2];
+
+       ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, "nextRid=*", attrs, &res);
+       if (ret != 1) {
+               if (res) ldb_search_free(ldb, res);
+               return -1;
+       }
+       str = ldb_msg_find_string(res[0], "nextRid", NULL);
+       if (str == NULL) {
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "attribute nextRid not found in %s\n", dn);
+               ldb_search_free(ldb, res);
+               return -1;
+       }
+       talloc_steal(mem_ctx, str);
+       ldb_search_free(ldb, res);
+
+       *id = strtol(str, NULL, 0);
+       if ((*id)+1 == 0) {
+               /* out of IDs ! */
+               return -1;
+       }
+
+       /* we do a delete and add as a single operation. That prevents
+          a race */
+       ZERO_STRUCT(msg);
+       msg.dn = talloc_strdup(mem_ctx, dn);
+       if (!msg.dn) {
+               return -1;
+       }
+       msg.num_elements = 2;
+       msg.elements = els;
+
+       els[0].num_values = 1;
+       els[0].values = &vals[0];
+       els[0].flags = LDB_FLAG_MOD_DELETE;
+       els[0].name = talloc_strdup(mem_ctx, "nextRid");
+       if (!els[0].name) {
+               return -1;
+       }
+
+       els[1].num_values = 1;
+       els[1].values = &vals[1];
+       els[1].flags = LDB_FLAG_MOD_ADD;
+       els[1].name = els[0].name;
+
+       vals[0].data = talloc_asprintf(mem_ctx, "%u", *id);
+       if (!vals[0].data) {
+               return -1;
+       }
+       vals[0].length = strlen(vals[0].data);
+
+       vals[1].data = talloc_asprintf(mem_ctx, "%u", (*id)+1);
+       if (!vals[1].data) {
+               return -1;
+       }
+       vals[1].length = strlen(vals[1].data);
+
+       ret = ldb_modify(ldb, &msg);
+       if (ret != 0) {
+               return 1;
+       }
+
+       (*id)++;
+
+       return 0;
+}
+
+/* search the domain related to the provided dn
+   allocate a new RID for the domain
+   return the new sid string
+*/
+static char *samldb_get_new_sid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *obj_dn)
+{
+       const char * const attrs[2] = { "objectSid", NULL };
+       struct ldb_message **res = NULL;
+       const char *dom_dn, *dom_sid;
+       char *obj_sid;
+       uint32_t rid;
+       int ret, tries = 10;
+
+       /* get the domain component part of the provided dn */
+
+       /* FIXME: quick search here, I think we should use something like
+          ldap_parse_dn here to be 100% sure we get the right domain dn */
+
+       /* FIXME: "dc=" is probably not utf8 safe either,
+          we need a multibyte safe substring search function here */
+       
+       dom_dn = strstr(obj_dn, "dc=");
+       if (dom_dn == NULL) {
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "Invalid dn (%s)!\n", obj_dn);
+               return NULL;
+       }
+
+       /* find the domain sid */
+
+       ret = ldb_search(ldb, dom_dn, LDB_SCOPE_BASE, "objectSid=*", attrs, &res);
+       if (ret != 1) {
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "samldb_get_new_sid: error retrieving domain sid!\n");
+               if (res) ldb_search_free(ldb, res);
+               return NULL;
+       }
+
+       dom_sid = ldb_msg_find_string(res[0], "objectSid", NULL);
+       if (dom_sid == NULL) {
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "samldb_get_new_sid: error retrieving domain sid!\n");
+               ldb_search_free(ldb, res);
+               return NULL;
+       }
+
+       talloc_steal(mem_ctx, dom_sid);
+       ldb_search_free(ldb, res);
+
+       /* allocate a new Rid for the domain */
+
+
+       /* we need to try multiple times to cope with two account
+          creations at the same time */
+       while (tries--) {
+               ret = samldb_allocate_next_rid(ldb, mem_ctx, dom_dn, &rid);
+               if (ret != 1) {
+                       break;
+               }
+       }
+       if (ret != 0) {
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "Failed to increment nextRid of %s\n", dom_dn);
+               return NULL;
+       }
+
+       /* return the new object sid */
+
+       obj_sid = talloc_asprintf(mem_ctx, "%s-%u", dom_sid, rid);
+
+       return obj_sid;
+}
+
 static char *samldb_generate_samAccountName(const void *mem_ctx) {
        char *name;
 
 static char *samldb_generate_samAccountName(const void *mem_ctx) {
        char *name;
 
@@ -240,6 +390,21 @@ static struct ldb_message *samldb_manage_group_object(struct ldb_module *module,
                }
        }
 
                }
        }
 
+       if ((attribute = samldb_find_attribute(msg2, "objectSid", NULL)) == NULL ) {
+               char *sidstr;
+
+               if ((sidstr = samldb_get_new_sid(module->ldb, msg2, msg2->dn)) == NULL) {
+                       ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_group_object: internal error! Can't generate new sid\n");
+                       talloc_free(msg2);
+                       return NULL;
+               }
+               
+               if ( ! samldb_add_attribute(msg2, "objectSid", sidstr)) {
+                       talloc_free(msg2);
+                       return NULL;
+               }
+       }
+
        if ( ! samldb_find_or_add_attribute(msg2, "instanceType", NULL, "4")) {
                return NULL;
        }
        if ( ! samldb_find_or_add_attribute(msg2, "instanceType", NULL, "4")) {
                return NULL;
        }
@@ -260,10 +425,6 @@ static struct ldb_message *samldb_manage_group_object(struct ldb_module *module,
                return NULL;
        }
 
                return NULL;
        }
 
-       if ( ! samldb_find_or_add_attribute(msg2, "objectSid", NULL, "foo")) { /* keep the schema module happy :) */
-               return NULL;
-       }
-
        /* TODO: objectGUID, objectSid, objectCategory */
        /* need a way to lock a new Sid */
 
        /* TODO: objectGUID, objectSid, objectCategory */
        /* need a way to lock a new Sid */
 
@@ -353,6 +514,21 @@ static struct ldb_message *samldb_manage_user_object(struct ldb_module *module,
                }
        }
 
                }
        }
 
+       if ((attribute = samldb_find_attribute(msg2, "objectSid", NULL)) == NULL ) {
+               char *sidstr;
+
+               if ((sidstr = samldb_get_new_sid(module->ldb, msg2, msg2->dn)) == NULL) {
+                       ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_user_object: internal error! Can't generate new sid\n");
+                       talloc_free(msg2);
+                       return NULL;
+               }
+               
+               if ( ! samldb_add_attribute(msg2, "objectSid", sidstr)) {
+                       talloc_free(msg2);
+                       return NULL;
+               }
+       }
+
        if ( ! samldb_find_or_add_attribute(msg2, "instanceType", NULL, "4")) {
                talloc_free(msg2);
                return NULL;
        if ( ! samldb_find_or_add_attribute(msg2, "instanceType", NULL, "4")) {
                talloc_free(msg2);
                return NULL;
@@ -372,10 +548,6 @@ static struct ldb_message *samldb_manage_user_object(struct ldb_module *module,
                return NULL;
        }
 
                return NULL;
        }
 
-       if ( ! samldb_find_or_add_attribute(msg2, "objectSid", NULL, "foo")) { /* keep the schema module happy :) */
-               return NULL;
-       }
-
        /* TODO: objectGUID, objectSid, objectCategory, userAccountControl, badPwdCount, codePage, countryCode, badPasswordTime, lastLogoff, lastLogon, pwdLastSet, primaryGroupID, accountExpires, logonCount */
 
        return msg2;
        /* TODO: objectGUID, objectSid, objectCategory, userAccountControl, badPwdCount, codePage, countryCode, badPasswordTime, lastLogoff, lastLogon, pwdLastSet, primaryGroupID, accountExpires, logonCount */
 
        return msg2;
index c95780bcebf0cf17f6fda3109d8103ab50bcfaf5..d6c4e2b406e82ba755cb781a41d382a3b4ecba3b 100644 (file)
@@ -36,10 +36,10 @@ user: computer
 template: userTemplate
 template: groupTemplate
 
 template: userTemplate
 template: groupTemplate
 
+#Add modules to the list to activate them by default
+#beware often order is important
 dn: @MODULES
 dn: @MODULES
-@MODULE: timestamps
-# uncomment this if you want to enable schema checking
-#@MODULE: schema
+@LIST: timestamps
 
 ###############################
 # Domain Naming Context
 
 ###############################
 # Domain Naming Context