#include "libcli/ldap/ldap.h"
#include "system/time.h"
#include "system/filesys.h"
-#include "db_wrap.h"
+#include "ldb_wrap.h"
+#include "util/util_ldb.h"
#include "dsdb/samdb/samdb.h"
#include "dsdb/common/flags.h"
+#include "param/param.h"
+
+char *samdb_relative_path(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ const char *name)
+{
+ const char *base_url =
+ (const char *)ldb_get_opaque(ldb, "ldb_url");
+ char *path, *p, *full_name;
+ if (name == NULL) {
+ return NULL;
+ }
+ if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) {
+ return talloc_strdup(mem_ctx, name);
+ }
+ path = talloc_strdup(mem_ctx, base_url);
+ if (path == NULL) {
+ return NULL;
+ }
+ if ( (p = strrchr(path, '/')) != NULL) {
+ p[0] = '\0';
+ full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name);
+ } else {
+ full_name = talloc_asprintf(mem_ctx, "./%s", name);
+ }
+ talloc_free(path);
+ return full_name;
+}
+
/*
connect to the SAM database
return an opaque context pointer on success, or NULL on failure
*/
struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx,
+ struct loadparm_context *lp_ctx,
struct auth_session_info *session_info)
{
struct ldb_context *ldb;
- ldb = ldb_wrap_connect(mem_ctx, lp_sam_url(), session_info,
+ ldb = ldb_wrap_connect(mem_ctx, lp_ctx,
+ lp_sam_url(lp_ctx), session_info,
NULL, 0, NULL);
if (!ldb) {
return NULL;
{
const struct ldb_val *v;
struct dom_sid *sid;
- NTSTATUS status;
+ enum ndr_err_code ndr_err;
v = ldb_msg_find_ldb_val(msg, attr);
if (v == NULL) {
return NULL;
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)) {
+ 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)) {
talloc_free(sid);
return NULL;
}
struct GUID samdb_result_guid(const struct ldb_message *msg, const char *attr)
{
const struct ldb_val *v;
- NTSTATUS status;
+ enum ndr_err_code ndr_err;
struct GUID guid;
TALLOC_CTX *mem_ctx;
mem_ctx = talloc_named_const(NULL, 0, "samdb_result_guid");
if (!mem_ctx) return guid;
- status = ndr_pull_struct_blob(v, mem_ctx, &guid,
- (ndr_pull_flags_fn_t)ndr_pull_GUID);
+ ndr_err = ndr_pull_struct_blob(v, mem_ctx, &guid,
+ (ndr_pull_flags_fn_t)ndr_pull_GUID);
talloc_free(mem_ctx);
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return guid;
}
{
int i;
struct ldb_message_element *el = ldb_msg_find_element(msg, name);
- struct ldb_val v;
-
- v.data = discard_const_p(uint8_t, value);
- v.length = strlen(value);
if (!el) {
return NULL;
struct ldb_result *res;
struct ldb_message *t;
int ret, i, j;
- struct ldb_dn *basedn = ldb_dn_new(ldb, ldb, "cn=Templates");
+ struct ldb_context *templates_ldb;
+ char *templates_ldb_path;
+ struct ldb_dn *basedn;
+
+ templates_ldb = talloc_get_type(ldb_get_opaque(ldb, "templates_ldb"), struct ldb_context);
+
+ if (!templates_ldb) {
+ templates_ldb_path = samdb_relative_path(ldb,
+ msg,
+ "templates.ldb");
+ if (!templates_ldb_path) {
+ *errstring = talloc_asprintf(msg, "samdb_copy_template: ERROR: Failed to contruct path for template db");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ templates_ldb = ldb_wrap_connect(ldb, global_loadparm,
+ templates_ldb_path, NULL,
+ NULL, 0, NULL);
+ talloc_free(templates_ldb_path);
+ if (!templates_ldb) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_set_opaque(ldb, "templates_ldb", templates_ldb);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
*errstring = NULL;
+ basedn = ldb_dn_new(templates_ldb, ldb, "cn=Templates");
if (!ldb_dn_add_child_fmt(basedn, "CN=Template%s", name)) {
+ talloc_free(basedn);
*errstring = talloc_asprintf(msg, "samdb_copy_template: ERROR: Failed to contruct DN for template '%s'",
name);
return LDB_ERR_OPERATIONS_ERROR;
}
/* pull the template record */
- ret = ldb_search(ldb, basedn, LDB_SCOPE_BASE, "cn=*", NULL, &res);
+ ret = ldb_search(templates_ldb, basedn, LDB_SCOPE_BASE, "(dn=*)", NULL, &res);
talloc_free(basedn);
if (ret != LDB_SUCCESS) {
- *errstring = talloc_steal(msg, ldb_errstring(ldb));
+ *errstring = talloc_steal(msg, ldb_errstring(templates_ldb));
return ret;
}
if (res->count != 1) {
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)) {
+ enum ndr_err_code ndr_err;
+
+ ndr_err = ndr_push_struct_blob(&v, mem_ctx, sid,
+ (ndr_push_flags_fn_t)ndr_push_dom_sid);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return -1;
}
return ldb_msg_add_value(msg, attr_name, &v, NULL);
return samdb_msg_add_string(sam_ldb, mem_ctx, msg, attr_name, str);
}
-/*
- add a record
-*/
-int samdb_add(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg)
-{
- return ldb_add(sam_ldb, msg);
-}
-
-/*
- delete a record
-*/
-int samdb_delete(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
-{
- return ldb_delete(sam_ldb, dn);
-}
-
-/*
- modify a record
-*/
-int samdb_modify(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg)
-{
- return ldb_modify(sam_ldb, msg);
-}
-
/*
replace elements in a record
*/
}
/* modify the samdb record */
- return samdb_modify(sam_ldb, mem_ctx, msg);
+ return ldb_modify(sam_ldb, msg);
}
/*
struct dom_sid *domain_sid;
/* see if we have a cached copy */
- domain_sid = ldb_get_opaque(ldb, "cache.domain_sid");
+ domain_sid = (struct dom_sid *)ldb_get_opaque(ldb, "cache.domain_sid");
if (domain_sid) {
return domain_sid;
}
struct ldb_dn *settings_dn;
/* see if we have a cached copy */
- settings_dn = ldb_get_opaque(ldb, "cache.settings_dn");
+ settings_dn = (struct ldb_dn *)ldb_get_opaque(ldb, "cache.settings_dn");
if (settings_dn) {
return settings_dn;
}
struct GUID *invocation_id;
/* see if we have a cached copy */
- invocation_id = ldb_get_opaque(ldb, "cache.invocation_id");
+ invocation_id = (struct GUID *)ldb_get_opaque(ldb, "cache.invocation_id");
if (invocation_id) {
return invocation_id;
}
struct GUID *invocation_id_old;
/* see if we have a cached copy */
- invocation_id_old = ldb_get_opaque(ldb, "cache.invocation_id");
+ invocation_id_old = (struct GUID *)ldb_get_opaque(ldb,
+ "cache.invocation_id");
tmp_ctx = talloc_new(ldb);
if (tmp_ctx == NULL) {
struct GUID *ntds_guid;
/* see if we have a cached copy */
- ntds_guid = ldb_get_opaque(ldb, "cache.ntds_guid");
+ ntds_guid = (struct GUID *)ldb_get_opaque(ldb, "cache.ntds_guid");
if (ntds_guid) {
return ntds_guid;
}
struct GUID *ntds_guid_old;
/* see if we have a cached copy */
- ntds_guid_old = ldb_get_opaque(ldb, "cache.ntds_guid");
+ ntds_guid_old = (struct GUID *)ldb_get_opaque(ldb, "cache.ntds_guid");
tmp_ctx = talloc_new(ldb);
if (tmp_ctx == NULL) {
/*
work out if we are the PDC for the domain of the current open ldb
*/
-BOOL samdb_is_pdc(struct ldb_context *ldb)
+bool samdb_is_pdc(struct ldb_context *ldb)
{
const char *dom_attrs[] = { "fSMORoleOwner", NULL };
int ret;
struct ldb_result *dom_res;
TALLOC_CTX *tmp_ctx;
- BOOL is_pdc;
+ bool is_pdc;
struct ldb_dn *pdc;
tmp_ctx = talloc_new(ldb);
if (tmp_ctx == NULL) {
DEBUG(1, ("talloc_new failed in samdb_is_pdc"));
- return False;
+ return false;
}
ret = ldb_search(ldb, ldb_get_default_basedn(ldb), LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
pdc = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, dom_res->msgs[0], "fSMORoleOwner");
if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), pdc) == 0) {
- is_pdc = True;
+ is_pdc = true;
} else {
- is_pdc = False;
+ is_pdc = false;
}
talloc_free(tmp_ctx);
failed:
DEBUG(1,("Failed to find if we are the PDC for this ldb\n"));
talloc_free(tmp_ctx);
- return False;
+ return false;
}
/* Find a domain object in the parents of a particular DN. */
-struct ldb_dn *samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
+int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn,
+ struct ldb_dn **parent_dn, const char **errstring)
{
TALLOC_CTX *local_ctx;
struct ldb_dn *sdn = dn;
const char *attrs[] = { NULL };
local_ctx = talloc_new(mem_ctx);
- if (local_ctx == NULL) return NULL;
+ if (local_ctx == NULL) return LDB_ERR_OPERATIONS_ERROR;
while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) {
ret = ldb_search(ldb, sdn, LDB_SCOPE_BASE,
if (res->count == 1) {
break;
}
+ } else {
+ break;
}
}
- if (ret != LDB_SUCCESS || res->count != 1) {
+ if (ret != LDB_SUCCESS) {
+ *errstring = talloc_asprintf(mem_ctx, "Error searching for parent domain of %s, failed searching for %s: %s",
+ ldb_dn_get_linearized(dn),
+ ldb_dn_get_linearized(sdn),
+ ldb_errstring(ldb));
talloc_free(local_ctx);
- return NULL;
+ return ret;
+ }
+ if (res->count != 1) {
+ *errstring = talloc_asprintf(mem_ctx, "Invalid dn (%s), not child of a domain object",
+ ldb_dn_get_linearized(dn));
+ talloc_free(local_ctx);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
}
- talloc_steal(mem_ctx, sdn);
+ *parent_dn = talloc_steal(mem_ctx, res->msgs[0]->dn);
talloc_free(local_ctx);
-
- return sdn;
+ return ret;
}
/*
check that a password is sufficiently complex
*/
-static BOOL samdb_password_complexity_ok(const char *pass)
+static bool samdb_password_complexity_ok(const char *pass)
{
return check_password_quality(pass);
}
const char *new_pass,
struct samr_Password *lmNewHash,
struct samr_Password *ntNewHash,
- BOOL user_change,
+ bool user_change,
enum samr_RejectReason *reject_reason,
struct samr_DomInfo1 **_dominfo)
{
int sambaLMPwdHistory_len, sambaNTPwdHistory_len;
struct dom_sid *domain_sid;
struct ldb_message **res;
- BOOL restrictions;
+ bool restrictions;
int count;
time_t now = time(NULL);
NTTIME now_nt;
const char *new_pass,
struct samr_Password *lmNewHash,
struct samr_Password *ntNewHash,
- BOOL user_change,
+ bool user_change,
enum samr_RejectReason *reject_reason,
struct samr_DomInfo1 **_dominfo)
{
struct dom_sid *group_sid,
int n_groupSIDs,
struct dom_sid **groupSIDs,
- BOOL is_authenticated,
+ bool is_authenticated,
struct security_token **token)
{
struct security_token *ptoken;
"foreignSecurityPrincipal");
/* create the alias */
- ret = samdb_add(sam_ctx, mem_ctx, msg);
+ ret = ldb_add(sam_ctx, msg);
if (ret != 0) {
DEBUG(0,("Failed to create foreignSecurityPrincipal "
"record %s: %s\n",