return samdb_msg_add_string(sam_ldb, mem_ctx, msg, attr_name, str);
}
+/*
+ * sets a signed integer in a message
+ */
+int samdb_msg_set_int(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
+ struct ldb_message *msg, const char *attr_name, int v)
+{
+ struct ldb_message_element *el;
+
+ el = ldb_msg_find_element(msg, attr_name);
+ if (el) {
+ el->num_values = 0;
+ }
+ return samdb_msg_add_int(sam_ldb, mem_ctx, msg, attr_name, v);
+}
+
+/*
+ * sets an unsigned integer in a message
+ */
+int samdb_msg_set_uint(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
+ struct ldb_message *msg, const char *attr_name,
+ unsigned int v)
+{
+ struct ldb_message_element *el;
+
+ el = ldb_msg_find_element(msg, attr_name);
+ if (el) {
+ el->num_values = 0;
+ }
+ return samdb_msg_add_uint(sam_ldb, mem_ctx, msg, attr_name, v);
+}
+
/*
* Handle ldb_request in transaction
*/
return server_site_dn;
}
+/*
+ find the site name from a computers DN record
+ */
+int samdb_find_site_for_computer(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx, struct ldb_dn *computer_dn,
+ const char **site_name)
+{
+ int ret;
+ struct ldb_dn *dn;
+ const struct ldb_val *rdn_val;
+
+ *site_name = NULL;
+
+ ret = samdb_reference_dn(ldb, mem_ctx, computer_dn, "serverReferenceBL", &dn);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ if (!ldb_dn_remove_child_components(dn, 2)) {
+ talloc_free(dn);
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+ rdn_val = ldb_dn_get_rdn_val(dn);
+ (*site_name) = talloc_strndup(mem_ctx, (const char *)rdn_val->data, rdn_val->length);
+ talloc_free(dn);
+ if (!*site_name) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ return LDB_SUCCESS;
+}
+
+/*
+ find the NTDS GUID from a computers DN record
+ */
+int samdb_find_ntdsguid_for_computer(struct ldb_context *ldb, struct ldb_dn *computer_dn,
+ struct GUID *ntds_guid)
+{
+ int ret;
+ struct ldb_dn *dn;
+
+ *ntds_guid = GUID_zero();
+
+ ret = samdb_reference_dn(ldb, ldb, computer_dn, "serverReferenceBL", &dn);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ if (!ldb_dn_add_child_fmt(dn, "CN=NTDS Settings")) {
+ talloc_free(dn);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = dsdb_find_guid_by_dn(ldb, dn, ntds_guid);
+ talloc_free(dn);
+ return ret;
+}
+
/*
find a 'reference' DN that points at another object
(eg. serverReference, rIDManagerReference etc)
attrs[0] = attribute;
attrs[1] = NULL;
- ret = ldb_search(ldb, mem_ctx, &res, base, LDB_SCOPE_BASE, attrs, NULL);
+ ret = dsdb_search(ldb, mem_ctx, &res, base, LDB_SCOPE_BASE, attrs, DSDB_SEARCH_ONE_ONLY, NULL);
if (ret != LDB_SUCCESS) {
return ret;
}
- if (res->count != 1) {
- talloc_free(res);
- return LDB_ERR_NO_SUCH_OBJECT;
- }
*dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, res->msgs[0], attribute);
if (!*dn) {
+ if (!ldb_msg_find_element(res->msgs[0], attribute)) {
+ ldb_asprintf_errstring(ldb, "Cannot find attribute %s of %s to calculate reference dn", attribute,
+ ldb_dn_get_linearized(base));
+ } else {
+ ldb_asprintf_errstring(ldb, "Cannot interpret attribute %s of %s as a dn", attribute,
+ ldb_dn_get_linearized(base));
+ }
talloc_free(res);
- ldb_asprintf_errstring(ldb, "Cannot find dn of attribute %s of %s", attribute,
- ldb_dn_get_linearized(base));
return LDB_ERR_NO_SUCH_ATTRIBUTE;
}
attrs[0] = attribute;
attrs[1] = NULL;
- ret = dsdb_search_dn(ldb, tmp_ctx, &res, dn, attrs, DSDB_SEARCH_SHOW_DELETED);
+ ret = dsdb_search_dn(ldb, tmp_ctx, &res, dn, attrs,
+ DSDB_SEARCH_SHOW_DELETED |
+ DSDB_SEARCH_SHOW_RECYCLED);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ret;
ZERO_STRUCTP(sid);
- ret = dsdb_search_dn(ldb, tmp_ctx, &res, dn, attrs, DSDB_SEARCH_SHOW_DELETED);
+ ret = dsdb_search_dn(ldb, tmp_ctx, &res, dn, attrs,
+ DSDB_SEARCH_SHOW_DELETED |
+ DSDB_SEARCH_SHOW_RECYCLED);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ret;
int *domainFunctionality =
talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int);
if (!domainFunctionality) {
- DEBUG(0,(__location__ ": WARNING: domainFunctionality not setup\n"));
+ /* this is expected during initial provision */
+ DEBUG(4,(__location__ ": WARNING: domainFunctionality not setup\n"));
return DS_DOMAIN_FUNCTION_2000;
}
return *domainFunctionality;
if (val->length < 13) {
return 0;
}
- p = memmem(val->data, val->length-2, "<RMD_FLAGS=", 11);
+ p = memmem(val->data, val->length, "<RMD_FLAGS=", 11);
if (!p) {
return 0;
}
return ldb_operr(samdb);
}
- ret = dsdb_search_dn(samdb, tmp_ctx, &res, dn, attrs, DSDB_SEARCH_SHOW_DELETED);
+ ret = dsdb_search_dn(samdb, tmp_ctx, &res, dn, attrs,
+ DSDB_SEARCH_SHOW_DELETED |
+ DSDB_SEARCH_SHOW_RECYCLED);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ret;
}
}
+ if (dsdb_flags & DSDB_SEARCH_SHOW_RECYCLED) {
+ ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_RECYCLED_OID, false, NULL);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
if (dsdb_flags & DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT) {
ret = ldb_request_add_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID, true, NULL);
if (ret != LDB_SUCCESS) {
return LDB_SUCCESS;
}
+/*
+ search for attrs on one DN, by the GUID of the DN, allowing for
+ dsdb_flags controls
+ */
+int dsdb_search_by_dn_guid(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_result **_res,
+ const struct GUID *guid,
+ const char * const *attrs,
+ uint32_t dsdb_flags)
+{
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ struct ldb_dn *dn;
+ int ret;
+
+ dn = ldb_dn_new_fmt(tmp_ctx, ldb, "<GUID=%s>", GUID_string(tmp_ctx, guid));
+ if (!ldb_dn_validate(dn)) {
+ talloc_free(tmp_ctx);
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+
+ ret = dsdb_search_dn(ldb, mem_ctx, _res, dn, attrs, dsdb_flags);
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
/*
general search with dsdb_flags for controls
*/
ret = dsdb_request_add_controls(req, dsdb_flags);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
+ ldb_reset_err_string(ldb);
return ret;
}
if (dsdb_flags & DSDB_SEARCH_ONE_ONLY) {
if (res->count == 0) {
talloc_free(tmp_ctx);
+ ldb_reset_err_string(ldb);
return LDB_ERR_NO_SUCH_OBJECT;
}
if (res->count != 1) {
talloc_free(tmp_ctx);
+ ldb_reset_err_string(ldb);
return LDB_ERR_CONSTRAINT_VIOLATION;
}
}
}
return WERR_OK;
}
+
+const char *samdb_dn_to_dnshostname(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_dn *server_dn)
+{
+ int ldb_ret;
+ struct ldb_result *res = NULL;
+ const char * const attrs[] = { "dNSHostName", NULL};
+
+ ldb_ret = ldb_search(ldb, mem_ctx, &res,
+ server_dn,
+ LDB_SCOPE_BASE,
+ attrs, NULL);
+ if (ldb_ret != LDB_SUCCESS) {
+ DEBUG(4, ("Failed to find dNSHostName for dn %s, ldb error: %s",
+ ldb_dn_get_linearized(server_dn), ldb_errstring(ldb)));
+ return NULL;
+ }
+
+ return samdb_result_string(res->msgs[0], "dNSHostName", NULL);
+}
+
+/*
+ returns true if an attribute is in the filter,
+ false otherwise, provided that attribute value is provided with the expression
+*/
+bool dsdb_attr_in_parse_tree(struct ldb_parse_tree *tree,
+ const char *attr)
+{
+ unsigned int i;
+ switch (tree->operation) {
+ case LDB_OP_AND:
+ case LDB_OP_OR:
+ for (i=0;i<tree->u.list.num_elements;i++) {
+ if (dsdb_attr_in_parse_tree(tree->u.list.elements[i],
+ attr))
+ return true;
+ }
+ return false;
+ case LDB_OP_NOT:
+ return dsdb_attr_in_parse_tree(tree->u.isnot.child, attr);
+ case LDB_OP_EQUALITY:
+ case LDB_OP_GREATER:
+ case LDB_OP_LESS:
+ case LDB_OP_APPROX:
+ if (ldb_attr_cmp(tree->u.equality.attr, attr) == 0) {
+ return true;
+ }
+ return false;
+ case LDB_OP_SUBSTRING:
+ if (ldb_attr_cmp(tree->u.substring.attr, attr) == 0) {
+ return true;
+ }
+ return false;
+ case LDB_OP_PRESENT:
+ /* (attrname=*) is not filtered out */
+ return false;
+ case LDB_OP_EXTENDED:
+ if (tree->u.extended.attr &&
+ ldb_attr_cmp(tree->u.extended.attr, attr) == 0) {
+ return true;
+ }
+ return false;
+ }
+ return false;
+}
+