summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-01-14 01:29:38 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:51:07 -0500
commitdcd63b97702fa5a5945a500acc4b65de0aa74927 (patch)
treeba518bc3c6ad18df4d10c638561853208ba7f732
parent5db0c6b3042292e0f343ced3d45f2f7a8f97de12 (diff)
downloadsamba-dcd63b97702fa5a5945a500acc4b65de0aa74927.tar.gz
samba-dcd63b97702fa5a5945a500acc4b65de0aa74927.tar.bz2
samba-dcd63b97702fa5a5945a500acc4b65de0aa74927.zip
r12926: Syncronsise GUIDs on users and domains from the server. These also
appear in DNS, so need to match. Andrew Bartlett (This used to be commit d092b0493d7c61112ef132c8fb259c15f189c5f6)
-rw-r--r--source4/libnet/libnet_rpc.c7
-rw-r--r--source4/libnet/libnet_rpc.h4
-rw-r--r--source4/libnet/libnet_samsync_ldb.c134
-rw-r--r--source4/libnet/libnet_vampire.c21
-rw-r--r--source4/libnet/libnet_vampire.h15
5 files changed, 114 insertions, 67 deletions
diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c
index aba393d7fb..5b63f482df 100644
--- a/source4/libnet/libnet_rpc.c
+++ b/source4/libnet/libnet_rpc.c
@@ -274,8 +274,15 @@ NTSTATUS libnet_RpcConnectDCInfo(struct libnet_context *ctx,
return status;
}
r->out.realm = lsa_query_info2.out.info->dns.dns_domain.string;
+ r->out.guid = talloc(r, struct GUID);
+ if (!r->out.guid) {
+ r->out.error_string = NULL;
+ return NT_STATUS_NO_MEMORY;
+ }
+ *r->out.guid = lsa_query_info2.out.info->dns.domain_guid;
} else {
r->out.realm = NULL;
+ r->out.guid = NULL;
}
/* Grab the domain SID (regardless of the result of the previous call */
diff --git a/source4/libnet/libnet_rpc.h b/source4/libnet/libnet_rpc.h
index ce88462485..333881debd 100644
--- a/source4/libnet/libnet_rpc.h
+++ b/source4/libnet/libnet_rpc.h
@@ -59,8 +59,10 @@ struct libnet_RpcConnectDCInfo {
struct dom_sid *domain_sid;
const char *domain_name;
- /* This parameter only present if the remote server is known to be AD */
+ /* These parameters only present if the remote server is known to be AD */
const char *realm;
+ struct GUID *guid;
+
const char *error_string;
} out;
};
diff --git a/source4/libnet/libnet_samsync_ldb.c b/source4/libnet/libnet_samsync_ldb.c
index da4e777a15..5140aa87ae 100644
--- a/source4/libnet/libnet_samsync_ldb.c
+++ b/source4/libnet/libnet_samsync_ldb.c
@@ -28,6 +28,7 @@
#include "libcli/ldap/ldap.h"
#include "dsdb/samdb/samdb.h"
#include "auth/auth.h"
+#include "librpc/gen_ndr/ndr_misc.h"
struct samsync_ldb_secret {
struct samsync_ldb_secret *prev, *next;
@@ -44,9 +45,7 @@ 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;
@@ -120,6 +119,11 @@ 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) {
const char *domain_attrs[] = {"nETBIOSName", "nCName", NULL};
struct ldb_message **msgs_domain;
@@ -141,30 +145,42 @@ static NTSTATUS samsync_ldb_handle_domain(TALLOC_CTX *mem_ctx,
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);
+ if (state->dom_sid[database]) {
+ /* Update the domain sid with the incoming
+ * domain (found on LSA pipe, database sid may
+ * be random) */
+ samdb_msg_add_dom_sid(state->sam_ldb, mem_ctx,
+ msg, "objectSid", state->dom_sid[database]);
} 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->samsync_state->domain_guid) {
+ NTSTATUS nt_status;
+ struct ldb_val v;
+ nt_status = ndr_push_struct_blob(&v, msg, state->samsync_state->domain_guid,
+ (ndr_push_flags_fn_t)ndr_push_GUID);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ *error_string = talloc_asprintf(mem_ctx, "ndr_push of domain GUID failed!");
+ return nt_status;
+ }
+
+ ldb_msg_add_value(msg, "objectGUID", &v);
+ }
} 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);
} 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;
@@ -195,10 +211,6 @@ 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);
@@ -230,7 +242,7 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
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 +254,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))",
@@ -264,29 +277,31 @@ 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_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);
+ }
}
cn_name = talloc_strdup(mem_ctx, user->account_name.string);
@@ -394,10 +409,12 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
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);
if (!msg->dn) {
- return NT_STATUS_NO_MEMORY;
+ msg->dn = ldb_dn_string_compose(mem_ctx, state->base_dn[database],
+ "CN=%s, CN=%s", cn_name, container);
+ if (!msg->dn) {
+ return NT_STATUS_NO_MEMORY;
+ }
}
ret = samdb_add(state->sam_ldb, mem_ctx, msg);
@@ -1132,34 +1149,39 @@ 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,
+ 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);
+ 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;
- if (realm) {
+ 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 (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,
+ NULL, state->samsync_state->machine_net_ctx->cred,
0, NULL);
- /* TODO: Make inquires to see if this is AD, then decide that
- * the ldap connection is critical */
+ 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;
}
diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c
index b9fb37fea6..ce65a6e460 100644
--- a/source4/libnet/libnet_vampire.c
+++ b/source4/libnet/libnet_vampire.c
@@ -153,6 +153,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx
struct dcerpc_pipe *p;
struct libnet_context *machine_net_ctx;
struct libnet_RpcConnectDCInfo *c;
+ struct libnet_SamSync_state *state;
const enum netr_SamDatabaseID database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
int i;
@@ -258,6 +259,20 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx
return nt_status;
}
+ state = talloc(samsync_ctx, struct libnet_SamSync_state);
+ if (!state) {
+ r->out.error_string = NULL;
+ talloc_free(samsync_ctx);
+ return nt_status;
+ }
+
+ state->domain_name = c->out.domain_name;
+ state->domain_sid = c->out.domain_sid;
+ state->realm = c->out.realm;
+ state->domain_guid = c->out.guid;
+ state->machine_net_ctx = machine_net_ctx;
+ state->netlogon_pipe = p;
+
/* initialise the callback layer. It may wish to contact the
* server with ldap, now we know the name */
@@ -265,11 +280,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx
char *error_string;
nt_status = r->in.init_fn(samsync_ctx,
r->in.fn_ctx,
- machine_net_ctx,
- p,
- c->out.domain_name,
- c->out.domain_sid,
- c->out.realm,
+ state,
&error_string);
if (!NT_STATUS_IS_OK(nt_status)) {
r->out.error_string = talloc_steal(mem_ctx, error_string);
diff --git a/source4/libnet/libnet_vampire.h b/source4/libnet/libnet_vampire.h
index 03a085aa87..5fd6504737 100644
--- a/source4/libnet/libnet_vampire.h
+++ b/source4/libnet/libnet_vampire.h
@@ -20,17 +20,22 @@
#include "librpc/gen_ndr/ndr_netlogon.h"
+struct libnet_SamSync_state {
+ struct libnet_context *machine_net_ctx;
+ struct dcerpc_pipe *netlogon_pipe;
+ const char *domain_name;
+ const struct dom_sid *domain_sid;
+ const char *realm;
+ struct GUID *domain_guid;
+};
+
/* struct and enum for doing a remote domain vampire dump */
struct libnet_SamSync {
struct {
const char *binding_string;
NTSTATUS (*init_fn)(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,
+ struct libnet_SamSync_state *samsync_state,
char **error_string);
NTSTATUS (*delta_fn)(TALLOC_CTX *mem_ctx,
void *private,