X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source4%2Flibnet%2Flibnet_samsync_ldb.c;h=10e5a34da462591816decb0066678542173a8218;hb=bfce9690bf6e6592d32dd41642a33cbe3c027b81;hp=da4e777a153fa29538941cc616119462a621956b;hpb=b15582ed816f3d477f978976f43b82cfa90bf6dc;p=obnox%2Fsamba%2Fsamba-obnox.git
diff --git a/source4/libnet/libnet_samsync_ldb.c b/source4/libnet/libnet_samsync_ldb.c
index da4e777a153..10e5a34da46 100644
--- a/source4/libnet/libnet_samsync_ldb.c
+++ b/source4/libnet/libnet_samsync_ldb.c
@@ -9,7 +9,7 @@
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 2 of the License, or
+ 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,
@@ -18,16 +18,20 @@
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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see .
*/
#include "includes.h"
#include "libnet/libnet.h"
-#include "libcli/ldap/ldap.h"
+#include "libcli/ldap/ldap_ndr.h"
#include "dsdb/samdb/samdb.h"
#include "auth/auth.h"
+#include "../lib/util/util_ldb.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+#include "ldb_wrap.h"
+#include "libcli/security/security.h"
+#include "param/param.h"
struct samsync_ldb_secret {
struct samsync_ldb_secret *prev, *next;
@@ -44,17 +48,23 @@ struct samsync_ldb_trusted_domain {
struct samsync_ldb_state {
/* Values from the LSA lookup */
- const char *domain_name;
- const struct dom_sid *domain_sid;
- const char *realm;
+ const struct libnet_SamSync_state *samsync_state;
struct dom_sid *dom_sid[3];
- struct ldb_context *sam_ldb, *remote_ldb;
+ struct ldb_context *sam_ldb, *remote_ldb, *pdb;
struct ldb_dn *base_dn[3];
struct samsync_ldb_secret *secrets;
struct samsync_ldb_trusted_domain *trusted_domains;
};
+/* This wrapper is needed for the "ADD_OR_DEL" macros */
+static int samdb_msg_add_string(struct ldb_context *sam_ldb,
+ TALLOC_CTX *mem_ctx, struct ldb_message *msg,
+ const char *attr_name, const char *str)
+{
+ return ldb_msg_add_string(msg, attr_name, str);
+}
+
static NTSTATUS samsync_ldb_add_foreignSecurityPrincipal(TALLOC_CTX *mem_ctx,
struct samsync_ldb_state *state,
struct dom_sid *sid,
@@ -77,7 +87,7 @@ static NTSTATUS samsync_ldb_add_foreignSecurityPrincipal(TALLOC_CTX *mem_ctx,
*error_string = talloc_asprintf(mem_ctx,
"Failed to find DN for "
"ForeignSecurityPrincipal container under %s",
- ldb_dn_linearize(mem_ctx, state->base_dn[SAM_DATABASE_DOMAIN]));
+ ldb_dn_get_linearized(state->base_dn[SAM_DATABASE_DOMAIN]));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -87,22 +97,20 @@ static NTSTATUS samsync_ldb_add_foreignSecurityPrincipal(TALLOC_CTX *mem_ctx,
}
/* add core elements to the ldb_message for the alias */
- msg->dn = ldb_dn_build_child(mem_ctx, "CN", sidstr, basedn);
- if (msg->dn == NULL)
- return NT_STATUS_NO_MEMORY;
+ msg->dn = basedn;
+ if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s", sidstr))
+ return NT_STATUS_UNSUCCESSFUL;
- samdb_msg_add_string(state->sam_ldb, mem_ctx, msg,
- "objectClass",
- "foreignSecurityPrincipal");
+ ldb_msg_add_string(msg, "objectClass", "foreignSecurityPrincipal");
*fsp_dn = msg->dn;
/* create the alias */
- ret = samdb_add(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
+ ret = ldb_add(state->sam_ldb, msg);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to create foreignSecurityPrincipal "
"record %s: %s",
- ldb_dn_linearize(mem_ctx, msg->dn),
+ ldb_dn_get_linearized(msg->dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -120,12 +128,20 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
struct ldb_message *msg;
int ret;
+ msg = ldb_msg_new(mem_ctx);
+ if (msg == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
if (database == SAM_DATABASE_DOMAIN) {
+ struct ldb_dn *partitions_basedn;
const char *domain_attrs[] = {"nETBIOSName", "nCName", NULL};
struct ldb_message **msgs_domain;
int ret_domain;
- ret_domain = gendb_search(state->sam_ldb, mem_ctx, NULL, &msgs_domain, domain_attrs,
+ partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
+
+ ret_domain = gendb_search(state->sam_ldb, mem_ctx, partitions_basedn, &msgs_domain, domain_attrs,
"(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))",
domain_name);
if (ret_domain == -1) {
@@ -139,39 +155,65 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_SUCH_DOMAIN;
}
- state->base_dn[database] = samdb_result_dn(state, msgs_domain[0], "nCName", NULL);
-
- if (state->domain_sid) {
- state->dom_sid[database] = dom_sid_dup(state, state->domain_sid);
+ state->base_dn[database] = samdb_result_dn(state->sam_ldb, state, msgs_domain[0], "nCName", NULL);
+
+ if (state->dom_sid[database]) {
+ /* Update the domain sid with the incoming
+ * domain (found on LSA pipe, database sid may
+ * be random) */
+ ret = samdb_msg_add_dom_sid(state->sam_ldb,
+ mem_ctx,
+ msg,
+ "objectSid",
+ state->dom_sid[database]);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
} else {
+ /* Well, we will have to use the one from the database */
state->dom_sid[database] = samdb_search_dom_sid(state->sam_ldb, state,
state->base_dn[database],
"objectSid", NULL);
+ if (state->dom_sid[database] == NULL) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ }
+
+ if (state->samsync_state->domain_guid) {
+ struct ldb_val v;
+ NTSTATUS status;
+ status = GUID_to_ndr_blob(state->samsync_state->domain_guid, msg, &v);
+ if (!NT_STATUS_IS_OK(status)) {
+ *error_string = talloc_asprintf(mem_ctx, "ndr_push of domain GUID failed!");
+ return status;
+ }
+
+ ret = ldb_msg_add_value(msg, "objectGUID", &v, NULL);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
}
} else if (database == SAM_DATABASE_BUILTIN) {
/* work out the builtin_dn - useful for so many calls its worth
fetching here */
const char *dnstring = samdb_search_string(state->sam_ldb, mem_ctx, NULL,
"distinguishedName", "objectClass=builtinDomain");
- state->base_dn[database] = ldb_dn_explode(state, dnstring);
- state->dom_sid[database] = dom_sid_parse_talloc(state, SID_BUILTIN);
+ state->base_dn[database] = ldb_dn_new(state, state->sam_ldb, dnstring);
+ if ( ! ldb_dn_validate(state->base_dn[database])) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
} else {
/* PRIVs DB */
return NT_STATUS_INVALID_PARAMETER;
}
- msg = ldb_msg_new(mem_ctx);
- if (msg == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
msg->dn = talloc_reference(mem_ctx, state->base_dn[database]);
if (!msg->dn) {
return NT_STATUS_NO_MEMORY;
}
- samdb_msg_add_string(state->sam_ldb, mem_ctx,
- msg, "oEMInformation", domain->comment.string);
+ ldb_msg_add_string(msg, "oEMInformation",
+ domain->oem_information.string);
samdb_msg_add_int64(state->sam_ldb, mem_ctx,
msg, "forceLogoff", domain->force_logoff_time);
@@ -195,16 +237,15 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
samdb_msg_add_uint64(state->sam_ldb, mem_ctx,
msg, "creationTime", domain->domain_create_time);
- /* Update the domain sid with the incoming domain */
- samdb_msg_add_dom_sid(state->sam_ldb, mem_ctx,
- msg, "objectSid", state->dom_sid[database]);
-
/* TODO: Account lockout, password properties */
- ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
-
- if (ret) {
- return NT_STATUS_INTERNAL_ERROR;
+ ret = dsdb_replace(state->sam_ldb, msg, 0);
+ if (ret != LDB_SUCCESS) {
+ *error_string = talloc_asprintf(mem_ctx,
+ "Failed to modify domain record %s: %s",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(state->sam_ldb));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
return NT_STATUS_OK;
}
@@ -223,14 +264,15 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
const struct dom_sid *user_sid;
struct ldb_message *msg;
struct ldb_message **msgs;
- struct ldb_message **remote_msgs;
- int ret, i;
+ struct ldb_message **remote_msgs = NULL;
+ unsigned int i;
+ int ret;
uint32_t acb;
- BOOL add = False;
+ bool add = false;
const char *attrs[] = { NULL };
/* we may change this to a global search, then fill in only the things not in ldap later */
const char *remote_attrs[] = { "userPrincipalName", "servicePrincipalName",
- "msDS-KeyVersionNumber", NULL};
+ "msDS-KeyVersionNumber", "objectGUID", NULL};
user_sid = dom_sid_add_rid(mem_ctx, state->dom_sid[database], rid);
if (!user_sid) {
@@ -242,6 +284,7 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
+ msg->dn = NULL;
/* search for the user, by rid */
ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[database],
&msgs, attrs, "(&(objectClass=user)(objectSid=%s))",
@@ -253,7 +296,7 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
} else if (ret == 0) {
- add = True;
+ add = true;
} else if (ret > 1) {
*error_string = talloc_asprintf(mem_ctx, "More than one user with SID: %s in local LDB",
dom_sid_string(mem_ctx, user_sid));
@@ -264,29 +307,30 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
}
/* and do the same on the remote database */
- ret = gendb_search(state->remote_ldb, mem_ctx, state->base_dn[database],
- &remote_msgs, remote_attrs, "(&(objectClass=user)(objectSid=%s))",
- ldap_encode_ndr_dom_sid(mem_ctx, user_sid));
-
- if (ret == -1) {
- *error_string = talloc_asprintf(mem_ctx, "remote LDAP for user %s failed: %s",
- dom_sid_string(mem_ctx, user_sid),
- ldb_errstring(state->remote_ldb));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- } else if (ret == 0) {
- *error_string = talloc_asprintf(mem_ctx, "User exists in samsync but not in remote LDAP domain! (base: %s, SID: %s)",
- ldb_dn_linearize(mem_ctx, state->base_dn[database]),
- dom_sid_string(mem_ctx, user_sid));
- return NT_STATUS_NO_SUCH_USER;
- } else if (ret > 1) {
- *error_string = talloc_asprintf(mem_ctx, "More than one user in remote LDAP domain with SID: %s",
- dom_sid_string(mem_ctx, user_sid));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
-
- /* Try to put things in the same location as the remote server */
- } else if (add) {
- msg->dn = remote_msgs[0]->dn;
- talloc_steal(msg, remote_msgs[0]->dn);
+ if (state->remote_ldb) {
+ ret = gendb_search(state->remote_ldb, mem_ctx, state->base_dn[database],
+ &remote_msgs, remote_attrs, "(&(objectClass=user)(objectSid=%s))",
+ ldap_encode_ndr_dom_sid(mem_ctx, user_sid));
+
+ if (ret == -1) {
+ *error_string = talloc_asprintf(mem_ctx, "remote LDAP for user %s failed: %s",
+ dom_sid_string(mem_ctx, user_sid),
+ ldb_errstring(state->remote_ldb));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ } else if (ret == 0) {
+ *error_string = talloc_asprintf(mem_ctx, "User exists in samsync but not in remote LDAP domain! (base: %s, SID: %s)",
+ ldb_dn_get_linearized(state->base_dn[database]),
+ dom_sid_string(mem_ctx, user_sid));
+ return NT_STATUS_NO_SUCH_USER;
+ } else if (ret > 1) {
+ *error_string = talloc_asprintf(mem_ctx, "More than one user in remote LDAP domain with SID: %s",
+ dom_sid_string(mem_ctx, user_sid));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+
+ /* Try to put things in the same location as the remote server */
+ } else if (add) {
+ msg->dn = talloc_steal(msg, remote_msgs[0]->dn);
+ }
}
cn_name = talloc_strdup(mem_ctx, user->account_name.string);
@@ -336,27 +380,27 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
- /* Passwords. Ensure there is no plaintext stored against
- * this entry, as we only have hashes */
- samdb_msg_add_delete(state->sam_ldb, mem_ctx, msg,
- "sambaPassword");
if (user->lm_password_present) {
samdb_msg_add_hash(state->sam_ldb, mem_ctx, msg,
- "lmPwdHash", &user->lmpassword);
- } else {
+ "dBCSPwd", &user->lmpassword);
+ } else if (!add) {
samdb_msg_add_delete(state->sam_ldb, mem_ctx, msg,
- "lmPwdHash");
+ "dBCSPwd");
}
if (user->nt_password_present) {
samdb_msg_add_hash(state->sam_ldb, mem_ctx, msg,
- "ntPwdHash", &user->ntpassword);
- } else {
+ "unicodePwd", &user->ntpassword);
+ } else if (!add) {
samdb_msg_add_delete(state->sam_ldb, mem_ctx, msg,
- "ntPwdHash");
+ "unicodePwd");
}
ADD_OR_DEL(string, "comment", comment.string);
- ADD_OR_DEL(string, "userParameters", parameters.string);
+
+ if (samdb_msg_add_parameters(state->sam_ldb, mem_ctx, msg, "userParameters", &user->parameters) != 0) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
ADD_OR_DEL(uint, "countryCode", country_code);
ADD_OR_DEL(uint, "codePage", code_page);
@@ -392,33 +436,41 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
obj_class = "user";
}
if (add) {
- samdb_msg_add_string(state->sam_ldb, mem_ctx, msg,
- "objectClass", obj_class);
- msg->dn = ldb_dn_string_compose(mem_ctx, state->base_dn[database],
- "CN=%s, CN=%s", cn_name, container);
+ ldb_msg_add_string(msg, "objectClass", obj_class);
if (!msg->dn) {
- return NT_STATUS_NO_MEMORY;
+ msg->dn = ldb_dn_copy(mem_ctx, state->base_dn[database]);
+ ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=%s", cn_name, container);
+ if (!msg->dn) {
+ return NT_STATUS_NO_MEMORY;
+ }
}
- ret = samdb_add(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
+ ret = ldb_add(state->sam_ldb, msg);
+ if (ret != LDB_SUCCESS) {
struct ldb_dn *first_try_dn = msg->dn;
/* Try again with the default DN */
- msg->dn = talloc_steal(msg, msgs[0]->dn);
- ret = samdb_add(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
- *error_string = talloc_asprintf(mem_ctx, "Failed to create user record. Tried both %s and %s: %s",
- ldb_dn_linearize(mem_ctx, first_try_dn),
- ldb_dn_linearize(mem_ctx, msg->dn),
+ if (!remote_msgs) {
+ *error_string = talloc_asprintf(mem_ctx, "Failed to create user record. Tried %s: %s",
+ ldb_dn_get_linearized(first_try_dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ } else {
+ msg->dn = talloc_steal(msg, remote_msgs[0]->dn);
+ ret = ldb_add(state->sam_ldb, msg);
+ if (ret != LDB_SUCCESS) {
+ *error_string = talloc_asprintf(mem_ctx, "Failed to create user record. Tried both %s and %s: %s",
+ ldb_dn_get_linearized(first_try_dn),
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(state->sam_ldb));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
}
}
} else {
- ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
+ ret = dsdb_replace(state->sam_ldb, msg, 0);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to modify user record %s: %s",
- ldb_dn_linearize(mem_ctx, msg->dn),
+ ldb_dn_get_linearized(msg->dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -457,10 +509,10 @@ static NTSTATUS samsync_ldb_delete_user(TALLOC_CTX *mem_ctx,
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
- if (ret != 0) {
+ ret = ldb_delete(state->sam_ldb, msgs[0]->dn);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to delete user record %s: %s",
- ldb_dn_linearize(mem_ctx, msgs[0]->dn),
+ ldb_dn_get_linearized(msgs[0]->dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -482,7 +534,7 @@ static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
struct ldb_message *msg;
struct ldb_message **msgs;
int ret;
- BOOL add = False;
+ bool add = false;
const char *attrs[] = { NULL };
msg = ldb_msg_new(mem_ctx);
@@ -499,7 +551,7 @@ static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
*error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
} else if (ret == 0) {
- add = True;
+ add = true;
} else if (ret > 1) {
*error_string = talloc_asprintf(mem_ctx, "More than one group/alias with SID: %s",
dom_sid_string(mem_ctx,
@@ -538,26 +590,25 @@ static NTSTATUS samsync_ldb_handle_group(TALLOC_CTX *mem_ctx,
obj_class = "group";
if (add) {
- samdb_msg_add_string(state->sam_ldb, mem_ctx, msg,
- "objectClass", obj_class);
- msg->dn = ldb_dn_string_compose(mem_ctx, state->base_dn[database],
- "CN=%s, CN=%s", cn_name, container);
+ ldb_msg_add_string(msg, "objectClass", obj_class);
+ msg->dn = ldb_dn_copy(mem_ctx, state->base_dn[database]);
+ ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=%s", cn_name, container);
if (!msg->dn) {
return NT_STATUS_NO_MEMORY;
}
- ret = samdb_add(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
+ ret = ldb_add(state->sam_ldb, msg);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to create group record %s: %s",
- ldb_dn_linearize(mem_ctx, msg->dn),
+ ldb_dn_get_linearized(msg->dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
} else {
- ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
+ ret = dsdb_replace(state->sam_ldb, msg, 0);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to modify group record %s: %s",
- ldb_dn_linearize(mem_ctx, msg->dn),
+ ldb_dn_get_linearized(msg->dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -596,10 +647,10 @@ static NTSTATUS samsync_ldb_delete_group(TALLOC_CTX *mem_ctx,
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
- if (ret != 0) {
+ ret = ldb_delete(state->sam_ldb, msgs[0]->dn);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to delete group record %s: %s",
- ldb_dn_linearize(mem_ctx, msgs[0]->dn),
+ ldb_dn_get_linearized(msgs[0]->dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -614,12 +665,13 @@ static NTSTATUS samsync_ldb_handle_group_member(TALLOC_CTX *mem_ctx,
char **error_string)
{
uint32_t rid = delta->delta_id_union.rid;
- struct netr_DELTA_GROUP_MEMBER *group_member = delta->delta_union.group_member;
+ struct netr_DELTA_GROUP_MEMBER *delta_group_member = delta->delta_union.group_member;
struct ldb_message *msg;
struct ldb_message **msgs;
int ret;
const char *attrs[] = { NULL };
- int i;
+ const char *str_dn;
+ uint32_t i;
msg = ldb_msg_new(mem_ctx);
if (msg == NULL) {
@@ -649,11 +701,11 @@ static NTSTATUS samsync_ldb_handle_group_member(TALLOC_CTX *mem_ctx,
talloc_free(msgs);
- for (i=0; inum_rids; i++) {
+ for (i=0; inum_rids; i++) {
/* search for the group, by rid */
ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[database], &msgs, attrs,
"(&(objectClass=user)(objectSid=%s))",
- ldap_encode_ndr_dom_sid(mem_ctx, dom_sid_add_rid(mem_ctx, state->dom_sid[database], group_member->rids[i])));
+ ldap_encode_ndr_dom_sid(mem_ctx, dom_sid_add_rid(mem_ctx, state->dom_sid[database], delta_group_member->rids[i])));
if (ret == -1) {
*error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));
@@ -663,16 +715,19 @@ static NTSTATUS samsync_ldb_handle_group_member(TALLOC_CTX *mem_ctx,
} else if (ret > 1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
} else {
- samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, "member", ldb_dn_linearize(mem_ctx, msgs[0]->dn));
+ str_dn = ldb_dn_alloc_linearized(msg, msgs[0]->dn);
+ NT_STATUS_HAVE_NO_MEMORY(str_dn);
+ ret = ldb_msg_add_string(msg, "member", str_dn);
+ if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
}
talloc_free(msgs);
}
- ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
+ ret = dsdb_replace(state->sam_ldb, msg, 0);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to modify group record %s: %s",
- ldb_dn_linearize(mem_ctx, msg->dn),
+ ldb_dn_get_linearized(msg->dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -694,7 +749,7 @@ static NTSTATUS samsync_ldb_handle_alias(TALLOC_CTX *mem_ctx,
struct ldb_message *msg;
struct ldb_message **msgs;
int ret;
- BOOL add = False;
+ bool add = false;
const char *attrs[] = { NULL };
msg = ldb_msg_new(mem_ctx);
@@ -711,7 +766,7 @@ static NTSTATUS samsync_ldb_handle_alias(TALLOC_CTX *mem_ctx,
*error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
} else if (ret == 0) {
- add = True;
+ add = true;
} else if (ret > 1) {
*error_string = talloc_asprintf(mem_ctx, "More than one group/alias with SID: %s",
dom_sid_string(mem_ctx,
@@ -752,26 +807,25 @@ static NTSTATUS samsync_ldb_handle_alias(TALLOC_CTX *mem_ctx,
obj_class = "group";
if (add) {
- samdb_msg_add_string(state->sam_ldb, mem_ctx, msg,
- "objectClass", obj_class);
- msg->dn = ldb_dn_string_compose(mem_ctx, state->base_dn[database],
- "CN=%s, CN=%s", cn_name, container);
+ ldb_msg_add_string(msg, "objectClass", obj_class);
+ msg->dn = ldb_dn_copy(mem_ctx, state->base_dn[database]);
+ ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=%s", cn_name, container);
if (!msg->dn) {
return NT_STATUS_NO_MEMORY;
}
- ret = samdb_add(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
+ ret = ldb_add(state->sam_ldb, msg);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to create alias record %s: %s",
- ldb_dn_linearize(mem_ctx, msg->dn),
+ ldb_dn_get_linearized(msg->dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
} else {
- ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
+ ret = dsdb_replace(state->sam_ldb, msg, 0);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to modify alias record %s: %s",
- ldb_dn_linearize(mem_ctx, msg->dn),
+ ldb_dn_get_linearized(msg->dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -805,10 +859,10 @@ static NTSTATUS samsync_ldb_delete_alias(TALLOC_CTX *mem_ctx,
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- ret = samdb_delete(state->sam_ldb, mem_ctx, msgs[0]->dn);
- if (ret != 0) {
+ ret = ldb_delete(state->sam_ldb, msgs[0]->dn);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to delete alias record %s: %s",
- ldb_dn_linearize(mem_ctx, msgs[0]->dn),
+ ldb_dn_get_linearized(msgs[0]->dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -828,7 +882,7 @@ static NTSTATUS samsync_ldb_handle_alias_member(TALLOC_CTX *mem_ctx,
struct ldb_message **msgs;
int ret;
const char *attrs[] = { NULL };
- int i;
+ uint32_t i;
msg = ldb_msg_new(mem_ctx);
if (msg == NULL) {
@@ -860,6 +914,7 @@ static NTSTATUS samsync_ldb_handle_alias_member(TALLOC_CTX *mem_ctx,
for (i=0; isids.num_sids; i++) {
struct ldb_dn *alias_member_dn;
+ const char *str_dn;
/* search for members, in the top basedn (normal users are builtin aliases) */
ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[SAM_DATABASE_DOMAIN], &msgs, attrs,
"(objectSid=%s)",
@@ -882,15 +937,18 @@ static NTSTATUS samsync_ldb_handle_alias_member(TALLOC_CTX *mem_ctx,
} else {
alias_member_dn = msgs[0]->dn;
}
- samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, "member", ldb_dn_linearize(mem_ctx, alias_member_dn));
+ str_dn = ldb_dn_alloc_linearized(msg, alias_member_dn);
+ NT_STATUS_HAVE_NO_MEMORY(str_dn);
+ ret = ldb_msg_add_string(msg, "member", str_dn);
+ if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
talloc_free(msgs);
}
- ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
+ ret = dsdb_replace(state->sam_ldb, msg, 0);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to modify group record %s: %s",
- ldb_dn_linearize(mem_ctx, msg->dn),
+ ldb_dn_get_linearized(msg->dn),
ldb_errstring(state->sam_ldb));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -908,53 +966,41 @@ static NTSTATUS samsync_ldb_handle_account(TALLOC_CTX *mem_ctx,
struct netr_DELTA_ACCOUNT *account = delta->delta_union.account;
struct ldb_message *msg;
- struct ldb_message **msgs;
- struct ldb_dn *privilege_dn;
int ret;
- const char *attrs[] = { NULL };
- int i;
+ uint32_t i;
+ char *dnstr, *sidstr;
msg = ldb_msg_new(mem_ctx);
if (msg == NULL) {
return NT_STATUS_NO_MEMORY;
}
- /* search for the account, by sid, in the top basedn */
- ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[SAM_DATABASE_DOMAIN], &msgs, attrs,
- "(objectSid=%s)", ldap_encode_ndr_dom_sid(mem_ctx, sid));
+ sidstr = dom_sid_string(msg, sid);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
- if (ret == -1) {
- *error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- } else if (ret == 0) {
- NTSTATUS nt_status;
- nt_status = samsync_ldb_add_foreignSecurityPrincipal(mem_ctx, state,
- sid,
- &privilege_dn,
- error_string);
- privilege_dn = talloc_steal(msg, privilege_dn);
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
- } else if (ret > 1) {
- *error_string = talloc_asprintf(mem_ctx, "More than one account with SID: %s",
- dom_sid_string(mem_ctx, sid));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- } else {
- privilege_dn = talloc_steal(msg, msgs[0]->dn);
- }
+ dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
- msg->dn = privilege_dn;
+ msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
for (i=0; i< account->privilege_entries; i++) {
- samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, "privilege",
- account->privilege_name[i].string);
+ ldb_msg_add_string(msg, "privilege", account->privilege_name[i].string);
+ }
+
+ ret = dsdb_replace(state->pdb, msg, 0);
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
+ talloc_free(msg);
+ return NT_STATUS_NO_MEMORY;
+ }
+ ldb_msg_add_string(msg, "comment", "added via samsync");
+ ret = ldb_add(state->pdb, msg);
}
- ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to modify privilege record %s",
- ldb_dn_linearize(mem_ctx, msg->dn));
+ ldb_dn_get_linearized(msg->dn));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -998,12 +1044,12 @@ static NTSTATUS samsync_ldb_delete_account(TALLOC_CTX *mem_ctx,
}
samdb_msg_add_delete(state->sam_ldb, mem_ctx, msg,
- "privilage");
+ "privilege");
- ret = samdb_replace(state->sam_ldb, mem_ctx, msg);
- if (ret != 0) {
+ ret = dsdb_replace(state->sam_ldb, msg, 0);
+ if (ret != LDB_SUCCESS) {
*error_string = talloc_asprintf(mem_ctx, "Failed to modify privilege record %s",
- ldb_dn_linearize(mem_ctx, msg->dn));
+ ldb_dn_get_linearized(msg->dn));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -1011,13 +1057,13 @@ static NTSTATUS samsync_ldb_delete_account(TALLOC_CTX *mem_ctx,
}
static NTSTATUS libnet_samsync_ldb_fn(TALLOC_CTX *mem_ctx,
- void *private,
+ void *private_data,
enum netr_SamDatabaseID database,
struct netr_DELTA_ENUM *delta,
char **error_string)
{
NTSTATUS nt_status = NT_STATUS_OK;
- struct samsync_ldb_state *state = talloc_get_type(private, struct samsync_ldb_state);
+ struct samsync_ldb_state *state = talloc_get_type(private_data, struct samsync_ldb_state);
*error_string = NULL;
switch (delta->delta_type) {
@@ -1131,35 +1177,43 @@ static NTSTATUS libnet_samsync_ldb_fn(TALLOC_CTX *mem_ctx,
}
static NTSTATUS libnet_samsync_ldb_init(TALLOC_CTX *mem_ctx,
- void *private,
- struct libnet_context *machine_net_ctx,
- struct dcerpc_pipe *p,
- const char *domain_name,
- const struct dom_sid *domain_sid,
- const char *realm,
+ void *private_data,
+ struct libnet_SamSync_state *samsync_state,
char **error_string)
{
- struct samsync_ldb_state *state = talloc_get_type(private, struct samsync_ldb_state);
- const char *server = dcerpc_server_name(p);
+ struct samsync_ldb_state *state = talloc_get_type(private_data, struct samsync_ldb_state);
+ const char *server = dcerpc_server_name(samsync_state->netlogon_pipe);
char *ldap_url;
- state->domain_name = domain_name;
- state->domain_sid = domain_sid;
- state->realm = realm;
+ state->samsync_state = samsync_state;
+
+ ZERO_STRUCT(state->dom_sid);
+ if (state->samsync_state->domain_sid) {
+ state->dom_sid[SAM_DATABASE_DOMAIN] = dom_sid_dup(state, state->samsync_state->domain_sid);
+ }
+
+ state->dom_sid[SAM_DATABASE_BUILTIN] = dom_sid_parse_talloc(state, SID_BUILTIN);
- if (realm) {
+ if (state->samsync_state->realm) {
if (!server || !*server) {
/* huh? how do we not have a server name? */
*error_string = talloc_strdup(mem_ctx, "No DCE/RPC server name available. How did we connect?");
return NT_STATUS_INVALID_PARAMETER;
}
- ldap_url = talloc_asprintf(state, "ldap://%s", dcerpc_server_name(p));
+ ldap_url = talloc_asprintf(state, "ldap://%s", server);
- state->remote_ldb = ldb_wrap_connect(mem_ctx, ldap_url,
- NULL, machine_net_ctx->cred,
- 0, NULL);
- /* TODO: Make inquires to see if this is AD, then decide that
- * the ldap connection is critical */
+ state->remote_ldb = ldb_wrap_connect(mem_ctx,
+ NULL,
+ state->samsync_state->machine_net_ctx->lp_ctx,
+ ldap_url,
+ NULL, state->samsync_state->machine_net_ctx->cred,
+ 0);
+ if (!state->remote_ldb) {
+ *error_string = talloc_asprintf(mem_ctx, "Failed to connect to remote LDAP server at %s (used to extract additional data in SamSync replication)", ldap_url);
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+ } else {
+ state->remote_ldb = NULL;
}
return NT_STATUS_OK;
}
@@ -1177,7 +1231,20 @@ NTSTATUS libnet_samsync_ldb(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, str
state->secrets = NULL;
state->trusted_domains = NULL;
- state->sam_ldb = samdb_connect(state, system_session(state));
+ state->sam_ldb = samdb_connect(mem_ctx,
+ ctx->event_ctx,
+ ctx->lp_ctx,
+ r->in.session_info,
+ 0);
+ if (!state->sam_ldb) {
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+
+ state->pdb = privilege_connect(mem_ctx,
+ ctx->lp_ctx);
+ if (!state->pdb) {
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
r2.out.error_string = NULL;
r2.in.binding_string = r->in.binding_string;