r8970: Add 'ADS' join support to Samba4.
authorAndrew Bartlett <abartlet@samba.org>
Wed, 3 Aug 2005 00:59:35 +0000 (00:59 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:31:01 +0000 (13:31 -0500)
We now fill in the servicePrincipalName over LDAP, just like XP does,
and store the kvno in our local db.

Andrew Bartlett

source/libnet/libnet_join.c
source/libnet/libnet_join.h

index e98217bd35342d3201f4e994ae437ff105130e42..d0008de7d731cca4a6f7bb5737b2fbfbc167335a 100644 (file)
@@ -82,6 +82,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
        struct policy_handle drsuapi_bind_handle;
        struct GUID drsuapi_bind_guid;
 
+       struct ldb_context *remote_ldb;
+
        uint32_t acct_flags;
        uint32_t rid, access_granted;
        int policy_min_pw_len = 0;
@@ -91,6 +93,17 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
        const char *realm = NULL; /* Also flag for remote being AD */
        const char *account_dn;
 
+       char *remote_ldb_url;
+       struct ldb_message **msgs, *msg;
+       int ldb_ret;
+
+       const char *attrs[] = {
+               "msDS-KeyVersionNumber",
+               "servicePrincipalName",
+               "dNSHostName",
+               NULL,
+       };
+
        tmp_ctx = talloc_named(mem_ctx, 0, "libnet_Join temp context");
        if (!tmp_ctx) {
                r->out.error_string = NULL;
@@ -476,7 +489,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                        talloc_free(tmp_ctx);
                        return status;
                }
-       } else if (!W_ERROR_IS_OK(r_crack_names.out.result)) {
+       } else if (!W_ERROR_IS_OK(r_drsuapi_bind.out.result)) {
                r->out.error_string
                                = talloc_asprintf(mem_ctx,
                                                  "DsBind failed - %s\n", win_errstr(r_drsuapi_bind.out.result));
@@ -525,8 +538,57 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
 
        account_dn = r_crack_names.out.ctr.ctr1->array[0].result_name;
 
-       printf("Account DN is: %s\n", account_dn);
-       
+       remote_ldb_url = talloc_asprintf(tmp_ctx, "ldap://%s", 
+                                        drsuapi_binding->host);
+       remote_ldb = ldb_wrap_connect(tmp_ctx, remote_ldb_url, 0, NULL);
+
+       if (!remote_ldb) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       /* search for the secret record */
+       ldb_ret = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE, 
+                            NULL, attrs, &msgs);
+
+       if (ldb_ret != 1) {
+               r->out.error_string
+                       = talloc_asprintf(mem_ctx,
+                                         "ldb_search for %s failed - %s\n", 
+                                         account_dn, 
+                                         ldb_errstring(remote_ldb));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+       r->out.kvno = ldb_msg_find_uint(msgs[0], "msDS-KeyVersionNumber", 0);
+
+       msg = ldb_msg_new(tmp_ctx);
+       if (!msg) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       msg->dn = msgs[0]->dn;
+
+       {
+               char *service_principal_name[2];
+               char *dns_host_name = strlower_talloc(mem_ctx, 
+                                                     talloc_asprintf(mem_ctx, 
+                                                                     "%s.%s", lp_netbios_name(), realm));
+               service_principal_name[0] = talloc_asprintf(tmp_ctx, "host/%s", dns_host_name);
+               service_principal_name[1] = talloc_asprintf(tmp_ctx, "host/%s", strlower_talloc(mem_ctx, lp_netbios_name()));
+
+               samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "dNSHostName", dns_host_name);
+               samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "servicePrincipalName", service_principal_name[0]);
+               samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "servicePrincipalName", service_principal_name[1]);
+               
+               ldb_ret = samdb_replace(remote_ldb, tmp_ctx, msg);
+               if (ldb_ret != 0) {
+                       r->out.error_string
+                               = talloc_asprintf(mem_ctx, 
+                                                 "Failed to replace entries on %s\n", 
+                                                 msg->dn);
+                       return NT_STATUS_INTERNAL_DB_CORRUPTION;
+               }
+       }
+
        /* close connection */
        talloc_free(tmp_ctx);
 
@@ -604,7 +666,11 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
        samdb_msg_add_string(ldb, mem_ctx, msg, "samAccountName", r2.in.account_name);
        
        samdb_msg_add_string(ldb, mem_ctx, msg, "secureChannelType", sct);
-       
+
+       if (r2.out.kvno) {
+               samdb_msg_add_uint(ldb, mem_ctx, msg, "msDS-KeyVersionNumber",
+                                  r2.out.kvno);
+       }
 
        if (ret == 0) {
        } else if (ret == -1) {
index 5f1fcebfe98ae5ba65e1376bf6ef9dfd5f8e5ded..bd8a6e2a2c9a26a609e20fe2f7933db16097926a 100644 (file)
@@ -34,6 +34,7 @@ struct libnet_JoinDomain {
                struct dom_sid *domain_sid;
                const char *domain_name;
                const char *realm;
+               unsigned int kvno;
        } out;
 };