/*
- ldb database library
+ SAM ldb module
Copyright (C) Simo Sorce 2004
- ** NOTE! The following LGPL license applies to the ldb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ * NOTICE: this module is NOT released under the GNU LGPL license as
+ * other ldb code. This module is release under the GNU GPL v2 or
+ * later license.
- This library is distributed in the hope that it will be useful,
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
*
* Component: ldb samldb module
*
- * Description: add object timestamping functionality
+ * Description: add embedded user/group creation functionality
*
* Author: Simo Sorce
*/
#include "includes.h"
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_private.h"
-#include <time.h>
+#include "system/time.h"
+#include "librpc/gen_ndr/ndr_security.h"
#define SAM_ACCOUNT_NAME_BASE "$000000-000000000000"
return ldb_next_search(module, base, scope, expression, attrs, res);
}
-static int samldb_search_free(struct ldb_module *module, struct ldb_message **res)
+static int samldb_search_bytree(struct ldb_module *module, const char *base,
+ enum ldb_scope scope, struct ldb_parse_tree *tree,
+ const char * const *attrs, struct ldb_message ***res)
{
-ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_search_free\n");
- return ldb_next_search_free(module, res);
+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_search\n");
+ return ldb_next_search_bytree(module, base, scope, tree, attrs, 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) talloc_free(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);
+ talloc_free(res);
+ return -1;
+ }
+
+ *id = strtol(str, NULL, 0);
+ if ((*id)+1 == 0) {
+ /* out of IDs ! */
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "Are we out of valid IDs ?\n");
+ talloc_free(res);
+ return -1;
+ }
+ talloc_free(res);
+
+ /* 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;
+}
+
+static char *samldb_search_domain(struct ldb_module *module, TALLOC_CTX *mem_ctx, const char *dn)
+{
+ const char *sdn;
+ struct ldb_message **res = NULL;
+ int ret = 0;
+
+ sdn = dn;
+ while ((sdn = strchr(sdn, ',')) != NULL) {
+
+ sdn++;
+
+ ret = ldb_search(module->ldb, sdn, LDB_SCOPE_BASE, "objectClass=domain", NULL, &res);
+ talloc_free(res);
+
+ if (ret == 1)
+ break;
+ }
+
+ if (ret != 1) {
+ return NULL;
+ }
+
+ return talloc_strdup(mem_ctx, sdn);
+}
+
+/* search the domain related to the provided dn
+ allocate a new RID for the domain
+ return the new sid string
+*/
+static struct dom_sid *samldb_get_new_sid(struct ldb_module *module,
+ TALLOC_CTX *mem_ctx, const char *obj_dn)
+{
+ const char * const attrs[2] = { "objectSid", NULL };
+ struct ldb_message **res = NULL;
+ const char *dom_dn;
+ uint32_t rid;
+ int ret, tries = 10;
+ struct dom_sid *dom_sid, *obj_sid;
+
+ /* 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 = samldb_search_domain(module, mem_ctx, obj_dn);
+ if (dom_dn == NULL) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Invalid dn (%s) not child of a domain object!\n", obj_dn);
+ return NULL;
+ }
+
+ /* find the domain sid */
+
+ ret = ldb_search(module->ldb, dom_dn, LDB_SCOPE_BASE, "objectSid=*", attrs, &res);
+ if (ret != 1) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_get_new_sid: error retrieving domain sid!\n");
+ talloc_free(res);
+ return NULL;
+ }
+
+ dom_sid = samdb_result_dom_sid(res, res[0], "objectSid");
+ if (dom_sid == NULL) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_get_new_sid: error retrieving domain sid!\n");
+ talloc_free(res);
+ return NULL;
+ }
+
+ /* 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(module->ldb, mem_ctx, dom_dn, &rid);
+ if (ret != 1) {
+ break;
+ }
+ }
+ if (ret != 0) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Failed to increment nextRid of %s\n", dom_dn);
+ talloc_free(res);
+ return NULL;
+ }
+
+ /* return the new object sid */
+ obj_sid = dom_sid_add_rid(mem_ctx, dom_sid, rid);
+
+ talloc_free(res);
+
+ return obj_sid;
}
static char *samldb_generate_samAccountName(const void *mem_ctx) {
if ( ! p ) {
return False;
}
- /* clear separator */
- *p = '\0';
-
- *rdn = talloc_strdup(mem_ctx, dn);
- /* put back separator */
- *p = ',';
+ *rdn = talloc_strndup(mem_ctx, dn, p - dn);
if ( ! *rdn) {
return False;
return NULL;
}
-static BOOL samldb_add_attribute(struct ldb_message *msg, const char *name, const char *value)
+static BOOL samldb_msg_add_string(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *value)
{
- struct ldb_message_element *attr;
- int i;
-
- attr = samldb_find_attribute(msg, name, NULL);
- if ( ! attr) {
- msg->num_elements++;
- msg->elements = talloc_realloc(msg, msg->elements, struct ldb_message_element, msg->num_elements);
- if ( ! msg->elements ) {
- return False;
- }
- attr = &msg->elements[msg->num_elements - 1];
-
- attr->name = talloc_strdup(msg, name);
- if ( ! attr->name ) {
- return False;
- }
- attr->flags = 0;
- attr->num_values = 0;
- attr->values = NULL;
- }
+ char *aname = talloc_strdup(msg, name);
+ char *aval = talloc_strdup(msg, value);
- i = attr->num_values;
- attr->num_values++;
- attr->values = talloc_realloc(msg, attr->values, struct ldb_val, attr->num_values);
- if ( ! attr->values ){
+ if (aname == NULL || aval == NULL) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_msg_add_string: talloc_strdup failed!\n");
return False;
}
- attr->values[i].data = talloc_strdup(msg, value);
- attr->values[i].length = strlen(value);
-
- if ( ! attr->values[i].data) {
+ if (ldb_msg_add_string(module->ldb, msg, aname, aval) != 0) {
return False;
}
return True;
}
-static BOOL samldb_find_or_add_attribute(struct ldb_message *msg, const char *name, const char *value, const char *set_value)
+static BOOL samldb_msg_add_sid(struct ldb_module *module, struct ldb_message *msg, const char *name, const struct dom_sid *sid)
+{
+ struct ldb_val v;
+ NTSTATUS status;
+ status = ndr_push_struct_blob(&v, msg, sid,
+ (ndr_push_flags_fn_t)ndr_push_dom_sid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return -1;
+ }
+ return (ldb_msg_add_value(module->ldb, msg, name, &v) == 0);
+}
+
+static BOOL samldb_find_or_add_attribute(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *value, const char *set_value)
{
if (samldb_find_attribute(msg, name, value) == NULL) {
- if ( ! samldb_add_attribute(msg, name, set_value)) {
- return False;
- }
+ return samldb_msg_add_string(module, msg, name, set_value);
}
return True;
}
-static struct ldb_message *samldb_manage_group_object(struct ldb_module *module, const struct ldb_message *msg)
+static int samldb_copy_template(struct ldb_module *module, struct ldb_message *msg, const char *filter)
+{
+ struct ldb_message **res, *t;
+ int ret, i, j;
+
+
+ /* pull the template record */
+ ret = ldb_search(module->ldb, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res);
+ if (ret != 1) {
+ ldb_debug(module->ldb, LDB_DEBUG_WARNING, "samldb: ERROR: template '%s' matched %d records\n", filter, ret);
+ return -1;
+ }
+ t = res[0];
+
+ for (i = 0; i < t->num_elements; i++) {
+ struct ldb_message_element *el = &t->elements[i];
+ /* some elements should not be copied from the template */
+ if (strcasecmp(el->name, "cn") == 0 ||
+ strcasecmp(el->name, "name") == 0 ||
+ strcasecmp(el->name, "sAMAccountName") == 0 ||
+ strcasecmp(el->name, "objectGUID") == 0) {
+ continue;
+ }
+ for (j = 0; j < el->num_values; j++) {
+ if (strcasecmp(el->name, "objectClass") == 0 &&
+ (strcasecmp((char *)el->values[j].data, "Template") == 0 ||
+ strcasecmp((char *)el->values[j].data, "userTemplate") == 0 ||
+ strcasecmp((char *)el->values[j].data, "groupTemplate") == 0 ||
+ strcasecmp((char *)el->values[j].data, "foreignSecurityTemplate") == 0 ||
+ strcasecmp((char *)el->values[j].data, "aliasTemplate") == 0 ||
+ strcasecmp((char *)el->values[j].data, "trustedDomainTemplate") == 0 ||
+ strcasecmp((char *)el->values[j].data, "secretTemplate") == 0)) {
+ continue;
+ }
+ if ( ! samldb_find_or_add_attribute(module, msg, el->name,
+ NULL,
+ (char *)el->values[j].data)) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Attribute adding failed...\n");
+ talloc_free(res);
+ return -1;
+ }
+ }
+ }
+
+ talloc_free(res);
+
+ return 0;
+}
+
+static struct ldb_message *samldb_fill_group_object(struct ldb_module *module, const struct ldb_message *msg)
{
struct ldb_message *msg2;
struct ldb_message_element *attribute;
char *rdn, *basedn;
- int i;
if (samldb_find_attribute(msg, "objectclass", "group") == NULL) {
return NULL;
}
- msg2 = talloc(module, struct ldb_message);
+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_fill_group_object\n");
+
+ /* build the new msg */
+ msg2 = ldb_msg_copy(module->ldb, msg);
if (!msg2) {
- ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_group_object: talloc failed!\n");
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: ldb_msg_copy failed!\n");
return NULL;
}
- /* build the new msg */
- msg2->dn = msg->dn;
- msg2->num_elements = msg->num_elements;
- msg2->private_data = msg->private_data;
- msg2->elements = talloc_array(msg2, struct ldb_message_element, msg2->num_elements);
- if (! msg2->elements) {
- ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_group_object: talloc_array failed!\n");
- talloc_free(msg2);
+ if (samldb_copy_template(module, msg2, "(&(CN=TemplateGroup)(objectclass=groupTemplate))") != 0) {
+ ldb_debug(module->ldb, LDB_DEBUG_WARNING, "samldb_fill_group_object: Error copying template!\n");
return NULL;
}
- for (i = 0; i < msg2->num_elements; i++) {
- msg2->elements[i] = msg->elements[i];
- }
if ( ! samldb_get_rdn_and_basedn(msg2, msg2->dn, &rdn, &basedn)) {
- talloc_free(msg2);
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: Bad DN (%s)!\n", msg2->dn);
return NULL;
}
if (strncasecmp(rdn, "cn", 2) != 0) {
- ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_group_object: Bad RDN (%s) for group!\n", rdn);
- talloc_free(msg2);
- return NULL;
- }
-
- if (! samldb_find_or_add_attribute(msg2, "objectclass", "top", "top")) {
- talloc_free(msg2);
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: Bad RDN (%s) for group!\n", rdn);
return NULL;
}
if ((attribute = samldb_find_attribute(msg2, "cn", NULL)) != NULL) {
- if (strcasecmp(rdn, attribute->values[0].data) != 0) {
- ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_group_object: Bad Attribute Syntax for CN\n");
- talloc_free(msg2);
+ if (strcasecmp(&rdn[3], attribute->values[0].data) != 0) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: Bad Attribute Syntax for CN\n");
return NULL;
}
} else { /* FIXME: remove this if ldb supports natively aliasing between the rdn and the "cn" attribute */
- if ( ! samldb_add_attribute(msg2, "cn", &rdn[3])) {
- talloc_free(msg2);
+ if ( ! samldb_msg_add_string(module, msg2, "cn", &rdn[3])) {
return NULL;
}
}
if ((attribute = samldb_find_attribute(msg2, "name", NULL)) != NULL) {
- if (strcasecmp(rdn, attribute->values[0].data) != 0) {
- ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_group_object: Bad Attribute Syntax for name\n");
- talloc_free(msg2);
+ if (strcasecmp(&rdn[3], attribute->values[0].data) != 0) {
return NULL;
}
} else { /* FIXME: remove this if ldb supports natively aliasing between the rdn and the "name" attribute */
- if ( ! samldb_add_attribute(msg2, "name", &rdn[3])) {
- talloc_free(msg2);
+ if ( ! samldb_msg_add_string(module, msg2, "name", &rdn[3])) {
return NULL;
}
}
- if ( ! samldb_find_or_add_attribute(msg2, "instanceType", NULL, "4")) {
- return NULL;
- }
-
- if ( ! samldb_find_or_add_attribute(msg2, "sAMAccountName", NULL, samldb_generate_samAccountName(msg2))) {
- return NULL;
- }
-
- if ( ! samldb_find_or_add_attribute(msg2, "sAMAccountType", NULL, "268435456")) {
- return NULL;
- }
-
- if ( ! samldb_find_or_add_attribute(msg2, "groupType", NULL, "-2147483646")) {
- return NULL;
- }
+ if ((attribute = samldb_find_attribute(msg2, "objectSid", NULL)) == NULL ) {
+ struct dom_sid *sid = samldb_get_new_sid(module, msg2, msg2->dn);
+ if (sid == NULL) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: internal error! Can't generate new sid\n");
+ return NULL;
+ }
- if ( ! samldb_find_or_add_attribute(msg2, "objectCategory", NULL, "foo")) { /* keep the schema module happy :) */
- return NULL;
+ if (!samldb_msg_add_sid(module, msg2, "objectSid", sid)) {
+ talloc_free(sid);
+ return NULL;
+ }
+ talloc_free(sid);
}
- if ( ! samldb_find_or_add_attribute(msg2, "objectSid", NULL, "foo")) { /* keep the schema module happy :) */
+ if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", NULL, samldb_generate_samAccountName(msg2))) {
return NULL;
}
- /* TODO: objectGUID, objectSid, objectCategory */
- /* need a way to lock a new Sid */
+ talloc_steal(msg, msg2);
return msg2;
}
-static struct ldb_message *samldb_manage_user_object(struct ldb_module *module, const struct ldb_message *msg)
+static struct ldb_message *samldb_fill_user_or_computer_object(struct ldb_module *module, const struct ldb_message *msg)
{
struct ldb_message *msg2;
struct ldb_message_element *attribute;
char *rdn, *basedn;
- int i;
- if (samldb_find_attribute(msg, "objectclass", "user") == NULL) {
+ if ((samldb_find_attribute(msg, "objectclass", "user") == NULL) &&
+ (samldb_find_attribute(msg, "objectclass", "computer") == NULL)) {
return NULL;
}
- msg2 = talloc(module, struct ldb_message);
- if (!msg2) {
- ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_user_object: talloc failed!\n");
- return NULL;
- }
+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_fill_user_or_computer_object\n");
/* build the new msg */
- msg2->dn = msg->dn;
- msg2->num_elements = msg->num_elements;
- msg2->private_data = msg->private_data;
- msg2->elements = talloc_array(msg2, struct ldb_message_element, msg2->num_elements);
- if (! msg2->elements) {
- ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_user_object: talloc_array failed!\n");
- talloc_free(msg2);
+ msg2 = ldb_msg_copy(module->ldb, msg);
+ if (!msg2) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: ldb_msg_copy failed!\n");
return NULL;
}
- for (i = 0; i < msg2->num_elements; i++) {
- msg2->elements[i] = msg->elements[i];
+
+ if (samldb_find_attribute(msg, "objectclass", "computer") == NULL) {
+ if (samldb_copy_template(module, msg2, "(&(CN=TemplateMemberServer)(objectclass=userTemplate))") != 0) {
+ ldb_debug(module->ldb, LDB_DEBUG_WARNING, "samldb_fill_user_or_computer_object: Error copying computer template!\n");
+ return NULL;
+ }
+ } else {
+ if (samldb_copy_template(module, msg2, "(&(CN=TemplateUser)(objectclass=userTemplate))") != 0) {
+ ldb_debug(module->ldb, LDB_DEBUG_WARNING, "samldb_fill_user_or_computer_object: Error copying user template!\n");
+ return NULL;
+ }
}
if ( ! samldb_get_rdn_and_basedn(msg2, msg2->dn, &rdn, &basedn)) {
- talloc_free(msg2);
return NULL;
}
if (strncasecmp(rdn, "cn", 2) != 0) {
- ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_group_object: Bad RDN (%s) for group!\n", rdn);
- talloc_free(msg2);
- return NULL;
- }
-
-
- if ( ! samldb_find_or_add_attribute(msg2, "objectclass", "top", "top")) {
- talloc_free(msg2);
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_user_or_computer_object: Bad RDN (%s) for group!\n", rdn);
return NULL;
}
- if ( ! samldb_find_or_add_attribute(msg2, "objectclass", "person", "person")) {
- talloc_free(msg2);
- return NULL;
- }
-
- if ( ! samldb_find_or_add_attribute(msg2, "objectclass", "organizationalPerson", "organizationalPerson")) {
- talloc_free(msg2);
+ /* if the only attribute was: "objectclass: computer", then make sure we also add "user" objectclass */
+ if ( ! samldb_find_or_add_attribute(module, msg2, "objectclass", "user", "user")) {
return NULL;
}
if ((attribute = samldb_find_attribute(msg2, "cn", NULL)) != NULL) {
- if (strcasecmp(rdn, attribute->values[0].data) != 0) {
- ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_user_object: Bad Attribute Syntax for CN\n");
- talloc_free(msg2);
+ if (strcasecmp(&rdn[3], attribute->values[0].data) != 0) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_user_or_computer_object: Bad Attribute Syntax for CN\n");
return NULL;
}
} else { /* FIXME: remove this if ldb supports natively aliasing between the rdn and the "cn" attribute */
- if ( ! samldb_add_attribute(msg2, "cn", &rdn[3])) {
- talloc_free(msg2);
+ if ( ! samldb_msg_add_string(module, msg2, "cn", &rdn[3])) {
return NULL;
}
}
if ((attribute = samldb_find_attribute(msg2, "name", NULL)) != NULL) {
- if (strcasecmp(rdn, attribute->values[0].data) != 0) {
- ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_manage_user_object: Bad Attribute Syntax for name\n");
- talloc_free(msg2);
+ if (strcasecmp(&rdn[3], attribute->values[0].data) != 0) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_user_or_computer_object: Bad Attribute Syntax for name\n");
return NULL;
}
} else { /* FIXME: remove this if ldb supports natively aliasing between the rdn and the "name" attribute */
- if ( ! samldb_add_attribute(msg2, "name", &rdn[3])) {
- talloc_free(msg2);
+ if ( ! samldb_msg_add_string(module, msg2, "name", &rdn[3])) {
return NULL;
}
}
- if ( ! samldb_find_or_add_attribute(msg2, "instanceType", NULL, "4")) {
- talloc_free(msg2);
- return NULL;
- }
-
- if ( ! samldb_find_or_add_attribute(msg2, "sAMAccountName", NULL, samldb_generate_samAccountName(msg2))) {
- talloc_free(msg2);
- return NULL;
- }
-
- if ( ! samldb_find_or_add_attribute(msg2, "sAMAccountType", NULL, "805306368")) {
- talloc_free(msg2);
- return NULL;
- }
+ if ((attribute = samldb_find_attribute(msg2, "objectSid", NULL)) == NULL ) {
+ struct dom_sid *sid;
+ sid = samldb_get_new_sid(module, msg2, msg2->dn);
+ if (sid == NULL) {
+ ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_user_or_computer_object: internal error! Can't generate new sid\n");
+ return NULL;
+ }
- if ( ! samldb_find_or_add_attribute(msg2, "objectCategory", NULL, "foo")) { /* keep the schema module happy :) */
- return NULL;
+ if ( ! samldb_msg_add_sid(module, msg2, "objectSid", sid)) {
+ talloc_free(sid);
+ return NULL;
+ }
+ talloc_free(sid);
}
- if ( ! samldb_find_or_add_attribute(msg2, "objectSid", NULL, "foo")) { /* keep the schema module happy :) */
+ if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", NULL, samldb_generate_samAccountName(msg2))) {
return NULL;
}
- /* TODO: objectGUID, objectSid, objectCategory, userAccountControl, badPwdCount, codePage, countryCode, badPasswordTime, lastLogoff, lastLogon, pwdLastSet, primaryGroupID, accountExpires, logonCount */
+ /* TODO: objectCategory, userAccountControl, badPwdCount, codePage, countryCode, badPasswordTime, lastLogoff, lastLogon, pwdLastSet, primaryGroupID, accountExpires, logonCount */
return msg2;
}
return ldb_next_add_record(module, msg);
}
- /* is group? add all group relevant missing objects */
- msg2 = samldb_manage_group_object(module, msg);
+ /* is user or computer? add all relevant missing objects */
+ msg2 = samldb_fill_user_or_computer_object(module, msg);
- /* is user? add all user relevant missing objects */
+ /* is group? add all relevant missing objects */
if ( ! msg2 ) {
- msg2 = samldb_manage_user_object(module, msg);
+ msg2 = samldb_fill_group_object(module, msg);
}
if (msg2) {
ret = ldb_next_add_record(module, msg2);
- talloc_free(msg2);
} else {
ret = ldb_next_add_record(module, msg);
}
static int samldb_destructor(void *module_ctx)
{
- struct ldb_module *ctx = module_ctx;
+ /* struct ldb_module *ctx = module_ctx; */
/* put your clean-up functions here */
return 0;
}
static const struct ldb_module_ops samldb_ops = {
- "samldb",
- samldb_search,
- samldb_search_free,
- samldb_add_record,
- samldb_modify_record,
- samldb_delete_record,
- samldb_rename_record,
- samldb_lock,
- samldb_unlock,
- samldb_errstring
+ .name = "samldb",
+ .search = samldb_search,
+ .search_bytree = samldb_search_bytree,
+ .add_record = samldb_add_record,
+ .modify_record = samldb_modify_record,
+ .delete_record = samldb_delete_record,
+ .rename_record = samldb_rename_record,
+ .named_lock = samldb_lock,
+ .named_unlock = samldb_unlock,
+ .errstring = samldb_errstring
};