diff options
Diffstat (limited to 'source4/dsdb')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samldb.c | 51 | ||||
-rw-r--r-- | source4/dsdb/samdb/samdb.c | 99 | ||||
-rw-r--r-- | source4/dsdb/samdb/samdb_privilege.c | 11 |
3 files changed, 118 insertions, 43 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 5472bed107..b5440c3cd1 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -35,7 +35,8 @@ #include "includes.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_private.h" -#include <time.h> +#include "system/time.h" +#include "librpc/gen_ndr/ndr_security.h" #define SAM_ACCOUNT_NAME_BASE "$000000-000000000000" @@ -169,14 +170,15 @@ static char *samldb_search_domain(struct ldb_module *module, TALLOC_CTX *mem_ctx allocate a new RID for the domain return the new sid string */ -static char *samldb_get_new_sid(struct ldb_module *module, TALLOC_CTX *mem_ctx, const char *obj_dn) +static struct dom_sid *samldb_get_new_sid(struct ldb_module *module, + TALLOC_CTX *mem_ctx, const char *obj_dn) { const char * const attrs[2] = { "objectSid", NULL }; struct ldb_message **res = NULL; - const char *dom_dn, *dom_sid; - char *obj_sid; + const char *dom_dn; uint32_t rid; int ret, tries = 10; + struct dom_sid *dom_sid, *obj_sid; /* get the domain component part of the provided dn */ @@ -197,11 +199,11 @@ static char *samldb_get_new_sid(struct ldb_module *module, TALLOC_CTX *mem_ctx, ret = ldb_search(module->ldb, dom_dn, LDB_SCOPE_BASE, "objectSid=*", attrs, &res); if (ret != 1) { ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_get_new_sid: error retrieving domain sid!\n"); - if (res) talloc_free(res); + talloc_free(res); return NULL; } - dom_sid = ldb_msg_find_string(res[0], "objectSid", NULL); + dom_sid = samdb_result_dom_sid(res, res[0], "objectSid"); if (dom_sid == NULL) { ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_get_new_sid: error retrieving domain sid!\n"); talloc_free(res); @@ -225,12 +227,10 @@ static char *samldb_get_new_sid(struct ldb_module *module, TALLOC_CTX *mem_ctx, } /* return the new object sid */ - - obj_sid = talloc_asprintf(mem_ctx, "%s-%u", dom_sid, rid); + obj_sid = dom_sid_add_rid(mem_ctx, dom_sid, rid); talloc_free(res); - return obj_sid; } @@ -307,6 +307,18 @@ static BOOL samldb_msg_add_string(struct ldb_module *module, struct ldb_message return True; } +static BOOL samldb_msg_add_sid(struct ldb_module *module, struct ldb_message *msg, const char *name, const struct dom_sid *sid) +{ + struct ldb_val v; + NTSTATUS status; + status = ndr_push_struct_blob(&v, msg, sid, + (ndr_push_flags_fn_t)ndr_push_dom_sid); + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + return (ldb_msg_add_value(module->ldb, msg, name, &v) == 0); +} + static BOOL samldb_find_or_add_attribute(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *value, const char *set_value) { if (samldb_find_attribute(msg, name, value) == NULL) { @@ -367,7 +379,7 @@ static struct ldb_message *samldb_fill_group_object(struct ldb_module *module, c { struct ldb_message *msg2; struct ldb_message_element *attribute; - char *rdn, *basedn, *sidstr; + char *rdn, *basedn; if (samldb_find_attribute(msg, "objectclass", "group") == NULL) { return NULL; @@ -418,15 +430,17 @@ static struct ldb_message *samldb_fill_group_object(struct ldb_module *module, c } if ((attribute = samldb_find_attribute(msg2, "objectSid", NULL)) == NULL ) { - - if ((sidstr = samldb_get_new_sid(module, msg2, msg2->dn)) == NULL) { + struct dom_sid *sid = samldb_get_new_sid(module, msg2, msg2->dn); + if (sid == NULL) { ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: internal error! Can't generate new sid\n"); return NULL; } - if ( ! samldb_msg_add_string(module, msg2, "objectSid", sidstr)) { + if (!samldb_msg_add_sid(module, msg2, "objectSid", sid)) { + talloc_free(sid); return NULL; } + talloc_free(sid); } if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", NULL, samldb_generate_samAccountName(msg2))) { @@ -444,7 +458,7 @@ static struct ldb_message *samldb_fill_user_or_computer_object(struct ldb_module { struct ldb_message *msg2; struct ldb_message_element *attribute; - char *rdn, *basedn, *sidstr; + char *rdn, *basedn; if ((samldb_find_attribute(msg, "objectclass", "user") == NULL) && (samldb_find_attribute(msg, "objectclass", "computer") == NULL)) { return NULL; @@ -500,15 +514,18 @@ static struct ldb_message *samldb_fill_user_or_computer_object(struct ldb_module } if ((attribute = samldb_find_attribute(msg2, "objectSid", NULL)) == NULL ) { - - if ((sidstr = samldb_get_new_sid(module, msg2, msg2->dn)) == NULL) { + struct dom_sid *sid; + sid = samldb_get_new_sid(module, msg2, msg2->dn); + if (sid == NULL) { ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_user_or_computer_object: internal error! Can't generate new sid\n"); return NULL; } - if ( ! samldb_msg_add_string(module, msg2, "objectSid", sidstr)) { + if ( ! samldb_msg_add_sid(module, msg2, "objectSid", sid)) { + talloc_free(sid); return NULL; } + talloc_free(sid); } if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", NULL, samldb_generate_samAccountName(msg2))) { diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c index 5f9764ce42..e2426738da 100644 --- a/source4/dsdb/samdb/samdb.c +++ b/source4/dsdb/samdb/samdb.c @@ -61,17 +61,17 @@ int samdb_search_domain(struct ldb_context *sam_ldb, while (i<count) { struct dom_sid *entry_sid; - entry_sid = samdb_result_dom_sid(mem_ctx, (*res)[i], - "objectSid"); + entry_sid = samdb_result_dom_sid(mem_ctx, (*res)[i], "objectSid"); if ((entry_sid == NULL) || (!dom_sid_in_domain(domain_sid, entry_sid))) { - /* Delete that entry from the result set */ (*res)[i] = (*res)[count-1]; count -= 1; + talloc_free(entry_sid); continue; } + talloc_free(entry_sid); i += 1; } @@ -125,6 +125,37 @@ const char *samdb_search_string(struct ldb_context *sam_ldb, } /* + search the sam for a dom_sid attribute in exactly 1 record +*/ +struct dom_sid *samdb_search_dom_sid(struct ldb_context *sam_ldb, + TALLOC_CTX *mem_ctx, + const char *basedn, + const char *attr_name, + const char *format, ...) _PRINTF_ATTRIBUTE(5,6) +{ + va_list ap; + int count; + struct ldb_message **res; + const char * const attrs[2] = { attr_name, NULL }; + struct dom_sid *sid; + + va_start(ap, format); + count = gendb_search_v(sam_ldb, mem_ctx, basedn, &res, attrs, format, ap); + va_end(ap); + if (count > 1) { + DEBUG(1,("samdb: search for %s %s not single valued (count=%d)\n", + attr_name, format, count)); + } + if (count != 1) { + talloc_free(res); + return NULL; + } + sid = samdb_result_dom_sid(mem_ctx, res[0], attr_name); + talloc_free(res); + return sid; +} + +/* return the count of the number of records in the sam matching the query */ int samdb_search_count(struct ldb_context *sam_ldb, @@ -274,16 +305,18 @@ const char *samdb_result_string(struct ldb_message *msg, const char *attr, pull a rid from a objectSid in a result set. */ uint32_t samdb_result_rid_from_sid(TALLOC_CTX *mem_ctx, struct ldb_message *msg, - const char *attr, uint32_t default_value) + const char *attr, uint32_t default_value) { struct dom_sid *sid; - const char *sidstr = ldb_msg_find_string(msg, attr, NULL); - if (!sidstr) return default_value; - - sid = dom_sid_parse_talloc(mem_ctx, sidstr); - if (!sid) return default_value; + uint32_t rid; - return sid->sub_auths[sid->num_auths-1]; + sid = samdb_result_dom_sid(mem_ctx, msg, attr); + if (sid == NULL) { + return default_value; + } + rid = sid->sub_auths[sid->num_auths-1]; + talloc_free(sid); + return rid; } /* @@ -292,10 +325,24 @@ uint32_t samdb_result_rid_from_sid(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct dom_sid *samdb_result_dom_sid(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr) { - const char *sidstr = ldb_msg_find_string(msg, attr, NULL); - if (!sidstr) return NULL; - - return dom_sid_parse_talloc(mem_ctx, sidstr); + const struct ldb_val *v; + struct dom_sid *sid; + NTSTATUS status; + v = ldb_msg_find_ldb_val(msg, attr); + if (v == NULL) { + return NULL; + } + sid = talloc(mem_ctx, struct dom_sid); + if (sid == NULL) { + return NULL; + } + status = ndr_pull_struct_blob(v, sid, sid, + (ndr_pull_flags_fn_t)ndr_pull_dom_sid); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(sid); + return NULL; + } + return sid; } /* @@ -324,15 +371,13 @@ struct GUID samdb_result_guid(struct ldb_message *msg, const char *attr) pull a sid prefix from a objectSid in a result set. this is used to find the domain sid for a user */ -const char *samdb_result_sid_prefix(TALLOC_CTX *mem_ctx, struct ldb_message *msg, - const char *attr) +struct dom_sid *samdb_result_sid_prefix(TALLOC_CTX *mem_ctx, struct ldb_message *msg, + const char *attr) { struct dom_sid *sid = samdb_result_dom_sid(mem_ctx, msg, attr); if (!sid || sid->num_auths < 1) return NULL; - sid->num_auths--; - - return dom_sid_string(mem_ctx, sid); + return sid; } /* @@ -704,6 +749,22 @@ int samdb_msg_add_string(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struc } /* + add a dom_sid element to a message +*/ +int samdb_msg_add_dom_sid(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, + const char *attr_name, struct dom_sid *sid) +{ + struct ldb_val v; + NTSTATUS status; + status = ndr_push_struct_blob(&v, mem_ctx, sid, + (ndr_push_flags_fn_t)ndr_push_dom_sid); + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + return ldb_msg_add_value(sam_ldb, msg, attr_name, &v); +} + +/* add a delete element operation to a message */ int samdb_msg_add_delete(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, diff --git a/source4/dsdb/samdb/samdb_privilege.c b/source4/dsdb/samdb/samdb_privilege.c index 77ddcbbdcd..bfd37f6417 100644 --- a/source4/dsdb/samdb/samdb_privilege.c +++ b/source4/dsdb/samdb/samdb_privilege.c @@ -31,29 +31,26 @@ static NTSTATUS samdb_privilege_setup_sid(void *samctx, TALLOC_CTX *mem_ctx, const struct dom_sid *sid, uint64_t *mask) { - char *sidstr; const char * const attrs[] = { "privilege", NULL }; struct ldb_message **res = NULL; struct ldb_message_element *el; int ret, i; + char *sidstr; *mask = 0; - sidstr = dom_sid_string(mem_ctx, sid); - if (sidstr == NULL) { - return NT_STATUS_NO_MEMORY; - } + 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); + talloc_free(sidstr); if (ret != 1) { - talloc_free(sidstr); /* not an error to not match */ return NT_STATUS_OK; } el = ldb_msg_find_element(res[0], "privilege"); if (el == NULL) { - talloc_free(sidstr); return NT_STATUS_OK; } |