#include "dsdb/common/util.h"
#include "lib/socket/socket.h"
#include "librpc/gen_ndr/irpc.h"
+#include "libds/common/flag_mapping.h"
/*
search the sam for the specified attributes in a specific domain, filter on
return the count of the number of records in the sam matching the query
*/
int samdb_search_count(struct ldb_context *sam_ldb,
+ TALLOC_CTX *mem_ctx,
struct ldb_dn *basedn,
- const char *format, ...) _PRINTF_ATTRIBUTE(3,4)
+ const char *format, ...) _PRINTF_ATTRIBUTE(4,5)
{
va_list ap;
- struct ldb_message **res;
const char *attrs[] = { NULL };
int ret;
- TALLOC_CTX *tmp_ctx = talloc_new(sam_ldb);
va_start(ap, format);
- ret = gendb_search_v(sam_ldb, tmp_ctx, basedn, &res, attrs, format, ap);
+ ret = gendb_search_v(sam_ldb, mem_ctx, basedn, NULL, attrs, format, ap);
va_end(ap);
- talloc_free(tmp_ctx);
return ret;
}
struct dom_sid *samdb_result_dom_sid(TALLOC_CTX *mem_ctx, const struct ldb_message *msg,
const char *attr)
{
+ bool ok;
const struct ldb_val *v;
struct dom_sid *sid;
- enum ndr_err_code ndr_err;
v = ldb_msg_find_ldb_val(msg, attr);
if (v == NULL) {
return NULL;
if (sid == NULL) {
return NULL;
}
- ndr_err = ndr_pull_struct_blob(v, sid, sid,
- (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ ok = sid_blob_parse(*v, sid);
+ if (!ok) {
talloc_free(sid);
return NULL;
}
return NULL;
}
-/*
- * This is intended for use by the "password hash" module since there
- * password changes can be specified through one message element with the
- * new password (to set) and another one with the old password (to unset).
- *
- * The first which sets a password (new value) can have flags
- * (LDB_FLAG_MOD_ADD, LDB_FLAG_MOD_REPLACE) but also none (on "add" operations
- * for entries). The latter (old value) has always specified
- * LDB_FLAG_MOD_DELETE.
- *
- * Returns LDB_ERR_NO_SUCH_ATTRIBUTE if the attribute which should be deleted
- * doesn't contain only one value (this is the Windows Server behaviour)
- * otherwise LDB_SUCCESS.
- */
-int samdb_msg_find_old_and_new_ldb_val(const struct ldb_message *msg,
- const char *name,
- const struct ldb_val **new_val,
- const struct ldb_val **old_val)
-{
- unsigned int i;
-
- *new_val = NULL;
- *old_val = NULL;
-
- if (msg == NULL) {
- return LDB_SUCCESS;
- }
-
- for (i = 0; i < msg->num_elements; i++) {
- if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
- if (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_DELETE) {
- *old_val = &msg->elements[i].values[0];
- } else {
- *new_val = &msg->elements[i].values[0];
- }
- }
- }
-
- return LDB_SUCCESS;
-}
-
int samdb_find_or_add_value(struct ldb_context *ldb, struct ldb_message *msg, const char *name, const char *set_value)
{
if (samdb_find_attribute(ldb, msg, name, set_value) == NULL) {
}
}
- vals = talloc_realloc(msg, el->values, struct ldb_val,
+ vals = talloc_realloc(msg->elements, el->values, struct ldb_val,
el->num_values + 1);
if (vals == NULL) {
return ldb_oom(sam_ldb);
}
}
- vals = talloc_realloc(msg, el->values, struct ldb_val,
+ vals = talloc_realloc(msg->elements, el->values, struct ldb_val,
el->num_values + 1);
if (vals == NULL) {
return ldb_oom(sam_ldb);
return false;
}
-/* Obtain the short name of the flexible single master operator
- * (FSMO), such as the PDC Emulator */
-const char *samdb_result_fsmo_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *msg,
- const char *attr)
-{
- /* Format is cn=NTDS Settings,cn=<NETBIOS name of FSMO>,.... */
- struct ldb_dn *fsmo_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, msg, attr);
- const struct ldb_val *val = ldb_dn_get_component_val(fsmo_dn, 1);
- const char *name = ldb_dn_get_component_name(fsmo_dn, 1);
-
- if (!name || (ldb_attr_cmp(name, "cn") != 0)) {
- /* Ensure this matches the format. This gives us a
- * bit more confidence that a 'cn' value will be a
- * ascii string */
- return NULL;
- }
- if (val) {
- return (char *)val->data;
- }
- return NULL;
-}
-
/*
work out the ntds settings dn for the current open ldb
*/
settings_dn = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, root_res->msgs[0], "dsServiceName");
/* cache the domain_sid in the ldb */
- if (ldb_set_opaque(ldb, "cache.settings_dn", settings_dn) != LDB_SUCCESS) {
+ if (ldb_set_opaque(ldb, "cache.ntds_settings_dn", settings_dn) != LDB_SUCCESS) {
goto failed;
}
talloc_free(dn);
return LDB_ERR_INVALID_DN_SYNTAX;
}
+
rdn_val = ldb_dn_get_rdn_val(dn);
+ if (rdn_val == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
(*site_name) = talloc_strndup(mem_ctx, (const char *)rdn_val->data, rdn_val->length);
talloc_free(dn);
if (!*site_name) {
* is for sure the same as our server site). If more sites do
* exist then we don't know which one to use and set the site
* name to "". */
- cnt = samdb_search_count(ldb, sites_container_dn,
+ cnt = samdb_search_count(ldb, mem_ctx, sites_container_dn,
"(objectClass=site)");
if (cnt == 1) {
site_name = samdb_server_site_name(ldb, mem_ctx);
DEBUG(1,("Searching for namingContexts in rootDSE failed: %s\n", ldb_errstring(samdb)));
talloc_free(tmp_ctx);
return ret;
- }
+ }
- el = ldb_msg_find_element(root_res->msgs[0], "namingContexts");
- if (!el) {
- DEBUG(1,("Finding namingContexts element in root_res failed: %s\n",
- ldb_errstring(samdb)));
- talloc_free(tmp_ctx);
- return LDB_ERR_NO_SUCH_ATTRIBUTE;
- }
+ el = ldb_msg_find_element(root_res->msgs[0], "namingContexts");
+ if ((el == NULL) || (el->num_values < 3)) {
+ struct ldb_message *tmp_msg;
+
+ DEBUG(5,("dsdb_find_nc_root: Finding a valid 'namingContexts' element in the RootDSE failed. Using a temporary list."));
+
+ /* This generates a temporary list of NCs in order to let the
+ * provisioning work. */
+ tmp_msg = ldb_msg_new(tmp_ctx);
+ if (tmp_msg == NULL) {
+ talloc_free(tmp_ctx);
+ return ldb_oom(samdb);
+ }
+ ret = ldb_msg_add_steal_string(tmp_msg, "namingContexts",
+ ldb_dn_alloc_linearized(tmp_msg, ldb_get_schema_basedn(samdb)));
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ ret = ldb_msg_add_steal_string(tmp_msg, "namingContexts",
+ ldb_dn_alloc_linearized(tmp_msg, ldb_get_config_basedn(samdb)));
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ ret = ldb_msg_add_steal_string(tmp_msg, "namingContexts",
+ ldb_dn_alloc_linearized(tmp_msg, ldb_get_default_basedn(samdb)));
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ el = &tmp_msg->elements[0];
+ }
nc_dns = talloc_array(tmp_ctx, struct ldb_dn *, el->num_values);
if (!nc_dns) {
}
}
+ if (dsdb_flags & DSDB_PROVISION) {
+ ret = ldb_request_add_control(req, LDB_CONTROL_PROVISION_OID, false, NULL);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
return LDB_SUCCESS;
}
return forest_name;
}
+/* returns back the default domain DNS name */
+const char *samdb_default_domain_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
+{
+ const char *domain_name = ldb_dn_canonical_string(mem_ctx,
+ ldb_get_default_basedn(ldb));
+ char *p;
+
+ if (domain_name == NULL) {
+ return NULL;
+ }
+
+ p = strchr(domain_name, '/');
+ if (p) {
+ *p = '\0';
+ }
+
+ return domain_name;
+}
+
/*
validate that an DSA GUID belongs to the specified user sid.
The user SID must be a domain controller account (either RODC or
return LDB_SUCCESS;
}
-static const char *secret_attributes[] = {
- "currentValue",
- "dBCSPwd",
- "initialAuthIncoming",
- "initialAuthOutgoing",
- "lmPwdHistory",
- "ntPwdHistory",
- "priorValue",
- "supplementalCredentials",
- "trustAuthIncoming",
- "trustAuthOutgoing",
- "unicodePwd",
+static const char * const secret_attributes[] = {
+ DSDB_SECRET_ATTRIBUTES,
NULL
};