r12926: Syncronsise GUIDs on users and domains from the server. These also
authorAndrew Bartlett <abartlet@samba.org>
Sat, 14 Jan 2006 01:29:38 +0000 (01:29 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:51:07 +0000 (13:51 -0500)
appear in DNS, so need to match.

Andrew Bartlett
(This used to be commit d092b0493d7c61112ef132c8fb259c15f189c5f6)

source4/libnet/libnet_rpc.c
source4/libnet/libnet_rpc.h
source4/libnet/libnet_samsync_ldb.c
source4/libnet/libnet_vampire.c
source4/libnet/libnet_vampire.h

index aba393d7fb95d95ea4c43c8342dca034c7e49a58..5b63f482df1d29ba1a42c7db4ec0580e873d79e7 100644 (file)
@@ -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 */
index ce88462485f2c401ed00fe2fcaec6dc0ae78f3c6..333881debd54f338b11847ca92510e13a97f643e 100644 (file)
@@ -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;
 };
index da4e777a153fa29538941cc616119462a621956b..5140aa87aeb7537a6db28cc0366d03dc026af33e 100644 (file)
@@ -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;
 }
index b9fb37fea63cf4bcfb1dcbda1f16a5af5f12f778..ce65a6e460a2a05a3076a6883d1ea8bb591a0558 100644 (file)
@@ -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);
index 03a085aa8716001944aa05e4e2f048caf832c4f3..5fd6504737452df4e87e41c52cfe3eb48dd12816 100644 (file)
 
 #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,