From 6637887373b9bee20a8fe8cc0b1e68f349cf49c3 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Fri, 25 Sep 2009 14:16:34 +0200 Subject: s4:dsdb/common/util - remove introduced "samdb_is_capable_dc" call I came up with a better solution which is invoked when we try to join a domain as a DC (in file "libnet_become_dc.c"). Consider a following commit for this patch. --- source4/dsdb/common/util.c | 57 ---------------------------------------------- 1 file changed, 57 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 45f19e93bb..72cbf634fa 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -1432,63 +1432,6 @@ struct ldb_dn *samdb_server_site_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx return server_site_dn; } -/* - * This works out if we are running on a supported forest/domain function - * level. Basically this means that we don't support mixed/interim (NT 4 DC - * support) levels. - * If errmsg isn't NULL we write in an adequate error message for printing out - * to the screen. - */ -bool samdb_is_capable_dc(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - char **errmsg) -{ - int32_t level_forest, level_domain, level_domain_mixed; - bool ret = true; - - level_forest = (int32_t) samdb_search_int64(ldb, mem_ctx, -1, - samdb_partitions_dn(ldb, mem_ctx), "msDS-Behavior-Version", - NULL); - level_domain = (int32_t) samdb_search_int64(ldb, mem_ctx, -1, - samdb_base_dn(ldb), "msDS-Behavior-Version", NULL); - level_domain_mixed = (int32_t) samdb_search_int64(ldb, mem_ctx, -1, - samdb_base_dn(ldb), "nTMixedDomain", NULL); - - if (errmsg != NULL) - *errmsg = talloc_strdup(mem_ctx, ""); - - if (level_forest == -1 || level_domain == -1 || level_domain_mixed == -1) { - ret = false; - if (errmsg != NULL) - *errmsg = talloc_strdup_append(*errmsg, - "\nATTENTION: Invalid values for forest and/or domain function level!" - ); - } - - if (level_forest == DS_DOMAIN_FUNCTION_2003_MIXED) { - ret = false; - if (errmsg != NULL) - *errmsg = talloc_strdup_append(*errmsg, - "\nATTENTION: You run SAMBA 4 on the 2003 with mixed domains (NT4 DC support) forest level. This isn't supported!" - ); - } - if ((level_domain == DS_DOMAIN_FUNCTION_2000 && level_domain_mixed != 0) - || level_domain == DS_DOMAIN_FUNCTION_2003_MIXED) { - ret = false; - if (errmsg != NULL) - *errmsg = talloc_strdup_append(*errmsg, - "\nATTENTION: You run SAMBA 4 on a mixed/interim (NT4 DC support) domain level. This isn't supported!" - ); - } - - if ((!ret) && (errmsg != NULL)) { - *errmsg = talloc_strdup_append(*errmsg, - "\nPlease raise the domain and/or forest level to an adequate value. Use for this the 'domainlevel' tool, the MS AD MMC tools or manipulate the needed attributes directly." - ); - } - - return ret; -} - /* work out if we are the PDC for the domain of the current open ldb */ -- cgit From fd22e0304782e20b9bbb29464b6c745d409ff4c6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Oct 2009 12:03:05 +1000 Subject: s4-ldb: Add support for binary blobs in DNs AD has the concept of a DN prefixed with B:NN:XXXXXX: that contains a binary blob. We need to support those in order to give correctly formatted binary blobs for things like wellKnownObjects This implementation is not ideal, as it allows for binary blobs on all DNs, whereas it should only allow them on those with a syntax of 2.5.5.7. We should clean this up in the future, but meanwhile this implementation at least gets us a working DC join of w2k8 to s4. This patch also uses a static function for marking DNs as invalid, which is very useful when debugging this code, as you can break on it in gdb. --- source4/dsdb/schema/schema_syntax.c | 136 ++++++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 23 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c index c564471d4b..cbbd4a8636 100644 --- a/source4/dsdb/schema/schema_syntax.c +++ b/source4/dsdb/schema/schema_syntax.c @@ -1204,6 +1204,8 @@ static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb, return WERR_OK; } + + static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb, const struct dsdb_schema *schema, const struct dsdb_attribute *attr, @@ -1212,6 +1214,7 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb, struct ldb_message_element *out) { uint32_t i; + int ret; out->flags = 0; out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName); @@ -1222,39 +1225,81 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb, W_ERROR_HAVE_NO_MEMORY(out->values); for (i=0; i < out->num_values; i++) { - struct drsuapi_DsReplicaObjectIdentifier3Binary id3b; - char *binary; - char *str; + struct drsuapi_DsReplicaObjectIdentifier3Binary id3; enum ndr_err_code ndr_err; + DATA_BLOB guid_blob; + struct ldb_dn *dn; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) { + W_ERROR_HAVE_NO_MEMORY(tmp_ctx); + } if (in->value_ctr.values[i].blob == NULL) { + talloc_free(tmp_ctx); return WERR_FOOBAR; } if (in->value_ctr.values[i].blob->length == 0) { + talloc_free(tmp_ctx); return WERR_FOOBAR; } - ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob, - out->values, schema->iconv_convenience, &id3b, - (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary); + + /* windows sometimes sends an extra two pad bytes here */ + ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob, + tmp_ctx, schema->iconv_convenience, &id3, + (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + talloc_free(tmp_ctx); return ntstatus_to_werror(status); } - /* TODO: handle id3.guid and id3.sid */ - binary = data_blob_hex_string(out->values, &id3b.binary); - W_ERROR_HAVE_NO_MEMORY(binary); + dn = ldb_dn_new(tmp_ctx, ldb, id3.dn); + if (!dn) { + talloc_free(tmp_ctx); + /* If this fails, it must be out of memory, as it does not do much parsing */ + W_ERROR_HAVE_NO_MEMORY(dn); + } - str = talloc_asprintf(out->values, "B:%u:%s:%s", - (unsigned int)(id3b.binary.length * 2), /* because of 2 hex chars per byte */ - binary, - id3b.dn); - W_ERROR_HAVE_NO_MEMORY(str); + ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, schema->iconv_convenience, &id3.guid, + (ndr_push_flags_fn_t)ndr_push_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + talloc_free(tmp_ctx); + return ntstatus_to_werror(status); + } - /* TODO: handle id3.guid and id3.sid */ - out->values[i] = data_blob_string_const(str); + ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return WERR_FOOBAR; + } + + talloc_free(guid_blob.data); + + if (id3.__ndr_size_sid) { + DATA_BLOB sid_blob; + ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience, &id3.sid, + (ndr_push_flags_fn_t)ndr_push_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + talloc_free(tmp_ctx); + return ntstatus_to_werror(status); + } + + ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return WERR_FOOBAR; + } + } + + /* set binary stuff */ + ldb_dn_set_binary(dn, &id3.binary); + + out->values[i] = data_blob_string_const(ldb_dn_get_extended_linearized(out->values, dn, 1)); + talloc_free(tmp_ctx); } return WERR_OK; @@ -1285,27 +1330,72 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb, W_ERROR_HAVE_NO_MEMORY(blobs); for (i=0; i < in->num_values; i++) { - struct drsuapi_DsReplicaObjectIdentifier3Binary id3b; + struct drsuapi_DsReplicaObjectIdentifier3Binary id3; enum ndr_err_code ndr_err; + const DATA_BLOB *guid_blob, *sid_blob; + struct ldb_dn *dn; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + W_ERROR_HAVE_NO_MEMORY(tmp_ctx); out->value_ctr.values[i].blob = &blobs[i]; - /* TODO: handle id3b.guid and id3b.sid, id3.binary */ - ZERO_STRUCT(id3b); - id3b.dn = (const char *)in->values[i].data; - id3b.binary = data_blob(NULL, 0); + dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]); + + W_ERROR_HAVE_NO_MEMORY(dn); + + guid_blob = ldb_dn_get_extended_component(dn, "GUID"); - ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3b, - (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary); + ZERO_STRUCT(id3); + + if (guid_blob) { + ndr_err = ndr_pull_struct_blob_all(guid_blob, + tmp_ctx, schema->iconv_convenience, &id3.guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + talloc_free(tmp_ctx); + return ntstatus_to_werror(status); + } + } + + sid_blob = ldb_dn_get_extended_component(dn, "SID"); + if (sid_blob) { + + ndr_err = ndr_pull_struct_blob_all(sid_blob, + tmp_ctx, schema->iconv_convenience, &id3.sid, + (ndr_pull_flags_fn_t)ndr_pull_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + talloc_free(tmp_ctx); + return ntstatus_to_werror(status); + } + } + + id3.dn = ldb_dn_get_linearized(dn); + if (strncmp(id3.dn, "B:", 2) == 0) { + id3.dn = strchr(id3.dn, ':'); + id3.dn = strchr(id3.dn+1, ':'); + id3.dn = strchr(id3.dn+1, ':'); + id3.dn++; + } + + /* get binary stuff */ + ldb_dn_get_binary(dn, &id3.binary); + + ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + talloc_free(tmp_ctx); return ntstatus_to_werror(status); } + talloc_free(tmp_ctx); } return WERR_OK; } + + static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(struct ldb_context *ldb, const struct dsdb_schema *schema, const struct dsdb_attribute *attr, -- cgit From 1726038708bcebd706dc4565963611dc86a33699 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 24 Sep 2009 07:06:03 -0700 Subject: s4-ldb: accept the binary DN OIDs in extended DN modules --- source4/dsdb/samdb/ldb_modules/extended_dn_out.c | 6 ++++-- source4/dsdb/samdb/ldb_modules/extended_dn_store.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c index f93090ace9..bb5e3795db 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c @@ -340,7 +340,8 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares) } /* Look to see if this attributeSyntax is a DN */ - if (strcmp(attribute->attributeSyntax_oid, "2.5.5.1") != 0) { + if (strcmp(attribute->attributeSyntax_oid, "2.5.5.1") != 0 && + strcmp(attribute->attributeSyntax_oid, "2.5.5.7") != 0) { continue; } @@ -617,7 +618,8 @@ static int extended_dn_out_dereference_init(struct ldb_module *module) NULL }; - if (strcmp(cur->syntax->attributeSyntax_oid, "2.5.5.1") != 0) { + if (strcmp(cur->syntax->attributeSyntax_oid, "2.5.5.1") != 0 && + strcmp(cur->syntax->attributeSyntax_oid, "2.5.5.7") != 0) { continue; } dereference_control->dereference diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c index 3234f6f269..122a9bb2b7 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c @@ -303,7 +303,8 @@ static int extended_dn_add(struct ldb_module *module, struct ldb_request *req) } /* We only setup an extended DN GUID on these particular DN objects */ - if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0) { + if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0 && + strcmp(schema_attr->attributeSyntax_oid, "2.5.5.7") != 0) { continue; } @@ -376,7 +377,8 @@ static int extended_dn_modify(struct ldb_module *module, struct ldb_request *req } /* We only setup an extended DN GUID on these particular DN objects */ - if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0) { + if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0 && + strcmp(schema_attr->attributeSyntax_oid, "2.5.5.7") != 0) { continue; } -- cgit From 0227697bf42081db6db1a8257922edc2a36f85fc Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Wed, 30 Sep 2009 20:34:35 +0200 Subject: s4:dsdb/common/sidmap - Remove As metze pointed out - this seems to be completely dead code. I too didn't find any dependencies in other code parts. Therefore remove it. --- source4/dsdb/common/sidmap.c | 612 ------------------------------------------- source4/dsdb/config.mk | 1 - 2 files changed, 613 deletions(-) delete mode 100644 source4/dsdb/common/sidmap.c (limited to 'source4/dsdb') diff --git a/source4/dsdb/common/sidmap.c b/source4/dsdb/common/sidmap.c deleted file mode 100644 index 3111a78e51..0000000000 --- a/source4/dsdb/common/sidmap.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - mapping routines for SID <-> unix uid/gid - - Copyright (C) Andrew Tridgell 2004 - - 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 3 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "system/passwd.h" -#include "../libds/common/flags.h" -#include "dsdb/samdb/samdb.h" -#include "auth/auth.h" -#include "libcli/ldap/ldap_ndr.h" -#include "lib/ldb/include/ldb.h" -#include "../lib/util/util_ldb.h" -#include "libcli/security/security.h" -#include "param/param.h" - -/* - these are used for the fallback local uid/gid to sid mapping - code. -*/ -#define SIDMAP_LOCAL_USER_BASE 0x80000000 -#define SIDMAP_LOCAL_GROUP_BASE 0xC0000000 -#define SIDMAP_MAX_LOCAL_UID 0x3fffffff -#define SIDMAP_MAX_LOCAL_GID 0x3fffffff - -/* - private context for sid mapping routines -*/ -struct sidmap_context { - struct ldb_context *samctx; -}; - -/* - open a sidmap context - use talloc_free to close -*/ -struct sidmap_context *sidmap_open(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, - struct loadparm_context *lp_ctx) -{ - struct sidmap_context *sidmap; - sidmap = talloc(mem_ctx, struct sidmap_context); - if (sidmap == NULL) { - return NULL; - } - sidmap->samctx = samdb_connect(sidmap, ev_ctx, lp_ctx, system_session(sidmap, lp_ctx)); - if (sidmap->samctx == NULL) { - talloc_free(sidmap); - return NULL; - } - - return sidmap; -} - - -/* - check the sAMAccountType field of a search result to see if - the account is a user account -*/ -static bool is_user_account(struct ldb_message *res) -{ - uint_t atype = samdb_result_uint(res, "sAMAccountType", 0); - if (atype && (!(atype & ATYPE_ACCOUNT))) { - return false; - } - return true; -} - -/* - check the sAMAccountType field of a search result to see if - the account is a group account -*/ -static bool is_group_account(struct ldb_message *res) -{ - uint_t atype = samdb_result_uint(res, "sAMAccountType", 0); - if (atype && atype == ATYPE_NORMAL_ACCOUNT) { - return false; - } - return true; -} - - - -/* - return the dom_sid of our primary domain -*/ -static NTSTATUS sidmap_primary_domain_sid(struct sidmap_context *sidmap, - TALLOC_CTX *mem_ctx, struct dom_sid **sid) -{ - const char *attrs[] = { "objectSid", NULL }; - int ret; - struct ldb_message **res = NULL; - - ret = gendb_search_dn(sidmap->samctx, mem_ctx, NULL, &res, attrs); - if (ret != 1) { - talloc_free(res); - return NT_STATUS_NO_SUCH_DOMAIN; - } - - *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid"); - talloc_free(res); - if (*sid == NULL) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - - -/* - map a sid to a unix uid -*/ -NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, - const struct dom_sid *sid, uid_t *uid) -{ - const char *attrs[] = { "sAMAccountName", "uidNumber", - "sAMAccountType", "unixName", NULL }; - int ret; - const char *s; - TALLOC_CTX *tmp_ctx; - struct ldb_message **res; - struct dom_sid *domain_sid; - NTSTATUS status; - - tmp_ctx = talloc_new(sidmap); - - ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, - "objectSid=%s", - ldap_encode_ndr_dom_sid(tmp_ctx, sid)); - - if (ret != 1) { - goto allocated_sid; - } - - /* make sure its a user, not a group */ - if (!is_user_account(res[0])) { - DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", - dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_INVALID_SID; - } - - /* first try to get the uid directly */ - s = samdb_result_string(res[0], "uidNumber", NULL); - if (s != NULL) { - *uid = strtoul(s, NULL, 0); - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - - /* next try via the UnixName attribute */ - s = samdb_result_string(res[0], "unixName", NULL); - if (s != NULL) { - struct passwd *pwd = getpwnam(s); - if (!pwd) { - DEBUG(0,("unixName %s for sid %s does not exist as a local user\n", s, - dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_USER; - } - *uid = pwd->pw_uid; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - - /* finally try via the sAMAccountName attribute */ - s = samdb_result_string(res[0], "sAMAccountName", NULL); - if (s != NULL) { - struct passwd *pwd = getpwnam(s); - if (!pwd) { - DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local user\n", - s, dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_USER; - } - *uid = pwd->pw_uid; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - - -allocated_sid: - status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_DOMAIN; - } - - if (dom_sid_in_domain(domain_sid, sid)) { - uint32_t rid = sid->sub_auths[sid->num_auths-1]; - if (rid >= SIDMAP_LOCAL_USER_BASE && - rid < SIDMAP_LOCAL_GROUP_BASE) { - *uid = rid - SIDMAP_LOCAL_USER_BASE; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - } - - - DEBUG(0,("sid_to_unixuid: no uidNumber, unixName or sAMAccountName for sid %s\n", - dom_sid_string(tmp_ctx, sid))); - - talloc_free(tmp_ctx); - return NT_STATUS_NONE_MAPPED; -} - - -/* - see if a sid is a group - very inefficient! -*/ -bool sidmap_sid_is_group(struct sidmap_context *sidmap, struct dom_sid *sid) -{ - const char *attrs[] = { "sAMAccountType", NULL }; - int ret; - TALLOC_CTX *tmp_ctx; - struct ldb_message **res; - NTSTATUS status; - struct dom_sid *domain_sid; - bool is_group; - - tmp_ctx = talloc_new(sidmap); - - ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, - "objectSid=%s", ldap_encode_ndr_dom_sid(tmp_ctx, sid)); - if (ret == 1) { - is_group = is_group_account(res[0]); - talloc_free(tmp_ctx); - return is_group; - } - - status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return false; - } - - if (dom_sid_in_domain(domain_sid, sid)) { - uint32_t rid = sid->sub_auths[sid->num_auths-1]; - if (rid >= SIDMAP_LOCAL_GROUP_BASE) { - talloc_free(tmp_ctx); - return true; - } - } - - talloc_free(tmp_ctx); - return false; -} - -/* - map a sid to a unix gid -*/ -NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, - const struct dom_sid *sid, gid_t *gid) -{ - const char *attrs[] = { "sAMAccountName", "gidNumber", - "unixName", "sAMAccountType", NULL }; - int ret; - const char *s; - TALLOC_CTX *tmp_ctx; - struct ldb_message **res; - NTSTATUS status; - struct dom_sid *domain_sid; - - tmp_ctx = talloc_new(sidmap); - - ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, - "objectSid=%s", ldap_encode_ndr_dom_sid(tmp_ctx, sid)); - if (ret != 1) { - goto allocated_sid; - } - - /* make sure its not a user */ - if (!is_group_account(res[0])) { - DEBUG(0,("sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT\n", - dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_INVALID_SID; - } - - /* first try to get the gid directly */ - s = samdb_result_string(res[0], "gidNumber", NULL); - if (s != NULL) { - *gid = strtoul(s, NULL, 0); - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - - /* next try via the UnixName attribute */ - s = samdb_result_string(res[0], "unixName", NULL); - if (s != NULL) { - struct group *grp = getgrnam(s); - if (!grp) { - DEBUG(0,("unixName '%s' for sid %s does not exist as a local group\n", - s, dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_GROUP; - } - *gid = grp->gr_gid; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - - /* finally try via the sAMAccountName attribute */ - s = samdb_result_string(res[0], "sAMAccountName", NULL); - if (s != NULL) { - struct group *grp = getgrnam(s); - if (!grp) { - DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local group\n", s, dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_GROUP; - } - *gid = grp->gr_gid; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - -allocated_sid: - status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_DOMAIN; - } - - if (dom_sid_in_domain(domain_sid, sid)) { - uint32_t rid = sid->sub_auths[sid->num_auths-1]; - if (rid >= SIDMAP_LOCAL_GROUP_BASE) { - *gid = rid - SIDMAP_LOCAL_GROUP_BASE; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - } - - DEBUG(0,("sid_to_unixgid: no gidNumber, unixName or sAMAccountName for sid %s\n", - dom_sid_string(tmp_ctx, sid))); - - talloc_free(tmp_ctx); - return NT_STATUS_NONE_MAPPED; -} - - -/* - map a unix uid to a dom_sid - the returned sid is allocated in the supplied mem_ctx -*/ -NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap, - TALLOC_CTX *mem_ctx, - const uid_t uid, struct dom_sid **sid) -{ - const char *attrs[] = { "sAMAccountName", "objectSid", "sAMAccountType", NULL }; - int ret, i; - TALLOC_CTX *tmp_ctx; - struct ldb_message **res; - struct passwd *pwd; - struct dom_sid *domain_sid; - NTSTATUS status; - - /* - we search for the mapping in the following order: - - - check if the uid is in the dynamic uid range assigned for winbindd - use. If it is, then look in winbindd sid mapping - database (not implemented yet) - - look for a user account in samdb that has uidNumber set to the - given uid - - look for a user account in samdb that has unixName or - sAMAccountName set to the name given by getpwuid() - - assign a SID by adding the uid to SIDMAP_LOCAL_USER_BASE in the local - domain - */ - - - tmp_ctx = talloc_new(mem_ctx); - - - /* - step 2: look for a user account in samdb that has uidNumber set to the - given uid - */ - - ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, - "uidNumber=%u", (unsigned int)uid); - for (i=0;isamctx, tmp_ctx, NULL, &res, attrs, - "(|(unixName=%s)(sAMAccountName=%s))", - pwd->pw_name, pwd->pw_name); - for (i=0;i SIDMAP_MAX_LOCAL_UID) { - return NT_STATUS_NONE_MAPPED; - } - - status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return status; - } - - *sid = dom_sid_add_rid(mem_ctx, domain_sid, SIDMAP_LOCAL_USER_BASE + uid); - talloc_free(tmp_ctx); - - if (*sid == NULL) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - - -/* - map a unix gid to a dom_sid - the returned sid is allocated in the supplied mem_ctx -*/ -NTSTATUS sidmap_gid_to_sid(struct sidmap_context *sidmap, - TALLOC_CTX *mem_ctx, - const gid_t gid, struct dom_sid **sid) -{ - const char *attrs[] = { "sAMAccountName", "objectSid", "sAMAccountType", NULL }; - int ret, i; - TALLOC_CTX *tmp_ctx; - struct ldb_message **res; - struct group *grp; - struct dom_sid *domain_sid; - NTSTATUS status; - - /* - we search for the mapping in the following order: - - - check if the gid is in the dynamic gid range assigned for winbindd - use. If it is, then look in winbindd sid mapping - database (not implemented yet) - - look for a group account in samdb that has gidNumber set to the - given gid - - look for a group account in samdb that has unixName or - sAMAccountName set to the name given by getgrgid() - - assign a SID by adding the gid to SIDMAP_LOCAL_GROUP_BASE in the local - domain - */ - - - tmp_ctx = talloc_new(sidmap); - - - /* - step 2: look for a group account in samdb that has gidNumber set to the - given gid - */ - - ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, - "gidNumber=%u", (unsigned int)gid); - for (i=0;isamctx, tmp_ctx, NULL, &res, attrs, - "(|(unixName=%s)(sAMAccountName=%s))", - grp->gr_name, grp->gr_name); - for (i=0;i SIDMAP_MAX_LOCAL_GID) { - return NT_STATUS_NONE_MAPPED; - } - - status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return status; - } - - *sid = dom_sid_add_rid(mem_ctx, domain_sid, SIDMAP_LOCAL_GROUP_BASE + gid); - talloc_free(tmp_ctx); - - if (*sid == NULL) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - -/* - check if a sid is in the range of auto-allocated SIDs from our primary domain, - and if it is, then return the name and atype -*/ -NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap, - TALLOC_CTX *mem_ctx, - const struct dom_sid *sid, - const char **name, - enum lsa_SidType *rtype) -{ - NTSTATUS status; - struct dom_sid *domain_sid; - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - uint32_t rid, atype; - - status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_NO_SUCH_DOMAIN; - } - - if (!dom_sid_in_domain(domain_sid, sid)) { - talloc_free(tmp_ctx); - return NT_STATUS_NONE_MAPPED; - } - - talloc_free(tmp_ctx); - - rid = sid->sub_auths[sid->num_auths-1]; - if (rid < SIDMAP_LOCAL_USER_BASE) { - return NT_STATUS_NONE_MAPPED; - } - - if (rid < SIDMAP_LOCAL_GROUP_BASE) { - struct passwd *pwd; - uid_t uid = rid - SIDMAP_LOCAL_USER_BASE; - atype = ATYPE_NORMAL_ACCOUNT; - *rtype = ds_atype_map(atype); - - pwd = getpwuid(uid); - if (pwd == NULL) { - *name = talloc_asprintf(mem_ctx, "uid%u", uid); - } else { - *name = talloc_strdup(mem_ctx, pwd->pw_name); - } - } else { - struct group *grp; - gid_t gid = rid - SIDMAP_LOCAL_GROUP_BASE; - atype = ATYPE_LOCAL_GROUP; - *rtype = ds_atype_map(atype); - grp = getgrgid(gid); - if (grp == NULL) { - *name = talloc_asprintf(mem_ctx, "gid%u", gid); - } else { - *name = talloc_strdup(mem_ctx, grp->gr_name); - } - } - - if (*name == NULL) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk index 4150ba0d54..eec4f95c9e 100644 --- a/source4/dsdb/config.mk +++ b/source4/dsdb/config.mk @@ -25,7 +25,6 @@ $(eval $(call proto_header_template,$(dsdbsrcdir)/samdb/samdb_proto.h,$(SAMDB_OB PRIVATE_DEPENDENCIES = LIBLDB SAMDB_COMMON_OBJ_FILES = $(addprefix $(dsdbsrcdir)/common/, \ - sidmap.o \ util.o) \ ../libds/common/flag_mapping.o $(eval $(call proto_header_template,$(dsdbsrcdir)/common/proto.h,$(SAMDB_COMMON_OBJ_FILES:.o=.c))) -- cgit From 48e5e215c93e1834bdacaa5a0f6dfde7788a0472 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Oct 2009 20:00:08 +1000 Subject: s4-samdb: added some debugging This helped track down the samba3sam.py failures --- source4/dsdb/samdb/ldb_modules/samldb.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index e59b5dd1ce..2d87a017fd 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -699,8 +699,14 @@ static int samldb_check_primaryGroupID_1(struct samldb_ctx *ac) static int samldb_check_primaryGroupID_2(struct samldb_ctx *ac) { - if (ac->res_dn == NULL) + if (ac->res_dn == NULL) { + struct ldb_context *ldb; + ldb = ldb_module_get_ctx(ac->module); + ldb_asprintf_errstring(ldb, + "Failed to find group sid %s", + dom_sid_string(ac->sid, ac->sid)); return LDB_ERR_UNWILLING_TO_PERFORM; + } return samldb_next_step(ac); } @@ -1866,7 +1872,7 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req) int ret; ldb = ldb_module_get_ctx(module); - ldb_debug(ldb, LDB_DEBUG_TRACE, "samldb_add_record\n"); + ldb_debug(ldb, LDB_DEBUG_TRACE, "samldb_add\n"); /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.add.message->dn)) { -- cgit From 61598258450589db4b42e3ef38453c37080c5265 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Oct 2009 20:00:42 +1000 Subject: s4-samldb: the samldb module requires that the primary group exists We need to create Domain Users in the test ldb --- source4/dsdb/samdb/ldb_modules/tests/samba3sam.py | 26 +++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py index fe96b88221..c61d3973a1 100644 --- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py +++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py @@ -311,6 +311,14 @@ class MapTestCase(MapBaseTestCase): "sambaDomainName": "TESTS" }) + # Add a set of split records + self.ldb.add_ldif(""" +dn: """+ self.samba4.dn("cn=Domain Users") + """ +objectClass: group +cn: Domain Users +objectSid: S-1-5-21-4231626423-2410014848-2360679739-513 +""") + # Add a set of split records self.ldb.add_ldif(""" dn: """+ self.samba4.dn("cn=X") + """ @@ -459,7 +467,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # errors, letting the search fail with no results. #res = self.ldb.search("(objectSid=S-1-5-21-4231626423-2410014848-2360679739-552)", scope=SCOPE_DEFAULT, attrs) res = self.ldb.search(expression="(objectSid=*)", base=None, scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon", "objectSid"]) - self.assertEquals(len(res), 3) + self.assertEquals(len(res), 4) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) self.assertEquals(str(res[0]["dnsHostName"]), "x") self.assertEquals(str(res[0]["lastLogon"]), "x") @@ -621,7 +629,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated local attribute res = self.ldb.search(expression="(!(revision=x))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 5) + self.assertEquals(len(res), 6) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "y") @@ -638,7 +646,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated remote attribute res = self.ldb.search(expression="(!(description=x))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 3) + self.assertEquals(len(res), 4) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Z")) self.assertEquals(str(res[0]["dnsHostName"]), "z") self.assertEquals(str(res[0]["lastLogon"]), "z") @@ -649,7 +657,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated conjunction of local attributes res = self.ldb.search(expression="(!(&(codePage=x)(revision=x)))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 5) + self.assertEquals(len(res), 6) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "y") @@ -666,7 +674,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated conjunction of remote attributes res = self.ldb.search(expression="(!(&(lastLogon=x)(description=x)))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 5) + self.assertEquals(len(res), 6) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y")) self.assertEquals(str(res[0]["dnsHostName"]), "y") self.assertEquals(str(res[0]["lastLogon"]), "y") @@ -683,7 +691,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated conjunction of local and remote attribute res = self.ldb.search(expression="(!(&(codePage=x)(description=x)))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 5) + self.assertEquals(len(res), 6) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "y") @@ -716,7 +724,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated disjunction of remote attributes res = self.ldb.search(expression="(!(|(badPwdCount=x)(lastLogon=x)))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 4) + self.assertEquals(len(res), 5) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y")) self.assertEquals(str(res[0]["dnsHostName"]), "y") self.assertEquals(str(res[0]["lastLogon"]), "y") @@ -730,7 +738,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated disjunction of local and remote attribute res = self.ldb.search(expression="(!(|(revision=x)(lastLogon=y)))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 4) + self.assertEquals(len(res), 5) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "x") @@ -743,7 +751,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by complex parse tree res = self.ldb.search(expression="(|(&(revision=x)(dnsHostName=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 6) + self.assertEquals(len(res), 7) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "y") -- cgit From 642dd95d817521f75f193a1e594b4dacf04d7b26 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 21 Sep 2009 17:24:43 -0700 Subject: s4:Ensure the selected RDN is the right one per the schema The relative DN must be the one that the most specific structural objectclass specifies. Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/objectclass.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 3cf252c71a..ad14acbcf8 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -547,7 +547,13 @@ static int objectclass_do_add(struct oc_context *ac) if (!current->next) { struct ldb_message_element *el; int32_t systemFlags = 0; - DATA_BLOB *sd; + const char *rdn_name = ldb_dn_get_rdn_name(msg->dn); + if (ldb_attr_cmp(rdn_name, current->objectclass->rDNAttID) != 0) { + ldb_asprintf_errstring(ldb, "RDN %s is not correct for most specific structural objectclass %s, should be %s", + rdn_name, current->objectclass->lDAPDisplayName, current->objectclass->rDNAttID); + return LDB_ERR_NAMING_VIOLATION; + } + if (!ldb_msg_find_element(msg, "objectCategory")) { value = talloc_strdup(msg, current->objectclass->defaultObjectCategory); if (value == NULL) { -- cgit From 8d7a987766b99e34b965b56bd2b1792ca7e95b5f Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Wed, 23 Sep 2009 13:36:40 +0400 Subject: s4-ldb: Use relax control to check in replace metadata module if we accept request that specify objectGUID attribute. --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 43 ++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 253596ddea..73c070aa0a 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -457,11 +457,14 @@ static int replmd_op_callback(struct ldb_request *req, struct ldb_reply *ares) static int replmd_add(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; + struct ldb_control *control; + struct ldb_control **saved_controls; struct replmd_replicated_request *ac; const struct dsdb_schema *schema; enum ndr_err_code ndr_err; struct ldb_request *down_req; struct ldb_message *msg; + const DATA_BLOB *guid_blob; struct GUID guid; struct ldb_val guid_value; struct replPropertyMetaDataBlob nmd; @@ -473,6 +476,14 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) char *time_str; int ret; uint32_t i, ni=0; + int allow_add_guid=0; + int remove_current_guid=0; + + /* check if there's a show deleted control */ + control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); + if (control) { + allow_add_guid = 1; + } /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.add.message->dn)) { @@ -498,10 +509,26 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ac->schema = schema; - if (ldb_msg_find_element(req->op.add.message, "objectGUID") != NULL) { - ldb_debug_set(ldb, LDB_DEBUG_ERROR, + guid_blob = ldb_msg_find_ldb_val(req->op.add.message, "objectGUID"); + if ( guid_blob != NULL ) { + if( !allow_add_guid ) { + ldb_debug_set(ldb, LDB_DEBUG_ERROR, "replmd_add: it's not allowed to add an object with objectGUID\n"); - return LDB_ERR_UNWILLING_TO_PERFORM; + return LDB_ERR_UNWILLING_TO_PERFORM; + } else { + NTSTATUS status = GUID_from_data_blob(guid_blob,&guid); + if ( !NT_STATUS_IS_OK(status)) { + ldb_debug_set(ldb, LDB_DEBUG_ERROR, + "replmd_add: Unable to parse as a GUID the attribute objectGUID\n"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + /* we remove this attribute as it can be a string and will not be treated + correctly and then we will readd it latter on in the good format*/ + remove_current_guid = 1; + } + } else { + /* a new GUID */ + guid = GUID_random(); } /* Get a sequence number from the backend */ @@ -510,8 +537,6 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) return ret; } - /* a new GUID */ - guid = GUID_random(); /* get our invocationId */ our_invocation_id = samdb_ntds_invocation_id(ldb); @@ -534,6 +559,9 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) if (!time_str) { return LDB_ERR_OPERATIONS_ERROR; } + if (remove_current_guid) { + ldb_msg_remove_attr(msg,"objectGUID"); + } /* * remove autogenerated attributes @@ -681,6 +709,11 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) return ret; } + /* if a control is there remove if from the modified request */ + if (control && !save_controls(control, down_req, &saved_controls)) { + return LDB_ERR_OPERATIONS_ERROR; + } + /* go on with the call chain */ return ldb_next_request(module, down_req); } -- cgit From 46c2af361252ae5543691854e8e3896d1e4b8e92 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Sep 2009 08:08:18 -0700 Subject: s4:dsdb Add 'lazy_commit' module to swallow the 'lazy commit' OID This allows this control to be specified as critical. We support the control because we choose to always be durable in our transactions. We really, really need a 'duplicate request' API, as at the moment we can't do this without a large, error-prone set of code that cannot cope with new request fields or types. Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/config.mk | 12 +++ source4/dsdb/samdb/ldb_modules/lazy_commit.c | 132 +++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 source4/dsdb/samdb/ldb_modules/lazy_commit.c (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index a49b238591..456ff5756c 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -369,3 +369,15 @@ INIT_FUNCTION = LDB_MODULE(acl) ################################################ ldb_acl_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/acl.o + +################################################ +# Start MODULE ldb_lazy_commit +[MODULE::ldb_lazy_commit] +PRIVATE_DEPENDENCIES = SAMDB +SUBSYSTEM = LIBLDB +INIT_FUNCTION = LDB_MODULE(lazy_commit) + +# End MODULE ldb_lazy_commit +################################################ + +ldb_lazy_commit_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/lazy_commit.o diff --git a/source4/dsdb/samdb/ldb_modules/lazy_commit.c b/source4/dsdb/samdb/ldb_modules/lazy_commit.c new file mode 100644 index 0000000000..69ac99e246 --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/lazy_commit.c @@ -0,0 +1,132 @@ +/* + ldb database library + + Copyright (C) Andrew Bartlett 2009 + + 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 3 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb lazy_commit module + * + * Description: module to pretend to support the 'lazy commit' control + * + * Author: Andrew Bartlett + */ + +#include "ldb_module.h" + +static int unlazy_op(struct ldb_module *module, struct ldb_request *req) +{ + int ret; + struct ldb_request *new_req; + struct ldb_control **saved_controls; + struct ldb_control *control = ldb_request_get_control(req, LDB_CONTROL_SERVER_LAZY_COMMIT); + if (!control) { + return ldb_next_request(module, req); + } + + switch (req->operation) { + case LDB_SEARCH: + ret = ldb_build_search_req_ex(&new_req, ldb_module_get_ctx(module), + req, + req->op.search.base, + req->op.search.scope, + req->op.search.tree, + req->op.search.attrs, + req->controls, + req->context, req->callback, + req); + break; + case LDB_ADD: + ret = ldb_build_add_req(&new_req, ldb_module_get_ctx(module), req, + req->op.add.message, + req->controls, + req->context, req->callback, + req); + break; + case LDB_MODIFY: + ret = ldb_build_mod_req(&new_req, ldb_module_get_ctx(module), req, + req->op.mod.message, + req->controls, + req->context, req->callback, + req); + break; + case LDB_DELETE: + ret = ldb_build_del_req(&new_req, ldb_module_get_ctx(module), req, + req->op.del.dn, + req->controls, + req->context, req->callback, + req); + break; + case LDB_RENAME: + ret = ldb_build_rename_req(&new_req, ldb_module_get_ctx(module), req, + req->op.rename.olddn, + req->op.rename.newdn, + req->controls, + req->context, req->callback, + req); + break; + case LDB_EXTENDED: + ret = ldb_build_extended_req(&new_req, ldb_module_get_ctx(module), + req, + req->op.extended.oid, + req->op.extended.data, + req->controls, + req->context, req->callback, + req); + break; + default: + ldb_set_errstring(ldb_module_get_ctx(module), + "Unsupported request type!"); + ret = LDB_ERR_UNWILLING_TO_PERFORM; + } + + if (ret != LDB_SUCCESS) { + return ret; + } + + save_controls(control, req, &saved_controls); + return ldb_next_request(module, new_req); +} + +static int unlazy_init(struct ldb_module *module) +{ + int ret; + struct ldb_context *ldb; + ldb = ldb_module_get_ctx(module); + + ret = ldb_mod_register_control(module, LDB_CONTROL_SHOW_DELETED_OID); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "lazy_commit: Unable to register control with rootdse!\n"); + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_init(module); +} + +const struct ldb_module_ops ldb_lazy_commit_module_ops = { + .name = "lazy_commit", + .search = unlazy_op, + .add = unlazy_op, + .modify = unlazy_op, + .del = unlazy_op, + .rename = unlazy_op, + .request = unlazy_op, + .extended = unlazy_op, + .init_context = unlazy_init, +}; -- cgit From 1c71c096459da85b1e5276d8c315b05e7bc870fa Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Sep 2009 08:34:33 -0700 Subject: s4:dsdb Don't allow creating of new objects with an isDefunct schema class --- source4/dsdb/samdb/ldb_modules/objectclass.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index ad14acbcf8..cc88d6b96d 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -138,7 +138,13 @@ static int objectclass_sort(struct ldb_module *module, if (!current->objectclass) { ldb_asprintf_errstring(ldb, "objectclass %.*s is not a valid objectClass in schema", (int)objectclass_element->values[i].length, (const char *)objectclass_element->values[i].data); - return LDB_ERR_OBJECT_CLASS_VIOLATION; + /* This looks weird, but windows apparently returns this for invalid objectClass values */ + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } else if (current->objectclass->isDefunct) { + ldb_asprintf_errstring(ldb, "objectclass %.*s marked as isDefunct objectClass in schema - not valid for new objects", + (int)objectclass_element->values[i].length, (const char *)objectclass_element->values[i].data); + /* This looks weird, but windows apparently returns this for invalid objectClass values */ + return LDB_ERR_NO_SUCH_ATTRIBUTE; } /* this is the root of the tree. We will start -- cgit From 984ea88156767776dc2ab0b7da84c9701c34f345 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Sep 2009 15:06:11 -0700 Subject: s4:dsdb rework instanceType module - put instanceType in provision The instanceType needs to be specified in future because that's how the partitions are actually created. --- source4/dsdb/samdb/ldb_modules/instancetype.c | 38 +++++++-------------------- 1 file changed, 9 insertions(+), 29 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/instancetype.c b/source4/dsdb/samdb/ldb_modules/instancetype.c index de46c0a42a..201ed04412 100644 --- a/source4/dsdb/samdb/ldb_modules/instancetype.c +++ b/source4/dsdb/samdb/ldb_modules/instancetype.c @@ -77,8 +77,6 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req) struct it_context *ac; uint32_t instance_type; int ret; - const struct ldb_control *partition_ctrl; - const struct dsdb_control_current_partition *partition; ldb = ldb_module_get_ctx(module); @@ -90,31 +88,19 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req) } if (ldb_msg_find_element(req->op.add.message, "instanceType")) { + unsigned int instanceType = ldb_msg_find_attr_as_uint(req->op.add.message, "instanceType", 0); + + if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) { + /* Do something in future */ + } + /* TODO: we need to validate and possibly create a new partition */ return ldb_next_request(module, req); } - partition_ctrl = ldb_request_get_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID); - if (!partition_ctrl) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "instancetype_add: no current partition control found"); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - partition = talloc_get_type(partition_ctrl->data, - struct dsdb_control_current_partition); - SMB_ASSERT(partition && partition->version == DSDB_CONTROL_CURRENT_PARTITION_VERSION); - - ac = talloc(req, struct it_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac->module = module; - ac->req = req; - /* we have to copy the message as the caller might have it as a const */ - msg = ldb_msg_copy_shallow(ac, req->op.add.message); + msg = ldb_msg_copy_shallow(req, req->op.add.message); if (msg == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; @@ -124,12 +110,6 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req) * TODO: calculate correct instance type */ instance_type = INSTANCE_TYPE_WRITE; - if (ldb_dn_compare(partition->dn, msg->dn) == 0) { - instance_type |= INSTANCE_TYPE_IS_NC_HEAD; - if (ldb_dn_compare(msg->dn, samdb_base_dn(ldb)) != 0) { - instance_type |= INSTANCE_TYPE_NC_ABOVE; - } - } ret = ldb_msg_add_fmt(msg, "instanceType", "%u", instance_type); if (ret != LDB_SUCCESS) { @@ -137,10 +117,10 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_OPERATIONS_ERROR; } - ret = ldb_build_add_req(&down_req, ldb, ac, + ret = ldb_build_add_req(&down_req, ldb, req, msg, req->controls, - ac, it_callback, + req->context, req->callback, req); if (ret != LDB_SUCCESS) { return ret; -- cgit From ff9fc4e4e0dd4e6a7563449de07934a0056f088b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Sep 2009 17:37:21 -0700 Subject: s4:dsdb Fix crash from LDAP login of DOM\\ The issue here is that when we resolve DOM\\ into an NT4 name, we would not initilise the nt4_account output. Andrew Bartlett --- source4/dsdb/samdb/cracknames.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c index 723f51356a..8f7f481e2d 100644 --- a/source4/dsdb/samdb/cracknames.c +++ b/source4/dsdb/samdb/cracknames.c @@ -1288,11 +1288,9 @@ NTSTATUS crack_name_to_nt4_name(TALLOC_CTX *mem_ctx, } p[0] = '\0'; - if (p[1]) { - *nt4_account = talloc_strdup(mem_ctx, &p[1]); - if (*nt4_account == NULL) { - return NT_STATUS_NO_MEMORY; - } + *nt4_account = talloc_strdup(mem_ctx, &p[1]); + if (*nt4_account == NULL) { + return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; -- cgit From 44df2488e30da783add33b4fb85d96ce65856484 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 29 Sep 2009 11:49:50 +0200 Subject: s4: fix various warnings (not "const" related ones) --- source4/dsdb/samdb/ldb_modules/anr.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/anr.c b/source4/dsdb/samdb/ldb_modules/anr.c index deeccac072..a5220b3f91 100644 --- a/source4/dsdb/samdb/ldb_modules/anr.c +++ b/source4/dsdb/samdb/ldb_modules/anr.c @@ -67,8 +67,10 @@ static struct ldb_parse_tree *make_parse_list(struct ldb_module *module, * Make an equality or prefix match tree, from the attribute, operation and matching value supplied */ static struct ldb_parse_tree *make_match_tree(struct ldb_module *module, - TALLOC_CTX *mem_ctx, enum ldb_parse_op op, - const char *attr, const DATA_BLOB *match) + TALLOC_CTX *mem_ctx, + enum ldb_parse_op op, + const char *attr, + struct ldb_val *match) { struct ldb_context *ldb; struct ldb_parse_tree *match_tree; @@ -123,7 +125,7 @@ struct anr_context { */ static int anr_replace_value(struct anr_context *ac, TALLOC_CTX *mem_ctx, - const struct ldb_val *match, + struct ldb_val *match, struct ldb_parse_tree **ntree) { struct ldb_parse_tree *tree = NULL; @@ -146,7 +148,7 @@ static int anr_replace_value(struct anr_context *ac, ac->found_anr = true; if (match->length > 1 && match->data[0] == '=') { - DATA_BLOB *match2 = talloc(mem_ctx, DATA_BLOB); + struct ldb_val *match2 = talloc(mem_ctx, struct ldb_val); *match2 = data_blob_const(match->data+1, match->length - 1); if (match2 == NULL){ ldb_oom(ldb); @@ -181,8 +183,8 @@ static int anr_replace_value(struct anr_context *ac, if (p) { struct ldb_parse_tree *first_split_filter, *second_split_filter, *split_filters, *match_tree_1, *match_tree_2; - DATA_BLOB *first_match = talloc(tree, DATA_BLOB); - DATA_BLOB *second_match = talloc(tree, DATA_BLOB); + struct ldb_val *first_match = talloc(tree, struct ldb_val); + struct ldb_val *second_match = talloc(tree, struct ldb_val); if (!first_match || !second_match) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; -- cgit From 6edb92f33785bb07f1bafc3c8729dc505282b9f7 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Wed, 23 Sep 2009 19:23:17 +0200 Subject: s4:samdb_set_password - cosmetic fixes --- source4/dsdb/common/util.c | 102 ++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 44 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 72cbf634fa..a355cfbb22 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -1586,18 +1586,19 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, enum samr_RejectReason *reject_reason, struct samr_DomInfo1 **_dominfo) { - const char * const user_attrs[] = { "userAccountControl", "lmPwdHistory", + const char * const user_attrs[] = { "userAccountControl", + "lmPwdHistory", "ntPwdHistory", "dBCSPwd", "unicodePwd", "objectSid", "pwdLastSet", NULL }; - const char * const domain_attrs[] = { "pwdProperties", "pwdHistoryLength", - "maxPwdAge", "minPwdAge", - "minPwdLength", NULL }; + const char * const domain_attrs[] = { "minPwdLength", "pwdProperties", + "pwdHistoryLength", + "maxPwdAge", "minPwdAge", NULL }; NTTIME pwdLastSet; + uint32_t minPwdLength, pwdProperties, pwdHistoryLength; int64_t minPwdAge; - uint_t minPwdLength, pwdProperties, pwdHistoryLength; - uint_t userAccountControl; + uint32_t userAccountControl; struct samr_Password *sambaLMPwdHistory, *sambaNTPwdHistory, *lmPwdHash, *ntPwdHash, *lmNewHash, *ntNewHash; struct samr_Password local_lmNewHash, local_ntNewHash; @@ -1618,14 +1619,14 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, if (count != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } - userAccountControl = samdb_result_uint(res[0], "userAccountControl", 0); - sambaLMPwdHistory_len = samdb_result_hashes(mem_ctx, res[0], - "lmPwdHistory", &sambaLMPwdHistory); - sambaNTPwdHistory_len = samdb_result_hashes(mem_ctx, res[0], - "ntPwdHistory", &sambaNTPwdHistory); - lmPwdHash = samdb_result_hash(mem_ctx, res[0], "dBCSPwd"); - ntPwdHash = samdb_result_hash(mem_ctx, res[0], "unicodePwd"); - pwdLastSet = samdb_result_uint64(res[0], "pwdLastSet", 0); + userAccountControl = samdb_result_uint(res[0], "userAccountControl", 0); + sambaLMPwdHistory_len = samdb_result_hashes(mem_ctx, res[0], + "lmPwdHistory", &sambaLMPwdHistory); + sambaNTPwdHistory_len = samdb_result_hashes(mem_ctx, res[0], + "ntPwdHistory", &sambaNTPwdHistory); + lmPwdHash = samdb_result_hash(mem_ctx, res[0], "dBCSPwd"); + ntPwdHash = samdb_result_hash(mem_ctx, res[0], "unicodePwd"); + pwdLastSet = samdb_result_uint64(res[0], "pwdLastSet", 0); /* Copy parameters */ lmNewHash = param_lmNewHash; @@ -1638,9 +1639,10 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, |UF_WORKSTATION_TRUST_ACCOUNT |UF_SERVER_TRUST_ACCOUNT)); - if (domain_dn) { + if (domain_dn != NULL) { /* pull the domain parameters */ - count = gendb_search_dn(ctx, mem_ctx, domain_dn, &res, domain_attrs); + count = gendb_search_dn(ctx, mem_ctx, domain_dn, &res, + domain_attrs); if (count != 1) { DEBUG(2, ("samdb_set_password: Domain DN %s is invalid, for user %s\n", ldb_dn_get_linearized(domain_dn), @@ -1649,14 +1651,15 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, } } else { /* work out the domain sid, and pull the domain from there */ - domain_sid = samdb_result_sid_prefix(mem_ctx, res[0], "objectSid"); + domain_sid = samdb_result_sid_prefix(mem_ctx, res[0], + "objectSid"); if (domain_sid == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } count = gendb_search(ctx, mem_ctx, NULL, &res, domain_attrs, - "(objectSid=%s)", - ldap_encode_ndr_dom_sid(mem_ctx, domain_sid)); + "(objectSid=%s)", + ldap_encode_ndr_dom_sid(mem_ctx, domain_sid)); if (count != 1) { DEBUG(2, ("samdb_set_password: Could not find domain to match SID: %s, for user %s\n", dom_sid_string(mem_ctx, domain_sid), @@ -1665,17 +1668,17 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, } } - pwdProperties = samdb_result_uint(res[0], "pwdProperties", 0); - pwdHistoryLength = samdb_result_uint(res[0], "pwdHistoryLength", 0); - minPwdLength = samdb_result_uint(res[0], "minPwdLength", 0); - minPwdAge = samdb_result_int64(res[0], "minPwdAge", 0); + minPwdLength = samdb_result_uint(res[0], "minPwdLength", 0); + pwdProperties = samdb_result_uint(res[0], "pwdProperties", 0); + pwdHistoryLength = samdb_result_uint(res[0], "pwdHistoryLength", 0); + minPwdAge = samdb_result_int64(res[0], "minPwdAge", 0); - if (userAccountControl & UF_PASSWD_NOTREQD) { + if ((userAccountControl & UF_PASSWD_NOTREQD) != 0) { /* see [MS-ADTS] 2.2.15 */ minPwdLength = 0; } - if (_dominfo) { + if (_dominfo != NULL) { struct samr_DomInfo1 *dominfo; /* on failure we need to fill in the reject reasons */ dominfo = talloc(mem_ctx, struct samr_DomInfo1); @@ -1690,11 +1693,13 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, *_dominfo = dominfo; } - if (restrictions && new_password) { + if ((restrictions != 0) && (new_password != 0)) { char *new_pass; - /* check the various password restrictions */ - if (restrictions && minPwdLength > utf16_len_n(new_password->data, new_password->length) / 2) { + /* checks if the "minPwdLength" property is satisfied */ + if ((restrictions != 0) + && (minPwdLength > utf16_len_n( + new_password->data, new_password->length)/2)) { if (reject_reason) { *reject_reason = SAMR_REJECT_TOO_SHORT; } @@ -1702,7 +1707,8 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, } /* Create the NT hash */ - mdfour(local_ntNewHash.hash, new_password->data, new_password->length); + mdfour(local_ntNewHash.hash, new_password->data, + new_password->length); ntNewHash = &local_ntNewHash; @@ -1713,9 +1719,11 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, new_password->data, new_password->length, (void **)&new_pass, NULL, false)) { - /* possibly check password complexity */ - if (restrictions && (pwdProperties & DOMAIN_PASSWORD_COMPLEX) && - !check_password_quality(new_pass)) { + /* checks the password complexity */ + if ((restrictions != 0) + && ((pwdProperties + & DOMAIN_PASSWORD_COMPLEX) != 0) + && (!check_password_quality(new_pass))) { if (reject_reason) { *reject_reason = SAMR_REJECT_COMPLEXITY; } @@ -1729,24 +1737,24 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, } } - if (restrictions && user_change) { + if ((restrictions != 0) && user_change) { /* are all password changes disallowed? */ - if (pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) { + if ((pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) != 0) { if (reject_reason) { *reject_reason = SAMR_REJECT_OTHER; } return NT_STATUS_PASSWORD_RESTRICTION; } - /* can this user change password? */ - if (userAccountControl & UF_PASSWD_CANT_CHANGE) { + /* can this user change the password? */ + if ((userAccountControl & UF_PASSWD_CANT_CHANGE) != 0) { if (reject_reason) { *reject_reason = SAMR_REJECT_OTHER; } return NT_STATUS_PASSWORD_RESTRICTION; } - /* yes, this is a minus. The ages are in negative 100nsec units! */ + /* Password minimum age: yes, this is a minus. The ages are in negative 100nsec units! */ if (pwdLastSet - minPwdAge > now_nt) { if (reject_reason) { *reject_reason = SAMR_REJECT_OTHER; @@ -1756,13 +1764,15 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, /* check the immediately past password */ if (pwdHistoryLength > 0) { - if (lmNewHash && lmPwdHash && memcmp(lmNewHash->hash, lmPwdHash->hash, 16) == 0) { + if (lmNewHash && lmPwdHash && memcmp(lmNewHash->hash, + lmPwdHash->hash, 16) == 0) { if (reject_reason) { *reject_reason = SAMR_REJECT_IN_HISTORY; } return NT_STATUS_PASSWORD_RESTRICTION; } - if (ntNewHash && ntPwdHash && memcmp(ntNewHash->hash, ntPwdHash->hash, 16) == 0) { + if (ntNewHash && ntPwdHash && memcmp(ntNewHash->hash, + ntPwdHash->hash, 16) == 0) { if (reject_reason) { *reject_reason = SAMR_REJECT_IN_HISTORY; } @@ -1771,11 +1781,14 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, } /* check the password history */ - sambaLMPwdHistory_len = MIN(sambaLMPwdHistory_len, pwdHistoryLength); - sambaNTPwdHistory_len = MIN(sambaNTPwdHistory_len, pwdHistoryLength); + sambaLMPwdHistory_len = MIN(sambaLMPwdHistory_len, + pwdHistoryLength); + sambaNTPwdHistory_len = MIN(sambaNTPwdHistory_len, + pwdHistoryLength); for (i=0; lmNewHash && ihash, sambaLMPwdHistory[i].hash, 16) == 0) { + if (memcmp(lmNewHash->hash, sambaLMPwdHistory[i].hash, + 16) == 0) { if (reject_reason) { *reject_reason = SAMR_REJECT_IN_HISTORY; } @@ -1783,7 +1796,8 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, } } for (i=0; ntNewHash && ihash, sambaNTPwdHistory[i].hash, 16) == 0) { + if (memcmp(ntNewHash->hash, sambaNTPwdHistory[i].hash, + 16) == 0) { if (reject_reason) { *reject_reason = SAMR_REJECT_IN_HISTORY; } @@ -1795,7 +1809,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, #define CHECK_RET(x) do { if (x != 0) return NT_STATUS_NO_MEMORY; } while(0) /* the password is acceptable. Start forming the new fields */ - if (new_password) { + if (new_password != NULL) { /* if we know the cleartext UTF16 password, then set it. * Modules in ldb will set all the appropriate * hashes */ -- cgit From 2cbff7496e477f9af180a564dbd908ec2a968716 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Fri, 25 Sep 2009 18:03:31 +0200 Subject: s4:samdb_set_password - Return the maximum password age when requested (not the minimum one) --- source4/dsdb/common/util.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index a355cfbb22..ce74c7b19c 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -1597,7 +1597,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, "maxPwdAge", "minPwdAge", NULL }; NTTIME pwdLastSet; uint32_t minPwdLength, pwdProperties, pwdHistoryLength; - int64_t minPwdAge; + int64_t maxPwdAge, minPwdAge; uint32_t userAccountControl; struct samr_Password *sambaLMPwdHistory, *sambaNTPwdHistory, *lmPwdHash, *ntPwdHash, *lmNewHash, *ntNewHash; @@ -1671,6 +1671,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, minPwdLength = samdb_result_uint(res[0], "minPwdLength", 0); pwdProperties = samdb_result_uint(res[0], "pwdProperties", 0); pwdHistoryLength = samdb_result_uint(res[0], "pwdHistoryLength", 0); + maxPwdAge = samdb_result_int64(res[0], "maxPwdAge", 0); minPwdAge = samdb_result_int64(res[0], "minPwdAge", 0); if ((userAccountControl & UF_PASSWD_NOTREQD) != 0) { @@ -1688,7 +1689,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, dominfo->min_password_length = minPwdLength; dominfo->password_properties = pwdProperties; dominfo->password_history_length = pwdHistoryLength; - dominfo->max_password_age = minPwdAge; + dominfo->max_password_age = maxPwdAge; dominfo->min_password_age = minPwdAge; *_dominfo = dominfo; } -- cgit From ab9c2320661901c05b217cc86a46e8b15e3f8425 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Sep 2009 21:13:22 -0700 Subject: s4:dsdb Pass down the exact error code on failure in repl_meta_data --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 73c070aa0a..59dc2ec928 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -667,27 +667,27 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ret = ldb_msg_add_value(msg, "objectGUID", &guid_value, NULL); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } ret = ldb_msg_add_string(msg, "whenChanged", time_str); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNCreated", seq_num); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNChanged", seq_num); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } ret = ldb_msg_add_value(msg, "replPropertyMetaData", &nmd_value, NULL); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } /* -- cgit From e6d82267454a4678484b62cd5b28527f845af84f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Sep 2009 16:40:30 -0700 Subject: s4:dsdb Return correct error on invalid attribute This error per the Microsoft testsuite --- source4/dsdb/samdb/ldb_modules/objectclass.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index cc88d6b96d..6d22141a3b 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -361,7 +361,8 @@ static int fix_attributes(struct ldb_context *ldb, const struct dsdb_schema *sch if (!attribute) { if (strcasecmp(msg->elements[i].name, "clearTextPassword") != 0) { ldb_asprintf_errstring(ldb, "attribute %s is not a valid attribute in schema", msg->elements[i].name); - return LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE; + /* Apparently Windows sends exactly this behaviour */ + return LDB_ERR_NO_SUCH_ATTRIBUTE; } } else { msg->elements[i].name = attribute->lDAPDisplayName; -- cgit From 2ab27d78b0f2c10a6d632015090872a0f6542add Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Fri, 2 Oct 2009 23:26:35 +0200 Subject: s4:repl_meta_data - various - Add more "talloc_free"s and right error values where needed - Add a pre-lookup for entries before searching for metadata attribute (also suggested by TODO list) - Now the most part of "ldap.py" works again --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 47 ++++++++++++++++++++----- 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 59dc2ec928..489985a22f 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -514,12 +514,14 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) if( !allow_add_guid ) { ldb_debug_set(ldb, LDB_DEBUG_ERROR, "replmd_add: it's not allowed to add an object with objectGUID\n"); + talloc_free(ac); return LDB_ERR_UNWILLING_TO_PERFORM; } else { NTSTATUS status = GUID_from_data_blob(guid_blob,&guid); if ( !NT_STATUS_IS_OK(status)) { ldb_debug_set(ldb, LDB_DEBUG_ERROR, "replmd_add: Unable to parse as a GUID the attribute objectGUID\n"); + talloc_free(ac); return LDB_ERR_UNWILLING_TO_PERFORM; } /* we remove this attribute as it can be a string and will not be treated @@ -534,15 +536,16 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) /* Get a sequence number from the backend */ ret = ldb_sequence_number(ldb, LDB_SEQ_NEXT, &seq_num); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } - /* get our invocationId */ our_invocation_id = samdb_ntds_invocation_id(ldb); if (!our_invocation_id) { ldb_debug_set(ldb, LDB_DEBUG_ERROR, "replmd_add: unable to find invocationId\n"); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } @@ -550,6 +553,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) msg = ldb_msg_copy_shallow(ac, req->op.add.message); if (msg == NULL) { ldb_oom(ldb); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } @@ -557,6 +561,8 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) unix_to_nt_time(&now, t); time_str = ldb_timestring(msg, t); if (!time_str) { + ldb_oom(ldb); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } if (remove_current_guid) { @@ -576,7 +582,8 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ret = ldb_msg_add_fmt(msg, "instanceType", "%u", INSTANCE_TYPE_WRITE); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + talloc_free(ac); + return ret; } } @@ -586,7 +593,8 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ret = ldb_msg_add_string(msg, "whenCreated", time_str); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + talloc_free(ac); + return ret; } /* build the replication meta_data */ @@ -598,6 +606,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) nmd.ctr.ctr1.count); if (!nmd.ctr.ctr1.array) { ldb_oom(ldb); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } @@ -613,6 +622,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ldb_debug_set(ldb, LDB_DEBUG_ERROR, "replmd_add: attribute '%s' not defined in schema\n", e->name); + talloc_free(ac); return LDB_ERR_NO_SUCH_ATTRIBUTE; } @@ -640,6 +650,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) */ ret = replmd_replPropertyMetaDataCtr1_sort(&nmd.ctr.ctr1, schema, msg->dn); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } @@ -650,6 +661,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) (ndr_push_flags_fn_t)ndr_push_GUID); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { ldb_oom(ldb); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } ndr_err = ndr_push_struct_blob(&nmd_value, msg, @@ -658,6 +670,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) (ndr_push_flags_fn_t)ndr_push_replPropertyMetaDataBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { ldb_oom(ldb); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } @@ -667,26 +680,31 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ret = ldb_msg_add_value(msg, "objectGUID", &guid_value, NULL); if (ret != LDB_SUCCESS) { ldb_oom(ldb); + talloc_free(ac); return ret; } ret = ldb_msg_add_string(msg, "whenChanged", time_str); if (ret != LDB_SUCCESS) { ldb_oom(ldb); + talloc_free(ac); return ret; } ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNCreated", seq_num); if (ret != LDB_SUCCESS) { ldb_oom(ldb); + talloc_free(ac); return ret; } ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNChanged", seq_num); if (ret != LDB_SUCCESS) { ldb_oom(ldb); + talloc_free(ac); return ret; } ret = ldb_msg_add_value(msg, "replPropertyMetaData", &nmd_value, NULL); if (ret != LDB_SUCCESS) { ldb_oom(ldb); + talloc_free(ac); return ret; } @@ -701,16 +719,19 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ac, replmd_op_callback, req); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } ret = replmd_notify(module, msg->dn, seq_num); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } /* if a control is there remove if from the modified request */ if (control && !save_controls(control, down_req, &saved_controls)) { + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } @@ -818,7 +839,7 @@ static int replmd_update_rpmd(struct ldb_module *module, /* search for the existing replPropertyMetaDataBlob */ ret = dsdb_search_dn_with_deleted(ldb, msg, &res, msg->dn, attrs); - if (ret != LDB_SUCCESS || res->count < 1) { + if (ret != LDB_SUCCESS || res->count != 1) { DEBUG(0,(__location__ ": Object %s failed to find replPropertyMetaData\n", ldb_dn_get_linearized(msg->dn))); return LDB_ERR_OPERATIONS_ERROR; @@ -913,9 +934,10 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) const struct dsdb_schema *schema; struct ldb_request *down_req; struct ldb_message *msg; - int ret; + struct ldb_result *res; time_t t = time(NULL); uint64_t seq_num = 0; + int ret; /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.mod.message->dn)) { @@ -944,13 +966,12 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) /* we have to copy the message as the caller might have it as a const */ msg = ldb_msg_copy_shallow(ac, req->op.mod.message); if (msg == NULL) { + ldb_oom(ldb); talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } /* TODO: - * - get the whole old object - * - if the old object doesn't exist report an error * - give an error when a readonly attribute should * be modified * - merge the changed into the old object @@ -959,8 +980,15 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) * attribute was changed */ + ret = dsdb_search_dn_with_deleted(ldb, msg, &res, msg->dn, NULL); + if (ret != LDB_SUCCESS) { + talloc_free(ac); + return ret; + } + ret = replmd_update_rpmd(module, msg, &seq_num); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } @@ -974,6 +1002,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) ac, replmd_op_callback, req); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } talloc_steal(down_req, msg); @@ -983,12 +1012,12 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) if (seq_num != 0) { if (add_time_element(msg, "whenChanged", t) != LDB_SUCCESS) { talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } if (add_uint64_element(msg, "uSNChanged", seq_num) != LDB_SUCCESS) { talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } } -- cgit From 90828cc7022807a6036700d0edc8061c408ef8a7 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Sat, 3 Oct 2009 10:52:53 +0200 Subject: s4:dsdb Don't allow creation of systemOnly objectclasses (except as part of the provision, which specifies the 'relax' control) Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/objectclass.c | 6 ++++++ source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 6d22141a3b..b3d54612dd 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -561,6 +561,12 @@ static int objectclass_do_add(struct oc_context *ac) return LDB_ERR_NAMING_VIOLATION; } + if (current->objectclass->systemOnly && !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) { + ldb_asprintf_errstring(ldb, "objectClass %s is systemOnly, rejecting creation of %s", + current->objectclass->lDAPDisplayName, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + if (!ldb_msg_find_element(msg, "objectCategory")) { value = talloc_strdup(msg, current->objectclass->defaultObjectCategory); if (value == NULL) { diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 489985a22f..74dd7e5bbb 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -476,10 +476,10 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) char *time_str; int ret; uint32_t i, ni=0; - int allow_add_guid=0; - int remove_current_guid=0; + bool allow_add_guid = false; + bool remove_current_guid = false; - /* check if there's a show deleted control */ + /* check if there's a show relax control (used by provision to say 'I know what I'm doing') */ control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); if (control) { allow_add_guid = 1; @@ -526,7 +526,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) } /* we remove this attribute as it can be a string and will not be treated correctly and then we will readd it latter on in the good format*/ - remove_current_guid = 1; + remove_current_guid = true; } } else { /* a new GUID */ -- cgit From f86beaaad96ac2dd7cf6a3a9d57f42c57c2440c2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Sep 2009 21:16:42 -0700 Subject: s4:dsdb Add objectClass and RDN constraints to objectClass module These additional constraints are applied, found by the Microsoft testsuite. - When the parent is not present, we now return 'NO_SUCH_OBJECT'. - Restrict the choice of RDN to the correct one per the schema - Honour the allowedChildClasses attribute from the parent's objectClass. Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/objectclass.c | 43 ++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index b3d54612dd..b68149f2f2 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -2,7 +2,7 @@ ldb database library Copyright (C) Simo Sorce 2006-2008 - Copyright (C) Andrew Bartlett 2005-2007 + Copyright (C) Andrew Bartlett 2005-2009 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 @@ -381,7 +381,7 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req) struct oc_context *ac; struct ldb_dn *parent_dn; int ret; - static const char * const parent_attrs[] = { "objectGUID", NULL }; + static const char * const parent_attrs[] = { "objectGUID", "objectClass", NULL }; ldb = ldb_module_get_ctx(module); @@ -465,7 +465,7 @@ static int objectclass_do_add(struct oc_context *ac) ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, parent does not exist!", ldb_dn_get_linearized(msg->dn)); talloc_free(mem_ctx); - return LDB_ERR_UNWILLING_TO_PERFORM; + return LDB_ERR_NO_SUCH_OBJECT; } } else { const struct ldb_val *parent_guid; @@ -491,9 +491,6 @@ static int objectclass_do_add(struct oc_context *ac) return LDB_ERR_UNWILLING_TO_PERFORM; } - /* TODO: Check this is a valid child to this parent, - * by reading the allowedChildClasses and - * allowedChildClasssesEffective attributes */ ret = ldb_msg_add_steal_value(msg, "parentGUID", discard_const(parent_guid)); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, failed to add parentGUID", @@ -555,12 +552,42 @@ static int objectclass_do_add(struct oc_context *ac) struct ldb_message_element *el; int32_t systemFlags = 0; const char *rdn_name = ldb_dn_get_rdn_name(msg->dn); - if (ldb_attr_cmp(rdn_name, current->objectclass->rDNAttID) != 0) { - ldb_asprintf_errstring(ldb, "RDN %s is not correct for most specific structural objectclass %s, should be %s", + if (current->objectclass->rDNAttID + && ldb_attr_cmp(rdn_name, current->objectclass->rDNAttID) != 0) { + ldb_asprintf_errstring(ldb, + "RDN %s is not correct for most specific structural objectclass %s, should be %s", rdn_name, current->objectclass->lDAPDisplayName, current->objectclass->rDNAttID); return LDB_ERR_NAMING_VIOLATION; } + if (ac->search_res && ac->search_res->message) { + struct ldb_message_element *oc_el + = ldb_msg_find_element(ac->search_res->message, "objectClass"); + + bool allowed_class = false; + int i, j; + for (i=0; !allowed_class && oc_el && i < oc_el->num_values; i++) { + const struct dsdb_class *sclass; + + sclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &oc_el->values[i]); + if (!sclass) { + /* We don't know this class? what is going on? */ + continue; + } + for (j=0; !allowed_class && sclass->possibleInferiors && sclass->possibleInferiors[j]; j++) { + if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, sclass->possibleInferiors[j]) == 0) { + allowed_class = true; + } + } + } + + if (!allowed_class) { + ldb_asprintf_errstring(ldb, "structural objectClass %s is not a valid child class for %s", + current->objectclass->lDAPDisplayName, ldb_dn_get_linearized(ac->search_res->message->dn)); + return LDB_ERR_NAMING_VIOLATION; + } + } + if (current->objectclass->systemOnly && !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) { ldb_asprintf_errstring(ldb, "objectClass %s is systemOnly, rejecting creation of %s", current->objectclass->lDAPDisplayName, ldb_dn_get_linearized(msg->dn)); -- cgit From 0e028fcb7d141d68de2baadeb2c0fae262f2bedc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Sep 2009 15:12:49 -0700 Subject: s4:dsdb add systemPossibleInferiors to schema code This allows us to figure out what the system can add, which will not be in possibleInferiors due to the systemOnly flag. Andrew Bartlett --- source4/dsdb/schema/schema.h | 1 + source4/dsdb/schema/schema_inferiors.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'source4/dsdb') diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h index 4e7e503931..ddd9b375f6 100644 --- a/source4/dsdb/schema/schema.h +++ b/source4/dsdb/schema/schema.h @@ -119,6 +119,7 @@ struct dsdb_class { const char **mustContain; const char **mayContain; const char **possibleInferiors; + const char **systemPossibleInferiors; const char *defaultSecurityDescriptor; diff --git a/source4/dsdb/schema/schema_inferiors.c b/source4/dsdb/schema/schema_inferiors.c index b02d557c58..264e471298 100644 --- a/source4/dsdb/schema/schema_inferiors.c +++ b/source4/dsdb/schema/schema_inferiors.c @@ -198,6 +198,25 @@ static void schema_fill_possible_inferiors(struct dsdb_schema *schema, struct ds schema_class->possibleInferiors = str_list_unique(schema_class->possibleInferiors); } +static void schema_fill_system_possible_inferiors(struct dsdb_schema *schema, struct dsdb_class *schema_class) +{ + struct dsdb_class *c2; + + for (c2=schema->classes; c2; c2=c2->next) { + char **superiors = schema_posssuperiors(schema, c2); + if (c2->objectClassCategory != 2 + && c2->objectClassCategory != 3 + && str_list_check(superiors, schema_class->lDAPDisplayName)) { + if (schema_class->possibleInferiors == NULL) { + schema_class->systemPossibleInferiors = str_list_make_empty(schema_class); + } + schema_class->systemPossibleInferiors = str_list_add_const(schema_class->systemPossibleInferiors, + c2->lDAPDisplayName); + } + } + schema_class->systemPossibleInferiors = str_list_unique(schema_class->systemPossibleInferiors); +} + /* fill in a string class name from a governs_ID */ @@ -285,6 +304,7 @@ void schema_fill_constructed(struct dsdb_schema *schema) for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) { schema_fill_possible_inferiors(schema, schema_class); + schema_fill_system_possible_inferiors(schema, schema_class); } /* free up our internal cache elements */ -- cgit From 4bc9a39eed3e47cd87ea8cd24f9ac4f9e2712f43 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Sep 2009 15:14:49 -0700 Subject: s4:dsdb Use possibleInferiors to restrict creation of child objects This also uses systemPossibleInferiors when the 'relax' control is specified, which is done by the provision. Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/objectclass.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index b68149f2f2..51a1ac845e 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -42,6 +42,7 @@ #include "libcli/security/security.h" #include "auth/auth.h" #include "param/param.h" +#include "../libds/common/flags.h" struct oc_context { @@ -566,7 +567,7 @@ static int objectclass_do_add(struct oc_context *ac) bool allowed_class = false; int i, j; - for (i=0; !allowed_class && oc_el && i < oc_el->num_values; i++) { + for (i=0; allowed_class == false && oc_el && i < oc_el->num_values; i++) { const struct dsdb_class *sclass; sclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &oc_el->values[i]); @@ -574,9 +575,19 @@ static int objectclass_do_add(struct oc_context *ac) /* We don't know this class? what is going on? */ continue; } - for (j=0; !allowed_class && sclass->possibleInferiors && sclass->possibleInferiors[j]; j++) { - if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, sclass->possibleInferiors[j]) == 0) { - allowed_class = true; + if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) { + for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) { + if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) { + allowed_class = true; + break; + } + } + } else { + for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) { + if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) { + allowed_class = true; + break; + } } } } -- cgit From cb143eafef1dae1e055454fa3a5e90183e6c4f5d Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Sat, 3 Oct 2009 15:08:00 +0200 Subject: s4:schema_inferiors - Fix wrong check --- source4/dsdb/schema/schema_inferiors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/schema/schema_inferiors.c b/source4/dsdb/schema/schema_inferiors.c index 264e471298..3be97b6b83 100644 --- a/source4/dsdb/schema/schema_inferiors.c +++ b/source4/dsdb/schema/schema_inferiors.c @@ -207,7 +207,7 @@ static void schema_fill_system_possible_inferiors(struct dsdb_schema *schema, st if (c2->objectClassCategory != 2 && c2->objectClassCategory != 3 && str_list_check(superiors, schema_class->lDAPDisplayName)) { - if (schema_class->possibleInferiors == NULL) { + if (schema_class->systemPossibleInferiors == NULL) { schema_class->systemPossibleInferiors = str_list_make_empty(schema_class); } schema_class->systemPossibleInferiors = str_list_add_const(schema_class->systemPossibleInferiors, -- cgit From 24422fae24744f9c9113342692db285ba1409799 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Sat, 3 Oct 2009 15:08:19 +0200 Subject: s4:objectclass - Free unused memory from responses --- source4/dsdb/samdb/ldb_modules/objectclass.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 51a1ac845e..b6f1a1aa23 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -881,6 +881,8 @@ static int oc_modify_callback(struct ldb_request *req, struct ldb_reply *ares) LDB_ERR_OPERATIONS_ERROR); } + talloc_free(ares); + ret = ldb_build_search_req(&search_req, ldb, ac, ac->req->op.mod.message->dn, LDB_SCOPE_BASE, "(objectClass=*)", @@ -1089,6 +1091,7 @@ static int objectclass_rename_callback(struct ldb_request *req, struct ldb_reply ares->response, ares->error); } + talloc_free(ares); /* the ac->search_res should contain the new parents objectGUID */ parent_guid = ldb_msg_find_ldb_val(ac->search_res->message, "objectGUID"); -- cgit From b43479741a3d9ae1abb91a5297a36f9d5e6d864b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Oct 2009 18:55:14 +1100 Subject: s4-repl: added RELAX control and fix transactions Added the RELAX control to dsdb_origin_objects_commit(), as it needs to modify system objects. This patch also fixes the use of ldb transactions in that function, and fixes a memory leak. --- source4/dsdb/repl/replicated_objects.c | 65 +++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 8 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c index 5d7ae11a57..9877803cba 100644 --- a/source4/dsdb/repl/replicated_objects.c +++ b/source4/dsdb/repl/replicated_objects.c @@ -424,35 +424,78 @@ WERROR dsdb_origin_objects_commit(struct ldb_context *ldb, return WERR_OK; } + ret = ldb_transaction_start(ldb); + if (ret != LDB_SUCCESS) { + return WERR_DS_INTERNAL_FAILURE; + } + objects = talloc_array(mem_ctx, struct ldb_message *, num_objects); - W_ERROR_HAVE_NO_MEMORY(objects); + if (objects == NULL) { + status = WERR_NOMEM; + goto cancel; + } for (i=0, cur = first_object; cur; cur = cur->next_object, i++) { status = dsdb_convert_object(ldb, schema, cur, objects, &objects[i]); - W_ERROR_NOT_OK_RETURN(status); + if (!W_ERROR_IS_OK(status)) { + goto cancel; + } } - ids = talloc_array(mem_ctx, + ids = talloc_array(objects, struct drsuapi_DsReplicaObjectIdentifier2, num_objects); - W_ERROR_HAVE_NO_MEMORY(objects); + if (ids == NULL) { + status = WERR_NOMEM; + goto cancel; + } for (i=0; i < num_objects; i++) { struct dom_sid *sid = NULL; + struct ldb_request *add_req; DEBUG(6,(__location__ ": adding %s\n", ldb_dn_get_linearized(objects[i]->dn))); + + ret = ldb_build_add_req(&add_req, + ldb, + objects, + objects[i], + NULL, + NULL, + ldb_op_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + status = WERR_DS_INTERNAL_FAILURE; + goto cancel; + } + + ret = ldb_request_add_control(add_req, LDB_CONTROL_RELAX_OID, true, NULL); + if (ret != LDB_SUCCESS) { + status = WERR_DS_INTERNAL_FAILURE; + goto cancel; + } - ret = ldb_add(ldb, objects[i]); - if (ret != 0) { + ret = ldb_request(ldb, add_req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(add_req->handle, LDB_WAIT_ALL); + } + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed add of %s - %s\n", + ldb_dn_get_linearized(objects[i]->dn), ldb_errstring(ldb))); + status = WERR_DS_INTERNAL_FAILURE; goto cancel; } + + talloc_free(add_req); + ret = ldb_search(ldb, objects, &res, objects[i]->dn, LDB_SCOPE_BASE, attrs, "(objectClass=*)"); - if (ret != 0) { + if (ret != LDB_SUCCESS) { + status = WERR_DS_INTERNAL_FAILURE; goto cancel; } ids[i].guid = samdb_result_guid(res->msgs[0], "objectGUID"); @@ -464,13 +507,19 @@ WERROR dsdb_origin_objects_commit(struct ldb_context *ldb, } } + ret = ldb_transaction_commit(ldb); + if (ret != LDB_SUCCESS) { + return WERR_DS_INTERNAL_FAILURE; + } + talloc_free(objects); *_num = num_objects; *_ids = ids; return WERR_OK; + cancel: talloc_free(objects); ldb_transaction_cancel(ldb); - return WERR_FOOBAR; + return status; } -- cgit From b87769c9a98904bb18c737923de4cb8d619528d1 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 6 Oct 2009 19:24:28 +0200 Subject: s4:acl module - intendation fix and comment enhancement --- source4/dsdb/samdb/ldb_modules/acl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index 1b02abcb8e..2f123145db 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -802,6 +802,7 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_OPERATIONS_ERROR; } +/* TODO Is this really right? */ /* if (what_is_user(module) == SECURITY_SYSTEM) */ return ldb_next_request(module, req); @@ -813,7 +814,7 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) ac->user_type = what_is_user(module); ac->sec_result = LDB_SUCCESS; if (!is_root_base_dn(ldb, req->op.mod.message->dn) && parent && !is_root_base_dn(ldb, parent)){ - filter = talloc_asprintf(req,"(&(objectClass=*)(|(%s=%s)(%s=%s))))", + filter = talloc_asprintf(req,"(&(objectClass=*)(|(%s=%s)(%s=%s))))", ldb_dn_get_component_name(parent,0), ldb_dn_get_component_val(parent,0)->data, ldb_dn_get_component_name(req->op.mod.message->dn,0), -- cgit From 0d7c34a5b4362ae8b1083a8bcf3a4115c37cafde Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 6 Oct 2009 19:26:15 +0200 Subject: s4:rootdse module - intendation fixup --- source4/dsdb/samdb/ldb_modules/rootdse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index a8e08ec3ad..83e4e3b50e 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -722,9 +722,9 @@ static int rootdse_modify(struct ldb_module *module, struct ldb_request *req) } _PUBLIC_ const struct ldb_module_ops ldb_rootdse_module_ops = { - .name = "rootdse", + .name = "rootdse", .init_context = rootdse_init, .search = rootdse_search, - .request = rootdse_request, + .request = rootdse_request, .modify = rootdse_modify }; -- cgit From 8536e1b947ad8a2bc5596a9a1de9a58262153ebf Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 6 Oct 2009 19:27:17 +0200 Subject: s4:various LDB modules - "build_request" functions - propagate result codes back It's very useful to know the exact result code when something fails and not only a generic (by the module) created one. Sure, there are some exception cases with specific results (special message constellations, attributes, values...) which shouldn't be changed at all (examples of them are in the "ldap.py" test). Therefore I looked very carefully to not change them. --- source4/dsdb/samdb/ldb_modules/kludge_acl.c | 2 +- source4/dsdb/samdb/ldb_modules/local_password.c | 5 ++--- source4/dsdb/samdb/ldb_modules/objectguid.c | 4 ++-- source4/dsdb/samdb/ldb_modules/partition.c | 20 ++++++++++++++------ 4 files changed, 19 insertions(+), 12 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c index 34f848de8a..79309e82bf 100644 --- a/source4/dsdb/samdb/ldb_modules/kludge_acl.c +++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c @@ -379,7 +379,7 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req) ac, kludge_acl_callback, req); if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; + return ret; } /* check if there's an SD_FLAGS control */ diff --git a/source4/dsdb/samdb/ldb_modules/local_password.c b/source4/dsdb/samdb/ldb_modules/local_password.c index 58c0f1f0d5..9c386b354d 100644 --- a/source4/dsdb/samdb/ldb_modules/local_password.c +++ b/source4/dsdb/samdb/ldb_modules/local_password.c @@ -633,8 +633,7 @@ static int lpdb_delete_callabck(struct ldb_request *req, ret = ldb_next_request(ac->module, search_req); if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); + return ldb_module_done(ac->req, NULL, NULL, ret); } return LDB_SUCCESS; } @@ -1082,7 +1081,7 @@ static int local_password_search(struct ldb_module *module, struct ldb_request * ac, lpdb_remote_search_callback, req); if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; + return ret; } /* perform the search */ diff --git a/source4/dsdb/samdb/ldb_modules/objectguid.c b/source4/dsdb/samdb/ldb_modules/objectguid.c index 3d218edc76..12dd402617 100644 --- a/source4/dsdb/samdb/ldb_modules/objectguid.c +++ b/source4/dsdb/samdb/ldb_modules/objectguid.c @@ -209,7 +209,7 @@ static int objectguid_add(struct ldb_module *module, struct ldb_request *req) ac, og_op_callback, req); if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; + return ret; } /* go on with the call chain */ @@ -267,7 +267,7 @@ static int objectguid_modify(struct ldb_module *module, struct ldb_request *req) ac, og_op_callback, req); if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; + return ret; } /* go on with the call chain */ diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 6e86d4c484..c5bbdf8dce 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -829,14 +829,22 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque res, ldb_extended_default_callback, NULL); - ret = ldb_next_request(module, treq); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(treq->handle, LDB_WAIT_ALL); + if (ret != LDB_SUCCESS) { + talloc_free(res); + return ret; } + + ret = ldb_next_request(module, treq); if (ret != LDB_SUCCESS) { talloc_free(res); return ret; } + ret = ldb_wait(treq->handle, LDB_WAIT_ALL); + if (ret != LDB_SUCCESS) { + talloc_free(res); + return ret; + } + seqr = talloc_get_type(res->extended->data, struct ldb_seqnum_result); if (seqr->flags & LDB_SEQ_TIMESTAMP_SEQUENCE) { @@ -1083,7 +1091,7 @@ static int partition_extended_schema_update_now(struct ldb_module *module, struc } /* fire the first one */ - ret = partition_call_first(ac); + ret = partition_call_first(ac); if (ret != LDB_SUCCESS){ return ret; @@ -1385,14 +1393,14 @@ static int partition_init(struct ldb_module *module) if (ret != LDB_SUCCESS) { ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_ERROR, "partition: Unable to register control with rootdse!\n"); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } ret = ldb_mod_register_control(module, LDB_CONTROL_SEARCH_OPTIONS_OID); if (ret != LDB_SUCCESS) { ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_ERROR, "partition: Unable to register control with rootdse!\n"); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } talloc_free(mem_ctx); -- cgit From b3377ef2ea71489749787ba13fba4dba1e9b6c6c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 7 Oct 2009 16:20:16 +1100 Subject: s4-drs: fixed a memory error introduced yesterday ids is retrurned via _ids, so it needs to be on the passed in mem_ctx --- source4/dsdb/repl/replicated_objects.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c index 9877803cba..ec5dcd4720 100644 --- a/source4/dsdb/repl/replicated_objects.c +++ b/source4/dsdb/repl/replicated_objects.c @@ -444,7 +444,7 @@ WERROR dsdb_origin_objects_commit(struct ldb_context *ldb, } } - ids = talloc_array(objects, + ids = talloc_array(mem_ctx, struct drsuapi_DsReplicaObjectIdentifier2, num_objects); if (ids == NULL) { -- cgit From 75eff6eaf3df69a397980f0717fc5cc720cfe0b9 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Wed, 7 Oct 2009 12:38:00 +0200 Subject: s4:subtree_delete - Make the initialisation of the child counter more clear --- source4/dsdb/samdb/ldb_modules/subtree_delete.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/subtree_delete.c b/source4/dsdb/samdb/ldb_modules/subtree_delete.c index 241cc5f7d6..e1ce9c1fa8 100644 --- a/source4/dsdb/samdb/ldb_modules/subtree_delete.c +++ b/source4/dsdb/samdb/ldb_modules/subtree_delete.c @@ -55,6 +55,8 @@ static struct subtree_delete_context *subdel_ctx_init(struct ldb_module *module, ac->module = module; ac->req = req; + ac->num_children = 0; + return ac; } -- cgit From 607ceff234c5c85849975087e9a40416b943c269 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Fri, 25 Sep 2009 22:44:00 +0200 Subject: s3/s4 - Adapt the IDL changes on various locations --- source4/dsdb/common/util.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index ce74c7b19c..9a8b59e55d 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -1583,7 +1583,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, struct samr_Password *param_lmNewHash, struct samr_Password *param_ntNewHash, bool user_change, - enum samr_RejectReason *reject_reason, + enum samPwdChangeReason *reject_reason, struct samr_DomInfo1 **_dominfo) { const char * const user_attrs[] = { "userAccountControl", @@ -1702,7 +1702,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, && (minPwdLength > utf16_len_n( new_password->data, new_password->length)/2)) { if (reject_reason) { - *reject_reason = SAMR_REJECT_TOO_SHORT; + *reject_reason = SAM_PWD_CHANGE_PASSWORD_TOO_SHORT; } return NT_STATUS_PASSWORD_RESTRICTION; } @@ -1726,7 +1726,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, & DOMAIN_PASSWORD_COMPLEX) != 0) && (!check_password_quality(new_pass))) { if (reject_reason) { - *reject_reason = SAMR_REJECT_COMPLEXITY; + *reject_reason = SAM_PWD_CHANGE_NOT_COMPLEX; } return NT_STATUS_PASSWORD_RESTRICTION; } @@ -1742,7 +1742,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, /* are all password changes disallowed? */ if ((pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) != 0) { if (reject_reason) { - *reject_reason = SAMR_REJECT_OTHER; + *reject_reason = SAM_PWD_CHANGE_NO_ERROR; } return NT_STATUS_PASSWORD_RESTRICTION; } @@ -1750,7 +1750,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, /* can this user change the password? */ if ((userAccountControl & UF_PASSWD_CANT_CHANGE) != 0) { if (reject_reason) { - *reject_reason = SAMR_REJECT_OTHER; + *reject_reason = SAM_PWD_CHANGE_NO_ERROR; } return NT_STATUS_PASSWORD_RESTRICTION; } @@ -1758,7 +1758,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, /* Password minimum age: yes, this is a minus. The ages are in negative 100nsec units! */ if (pwdLastSet - minPwdAge > now_nt) { if (reject_reason) { - *reject_reason = SAMR_REJECT_OTHER; + *reject_reason = SAM_PWD_CHANGE_NO_ERROR; } return NT_STATUS_PASSWORD_RESTRICTION; } @@ -1768,14 +1768,14 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, if (lmNewHash && lmPwdHash && memcmp(lmNewHash->hash, lmPwdHash->hash, 16) == 0) { if (reject_reason) { - *reject_reason = SAMR_REJECT_IN_HISTORY; + *reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY; } return NT_STATUS_PASSWORD_RESTRICTION; } if (ntNewHash && ntPwdHash && memcmp(ntNewHash->hash, ntPwdHash->hash, 16) == 0) { if (reject_reason) { - *reject_reason = SAMR_REJECT_IN_HISTORY; + *reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY; } return NT_STATUS_PASSWORD_RESTRICTION; } @@ -1791,7 +1791,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, if (memcmp(lmNewHash->hash, sambaLMPwdHistory[i].hash, 16) == 0) { if (reject_reason) { - *reject_reason = SAMR_REJECT_IN_HISTORY; + *reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY; } return NT_STATUS_PASSWORD_RESTRICTION; } @@ -1800,7 +1800,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, if (memcmp(ntNewHash->hash, sambaNTPwdHistory[i].hash, 16) == 0) { if (reject_reason) { - *reject_reason = SAMR_REJECT_IN_HISTORY; + *reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY; } return NT_STATUS_PASSWORD_RESTRICTION; } @@ -1833,6 +1833,9 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, } } + if (reject_reason) { + *reject_reason = SAM_PWD_CHANGE_NO_ERROR; + } return NT_STATUS_OK; } @@ -1851,7 +1854,7 @@ NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, struct samr_Password *lmNewHash, struct samr_Password *ntNewHash, bool user_change, - enum samr_RejectReason *reject_reason, + enum samPwdChangeReason *reject_reason, struct samr_DomInfo1 **_dominfo) { NTSTATUS nt_status; -- cgit From 1dfa2ed42361bb8d22446513a85f0523a740982c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Oct 2009 16:44:19 +1100 Subject: s4:provision Remove all references to samba4LocalDomain This was a bad idea all along, as Simo said at the time. With the full MS schema and enforcement of it, it is an even worse idea. This fixes the provision of the member server in 'make test' Andrew Bartlett --- source4/dsdb/common/util.c | 2 +- source4/dsdb/samdb/ldb_modules/password_hash.c | 2 +- source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++------ 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 9a8b59e55d..f86a842fb4 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -1531,7 +1531,7 @@ int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) { ret = ldb_search(ldb, local_ctx, &res, sdn, LDB_SCOPE_BASE, attrs, - "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))"); + "(|(objectClass=domain)(objectClass=builtinDomain))"); if (ret == LDB_SUCCESS) { if (res->count == 1) { break; diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index fdb044198b..adb62d3544 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -1673,7 +1673,7 @@ static int build_domain_data_request(struct ph_context *ac) ldb = ldb_module_get_ctx(ac->module); filter = talloc_asprintf(ac, - "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))", + "(&(objectSid=%s)(|(objectClass=domain)(objectClass=builtinDomain)))", ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); if (filter == NULL) { ldb_oom(ldb); diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 2d87a017fd..2a0bb2dfe6 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -284,8 +284,7 @@ static int samldb_get_parent_domain(struct samldb_ctx *ac) ret = ldb_build_search_req(&req, ldb, ac, dn, LDB_SCOPE_BASE, "(|(objectClass=domain)" - "(objectClass=builtinDomain)" - "(objectClass=samba4LocalDomain))", + "(objectClass=builtinDomain))", attrs, NULL, ac, samldb_get_parent_domain_callback, @@ -559,10 +558,10 @@ static int samldb_get_sid_domain(struct samldb_ctx *ac) /* get the domain component part of the provided SID */ ac->domain_sid->num_auths--; - filter = talloc_asprintf(ac, "(&(objectSid=%s)" - "(|(objectClass=domain)" - "(objectClass=builtinDomain)" - "(objectClass=samba4LocalDomain)))", + filter = talloc_asprintf(ac, + "(&(objectSid=%s)" + "(|(objectClass=domain)" + "(objectClass=builtinDomain)))", ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); if (filter == NULL) { return LDB_ERR_OPERATIONS_ERROR; -- cgit From 1e5562ff0410c1cedb2279eb7e0362f8d3867972 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 10 Oct 2009 09:06:07 +1100 Subject: s4:dsdb Add new functions to help modules do an ldb_search() These take an ldb_module argument, and avoid doing the search from the top of the stack again. (This will help when modules are initialised before being added to the partition set) Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/config.mk | 20 +++-- source4/dsdb/samdb/ldb_modules/naming_fsmo.c | 26 +----- source4/dsdb/samdb/ldb_modules/pdc_fsmo.c | 20 +---- source4/dsdb/samdb/ldb_modules/util.c | 128 +++++++++++++++++++++++++++ source4/dsdb/samdb/ldb_modules/util.h | 22 +++++ 5 files changed, 173 insertions(+), 43 deletions(-) create mode 100644 source4/dsdb/samdb/ldb_modules/util.c create mode 100644 source4/dsdb/samdb/ldb_modules/util.h (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 456ff5756c..ea4e722822 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -1,3 +1,13 @@ +################################################ +# Start SUBSYSTEM DSDB_MODULE_HELPERS +[SUBSYSTEM::DSDB_MODULE_HELPERS] +PRIVATE_DEPENDENCIES = LIBLDB + +DSDB_MODULE_HELPERS_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/util.o + +$(eval $(call proto_header_template,$(dsdbsrcdir)/samdb/ldb_modules/util_proto.h,$(DSDB_MODULE_HELPERS_OBJ_FILES:.o=.c))) + + ################################################ # Start MODULE ldb_objectguid [MODULE::ldb_objectguid] @@ -15,7 +25,7 @@ ldb_objectguid_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/objectguid.o SUBSYSTEM = LIBLDB PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS \ LIBNDR NDR_DRSUAPI \ - NDR_DRSBLOBS LIBNDR + NDR_DRSBLOBS LIBNDR DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(repl_meta_data) # End MODULE ldb_repl_meta_data ################################################ @@ -39,7 +49,7 @@ ldb_dsdb_cache_OBJ_FILES = \ # Start MODULE ldb_schema_fsmo [MODULE::ldb_schema_fsmo] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS +PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(schema_fsmo) # End MODULE ldb_schema_fsmo ################################################ @@ -51,7 +61,7 @@ ldb_schema_fsmo_OBJ_FILES = \ # Start MODULE ldb_naming_fsmo [MODULE::ldb_naming_fsmo] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS +PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(naming_fsmo) # End MODULE ldb_naming_fsmo ################################################ @@ -63,7 +73,7 @@ ldb_naming_fsmo_OBJ_FILES = \ # Start MODULE ldb_pdc_fsmo [MODULE::ldb_pdc_fsmo] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS +PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(pdc_fsmo) # End MODULE ldb_pdc_fsmo ################################################ @@ -220,7 +230,7 @@ ldb_show_deleted_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/show_deleted.o # Start MODULE ldb_partition [MODULE::ldb_partition] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SAMDB +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SAMDB DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(partition) # End MODULE ldb_partition ################################################ diff --git a/source4/dsdb/samdb/ldb_modules/naming_fsmo.c b/source4/dsdb/samdb/ldb_modules/naming_fsmo.c index 607bf054d2..15cad259ce 100644 --- a/source4/dsdb/samdb/ldb_modules/naming_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/naming_fsmo.c @@ -28,6 +28,7 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "../lib/util/dlinklist.h" +#include "dsdb/samdb/ldb_modules/util.h" static int naming_fsmo_init(struct ldb_module *module) { @@ -65,34 +66,15 @@ static int naming_fsmo_init(struct ldb_module *module) } ldb_module_set_private(module, naming_fsmo); - ret = ldb_search(ldb, mem_ctx, &naming_res, - naming_dn, LDB_SCOPE_BASE, - naming_attrs, NULL); + ret = dsdb_module_search_dn(module, mem_ctx, &naming_res, + naming_dn, + naming_attrs); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_debug(ldb, LDB_DEBUG_WARNING, "naming_fsmo_init: no partitions dn present: (skip loading of naming contexts details)\n"); talloc_free(mem_ctx); return ldb_next_init(module); } - if (ret != LDB_SUCCESS) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "naming_fsmo_init: failed to search the cross-ref container: %s: %s", - ldb_strerror(ret), ldb_errstring(ldb)); - talloc_free(mem_ctx); - return ret; - } - if (naming_res->count == 0) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "naming_fsmo_init: no cross-ref container present: (skip loading of naming contexts details)\n"); - talloc_free(mem_ctx); - return ldb_next_init(module); - } else if (naming_res->count > 1) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "naming_fsmo_init: [%u] cross-ref containers found on a base search", - naming_res->count); - talloc_free(mem_ctx); - return LDB_ERR_CONSTRAINT_VIOLATION; - } naming_fsmo->master_dn = ldb_msg_find_attr_as_dn(ldb, naming_fsmo, naming_res->msgs[0], "fSMORoleOwner"); if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), naming_fsmo->master_dn) == 0) { diff --git a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c index 950f87eb74..6d814f9334 100644 --- a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c @@ -27,6 +27,7 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "../lib/util/dlinklist.h" +#include "dsdb/samdb/ldb_modules/util.h" static int pdc_fsmo_init(struct ldb_module *module) { @@ -64,9 +65,9 @@ static int pdc_fsmo_init(struct ldb_module *module) } ldb_module_set_private(module, pdc_fsmo); - ret = ldb_search(ldb, mem_ctx, &pdc_res, - pdc_dn, LDB_SCOPE_BASE, - pdc_attrs, NULL); + ret = dsdb_module_search_dn(module, mem_ctx, &pdc_res, + pdc_dn, + pdc_attrs); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_debug(ldb, LDB_DEBUG_WARNING, "pdc_fsmo_init: no domain object present: (skip loading of domain details)\n"); @@ -79,19 +80,6 @@ static int pdc_fsmo_init(struct ldb_module *module) talloc_free(mem_ctx); return ret; } - if (pdc_res->count == 0) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "pdc_fsmo_init: no domain object present: (skip loading of domain details)\n"); - talloc_free(mem_ctx); - return ldb_next_init(module); - } else if (pdc_res->count > 1) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "pdc_fsmo_init: [%u] domain objects found on a base search", - pdc_res->count); - DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb))); - talloc_free(mem_ctx); - return LDB_ERR_CONSTRAINT_VIOLATION; - } pdc_fsmo->master_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, pdc_res->msgs[0], "fSMORoleOwner"); if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), pdc_fsmo->master_dn) == 0) { diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c new file mode 100644 index 0000000000..476eb08ed0 --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -0,0 +1,128 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + + Copyright (C) Andrew Tridgell 2009 + Copyright (C) Andrew Bartlett 2009 + + 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 3 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "ldb.h" +#include "ldb_module.h" + +/* + search for attrs on one DN, in the modules below + */ +int dsdb_module_search_dn(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_result **_res, + struct ldb_dn *basedn, + const char * const *attrs) +{ + int ret; + struct ldb_request *req; + TALLOC_CTX *tmp_ctx; + struct ldb_result *res; + + tmp_ctx = talloc_new(mem_ctx); + + res = talloc_zero(tmp_ctx, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx, + basedn, + LDB_SCOPE_BASE, + NULL, + attrs, + NULL, + res, + ldb_search_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + ret = ldb_next_request(module, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + if (res->count != 1) { + /* we may be reading a DB that does not have the 'check base on search' option... */ + ret = LDB_ERR_NO_SUCH_OBJECT; + } else { + *_res = talloc_steal(mem_ctx, res); + } + talloc_free(tmp_ctx); + return ret; +} + +/* + search for attrs in the modules below + */ +int dsdb_module_search(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_result **_res, + struct ldb_dn *basedn, enum ldb_scope scope, + const char * const *attrs, + const char *expression) +{ + int ret; + struct ldb_request *req; + TALLOC_CTX *tmp_ctx; + struct ldb_result *res; + + tmp_ctx = talloc_new(mem_ctx); + + res = talloc_zero(tmp_ctx, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx, + basedn, + scope, + expression, + attrs, + NULL, + res, + ldb_search_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + ret = ldb_next_request(module, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + talloc_free(req); + if (ret == LDB_SUCCESS) { + *_res = talloc_steal(mem_ctx, res); + } + talloc_free(tmp_ctx); + return ret; +} + diff --git a/source4/dsdb/samdb/ldb_modules/util.h b/source4/dsdb/samdb/ldb_modules/util.h new file mode 100644 index 0000000000..0a1ab83c6d --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/util.h @@ -0,0 +1,22 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + + Copyright (C) Andrew Tridgell 2009 + Copyright (C) Andrew Bartlett 2009 + + 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 3 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "dsdb/samdb/ldb_modules/util_proto.h" -- cgit From c9f70fc3c7a6a44696a64ca40eca6e1995db35b9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 10 Oct 2009 09:10:03 +1100 Subject: s4:dsdb Search for the schema with dsdb_module_search(), in schema_fsmo This avoids using an ldb_search(), which would run from the top of the module stack. This will help us load the schema before the partitions are initialised. Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/schema_fsmo.c | 113 ++++++++++++++++++++++++--- source4/dsdb/schema/schema_init.c | 111 +------------------------- 2 files changed, 102 insertions(+), 122 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c index c482ab57df..2b6606c147 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c @@ -5,6 +5,7 @@ checkings, it also loads the dsdb_schema. Copyright (C) Stefan Metzmacher 2007 + Copyright (C) Andrew Bartlett 2009 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 @@ -28,6 +29,7 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "param/param.h" +#include "dsdb/samdb/ldb_modules/util.h" static int generate_objectClasses(struct ldb_context *ldb, struct ldb_message *msg, const struct dsdb_schema *schema); @@ -90,13 +92,107 @@ struct schema_fsmo_search_data { const struct dsdb_schema *schema; }; +/* + Given an LDB module (pointing at the schema DB), and the DN, set the populated schema +*/ + +static int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_module *module, + struct smb_iconv_convenience *iconv_convenience, + struct ldb_dn *schema_dn, + struct dsdb_schema **schema) +{ + TALLOC_CTX *tmp_ctx; + char *error_string; + int ret; + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct ldb_result *schema_res; + struct ldb_result *a_res; + struct ldb_result *c_res; + static const char *schema_attrs[] = { + "prefixMap", + "schemaInfo", + "fSMORoleOwner", + NULL + }; + unsigned flags; + + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* we don't want to trace the schema load */ + flags = ldb_get_flags(ldb); + ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING); + + /* + * setup the prefix mappings and schema info + */ + ret = dsdb_module_search_dn(module, tmp_ctx, &schema_res, + schema_dn, schema_attrs); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + goto failed; + } else if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema: failed to search the schema head: %s", + ldb_errstring(ldb)); + goto failed; + } + + /* + * load the attribute definitions + */ + ret = dsdb_module_search(module, tmp_ctx, &a_res, + schema_dn, LDB_SCOPE_ONELEVEL, NULL, + "(objectClass=attributeSchema)"); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema: failed to search attributeSchema objects: %s", + ldb_errstring(ldb)); + goto failed; + } + + /* + * load the objectClass definitions + */ + ret = dsdb_module_search(module, tmp_ctx, &c_res, + schema_dn, LDB_SCOPE_ONELEVEL, NULL, + "(objectClass=classSchema)"); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema: failed to search attributeSchema objects: %s", + ldb_errstring(ldb)); + goto failed; + } + + ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb, + lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), + schema_res, a_res, c_res, schema, &error_string); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema load failed: %s", + error_string); + goto failed; + } + talloc_steal(mem_ctx, *schema); + +failed: + if (flags & LDB_FLG_ENABLE_TRACING) { + flags = ldb_get_flags(ldb); + ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING); + } + talloc_free(tmp_ctx); + return ret; +} + + static int schema_fsmo_init(struct ldb_module *module) { struct ldb_context *ldb; TALLOC_CTX *mem_ctx; struct ldb_dn *schema_dn; struct dsdb_schema *schema; - char *error_string = NULL; int ret; struct schema_fsmo_private_data *data; @@ -134,9 +230,9 @@ static int schema_fsmo_init(struct ldb_module *module) return LDB_ERR_OPERATIONS_ERROR; } - ret = dsdb_schema_from_schema_dn(mem_ctx, ldb, + ret = dsdb_schema_from_schema_dn(mem_ctx, module, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - schema_dn, &schema, &error_string); + schema_dn, &schema); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_reset_err_string(ldb); @@ -147,9 +243,6 @@ static int schema_fsmo_init(struct ldb_module *module) } if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, - "schema_fsmo_init: dsdb_schema load failed: %s", - error_string); talloc_free(mem_ctx); return ret; } @@ -246,7 +339,6 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r struct ldb_context *ldb; struct ldb_dn *schema_dn; struct dsdb_schema *schema; - char *error_string = NULL; int ret; TALLOC_CTX *mem_ctx; @@ -270,9 +362,9 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r return LDB_ERR_OPERATIONS_ERROR; } - ret = dsdb_schema_from_schema_dn(mem_ctx, ldb, + ret = dsdb_schema_from_schema_dn(mem_ctx, module, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - schema_dn, &schema, &error_string); + schema_dn, &schema); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_reset_err_string(ldb); @@ -283,9 +375,6 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r } if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, - "schema_fsmo_extended: dsdb_schema load failed: %s", - error_string); talloc_free(mem_ctx); return ldb_next_request(module, req); } diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index b876ab09fc..74cf53d8f1 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -906,7 +906,7 @@ WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema, /* Create a DSDB schema from the ldb results provided. This is called directly when the schema is provisioned from an on-disk LDIF file, or - from dsdb_schema_from_schema_dn below + from dsdb_schema_from_schema_dn in schema_fsmo */ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, @@ -1013,115 +1013,6 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, return LDB_SUCCESS; } -/* - Given an LDB, and the DN, return a populated schema -*/ - -int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, - struct smb_iconv_convenience *iconv_convenience, - struct ldb_dn *schema_dn, - struct dsdb_schema **schema, - char **error_string_out) -{ - TALLOC_CTX *tmp_ctx; - char *error_string; - int ret; - - struct ldb_result *schema_res; - struct ldb_result *a_res; - struct ldb_result *c_res; - static const char *schema_attrs[] = { - "prefixMap", - "schemaInfo", - "fSMORoleOwner", - NULL - }; - unsigned flags; - - tmp_ctx = talloc_new(mem_ctx); - if (!tmp_ctx) { - dsdb_oom(error_string_out, mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* we don't want to trace the schema load */ - flags = ldb_get_flags(ldb); - ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING); - - /* - * setup the prefix mappings and schema info - */ - ret = ldb_search(ldb, tmp_ctx, &schema_res, - schema_dn, LDB_SCOPE_BASE, schema_attrs, NULL); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - goto failed; - } else if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: failed to search the schema head: %s", - ldb_errstring(ldb)); - goto failed; - } - if (schema_res->count != 1) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: [%u] schema heads found on a base search", - schema_res->count); - goto failed; - } - - /* - * load the attribute definitions - */ - ret = ldb_search(ldb, tmp_ctx, &a_res, - schema_dn, LDB_SCOPE_ONELEVEL, NULL, - "(objectClass=attributeSchema)"); - if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: failed to search attributeSchema objects: %s", - ldb_errstring(ldb)); - goto failed; - } - - /* - * load the objectClass definitions - */ - ret = ldb_search(ldb, tmp_ctx, &c_res, - schema_dn, LDB_SCOPE_ONELEVEL, NULL, - "(objectClass=classSchema)"); - if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: failed to search attributeSchema objects: %s", - ldb_errstring(ldb)); - goto failed; - } - - ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb, - lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - schema_res, a_res, c_res, schema, &error_string); - if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema load failed: %s", - error_string); - goto failed; - } - talloc_steal(mem_ctx, *schema); - talloc_free(tmp_ctx); - - if (flags & LDB_FLG_ENABLE_TRACING) { - flags = ldb_get_flags(ldb); - ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING); - } - - return LDB_SUCCESS; - -failed: - if (flags & LDB_FLG_ENABLE_TRACING) { - flags = ldb_get_flags(ldb); - ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING); - } - talloc_free(tmp_ctx); - return ret; -} - static const struct { const char *name; -- cgit From aee3c190156ed6f644535ab62ffe72b74e611b43 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Oct 2009 13:10:00 +1100 Subject: s4:dsdb Make dsdb_read_prefixes_from_ldb static --- source4/dsdb/schema/schema_init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index 74cf53d8f1..9dd3ce0ccc 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -30,6 +30,8 @@ #include "param/param.h" #include "lib/ldb/include/ldb_module.h" +static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes); + struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience) { struct dsdb_schema *schema = talloc_zero(mem_ctx, struct dsdb_schema); @@ -519,7 +521,7 @@ WERROR dsdb_write_prefixes_from_schema_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_co return WERR_OK; } -WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes) +static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes) { struct prefixMapBlob *blob; enum ndr_err_code ndr_err; -- cgit From d511d889a09dee93338d93fcef22625089ae110c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Oct 2009 13:17:09 +1100 Subject: s4:schema Add some error checking to the schema load --- source4/dsdb/schema/schema_inferiors.c | 27 +++++++++++++++++++++------ source4/dsdb/schema/schema_set.c | 5 ++++- 2 files changed, 25 insertions(+), 7 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/schema/schema_inferiors.c b/source4/dsdb/schema/schema_inferiors.c index 3be97b6b83..ecac74a954 100644 --- a/source4/dsdb/schema/schema_inferiors.c +++ b/source4/dsdb/schema/schema_inferiors.c @@ -149,19 +149,22 @@ void schema_subclasses_order_recurse(struct dsdb_schema *schema, struct dsdb_cla return; } -static void schema_create_subclasses(struct dsdb_schema *schema) +static int schema_create_subclasses(struct dsdb_schema *schema) { - struct dsdb_class *schema_class; + struct dsdb_class *schema_class, *top; for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) { struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf); if (schema_class2 == NULL) { DEBUG(0,("ERROR: no subClassOf for '%s'\n", schema_class->lDAPDisplayName)); - continue; + return LDB_ERR_OPERATIONS_ERROR; } if (schema_class2 && schema_class != schema_class2) { if (schema_class2->subclasses_direct == NULL) { schema_class2->subclasses_direct = str_list_make_empty(schema_class2); + if (!schema_class2->subclasses_direct) { + return LDB_ERR_OPERATIONS_ERROR; + } } schema_class2->subclasses_direct = str_list_add_const(schema_class2->subclasses_direct, schema_class->lDAPDisplayName); @@ -175,7 +178,14 @@ static void schema_create_subclasses(struct dsdb_schema *schema) schema_class->subClass_order = 0; } - schema_subclasses_order_recurse(schema, dsdb_class_by_lDAPDisplayName(schema, "top"), 1); + top = dsdb_class_by_lDAPDisplayName(schema, "top"); + if (!top) { + DEBUG(0,("ERROR: no 'top' class in loaded schema\n")); + return LDB_ERR_OPERATIONS_ERROR; + } + + schema_subclasses_order_recurse(schema, top, 1); + return LDB_SUCCESS; } static void schema_fill_possible_inferiors(struct dsdb_schema *schema, struct dsdb_class *schema_class) @@ -294,13 +304,17 @@ static void schema_fill_from_ids(struct dsdb_schema *schema) } } -void schema_fill_constructed(struct dsdb_schema *schema) +int schema_fill_constructed(struct dsdb_schema *schema) { + int ret; struct dsdb_class *schema_class; schema_fill_from_ids(schema); - schema_create_subclasses(schema); + ret = schema_create_subclasses(schema); + if (ret != LDB_SUCCESS) { + return ret; + } for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) { schema_fill_possible_inferiors(schema, schema_class); @@ -318,4 +332,5 @@ void schema_fill_constructed(struct dsdb_schema *schema) schema_class->subclasses = NULL; schema_class->posssuperiors = NULL; } + return LDB_SUCCESS; } diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index 6f09f63596..9f22b32334 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -346,7 +346,10 @@ int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema) return ret; } - schema_fill_constructed(schema); + ret = schema_fill_constructed(schema); + if (ret != LDB_SUCCESS) { + return ret; + } ret = ldb_set_opaque(ldb, "dsdb_schema", schema); if (ret != LDB_SUCCESS) { -- cgit From 8b67e1ab703e85182eb288138d3fb1fa8a903002 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Mon, 12 Oct 2009 17:32:24 +0200 Subject: s4:objectclass ldb module - Check for empty messages I think the check for empty messages fits best here. --- source4/dsdb/samdb/ldb_modules/objectclass.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index b6f1a1aa23..b5e058df0b 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -706,7 +706,13 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req if (!schema) { return ldb_next_request(module, req); } - objectclass_element = ldb_msg_find_element(req->op.mod.message, "objectClass"); + + /* As with the "real" AD we don't accept empty messages */ + if (req->op.mod.message->num_elements == 0) { + ldb_set_errstring(ldb, "objectclass: modify message must have " + "elements/attributes!"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } ac = oc_init_context(module, req); if (ac == NULL) { @@ -715,6 +721,7 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req /* If no part of this touches the objectClass, then we don't * need to make any changes. */ + objectclass_element = ldb_msg_find_element(req->op.mod.message, "objectClass"); /* If the only operation is the deletion of the objectClass * then go on with just fixing the attribute case */ -- cgit From e9686985cbf1f5234d9e9731176b1eb4e02911e8 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Mon, 12 Oct 2009 19:09:18 +0200 Subject: s4: Changes the old occurences of "lp_realm" in "lp_dnsdomain" where needed For KERBEROS applications the realm should be upcase (function "lp_realm") but for DNS ones it should be used lowcase (function "lp_dnsdomain"). This patch implements the use of both in the right way. --- source4/dsdb/kcc/kcc_periodic.c | 2 +- source4/dsdb/repl/drepl_out_helpers.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/kcc/kcc_periodic.c b/source4/dsdb/kcc/kcc_periodic.c index 44e0c7ae8b..30d43033cb 100644 --- a/source4/dsdb/kcc/kcc_periodic.c +++ b/source4/dsdb/kcc/kcc_periodic.c @@ -152,7 +152,7 @@ static NTSTATUS kccsrv_simple_update(struct kccsrv_service *s, TALLOC_CTX *mem_c r1->other_info = talloc_zero(reps, struct repsFromTo1OtherInfo); r1->other_info->dns_name = talloc_asprintf(r1->other_info, "%s._msdcs.%s", GUID_string(mem_ctx, &ntds_guid), - lp_realm(s->task->lp_ctx)); + lp_dnsdomain(s->task->lp_ctx)); r1->source_dsa_obj_guid = ntds_guid; r1->source_dsa_invocation_id = invocation_id; r1->replica_flags = diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index 5c63c111f3..598ceb58b9 100644 --- a/source4/dsdb/repl/drepl_out_helpers.c +++ b/source4/dsdb/repl/drepl_out_helpers.c @@ -506,10 +506,9 @@ static void dreplsrv_update_refs_send(struct dreplsrv_op_pull_source_state *st) ntds_guid_str = GUID_string(r, &service->ntds_guid); if (composite_nomem(ntds_guid_str, c)) return; - /* lp_realm() is not really right here */ ntds_dns_name = talloc_asprintf(r, "%s._msdcs.%s", ntds_guid_str, - lp_realm(service->task->lp_ctx)); + lp_dnsdomain(service->task->lp_ctx)); if (composite_nomem(ntds_dns_name, c)) return; r->in.bind_handle = &drsuapi->bind_handle; -- cgit From 5931734be69d802a6fabbf2ec70866c60cac4b25 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Wed, 14 Oct 2009 11:40:25 +0200 Subject: s4:password_hash - load the domain parameters from the "loadparm context" And don't cut them out from the DNS hostname. --- source4/dsdb/samdb/ldb_modules/password_hash.c | 53 ++++++-------------------- 1 file changed, 11 insertions(+), 42 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index adb62d3544..a3c99f4222 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -87,9 +87,9 @@ struct domain_data { bool store_cleartext; uint_t pwdProperties; uint_t pwdHistoryLength; - char *netbios_domain; - char *dns_domain; - char *realm; + const char *netbios_domain; + const char *dns_domain; + const char *realm; }; struct setup_password_fields_io { @@ -1552,9 +1552,8 @@ static int get_domain_data_callback(struct ldb_request *req, struct ldb_context *ldb; struct domain_data *data; struct ph_context *ac; + struct loadparm_context *lp_ctx; int ret; - char *tmp; - char *p; ac = talloc_get_type(req->context, struct ph_context); ldb = ldb_module_get_ctx(ac->module); @@ -1591,43 +1590,13 @@ static int get_domain_data_callback(struct ldb_request *req, * but that doesn't really matter, as it's just used for salt * and kerberos principals, which don't exist here */ - tmp = ldb_dn_canonical_string(data, ares->message->dn); - if (!tmp) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } + lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), + struct loadparm_context); - /* But it puts a trailing (or just before 'builtin') / on things, so kill that */ - p = strchr(tmp, '/'); - if (p) { - p[0] = '\0'; - } - - data->dns_domain = strlower_talloc(data, tmp); - if (data->dns_domain == NULL) { - ldb_oom(ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - data->realm = strupper_talloc(data, tmp); - if (data->realm == NULL) { - ldb_oom(ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - /* FIXME: NetbIOS name is *always* the first domain component ?? -SSS */ - p = strchr(tmp, '.'); - if (p) { - p[0] = '\0'; - } - data->netbios_domain = strupper_talloc(data, tmp); - if (data->netbios_domain == NULL) { - ldb_oom(ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } + data->dns_domain = lp_dnsdomain(lp_ctx); + data->realm = lp_realm(lp_ctx); + data->netbios_domain = lp_workgroup(lp_ctx); - talloc_free(tmp); ac->domain = data; break; @@ -1673,7 +1642,7 @@ static int build_domain_data_request(struct ph_context *ac) ldb = ldb_module_get_ctx(ac->module); filter = talloc_asprintf(ac, - "(&(objectSid=%s)(|(objectClass=domain)(objectClass=builtinDomain)))", + "(objectSid=%s)", ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); if (filter == NULL) { ldb_oom(ldb); @@ -1682,7 +1651,7 @@ static int build_domain_data_request(struct ph_context *ac) return ldb_build_search_req(&ac->dom_req, ldb, ac, ldb_get_default_basedn(ldb), - LDB_SCOPE_SUBTREE, + LDB_SCOPE_BASE, filter, attrs, NULL, ac, get_domain_data_callback, -- cgit From 94897d7a7c5925983f362f498f78a32a26aa088b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Oct 2009 19:48:13 +1100 Subject: s4-dsdb: added samdb_rodc() and samdb_ntds_options() Later we will need to make samdb_rodc() look in the database, but for now we should at least have the function in a central place --- source4/dsdb/common/util.c | 50 +++++++++++++++++++++++++++++++++++ source4/dsdb/repl/drepl_out_helpers.c | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index f86a842fb4..c9562b0de7 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -2528,3 +2528,53 @@ int drsuapi_DsReplicaCursor2_compare(const struct drsuapi_DsReplicaCursor2 *c1, { return GUID_compare(&c1->source_dsa_invocation_id, &c2->source_dsa_invocation_id); } + +/* + see if we are a RODC + + TODO: This should take a sam_ctx, and lookup the right object (with + a cache) +*/ +bool samdb_rodc(struct loadparm_context *lp_ctx) +{ + return lp_parm_bool(lp_ctx, NULL, "repl", "RODC", false); +} + + +/* + return NTDS options flags. See MS-ADTS 7.1.1.2.2.1.2.1.1 + + flags are DS_NTDS_OPTION_* +*/ +int samdb_ntds_options(struct ldb_context *ldb, uint32_t *options) +{ + TALLOC_CTX *tmp_ctx; + const char *attrs[] = { "options", NULL }; + int ret; + struct ldb_result *res; + + tmp_ctx = talloc_new(ldb); + if (tmp_ctx == NULL) { + goto failed; + } + + ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL); + if (ret) { + goto failed; + } + + if (res->count != 1) { + goto failed; + } + + *options = samdb_result_uint(res->msgs[0], "options", 0); + + talloc_free(tmp_ctx); + + return LDB_SUCCESS; + +failed: + DEBUG(1,("Failed to find our own NTDS Settings objectGUID in the ldb!\n")); + talloc_free(tmp_ctx); + return LDB_ERR_NO_SUCH_OBJECT; +} diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index 598ceb58b9..c86956c42f 100644 --- a/source4/dsdb/repl/drepl_out_helpers.c +++ b/source4/dsdb/repl/drepl_out_helpers.c @@ -519,7 +519,7 @@ static void dreplsrv_update_refs_send(struct dreplsrv_op_pull_source_state *st) r->in.req.req1.options = DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE | DRSUAPI_DS_REPLICA_UPDATE_DELETE_REFERENCE; - if (!lp_parm_bool(service->task->lp_ctx, NULL, "repl", "RODC", false)) { + if (!samdb_rodc(service->task->lp_ctx)) { r->in.req.req1.options |= DRSUAPI_DS_REPLICA_UPDATE_WRITEABLE; } -- cgit From fdeeafb481778ee9ef7e87f8afa046d5f311a769 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 15 Oct 2009 15:54:20 +1100 Subject: s4-dsdb: implement limit on rDN length w2k8 imposes a limit of 64 characters on the rDN --- source4/dsdb/samdb/ldb_modules/objectclass.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index b5e058df0b..003d6731d4 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -330,6 +330,8 @@ static int fix_dn(TALLOC_CTX *mem_ctx, struct ldb_dn **fixed_dn) { char *upper_rdn_attr; + const struct ldb_val *rdn_val; + /* Fix up the DN to be in the standard form, taking particular care to match the parent DN */ *fixed_dn = ldb_dn_copy(mem_ctx, parent_dn); @@ -339,15 +341,21 @@ static int fix_dn(TALLOC_CTX *mem_ctx, if (!upper_rdn_attr) { return LDB_ERR_OPERATIONS_ERROR; } - + /* Create a new child */ if (ldb_dn_add_child_fmt(*fixed_dn, "X=X") == false) { return LDB_ERR_OPERATIONS_ERROR; } + /* AD doesn't allow the rDN to be longer than 64 characters */ + rdn_val = ldb_dn_get_rdn_val(newdn); + if (!rdn_val || rdn_val->length > 64) { + DEBUG(2,(__location__ ": rDN longer than 64 limit for '%s'\n", ldb_dn_get_linearized(newdn))); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + /* And replace it with CN=foo (we need the attribute in upper case */ - return ldb_dn_set_component(*fixed_dn, 0, upper_rdn_attr, - *ldb_dn_get_rdn_val(newdn)); + return ldb_dn_set_component(*fixed_dn, 0, upper_rdn_attr, *rdn_val); } /* Fix all attribute names to be in the correct case, and check they are all valid per the schema */ -- cgit From 40a8a2268454a55103c5c675d6fc07efa3cb6f31 Mon Sep 17 00:00:00 2001 From: Kamen Mazdrashki Date: Sun, 11 Oct 2009 21:00:55 +0300 Subject: s4/drs: Propagate redefinition of drsuapi_DsReplicaOID into code base The biggest change is that 'oid' field is transmited in binary format. Also the field name is changed to 'binary_oid' so that field format to be clear for callers. After those changes, Samba4 should work the way it works before - i.e. no added value here but we should not fail when partial-oid is part of prefixMap transmited from Win server. Also, thre is a bug in this patch - partial-binary-OIDs are not handled correctly. Partial-binary-OIDs received during replication will be encoded, but not handled correctly. --- source4/dsdb/schema/schema_init.c | 166 ++++++++++++++++++++++++-------------- 1 file changed, 105 insertions(+), 61 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index 9dd3ce0ccc..f8b7d5dd44 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -29,6 +29,7 @@ #include "librpc/gen_ndr/ndr_drsblobs.h" #include "param/param.h" #include "lib/ldb/include/ldb_module.h" +#include "../lib/util/asn1.h" static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes); @@ -52,11 +53,11 @@ WERROR dsdb_load_oid_mappings_drsuapi(struct dsdb_schema *schema, const struct d W_ERROR_HAVE_NO_MEMORY(schema->prefixes); for (i=0, j=0; i < ctr->num_mappings; i++) { - if (ctr->mappings[i].oid.oid == NULL) { + if (ctr->mappings[i].oid.binary_oid == NULL) { return WERR_INVALID_PARAM; } - if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) { + if (ctr->mappings[i].oid.binary_oid[0] == 0xFF) { if (ctr->mappings[i].id_prefix != 0) { return WERR_INVALID_PARAM; } @@ -66,21 +67,33 @@ WERROR dsdb_load_oid_mappings_drsuapi(struct dsdb_schema *schema, const struct d return WERR_INVALID_PARAM; } - if (ctr->mappings[i].oid.__ndr_size != 21) { + if (ctr->mappings[i].oid.length != 21) { return WERR_INVALID_PARAM; } - schema->schema_info = talloc_strdup(schema, ctr->mappings[i].oid.oid); + schema->schema_info = hex_encode_talloc(schema, + ctr->mappings[i].oid.binary_oid, + ctr->mappings[i].oid.length); W_ERROR_HAVE_NO_MEMORY(schema->schema_info); } else { + DATA_BLOB oid_blob; + const char *partial_oid = NULL; + /* the last array member should contain the magic value not a oid */ if (i == (ctr->num_mappings - 1)) { return WERR_INVALID_PARAM; } + oid_blob = data_blob_const(ctr->mappings[i].oid.binary_oid, + ctr->mappings[i].oid.length); + if (!ber_read_partial_OID_String(schema->prefixes, oid_blob, &partial_oid)) { + DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X", + ctr->mappings[i].id_prefix)); + return WERR_INVALID_PARAM; + } + schema->prefixes[j].id = ctr->mappings[i].id_prefix<<16; - schema->prefixes[j].oid = talloc_asprintf(schema->prefixes, "%s.", - ctr->mappings[i].oid.oid); + schema->prefixes[j].oid = partial_oid; W_ERROR_HAVE_NO_MEMORY(schema->prefixes[j].oid); schema->prefixes[j].oid_len = strlen(schema->prefixes[j].oid); j++; @@ -98,7 +111,7 @@ WERROR dsdb_load_oid_mappings_ldb(struct dsdb_schema *schema, WERROR status; enum ndr_err_code ndr_err; struct prefixMapBlob pfm; - char *schema_info; + DATA_BLOB schema_info_blob; TALLOC_CTX *mem_ctx = talloc_new(schema); W_ERROR_HAVE_NO_MEMORY(mem_ctx); @@ -127,12 +140,12 @@ WERROR dsdb_load_oid_mappings_ldb(struct dsdb_schema *schema, pfm.ctr.dsdb.num_mappings); W_ERROR_HAVE_NO_MEMORY(pfm.ctr.dsdb.mappings); - schema_info = data_blob_hex_string(pfm.ctr.dsdb.mappings, schemaInfo); - W_ERROR_HAVE_NO_MEMORY(schema_info); + schema_info_blob = data_blob_dup_talloc(pfm.ctr.dsdb.mappings, schemaInfo); + W_ERROR_HAVE_NO_MEMORY(schema_info_blob.data); pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].id_prefix = 0; - pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.__ndr_size = schemaInfo->length; - pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.oid = schema_info; + pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.length = schemaInfo->length; + pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.binary_oid = schema_info_blob.data; /* call the drsuapi version */ status = dsdb_load_oid_mappings_drsuapi(schema, &pfm.ctr.dsdb); @@ -148,6 +161,7 @@ WERROR dsdb_get_oid_mappings_drsuapi(const struct dsdb_schema *schema, TALLOC_CTX *mem_ctx, struct drsuapi_DsReplicaOIDMapping_Ctr **_ctr) { + DATA_BLOB oid_blob; struct drsuapi_DsReplicaOIDMapping_Ctr *ctr; uint32_t i; @@ -160,18 +174,23 @@ WERROR dsdb_get_oid_mappings_drsuapi(const struct dsdb_schema *schema, W_ERROR_HAVE_NO_MEMORY(ctr->mappings); for (i=0; i < schema->num_prefixes; i++) { + if (!ber_write_partial_OID_String(ctr->mappings, &oid_blob, schema->prefixes[i].oid)) { + DEBUG(0, ("write_partial_OID failed for %s", schema->prefixes[i].oid)); + return WERR_INTERNAL_ERROR; + } + ctr->mappings[i].id_prefix = schema->prefixes[i].id>>16; - ctr->mappings[i].oid.oid = talloc_strndup(ctr->mappings, - schema->prefixes[i].oid, - schema->prefixes[i].oid_len - 1); - W_ERROR_HAVE_NO_MEMORY(ctr->mappings[i].oid.oid); + ctr->mappings[i].oid.length = oid_blob.length; + ctr->mappings[i].oid.binary_oid = oid_blob.data; } if (include_schema_info) { + oid_blob = strhex_to_data_blob(ctr->mappings, schema->schema_info); + W_ERROR_HAVE_NO_MEMORY(oid_blob.data); + ctr->mappings[i].id_prefix = 0; - ctr->mappings[i].oid.oid = talloc_strdup(ctr->mappings, - schema->schema_info); - W_ERROR_HAVE_NO_MEMORY(ctr->mappings[i].oid.oid); + ctr->mappings[i].oid.length = oid_blob.length; + ctr->mappings[i].oid.binary_oid = oid_blob.data; } *_ctr = ctr; @@ -211,13 +230,14 @@ WERROR dsdb_get_oid_mappings_ldb(const struct dsdb_schema *schema, WERROR dsdb_verify_oid_mappings_drsuapi(const struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr) { uint32_t i,j; + DATA_BLOB oid_blob; for (i=0; i < ctr->num_mappings; i++) { - if (ctr->mappings[i].oid.oid == NULL) { + if (ctr->mappings[i].oid.binary_oid == NULL) { return WERR_INVALID_PARAM; } - if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) { + if (ctr->mappings[i].oid.binary_oid[0] == 0xFF) { if (ctr->mappings[i].id_prefix != 0) { return WERR_INVALID_PARAM; } @@ -227,13 +247,19 @@ WERROR dsdb_verify_oid_mappings_drsuapi(const struct dsdb_schema *schema, const return WERR_INVALID_PARAM; } - if (ctr->mappings[i].oid.__ndr_size != 21) { + if (ctr->mappings[i].oid.length != 21) { return WERR_INVALID_PARAM; } - if (strcasecmp(schema->schema_info, ctr->mappings[i].oid.oid) != 0) { + oid_blob = strhex_to_data_blob(NULL, schema->schema_info); + W_ERROR_HAVE_NO_MEMORY(oid_blob.data); + + if (memcmp(oid_blob.data, ctr->mappings[i].oid.binary_oid, 21) != 0) { + data_blob_free(&oid_blob); return WERR_DS_DRA_SCHEMA_MISMATCH; } + + data_blob_free(&oid_blob); } else { /* the last array member should contain the magic value not a oid */ if (i == (ctr->num_mappings - 1)) { @@ -241,21 +267,26 @@ WERROR dsdb_verify_oid_mappings_drsuapi(const struct dsdb_schema *schema, const } for (j=0; j < schema->num_prefixes; j++) { - size_t oid_len; if (schema->prefixes[j].id != (ctr->mappings[i].id_prefix<<16)) { continue; } - oid_len = strlen(ctr->mappings[i].oid.oid); + if (!ber_write_partial_OID_String(NULL, &oid_blob, schema->prefixes[j].oid)) { + return WERR_INTERNAL_ERROR; + } - if (oid_len != (schema->prefixes[j].oid_len - 1)) { + if (oid_blob.length != ctr->mappings[j].oid.length) { + data_blob_free(&oid_blob); return WERR_DS_DRA_SCHEMA_MISMATCH; } - if (strncmp(ctr->mappings[i].oid.oid, schema->prefixes[j].oid, oid_len) != 0) { - return WERR_DS_DRA_SCHEMA_MISMATCH; + if (memcmp(ctr->mappings[i].oid.binary_oid, oid_blob.data, oid_blob.length) != 0) { + data_blob_free(&oid_blob); + return WERR_DS_DRA_SCHEMA_MISMATCH; } + data_blob_free(&oid_blob); + break; } @@ -284,7 +315,7 @@ WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CT continue; } - val = talloc_asprintf(mem_ctx, "%s%u", + val = talloc_asprintf(mem_ctx, "%s.%u", schema->prefixes[i].oid, in & 0xFFFF); W_ERROR_HAVE_NO_MEMORY(val); @@ -391,8 +422,6 @@ WERROR dsdb_prefix_map_update(TALLOC_CTX *mem_ctx, uint32_t *num_prefixes, struc DEBUG(0,("dsdb_prefix_map_update: size of the remaining string invalid\n")); return WERR_FOOBAR; } - /* Add one because we need to copy the dot */ - size += 1; /* Create a spot in the prefixMap for one more prefix*/ (*prefixes) = talloc_realloc(mem_ctx, *prefixes, struct dsdb_schema_oid_prefix, new_num_prefixes); @@ -412,37 +441,33 @@ WERROR dsdb_prefix_map_update(TALLOC_CTX *mem_ctx, uint32_t *num_prefixes, struc WERROR dsdb_find_prefix_for_oid(uint32_t num_prefixes, const struct dsdb_schema_oid_prefix *prefixes, const char *in, uint32_t *out) { uint32_t i; + char *oid_prefix; + char *pstr; + char *end_str; + unsigned val; - for (i=0; i < num_prefixes; i++) { - const char *val_str; - char *end_str; - unsigned val; - - if (strncmp(prefixes[i].oid, in, prefixes[i].oid_len) != 0) { - continue; - } + /* make oid prefix, i.e. oid w/o last subidentifier */ + pstr = strrchr(in, '.'); + if (!pstr) return WERR_INVALID_PARAM; + if (pstr < in) return WERR_INVALID_PARAM; + if ((pstr - in) < 4) return WERR_INVALID_PARAM; - val_str = in + prefixes[i].oid_len; - end_str = NULL; - errno = 0; + oid_prefix = talloc_strndup(0, in, pstr - in); - if (val_str[0] == '\0') { - return WERR_INVALID_PARAM; + for (i=0; i < num_prefixes; i++) { + if (strcmp(prefixes[i].oid, oid_prefix) == 0) { + break; } + } - /* two '.' chars are invalid */ - if (val_str[0] == '.') { - return WERR_INVALID_PARAM; - } + talloc_free(oid_prefix); - val = strtoul(val_str, &end_str, 10); - if (end_str[0] == '.' && end_str[1] != '\0') { - /* - * if it's a '.' and not the last char - * then maybe an other mapping apply - */ - continue; - } else if (end_str[0] != '\0') { + if (i < num_prefixes) { + /* move next to '.' char */ + pstr++; + + val = strtoul(pstr, &end_str, 10); + if (end_str[0] != '\0') { return WERR_INVALID_PARAM; } else if (val > 0xFFFF) { return WERR_INVALID_PARAM; @@ -489,8 +514,16 @@ WERROR dsdb_write_prefixes_from_schema_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_co } for (i=0; i < schema->num_prefixes; i++) { - pm.ctr.dsdb.mappings[i].id_prefix = schema->prefixes[i].id>>16; - pm.ctr.dsdb.mappings[i].oid.oid = talloc_strdup(pm.ctr.dsdb.mappings, schema->prefixes[i].oid); + DATA_BLOB oid_blob; + + if (!ber_write_partial_OID_String(pm.ctr.dsdb.mappings, &oid_blob, schema->prefixes[i].oid)) { + DEBUG(0, ("write_partial_OID failed for %s", schema->prefixes[i].oid)); + return WERR_INTERNAL_ERROR; + } + + pm.ctr.dsdb.mappings[i].id_prefix = schema->prefixes[i].id>>16; + pm.ctr.dsdb.mappings[i].oid.length = oid_blob.length; + pm.ctr.dsdb.mappings[i].oid.binary_oid = oid_blob.data; } ndr_err = ndr_push_struct_blob(&ndr_blob, msg, @@ -528,7 +561,7 @@ static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_contex uint32_t i; const struct ldb_val *prefix_val; struct ldb_dn *schema_dn; - struct ldb_result *schema_res; + struct ldb_result *schema_res = NULL; int ret; static const char *schema_attrs[] = { "prefixMap", @@ -588,10 +621,21 @@ static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_contex return WERR_NOMEM; } for (i=0; i < blob->ctr.dsdb.num_mappings; i++) { - char *oid; + DATA_BLOB oid_blob; + const char *partial_oid; + + oid_blob = data_blob_const(blob->ctr.dsdb.mappings[i].oid.binary_oid, + blob->ctr.dsdb.mappings[i].oid.length); + + if (!ber_read_partial_OID_String(mem_ctx, oid_blob, &partial_oid)) { + DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X", + blob->ctr.dsdb.mappings[i].id_prefix)); + talloc_free(blob); + return WERR_INVALID_PARAM; + } + (*prefixes)[i].id = blob->ctr.dsdb.mappings[i].id_prefix<<16; - oid = talloc_strdup(mem_ctx, blob->ctr.dsdb.mappings[i].oid.oid); - (*prefixes)[i].oid = talloc_asprintf_append(oid, "."); + (*prefixes)[i].oid = partial_oid; (*prefixes)[i].oid_len = strlen((*prefixes)[i].oid); } -- cgit From 784e0c199e8b083865ac96930c3b55d709a2bec5 Mon Sep 17 00:00:00 2001 From: Kamen Mazdrashki Date: Thu, 8 Oct 2009 02:55:28 +0300 Subject: s4/drs: prefixMap module initial definition --- source4/dsdb/config.mk | 3 ++- source4/dsdb/schema/prefixmap.h | 45 ++++++++++++++++++++++++++++++++++ source4/dsdb/schema/schema_prefixmap.c | 22 +++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 source4/dsdb/schema/prefixmap.h create mode 100644 source4/dsdb/schema/schema_prefixmap.c (limited to 'source4/dsdb') diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk index eec4f95c9e..59daa745e9 100644 --- a/source4/dsdb/config.mk +++ b/source4/dsdb/config.mk @@ -39,7 +39,8 @@ SAMDB_SCHEMA_OBJ_FILES = $(addprefix $(dsdbsrcdir)/schema/, \ schema_syntax.o \ schema_description.o \ schema_convert_to_ol.o \ - schema_inferiors.o) + schema_inferiors.o \ + schema_prefixmap.o) $(eval $(call proto_header_template,$(dsdbsrcdir)/schema/proto.h,$(SAMDB_SCHEMA_OBJ_FILES:.o=.c))) # PUBLIC_HEADERS += dsdb/schema/schema.h diff --git a/source4/dsdb/schema/prefixmap.h b/source4/dsdb/schema/prefixmap.h new file mode 100644 index 0000000000..7b28c88749 --- /dev/null +++ b/source4/dsdb/schema/prefixmap.h @@ -0,0 +1,45 @@ +/* + Unix SMB/CIFS implementation. + + DRS::prefixMap data structures + + Copyright (C) Kamen Mazdrashki 2009 + + 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 3 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _DSDB_PREFIXMAP_H +#define _DSDB_PREFIXMAP_H + +/** + * oid-prefix in prefixmap + */ +struct dsdb_schema_prefixmap_oid { + uint32_t id; + DATA_BLOB *bin_oid; /* partial binary-oid prefix */ +}; + +/** + * DSDB prefixMap internal presentation + */ +struct dsdb_schema_prefixmap { + uint32_t length; + struct dsdb_schema_prefixmap_oid *prefixes; +}; + + +#include "dsdb/schema/proto.h" + + +#endif /* _DSDB_PREFIXMAP_H */ diff --git a/source4/dsdb/schema/schema_prefixmap.c b/source4/dsdb/schema/schema_prefixmap.c new file mode 100644 index 0000000000..d24c5add00 --- /dev/null +++ b/source4/dsdb/schema/schema_prefixmap.c @@ -0,0 +1,22 @@ +/* + Unix SMB/CIFS implementation. + + DRS::prefixMap implementation + + Copyright (C) Kamen Mazdrashki 2009 + + 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 3 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" -- cgit From 30be3fd143bc558ffdac2a6fcf992d5a39f8f7d9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 Oct 2009 17:05:27 +1100 Subject: s4-privileges: moved privileges to private/privilege.ldb We were storing privileges in the sam, which was OK when we were a standalone DC, but is no good when we replicate with a windows DC. This moves the privileges to a separate (local) database --- source4/dsdb/samdb/samdb_privilege.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/samdb_privilege.c b/source4/dsdb/samdb/samdb_privilege.c index e9c6f4c527..e7742c681c 100644 --- a/source4/dsdb/samdb/samdb_privilege.c +++ b/source4/dsdb/samdb/samdb_privilege.c @@ -26,11 +26,30 @@ #include "libcli/security/security.h" #include "../lib/util/util_ldb.h" #include "param/param.h" +#include "ldb_wrap.h" + +/* connect to the privilege database */ +struct ldb_context *privilege_connect(TALLOC_CTX *mem_ctx, + struct tevent_context *ev_ctx, + struct loadparm_context *lp_ctx) +{ + char *path; + struct ldb_context *pdb; + + path = private_path(mem_ctx, lp_ctx, "privilege.ldb"); + if (!path) return NULL; + + pdb = ldb_wrap_connect(mem_ctx, ev_ctx, lp_ctx, path, + NULL, NULL, 0, NULL); + talloc_free(path); + + return pdb; +} /* add privilege bits for one sid to a security_token */ -static NTSTATUS samdb_privilege_setup_sid(void *samctx, TALLOC_CTX *mem_ctx, +static NTSTATUS samdb_privilege_setup_sid(struct ldb_context *pdb, TALLOC_CTX *mem_ctx, struct security_token *token, const struct dom_sid *sid) { @@ -43,7 +62,7 @@ static NTSTATUS samdb_privilege_setup_sid(void *samctx, TALLOC_CTX *mem_ctx, sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid); NT_STATUS_HAVE_NO_MEMORY(sidstr); - ret = gendb_search(samctx, mem_ctx, NULL, &res, attrs, "objectSid=%s", sidstr); + ret = gendb_search(pdb, mem_ctx, NULL, &res, attrs, "objectSid=%s", sidstr); talloc_free(sidstr); if (ret != 1) { /* not an error to not match */ @@ -76,7 +95,7 @@ static NTSTATUS samdb_privilege_setup_sid(void *samctx, TALLOC_CTX *mem_ctx, NTSTATUS samdb_privilege_setup(struct tevent_context *ev_ctx, struct loadparm_context *lp_ctx, struct security_token *token) { - void *samctx; + struct ldb_context *pdb; TALLOC_CTX *mem_ctx; int i; NTSTATUS status; @@ -98,8 +117,8 @@ NTSTATUS samdb_privilege_setup(struct tevent_context *ev_ctx, } mem_ctx = talloc_new(token); - samctx = samdb_connect(mem_ctx, ev_ctx, lp_ctx, system_session(mem_ctx, lp_ctx)); - if (samctx == NULL) { + pdb = privilege_connect(mem_ctx, ev_ctx, lp_ctx); + if (pdb == NULL) { talloc_free(mem_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -107,7 +126,7 @@ NTSTATUS samdb_privilege_setup(struct tevent_context *ev_ctx, token->privilege_mask = 0; for (i=0;inum_sids;i++) { - status = samdb_privilege_setup_sid(samctx, mem_ctx, + status = samdb_privilege_setup_sid(pdb, mem_ctx, token, token->sids[i]); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); -- cgit