summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb/samdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/config.mk20
-rw-r--r--source4/dsdb/samdb/ldb_modules/extended_dn.c107
-rw-r--r--source4/dsdb/samdb/ldb_modules/kludge_acl.c57
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectguid.c72
-rw-r--r--source4/dsdb/samdb/ldb_modules/password_hash.c721
-rw-r--r--source4/dsdb/samdb/ldb_modules/rootdse.c42
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c101
7 files changed, 53 insertions, 1067 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk
index 20f6e182e5..3790d731d9 100644
--- a/source4/dsdb/samdb/ldb_modules/config.mk
+++ b/source4/dsdb/samdb/ldb_modules/config.mk
@@ -33,16 +33,16 @@ OBJ_FILES = \
# End MODULE ldb_samldb
################################################
-################################################
-# Start MODULE ldb_proxy
-[MODULE::ldb_proxy]
-SUBSYSTEM = ldb
-INIT_FUNCTION = proxy_module_init
-OBJ_FILES = \
- proxy.o
-#
-# End MODULE ldb_proxy
-################################################
+# ################################################
+# # Start MODULE ldb_proxy
+# [MODULE::ldb_proxy]
+# SUBSYSTEM = ldb
+# INIT_FUNCTION = proxy_module_init
+# OBJ_FILES = \
+# proxy.o
+#
+# # End MODULE ldb_proxy
+# ################################################
################################################
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn.c b/source4/dsdb/samdb/ldb_modules/extended_dn.c
index 8ca82b2670..1f2d406a28 100644
--- a/source4/dsdb/samdb/ldb_modules/extended_dn.c
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn.c
@@ -167,90 +167,6 @@ static BOOL inject_extended_dn(struct ldb_message *msg,
}
/* search */
-static int extended_search(struct ldb_module *module, struct ldb_control *control, struct ldb_request *req)
-{
- struct ldb_result *extended_result;
- struct ldb_control **saved_controls;
- struct ldb_extended_dn_control *extended_ctrl;
- int i, ret;
- const char * const *saved_attrs = NULL;
- char **new_attrs;
- BOOL remove_guid = False;
- BOOL remove_sid = False;
-
- extended_ctrl = talloc_get_type(control->data, struct ldb_extended_dn_control);
- if (!extended_ctrl) {
- return LDB_ERR_PROTOCOL_ERROR;
- }
-
- /* save it locally and remove it from the list */
- if (!save_controls(control, req, &saved_controls)) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* check if attrs only is specified, in that case check wether we need to modify them */
- if (req->op.search.attrs) {
- if (! is_attr_in_list(req->op.search.attrs, "objectGUID")) {
- remove_guid = True;
- }
- if (! is_attr_in_list(req->op.search.attrs, "objectSID")) {
- remove_sid = True;
- }
- if (remove_guid || remove_sid) {
- new_attrs = copy_attrs(req, req->op.search.attrs);
- if (!new_attrs)
- return LDB_ERR_OPERATIONS_ERROR;
-
- saved_attrs = req->op.search.attrs;
-
- if (remove_guid) {
- if (!add_attrs(req, &new_attrs, "objectGUID"))
- return LDB_ERR_OPERATIONS_ERROR;
- }
- if (remove_sid) {
- if (!add_attrs(req, &new_attrs, "objectSID"))
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- req->op.search.attrs = (const char * const *)new_attrs;
- }
- }
-
- ret = ldb_next_request(module, req);
-
- /* put request back into original shape */
- /* TODO: build a new req and don't touch the original one */
-
- if (req->controls) talloc_free(req->controls);
- req->controls = saved_controls;
-
- if (saved_attrs) {
- talloc_free(new_attrs);
- req->op.search.attrs = saved_attrs;
- }
-
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
- extended_result = req->op.search.res;
-
- for (i = 0; i < extended_result->count; i++) {
- /* TODO: the following funtion updates only dn and
- * distinguishedName. We still need to address other
- * DN entries like objectCategory
- */
- if (!inject_extended_dn(extended_result->msgs[i],
- extended_ctrl->type,
- remove_guid, remove_sid)) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
- return LDB_SUCCESS;
-}
-
-/* search */
struct extended_async_context {
struct ldb_module *module;
@@ -387,28 +303,6 @@ static int extended_search_async(struct ldb_module *module, struct ldb_request *
return ret;
}
-static int extended_request(struct ldb_module *module, struct ldb_request *req)
-{
- struct ldb_control *control;
-
- /* check if there's an extended dn control */
- control = get_control_from_list(req->controls, LDB_CONTROL_EXTENDED_DN_OID);
- if (control == NULL) {
- /* not found go on */
- return ldb_next_request(module, req);
- }
-
- switch (req->operation) {
-
- case LDB_REQ_SEARCH:
- return extended_search(module, control, req);
-
- default:
- return LDB_ERR_OPERATIONS_ERROR;
-
- }
-}
-
static int extended_init(struct ldb_module *module)
{
struct ldb_request *req;
@@ -437,7 +331,6 @@ static int extended_init(struct ldb_module *module)
static const struct ldb_module_ops extended_dn_ops = {
.name = "extended_dn",
.search = extended_search_async,
- .request = extended_request,
.init_context = extended_init
};
diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
index 23d96ba2b7..4e09faf269 100644
--- a/source4/dsdb/samdb/ldb_modules/kludge_acl.c
+++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
@@ -98,40 +98,6 @@ static const char *user_name(TALLOC_CTX *mem_ctx, struct ldb_module *module)
}
/* search */
-static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
-{
- struct kludge_private_data *data = talloc_get_type(module->private_data, struct kludge_private_data);
- struct ldb_message *msg;
- enum user_is user_type;
- int i, j, ret;
-
- /* go down the path and wait for reply to filter out stuff if needed */
- ret = ldb_next_request(module, req);
-
- /* We may not be fully initialised yet, or we might have just
- * got an error */
- if (ret != LDB_SUCCESS || !data->password_attrs) {
- return ret;
- }
-
- user_type = what_is_user(module);
- switch (user_type) {
- case SYSTEM:
- case ADMINISTRATOR:
- return ret;
- default:
- /* For every message, remove password attributes */
- for (i=0; i < req->op.search.res->count; i++) {
- msg = req->op.search.res->msgs[i];
- for (j=0; data->password_attrs[j]; j++) {
- ldb_msg_remove_attr(msg, data->password_attrs[j]);
- }
- }
- }
- return ret;
-}
-
-/* search */
struct kludge_acl_async_context {
struct ldb_module *module;
@@ -260,28 +226,6 @@ static int kludge_acl_del_trans(struct ldb_module *module)
return ldb_next_del_trans(module);
}
-static int kludge_acl_request(struct ldb_module *module, struct ldb_request *req)
-{
- switch (req->operation) {
-
- case LDB_REQ_ADD:
- case LDB_REQ_MODIFY:
- case LDB_REQ_DELETE:
- case LDB_REQ_RENAME:
- return kludge_acl_change(module, req);
-
- case LDB_REQ_SEARCH:
- return kludge_acl_search(module, req);
-
- case LDB_REQ_REGISTER:
- return ldb_next_request(module, req);
-
- default:
- /* anything else must be something new, let's throw an error */
- return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
- }
-}
-
static int kludge_acl_init(struct ldb_module *module)
{
int ret, i;
@@ -351,7 +295,6 @@ static const struct ldb_module_ops kludge_acl_ops = {
.modify = kludge_acl_change,
.del = kludge_acl_change,
.rename = kludge_acl_change,
- .request = kludge_acl_request,
.start_transaction = kludge_acl_start_trans,
.end_transaction = kludge_acl_end_trans,
.del_transaction = kludge_acl_del_trans,
diff --git a/source4/dsdb/samdb/ldb_modules/objectguid.c b/source4/dsdb/samdb/ldb_modules/objectguid.c
index 5ac3260339..643f8c17fd 100644
--- a/source4/dsdb/samdb/ldb_modules/objectguid.c
+++ b/source4/dsdb/samdb/ldb_modules/objectguid.c
@@ -53,62 +53,6 @@ static struct ldb_message_element *objectguid_find_attribute(const struct ldb_me
/* add_record: add objectGUID attribute */
static int objectguid_add(struct ldb_module *module, struct ldb_request *req)
{
- struct ldb_message *msg = req->op.add.message;
- struct ldb_val v;
- struct ldb_message *msg2;
- struct ldb_message_element *attribute;
- struct GUID guid;
- NTSTATUS nt_status;
- int ret, i;
-
- ldb_debug(module->ldb, LDB_DEBUG_TRACE, "objectguid_add_record\n");
-
- if (ldb_dn_is_special(msg->dn)) { /* do not manipulate our control entries */
- return ldb_next_request(module, req);
- }
-
- if ((attribute = objectguid_find_attribute(msg, "objectGUID")) != NULL ) {
- return ldb_next_request(module, req);
- }
-
- msg2 = talloc(module, struct ldb_message);
- if (!msg2) {
- return -1;
- }
-
- 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);
- for (i = 0; i < msg2->num_elements; i++) {
- msg2->elements[i] = msg->elements[i];
- }
-
- /* a new GUID */
- guid = GUID_random();
-
- nt_status = ndr_push_struct_blob(&v, msg2, &guid,
- (ndr_push_flags_fn_t)ndr_push_GUID);
- if (!NT_STATUS_IS_OK(nt_status)) {
- return -1;
- }
-
- ret = ldb_msg_add_value(msg2, "objectGUID", &v);
- if (ret) {
- return ret;
- }
-
- req->op.add.message = msg2;
- ret = ldb_next_request(module, req);
- req->op.add.message = msg;
-
- talloc_free(msg2);
-
- return ret;
-}
-
-static int objectguid_add_async(struct ldb_module *module, struct ldb_request *req)
-{
struct ldb_request *down_req;
struct ldb_message_element *attribute;
struct ldb_message *msg;
@@ -167,23 +111,9 @@ static int objectguid_add_async(struct ldb_module *module, struct ldb_request *r
return ret;
}
-static int objectguid_request(struct ldb_module *module, struct ldb_request *req)
-{
- switch (req->operation) {
-
- case LDB_REQ_ADD:
- return objectguid_add(module, req);
-
- default:
- return ldb_next_request(module, req);
-
- }
-}
-
static const struct ldb_module_ops objectguid_ops = {
.name = "objectguid",
- .add = objectguid_add_async,
- .request = objectguid_request
+ .add = objectguid_add,
};
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index bdf1bcc27a..16fe6b8f4d 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -65,678 +65,10 @@
*
*/
-
-static int password_hash_handle(struct ldb_module *module, struct ldb_request *req,
- const struct ldb_message *msg)
-{
- int ret, old_ret = -1;
- uint_t pwdProperties, pwdHistoryLength;
- uint_t userAccountControl;
- const char *dnsDomain, *realm;
- const char *sambaPassword = NULL;
- struct samr_Password *sambaLMPwdHistory, *sambaNTPwdHistory;
- struct samr_Password *lmPwdHash, *ntPwdHash;
- struct samr_Password *lmOldHash = NULL, *ntOldHash = NULL;
- struct samr_Password *new_sambaLMPwdHistory, *new_sambaNTPwdHistory;
- struct samr_Password local_lmNewHash, local_ntNewHash;
- int sambaLMPwdHistory_len, sambaNTPwdHistory_len;
- uint_t kvno;
- struct dom_sid *domain_sid;
- time_t now = time(NULL);
- NTTIME now_nt;
- int i;
- krb5_error_code krb5_ret;
-
- struct smb_krb5_context *smb_krb5_context;
-
- struct ldb_message_element *attribute;
- struct ldb_dn *dn = msg->dn;
- struct ldb_message *msg2;
-
- struct ldb_request *search_request = NULL;
- struct ldb_request *modify_request;
- struct ldb_request *modified_orig_request;
- struct ldb_result *res, *dom_res, *old_res;
-
- struct ldb_message_element *objectclasses;
- struct ldb_val computer_val;
- struct ldb_val person_val;
- BOOL is_computer;
-
- struct ldb_message *modify_msg;
-
- const char *domain_expression;
- const char *old_user_attrs[] = { "lmPwdHash", "ntPwdHash", NULL };
- const char *user_attrs[] = { "userAccountControl", "sambaLMPwdHistory",
- "sambaNTPwdHistory",
- "ntPwdHash",
- "objectSid", "msDS-KeyVersionNumber",
- "objectClass", "userPrincipalName",
- "samAccountName",
- NULL };
- const char * const domain_attrs[] = { "pwdProperties", "pwdHistoryLength",
- "dnsDomain", NULL };
-
- TALLOC_CTX *mem_ctx;
-
- /* Do the original action */
-
- mem_ctx = talloc_new(module);
- if (!mem_ctx) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (req->operation == LDB_REQ_MODIFY) {
- search_request = talloc(mem_ctx, struct ldb_request);
- if (!search_request) {
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* Look up the old ntPwdHash and lmPwdHash values, so
- * we can later place these into the password
- * history */
-
- search_request->operation = LDB_REQ_SEARCH;
- search_request->op.search.base = dn;
- search_request->op.search.scope = LDB_SCOPE_BASE;
- search_request->op.search.tree = ldb_parse_tree(module->ldb, NULL);
- search_request->op.search.attrs = old_user_attrs;
- search_request->controls = NULL;
-
- old_ret = ldb_next_request(module, search_request);
- }
-
- /* we can't change things untill we copy it */
- msg2 = ldb_msg_copy_shallow(mem_ctx, msg);
-
- /* look again, this time at the copied attribute */
- if (!msg2 || (attribute = ldb_msg_find_element(msg2, "sambaPassword")) == NULL ) {
- talloc_free(mem_ctx);
- /* Gah? where did it go? Oh well... */
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* Wipe out the sambaPassword attribute set, we will handle it in
- * the second modify. We might not want it written to disk */
-
- if (req->operation == LDB_REQ_ADD) {
- if (attribute->num_values > 1) {
- ldb_set_errstring(module->ldb,
- talloc_asprintf(mem_ctx, "sambaPassword_handle: "
- "attempted set of multiple sambaPassword attributes on %s rejected",
- ldb_dn_linearize(mem_ctx, dn)));
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
-
- if (attribute->num_values == 1) {
- sambaPassword = (const char *)attribute->values[0].data;
- ldb_msg_remove_attr(msg2, "sambaPassword");
- }
- } else if (((attribute->flags & LDB_FLAG_MOD_MASK) == LDB_FLAG_MOD_ADD)
- || ((attribute->flags & LDB_FLAG_MOD_MASK) == LDB_FLAG_MOD_REPLACE)) {
- if (attribute->num_values > 1) {
- ldb_set_errstring(module->ldb,
- talloc_asprintf(mem_ctx, "sambaPassword_handle: "
- "attempted set of multiple sambaPassword attributes on %s rejected",
- ldb_dn_linearize(mem_ctx, dn)));
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
-
- if (attribute->num_values == 1) {
- sambaPassword = (const char *)attribute->values[0].data;
- ldb_msg_remove_attr(msg2, "sambaPassword");
- }
- }
-
- modified_orig_request = talloc(mem_ctx, struct ldb_request);
- if (!modified_orig_request) {
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- *modified_orig_request = *req;
- switch (modified_orig_request->operation) {
- case LDB_REQ_ADD:
- modified_orig_request->op.add.message = msg2;
- break;
- case LDB_REQ_MODIFY:
- modified_orig_request->op.mod.message = msg2;
- break;
- default:
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* Send the (modified) request of the original caller down to the database */
- ret = ldb_next_request(module, modified_orig_request);
- if (ret) {
- talloc_free(mem_ctx);
- return ret;
- }
-
- /* While we do the search first (for the old password hashes),
- * we don't want to override any error that the modify may
- * have returned. Now check the error */
- if (req->operation == LDB_REQ_MODIFY) {
- if (old_ret) {
- talloc_free(mem_ctx);
- return old_ret;
- }
-
- /* Find out the old passwords details of the user */
- old_res = search_request->op.search.res;
- talloc_steal(mem_ctx, old_res);
- talloc_free(search_request);
-
- if (old_res->count != 1) {
- ldb_set_errstring(module->ldb,
- talloc_asprintf(mem_ctx, "password_hash_handle: "
- "(pre) search for %s found %d != 1 objects, for entry we just modified",
- ldb_dn_linearize(mem_ctx, dn),
- old_res->count));
- /* What happend? The above add/modify worked... */
- talloc_free(mem_ctx);
- return LDB_ERR_NO_SUCH_OBJECT;
- }
-
- lmOldHash = samdb_result_hash(mem_ctx, old_res->msgs[0], "lmPwdHash");
- ntOldHash = samdb_result_hash(mem_ctx, old_res->msgs[0], "ntPwdHash");
- }
-
- /* Start finding out details we need for the second modify.
- * We do this after the first add/modify because other modules
- * will have filled in the templates, and we may have had
- * things like the username (affecting the salt) changed along
- * with the password. */
-
- /* Now find out what is on the entry after the above add/modify */
- search_request = talloc(mem_ctx, struct ldb_request);
- if (!search_request) {
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- search_request->operation = LDB_REQ_SEARCH;
- search_request->op.search.base = dn;
- search_request->op.search.scope = LDB_SCOPE_BASE;
- search_request->op.search.tree = ldb_parse_tree(module->ldb, NULL);
- search_request->op.search.attrs = user_attrs;
- search_request->controls = NULL;
-
- ret = ldb_next_request(module, search_request);
- if (ret) {
- talloc_free(mem_ctx);
- return ret;
- }
-
- /* Find out the full details of the user */
- res = search_request->op.search.res;
- talloc_steal(mem_ctx, res);
- talloc_free(search_request);
-
- if (res->count != 1) {
- ldb_set_errstring(module->ldb,
- talloc_asprintf(mem_ctx, "password_hash_handle: "
- "search for %s found %d != 1 objects, for entry we just added/modified",
- ldb_dn_linearize(mem_ctx, dn),
- res->count));
- /* What happend? The above add/modify worked... */
- talloc_free(mem_ctx);
- return LDB_ERR_NO_SUCH_OBJECT;
- }
-
- userAccountControl = samdb_result_uint(res->msgs[0], "userAccountControl", 0);
- sambaLMPwdHistory_len = samdb_result_hashes(mem_ctx, res->msgs[0],
- "sambaLMPwdHistory", &sambaLMPwdHistory);
- sambaNTPwdHistory_len = samdb_result_hashes(mem_ctx, res->msgs[0],
- "sambaNTPwdHistory", &sambaNTPwdHistory);
- ntPwdHash = samdb_result_hash(mem_ctx, res->msgs[0], "ntPwdHash");
- kvno = samdb_result_uint(res->msgs[0], "msDS-KeyVersionNumber", 0);
-
- domain_sid = samdb_result_sid_prefix(mem_ctx, res->msgs[0], "objectSid");
-
-
- objectclasses = ldb_msg_find_element(res->msgs[0], "objectClass");
- person_val = data_blob_string_const("person");
-
- if (!objectclasses || !ldb_msg_find_val(objectclasses, &person_val)) {
- /* Not a 'person', so the rest of this doesn't make
- * sense. How we got a sambaPassword this far I don't
- * know... */
- ldb_set_errstring(module->ldb,
- talloc_asprintf(mem_ctx, "password_hash_handle: "
- "attempted set of sambaPassword on non-'person' object %s rejected",
- ldb_dn_linearize(mem_ctx, dn)));
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
-
- computer_val = data_blob_string_const("computer");
-
- if (ldb_msg_find_val(objectclasses, &computer_val)) {
- is_computer = True;
- } else {
- is_computer = False;
- }
-
- domain_expression = talloc_asprintf(mem_ctx, "(&(objectSid=%s)(objectClass=domain))",
- ldap_encode_ndr_dom_sid(mem_ctx, domain_sid));
-
- /* Find the user's domain, then find out the domain password
- * properties */
- ret = ldb_search(module->ldb, NULL, LDB_SCOPE_SUBTREE, domain_expression,
- domain_attrs, &dom_res);
- if (ret) {
- talloc_free(mem_ctx);
- return ret;
- }
-
- if (dom_res->count != 1) {
- /* What happend? The user we are modifying must be odd... */
- ldb_set_errstring(module->ldb,
- talloc_asprintf(mem_ctx, "password_hash_handle: "
- "search for domain %s found %d != 1 objects",
- dom_sid_string(mem_ctx, domain_sid),
- dom_res->count));
- talloc_free(mem_ctx);
- return LDB_ERR_NO_SUCH_OBJECT;
- }
-
- pwdProperties = samdb_result_uint(dom_res->msgs[0], "pwdProperties", 0);
- pwdHistoryLength = samdb_result_uint(dom_res->msgs[0], "pwdHistoryLength", 0);
- dnsDomain = ldb_msg_find_string(dom_res->msgs[0], "dnsDomain", NULL);
- realm = strupper_talloc(mem_ctx, dnsDomain);
-
- /* Some operations below require kerberos contexts */
- if (smb_krb5_init_context(mem_ctx, &smb_krb5_context) != 0) {
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* Prepare the modifications to set all the hash/key types */
- modify_msg = ldb_msg_new(req);
- modify_msg->dn = talloc_reference(modify_msg, dn);
-
-#define CHECK_RET(x) \
- do { \
- int check_ret = x; \
- if (check_ret != LDB_SUCCESS) { \
- talloc_free(mem_ctx); \
- return check_ret; \
- } \
- } while(0)
-
- /* Setup krb5Key (we want to either delete an existing value,
- * or replace with a new one). Both the unicode and NT hash
- * only branches append keys to this multivalued entry. */
- CHECK_RET(ldb_msg_add_empty(modify_msg, "krb5Key", LDB_FLAG_MOD_REPLACE));
-
- /* Yay, we can compute new password hashes from the unicode
- * password */
- if (sambaPassword) {
- Principal *salt_principal;
- const char *user_principal_name = ldb_msg_find_string(res->msgs[0], "userPrincipalName", NULL);
-
- Key *keys;
- size_t num_keys;
-
- /* compute the new nt and lm hashes */
- if (E_deshash(sambaPassword, local_lmNewHash.hash)) {
- lmPwdHash = &local_lmNewHash;
- } else {
- lmPwdHash = NULL;
- }
- E_md4hash(sambaPassword, local_ntNewHash.hash);
- ntPwdHash = &local_ntNewHash;
- CHECK_RET(ldb_msg_add_empty(modify_msg, "ntPwdHash",
- LDB_FLAG_MOD_REPLACE));
- CHECK_RET(samdb_msg_add_hash(module->ldb, req,
- modify_msg, "ntPwdHash",
- ntPwdHash));
- CHECK_RET(ldb_msg_add_empty(modify_msg, "lmPwdHash",
- LDB_FLAG_MOD_REPLACE));
- if (lmPwdHash) {
- CHECK_RET(samdb_msg_add_hash(module->ldb, req,
- modify_msg, "lmPwdHash",
- lmPwdHash));
- }
-
- /* Many, many thanks to lukeh@padl.com for this
- * algorithm, described in his Nov 10 2004 mail to
- * samba-technical@samba.org */
-
- if (is_computer) {
- /* Determine a salting principal */
- char *samAccountName = talloc_strdup(mem_ctx, ldb_msg_find_string(res->msgs[0], "samAccountName", NULL));
- char *saltbody;
- if (!samAccountName) {
- ldb_set_errstring(module->ldb,
- talloc_asprintf(mem_ctx, "password_hash_handle: "
- "generation of new kerberos keys failed: %s is a computer without a samAccountName",
- ldb_dn_linearize(mem_ctx, dn)));
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- if (samAccountName[strlen(samAccountName)-1] == '$') {
- samAccountName[strlen(samAccountName)-1] = '\0';
- }
- saltbody = talloc_asprintf(mem_ctx, "%s.%s", samAccountName, dnsDomain);
-
- krb5_ret = krb5_make_principal(smb_krb5_context->krb5_context, &salt_principal, realm, "host", saltbody, NULL);
- } else if (user_principal_name) {
- char *p;
- user_principal_name = talloc_strdup(mem_ctx, user_principal_name);
- if (!user_principal_name) {
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- } else {
- p = strchr(user_principal_name, '@');
- if (p) {
- p[0] = '\0';
- }
- krb5_ret = krb5_make_principal(smb_krb5_context->krb5_context, &salt_principal, realm, user_principal_name, NULL);
- }
- } else {
- const char *samAccountName = ldb_msg_find_string(res->msgs[0], "samAccountName", NULL);
- if (!samAccountName) {
- ldb_set_errstring(module->ldb,
- talloc_asprintf(mem_ctx, "password_hash_handle: "
- "generation of new kerberos keys failed: %s has no samAccountName",
- ldb_dn_linearize(mem_ctx, dn)));
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- krb5_ret = krb5_make_principal(smb_krb5_context->krb5_context, &salt_principal, realm, samAccountName, NULL);
- }
-
-
- if (krb5_ret) {
- ldb_set_errstring(module->ldb,
- talloc_asprintf(mem_ctx, "password_hash_handle: "
- "generation of a saltking principal failed: %s",
- smb_get_krb5_error_message(smb_krb5_context->krb5_context,
- krb5_ret, mem_ctx)));
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* TODO: We may wish to control the encryption types chosen in future */
- krb5_ret = hdb_generate_key_set_password(smb_krb5_context->krb5_context,
- salt_principal, sambaPassword, &keys, &num_keys);
- krb5_free_principal(smb_krb5_context->krb5_context, salt_principal);
-
- if (krb5_ret) {
- ldb_set_errstring(module->ldb,
- talloc_asprintf(mem_ctx, "password_hash_handle: "
- "generation of new kerberos keys failed: %s",
- smb_get_krb5_error_message(smb_krb5_context->krb5_context,
- krb5_ret, mem_ctx)));
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* Walking all the key types generated, transform each
- * key into an ASN.1 blob
- */
- for (i=0; i < num_keys; i++) {
- unsigned char *buf;
- size_t buf_size;
- size_t len;
- struct ldb_val val;
-
- if (keys[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) {
- /* We might end up doing this below:
- * This ensures we get the unicode
- * conversion right. This should also
- * be fixed in the Heimdal libs */
- continue;
- }
- ASN1_MALLOC_ENCODE(Key, buf, buf_size, &keys[i], &len, krb5_ret);
- if (krb5_ret) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- val.data = talloc_memdup(req, buf, len);
- val.length = len;
- free(buf);
- if (!val.data || krb5_ret) {
- hdb_free_keys (smb_krb5_context->krb5_context, num_keys, keys);
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ret = ldb_msg_add_value(modify_msg, "krb5Key", &val);
- if (ret != LDB_SUCCESS) {
- hdb_free_keys (smb_krb5_context->krb5_context, num_keys, keys);
- talloc_free(mem_ctx);
- return ret;
- }
- }
-
- hdb_free_keys (smb_krb5_context->krb5_context, num_keys, keys);
- }
-
- /* Possibly kill off the cleartext or store it */
- CHECK_RET(ldb_msg_add_empty(modify_msg, "sambaPassword", LDB_FLAG_MOD_REPLACE));
-
- if (sambaPassword && (pwdProperties & DOMAIN_PASSWORD_STORE_CLEARTEXT) &&
- (userAccountControl & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
- CHECK_RET(ldb_msg_add_string(modify_msg, "sambaPassword", sambaPassword));
- }
-
- /* Even if we didn't get a sambaPassword, we can still setup
- * krb5Key from the NT hash.
- *
- * This is an append, so it works with the 'continue' in the
- * unicode loop above, to use Samba's NT hash function, which
- * is more correct than Heimdal's
- */
- if (ntPwdHash) {
- unsigned char *buf;
- size_t buf_size;
- size_t len;
- struct ldb_val val;
- Key key;
-
- key.mkvno = 0;
- key.salt = NULL; /* No salt for this enc type */
-
- krb5_ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
- ETYPE_ARCFOUR_HMAC_MD5,
- ntPwdHash->hash, sizeof(ntPwdHash->hash),
- &key.key);
- if (krb5_ret) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ASN1_MALLOC_ENCODE(Key, buf, buf_size, &key, &len, krb5_ret);
- if (krb5_ret) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &key.key);
-
- val.data = talloc_memdup(req, buf, len);
- val.length = len;
- free(buf);
- if (!val.data || ret) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- CHECK_RET(ldb_msg_add_value(modify_msg, "krb5Key", &val));
- }
-
- /* If the original caller did anything with pwdLastSet then skip this. It could be an incoming samsync */
- attribute = ldb_msg_find_element(msg, "pwdLastSet");
- if (attribute == NULL) {
- /* Update the password last set time */
- unix_to_nt_time(&now_nt, now);
- CHECK_RET(ldb_msg_add_empty(modify_msg, "pwdLastSet", LDB_FLAG_MOD_REPLACE));
- CHECK_RET(samdb_msg_add_uint64(module->ldb, mem_ctx, modify_msg, "pwdLastSet", now_nt));
- }
-
- /* If the original caller did anything with "msDS-KeyVersionNumber" then skip this. It could be an incoming samsync */
- attribute = ldb_msg_find_element(msg, "msDS-KeyVersionNumber");
- if (attribute == NULL) {
- if (kvno == 0) {
- CHECK_RET(ldb_msg_add_empty(modify_msg, "msDS-KeyVersionNumber",
- LDB_FLAG_MOD_REPLACE));
- CHECK_RET(samdb_msg_add_uint(module->ldb, mem_ctx, modify_msg, "msDS-KeyVersionNumber", kvno + 1));
- } else {
- /* While we should be in a transaction, go one extra
- * step in the dance for an 'atomic' increment. This
- * may be of value against remote LDAP servers. (Note
- * however that Mulitmaster replication stil offers no
- * such guarantee) */
-
- struct ldb_val old_kvno, new_kvno;
- old_kvno.data = (uint8_t *)talloc_asprintf(mem_ctx, "%u", kvno);
- if (!old_kvno.data) {
- return -1;
- }
- old_kvno.length = strlen((char *)old_kvno.data);
-
- new_kvno.data = (uint8_t *)talloc_asprintf(mem_ctx, "%u", kvno + 1);
- if (!new_kvno.data) {
- return -1;
- }
- new_kvno.length = strlen((char *)new_kvno.data);
-
- CHECK_RET(ldb_msg_add_empty(modify_msg, "msDS-KeyVersionNumber",
- LDB_FLAG_MOD_DELETE));
- CHECK_RET(ldb_msg_add_empty(modify_msg, "msDS-KeyVersionNumber",
- LDB_FLAG_MOD_ADD));
- modify_msg->elements[modify_msg->num_elements - 2].num_values = 1;
- modify_msg->elements[modify_msg->num_elements - 2].values = &old_kvno;
- modify_msg->elements[modify_msg->num_elements - 1].num_values = 1;
- modify_msg->elements[modify_msg->num_elements - 1].values = &new_kvno;
- }
- }
-
- CHECK_RET(ldb_msg_add_empty(modify_msg, "sambaLMPwdHistory",
- LDB_FLAG_MOD_REPLACE));
- CHECK_RET(ldb_msg_add_empty(modify_msg, "sambaNTPwdHistory",
- LDB_FLAG_MOD_REPLACE));
-
- /* If we have something to put into the history, or an old
- * history element to expire, update the history */
- if (pwdHistoryLength > 0 &&
- ((sambaNTPwdHistory_len > 0) || (sambaLMPwdHistory_len > 0)
- || lmOldHash || ntOldHash)) {
- /* store the password history */
- new_sambaLMPwdHistory = talloc_array(mem_ctx, struct samr_Password,
- pwdHistoryLength);
- if (!new_sambaLMPwdHistory) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- new_sambaNTPwdHistory = talloc_array(mem_ctx, struct samr_Password,
- pwdHistoryLength);
- if (!new_sambaNTPwdHistory) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- for (i=0;i<MIN(pwdHistoryLength-1, sambaLMPwdHistory_len);i++) {
- new_sambaLMPwdHistory[i+1] = sambaLMPwdHistory[i];
- }
- for (i=0;i<MIN(pwdHistoryLength-1, sambaNTPwdHistory_len);i++) {
- new_sambaNTPwdHistory[i+1] = sambaNTPwdHistory[i];
- }
-
- /* Don't store 'long' passwords in the LM history,
- but make sure to 'expire' one password off the other end */
- if (lmOldHash) {
- new_sambaLMPwdHistory[0] = *lmOldHash;
- } else {
- ZERO_STRUCT(new_sambaLMPwdHistory[0]);
- }
- sambaLMPwdHistory_len = MIN(sambaLMPwdHistory_len + 1, pwdHistoryLength);
-
- /* Likewise, we might not have an old NT password (lm
- * only password change function on previous change) */
- if (ntOldHash) {
- new_sambaNTPwdHistory[0] = *ntOldHash;
- } else {
- ZERO_STRUCT(new_sambaNTPwdHistory[0]);
- }
- sambaNTPwdHistory_len = MIN(sambaNTPwdHistory_len + 1, pwdHistoryLength);
-
- CHECK_RET(samdb_msg_add_hashes(mem_ctx, modify_msg,
- "sambaLMPwdHistory",
- new_sambaLMPwdHistory,
- sambaLMPwdHistory_len));
-
- CHECK_RET(samdb_msg_add_hashes(mem_ctx, modify_msg,
- "sambaNTPwdHistory",
- new_sambaNTPwdHistory,
- sambaNTPwdHistory_len));
- }
-
- /* Too much code above, we should check we got it close to reasonable */
- CHECK_RET(ldb_msg_sanity_check(modify_msg));
-
- modify_request = talloc(mem_ctx, struct ldb_request);
- if (!modify_request) {
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- modify_request->operation = LDB_REQ_MODIFY;
- modify_request->op.mod.message = modify_msg;
- modify_request->controls = NULL;
-
- ret = ldb_next_request(module, modify_request);
-
- talloc_free(mem_ctx);
- return ret;
-}
-
-/* add_record: do things with the sambaPassword attribute */
-static int password_hash_add(struct ldb_module *module, struct ldb_request *req)
-{
- const struct ldb_message *msg = req->op.add.message;
-
- ldb_debug(module->ldb, LDB_DEBUG_TRACE, "password_hash_add_record\n");
-
- if (ldb_dn_is_special(msg->dn)) { /* do not manipulate our control entries */
- return ldb_next_request(module, req);
- }
-
- /* If no part of this touches the sambaPassword, then we don't
- * need to make any changes. For password changes/set there should
- * be a 'delete' or a 'modify' on this attribute. */
- if (ldb_msg_find_element(msg, "sambaPassword") == NULL ) {
- return ldb_next_request(module, req);
- }
-
- return password_hash_handle(module, req, msg);
-}
-
-/* modify_record: do things with the sambaPassword attribute */
-static int password_hash_modify(struct ldb_module *module, struct ldb_request *req)
-{
- const struct ldb_message *msg = req->op.mod.message;
-
- ldb_debug(module->ldb, LDB_DEBUG_TRACE, "password_hash_modify_record\n");
-
- if (ldb_dn_is_special(msg->dn)) { /* do not manipulate our control entries */
- return ldb_next_request(module, req);
- }
-
- /* If no part of this touches the sambaPassword, then we don't
- * need to make any changes. For password changes/set there should
- * be a 'delete' or a 'modify' on this attribute. */
- if (ldb_msg_find_element(msg, "sambaPassword") == NULL ) {
- return ldb_next_request(module, req);
- }
-
- return password_hash_handle(module, req, msg);
-}
-
-enum ph_type {PH_ADD, PH_MOD};
-enum ph_step {PH_ADD_SEARCH_DOM, PH_ADD_DO_ADD, PH_MOD_DO_REQ, PH_MOD_SEARCH_SELF, PH_MOD_SEARCH_DOM, PH_MOD_DO_MOD};
-
struct ph_async_context {
- enum ph_type type;
- enum ph_step step;
+ enum ph_type {PH_ADD, PH_MOD} type;
+ enum ph_step {PH_ADD_SEARCH_DOM, PH_ADD_DO_ADD, PH_MOD_DO_REQ, PH_MOD_SEARCH_SELF, PH_MOD_SEARCH_DOM, PH_MOD_DO_MOD} step;
struct ldb_module *module;
struct ldb_request *orig_req;
@@ -1212,7 +544,7 @@ static struct domain_data *get_domain_data(struct ldb_module *module, void *mem_
return data;
}
-static int password_hash_add_async(struct ldb_module *module, struct ldb_request *req)
+static int password_hash_add(struct ldb_module *module, struct ldb_request *req)
{
struct ldb_async_handle *h;
struct ph_async_context *ac;
@@ -1220,7 +552,7 @@ static int password_hash_add_async(struct ldb_module *module, struct ldb_request
struct dom_sid *domain_sid;
int ret;
- ldb_debug(module->ldb, LDB_DEBUG_TRACE, "password_hash_add_async\n");
+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "password_hash_add\n");
if (ldb_dn_is_special(req->op.add.message->dn)) { /* do not manipulate our control entries */
return ldb_next_request(module, req);
@@ -1278,7 +610,7 @@ static int password_hash_add_async(struct ldb_module *module, struct ldb_request
return ldb_next_request(module, ac->dom_req);
}
-static int password_hash_add_async_do_add(struct ldb_async_handle *h) {
+static int password_hash_add_do_add(struct ldb_async_handle *h) {
struct ph_async_context *ac;
struct domain_data *domain;
@@ -1357,9 +689,9 @@ static int password_hash_add_async_do_add(struct ldb_async_handle *h) {
return ldb_next_request(ac->module, ac->down_req);
}
-static int password_hash_mod_async_search_self(struct ldb_async_handle *h);
+static int password_hash_mod_search_self(struct ldb_async_handle *h);
-static int password_hash_modify_async(struct ldb_module *module, struct ldb_request *req)
+static int password_hash_modify(struct ldb_module *module, struct ldb_request *req)
{
struct ldb_async_handle *h;
struct ph_async_context *ac;
@@ -1367,7 +699,7 @@ static int password_hash_modify_async(struct ldb_module *module, struct ldb_requ
struct ldb_message_element *ntAttr;
struct ldb_message_element *lmAttr;
- ldb_debug(module->ldb, LDB_DEBUG_TRACE, "password_hash_add_async\n");
+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "password_hash_modify\n");
if (ldb_dn_is_special(req->op.mod.message->dn)) { /* do not manipulate our control entries */
return ldb_next_request(module, req);
@@ -1437,7 +769,7 @@ static int password_hash_modify_async(struct ldb_module *module, struct ldb_requ
if (ac->down_req->op.mod.message->num_elements == 0) {
talloc_free(ac->down_req);
ac->down_req = NULL;
- return password_hash_mod_async_search_self(h);
+ return password_hash_mod_search_self(h);
}
ac->down_req->async.context = NULL;
@@ -1483,7 +815,7 @@ static int get_self_callback(struct ldb_context *ldb, void *context, struct ldb_
return LDB_SUCCESS;
}
-static int password_hash_mod_async_search_self(struct ldb_async_handle *h) {
+static int password_hash_mod_search_self(struct ldb_async_handle *h) {
struct ph_async_context *ac;
@@ -1515,7 +847,7 @@ static int password_hash_mod_async_search_self(struct ldb_async_handle *h) {
return ldb_next_request(ac->module, ac->search_req);
}
-static int password_hash_mod_async_search_dom(struct ldb_async_handle *h) {
+static int password_hash_mod_search_dom(struct ldb_async_handle *h) {
struct ph_async_context *ac;
struct dom_sid *domain_sid;
@@ -1541,7 +873,7 @@ static int password_hash_mod_async_search_dom(struct ldb_async_handle *h) {
return ldb_next_request(ac->module, ac->dom_req);
}
-static int password_hash_mod_async_do_mod(struct ldb_async_handle *h) {
+static int password_hash_mod_do_mod(struct ldb_async_handle *h) {
struct ph_async_context *ac;
struct domain_data *domain;
@@ -1700,7 +1032,7 @@ static int ph_async_wait(struct ldb_async_handle *handle) {
}
/* domain search done, go on */
- return password_hash_add_async_do_add(handle);
+ return password_hash_add_do_add(handle);
case PH_ADD_DO_ADD:
ret = ldb_async_wait(ac->down_req->async.handle, LDB_WAIT_NONE);
@@ -1737,7 +1069,7 @@ static int ph_async_wait(struct ldb_async_handle *handle) {
}
/* non-password mods done, go on */
- return password_hash_mod_async_search_self(handle);
+ return password_hash_mod_search_self(handle);
case PH_MOD_SEARCH_SELF:
ret = ldb_async_wait(ac->search_req->async.handle, LDB_WAIT_NONE);
@@ -1756,7 +1088,7 @@ static int ph_async_wait(struct ldb_async_handle *handle) {
}
/* self search done, go on */
- return password_hash_mod_async_search_dom(handle);
+ return password_hash_mod_search_dom(handle);
case PH_MOD_SEARCH_DOM:
ret = ldb_async_wait(ac->dom_req->async.handle, LDB_WAIT_NONE);
@@ -1775,7 +1107,7 @@ static int ph_async_wait(struct ldb_async_handle *handle) {
}
/* domain search done, go on */
- return password_hash_mod_async_do_mod(handle);
+ return password_hash_mod_do_mod(handle);
case PH_MOD_DO_MOD:
ret = ldb_async_wait(ac->mod_req->async.handle, LDB_WAIT_NONE);
@@ -1830,27 +1162,10 @@ static int password_hash_async_wait(struct ldb_async_handle *handle, enum ldb_as
}
}
-static int password_hash_request(struct ldb_module *module, struct ldb_request *req)
-{
- switch (req->operation) {
-
- case LDB_REQ_ADD:
- return password_hash_add(module, req);
-
- case LDB_REQ_MODIFY:
- return password_hash_modify(module, req);
-
- default:
- return ldb_next_request(module, req);
-
- }
-}
-
static const struct ldb_module_ops password_hash_ops = {
.name = "password_hash",
- .add = password_hash_add_async,
- .modify = password_hash_modify_async,
- .request = password_hash_request,
+ .add = password_hash_add,
+ .modify = password_hash_modify,
.async_wait = password_hash_async_wait
};
diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index 7e408264ec..46b34a469b 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -120,42 +120,6 @@ failed:
/*
handle search requests
*/
-static int rootdse_search_bytree(struct ldb_module *module, struct ldb_request *req)
-{
- struct ldb_search *s = &req->op.search;
- int ret;
- TALLOC_CTX *tmp_ctx;
-
- /* see if its for the rootDSE */
- if (s->scope != LDB_SCOPE_BASE ||
- (s->base && s->base->comp_num != 0)) {
- return ldb_next_request(module, req);
- }
-
- tmp_ctx = talloc_new(module);
-
- /* in our db we store the rootDSE with a DN of cn=rootDSE */
- s->base = ldb_dn_explode(tmp_ctx, "cn=rootDSE");
- s->tree = ldb_parse_tree(tmp_ctx, "dn=*");
- if (s->base == NULL || s->tree == NULL) {
- ldb_oom(module->ldb);
- talloc_free(tmp_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* grab the static contents of the record */
- ret = ldb_next_request(module, req);
-
- req->op.search.res = s->res;
-
- if ((ret == LDB_SUCCESS) && (s->res->msgs != NULL)) {
- ret = rootdse_add_dynamic(module, s->res->msgs[0], s->attrs);
- }
-
- talloc_free(tmp_ctx);
-
- return ret;
-}
struct rootdse_async_context {
struct ldb_module *module;
@@ -192,7 +156,7 @@ error:
return LDB_ERR_OPERATIONS_ERROR;
}
-static int rootdse_search_async(struct ldb_module *module, struct ldb_request *req)
+static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
{
struct rootdse_async_context *ac;
struct ldb_request *down_req;
@@ -274,8 +238,6 @@ static int rootdse_register_control(struct ldb_module *module, struct ldb_reques
static int rootdse_request(struct ldb_module *module, struct ldb_request *req)
{
switch (req->operation) {
- case LDB_REQ_SEARCH:
- return rootdse_search_bytree(module, req);
case LDB_REQ_REGISTER:
return rootdse_register_control(module, req);
@@ -305,7 +267,7 @@ static int rootdse_init(struct ldb_module *module)
static const struct ldb_module_ops rootdse_ops = {
.name = "rootdse",
.init_context = rootdse_init,
- .search = rootdse_search_async,
+ .search = rootdse_search,
.request = rootdse_request
};
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 368fd161d4..40092e68de 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -615,13 +615,28 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const
return LDB_ERR_OPERATIONS_ERROR;
}
+ /* remove objectclasses so that they will be added in the right order for MMC to be happy */
+ ldb_msg_remove_attr(msg, "objectclass");
+
if (samldb_find_attribute(msg, "objectclass", "computer") != NULL) {
+
ret = samldb_copy_template(module, msg2, "(&(CN=TemplateComputer)(objectclass=userTemplate))");
if (ret) {
ldb_debug(module->ldb, LDB_DEBUG_WARNING, "samldb_fill_user_or_computer_object: Error copying computer template!\n");
talloc_free(mem_ctx);
return ret;
}
+
+ /* readd user and then computer objectclasses */
+ if ( ! samldb_find_or_add_value(module, msg2, "objectclass", "user", "user")) {
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ if ( ! samldb_find_or_add_value(module, msg2, "objectclass", "computer", "computer")) {
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
} else {
ret = samldb_copy_template(module, msg2, "(&(CN=TemplateUser)(objectclass=userTemplate))");
if (ret) {
@@ -629,6 +644,11 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const
talloc_free(mem_ctx);
return ret;
}
+ /* readd user objectclass */
+ if ( ! samldb_find_or_add_value(module, msg2, "objectclass", "user", "user")) {
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
}
rdn = ldb_dn_get_rdn(msg2, msg2->dn);
@@ -639,14 +659,6 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const
return LDB_ERR_CONSTRAINT_VIOLATION;
}
- /* if the only attribute was: "objectclass: computer", then make sure we also add "user" objectclass */
- if ( ! samldb_find_or_add_value(module, msg2, "objectclass", "user", "user")) {
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* meddle with objectclass */
-
if (ldb_msg_find_element(msg2, "samAccountName") == NULL) {
name = samldb_generate_samAccountName(module, mem_ctx);
if (!name) {
@@ -769,61 +781,6 @@ static int samldb_fill_foreignSecurityPrincipal_object(struct ldb_module *module
}
/* add_record */
-static int samldb_add(struct ldb_module *module, struct ldb_request *req)
-{
- struct ldb_message *msg = req->op.add.message;
- struct ldb_message *msg2 = NULL;
- int ret;
-
- ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_add_record\n");
-
-
- if (ldb_dn_is_special(msg->dn)) { /* do not manipulate our control entries */
- return ldb_next_request(module, req);
- }
-
- /* is user or computer? */
- if ((samldb_find_attribute(msg, "objectclass", "user") != NULL) ||
- (samldb_find_attribute(msg, "objectclass", "computer") != NULL)) {
- /* add all relevant missing objects */
- ret = samldb_fill_user_or_computer_object(module, msg, &msg2);
- if (ret) {
- return ret;
- }
- }
-
- /* is group? add all relevant missing objects */
- if ( ! msg2 ) {
- if (samldb_find_attribute(msg, "objectclass", "group") != NULL) {
- ret = samldb_fill_group_object(module, msg, &msg2);
- if (ret) {
- return ret;
- }
- }
- }
-
- /* perhaps a foreignSecurityPrincipal? */
- if ( ! msg2 ) {
- if (samldb_find_attribute(msg, "objectclass", "foreignSecurityPrincipal") != NULL) {
- ret = samldb_fill_foreignSecurityPrincipal_object(module, msg, &msg2);
- if (ret) {
- return ret;
- }
- }
- }
-
- if (msg2) {
- req->op.add.message = msg2;
- ret = ldb_next_request(module, req);
- req->op.add.message = msg;
- } else {
- ret = ldb_next_request(module, req);
- }
-
- return ret;
-}
-
-/* add_record */
/*
* FIXME
@@ -833,7 +790,7 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req)
* left SYNC for now until we think of a good solution.
*/
-static int samldb_add_async(struct ldb_module *module, struct ldb_request *req)
+static int samldb_add(struct ldb_module *module, struct ldb_request *req)
{
const struct ldb_message *msg = req->op.add.message;
struct ldb_message *msg2 = NULL;
@@ -908,19 +865,6 @@ static int samldb_destructor(void *module_ctx)
return 0;
}
-static int samldb_request(struct ldb_module *module, struct ldb_request *req)
-{
- switch (req->operation) {
-
- case LDB_REQ_ADD:
- return samldb_add(module, req);
-
- default:
- return ldb_next_request(module, req);
-
- }
-}
-
static int samldb_init(struct ldb_module *module)
{
talloc_set_destructor(module, samldb_destructor);
@@ -930,8 +874,7 @@ static int samldb_init(struct ldb_module *module)
static const struct ldb_module_ops samldb_ops = {
.name = "samldb",
.init_context = samldb_init,
- .add = samldb_add_async,
- .request = samldb_request
+ .add = samldb_add,
};