s4:dsdb/repl: fix the usage of 'GC/' prefixed principal names
authorStefan Metzmacher <metze@samba.org>
Tue, 14 Aug 2012 12:36:41 +0000 (14:36 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 14 Aug 2012 16:57:41 +0000 (18:57 +0200)
The "serverReference" attribute is available on the "server" object
not on the "nTDSA" object.

This allows connections to RODCs, as they don't have a
E3514235-4B06-11D1-AB04-00C04FC2DCD2/${NTDSGUID}/${DNSDOMAIN}
principal.

Pair-Programmed-With: Bj√∂rn Baumbach <bb@sernet.de>

metze

Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Tue Aug 14 18:57:41 CEST 2012 on sn-devel-104

source4/dsdb/repl/drepl_partitions.c

index 7464dc15546508b790470781b0e70a68b9ad4bae..5949f42d0646486fbdfe371fecc1ab0feb59d5e9 100644 (file)
@@ -128,32 +128,16 @@ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
 /*
   Check if particular SPN exists for an account
  */
-static bool dreplsrv_spn_exists(struct ldb_context *samdb, struct ldb_dn *ntds_dn,
+static bool dreplsrv_spn_exists(struct ldb_context *samdb, struct ldb_dn *account_dn,
                                const char *principal_name)
 {
        TALLOC_CTX *tmp_ctx;
-       const char *attrs[] = { "serverReference", NULL };
        const char *attrs_empty[] = { NULL };
        int ret;
        struct ldb_result *res;
-       struct ldb_dn *account_dn;
 
        tmp_ctx = talloc_new(samdb);
 
-       ret = dsdb_search_dn(samdb, tmp_ctx, &res, ntds_dn, attrs, 0);
-       if (ret != LDB_SUCCESS) {
-               talloc_free(tmp_ctx);
-               return false;
-       }
-
-       account_dn = ldb_msg_find_attr_as_dn(samdb, tmp_ctx, res->msgs[0], "serverReference");
-       if (account_dn == NULL) {
-               talloc_free(tmp_ctx);
-               return false;
-       }
-
-       talloc_free(res);
-
        ret = dsdb_search(samdb, tmp_ctx, &res, account_dn, LDB_SCOPE_BASE, attrs_empty,
                        0, "servicePrincipalName=%s",
                        ldb_binary_encode_string(tmp_ctx, principal_name));
@@ -176,11 +160,11 @@ NTSTATUS dreplsrv_get_target_principal(struct dreplsrv_service *s,
 {
        TALLOC_CTX *tmp_ctx;
        struct ldb_result *res;
-       const char *attrs_server[] = { "dNSHostName", NULL };
+       const char *attrs_server[] = { "dNSHostName", "serverReference", NULL };
        const char *attrs_ntds[] = { "msDS-HasDomainNCs", "hasMasterNCs", NULL };
        int ret;
        const char *hostname, *dnsdomain=NULL;
-       struct ldb_dn *ntds_dn, *server_dn;
+       struct ldb_dn *ntds_dn, *server_dn, *computer_dn;
        struct ldb_dn *forest_dn, *nc_dn;
 
        *target_principal = NULL;
@@ -221,7 +205,8 @@ NTSTATUS dreplsrv_get_target_principal(struct dreplsrv_service *s,
        }
 
        hostname = ldb_msg_find_attr_as_string(res->msgs[0], "dNSHostName", NULL);
-       if (hostname != NULL) {
+       computer_dn = ldb_msg_find_attr_as_dn(s->samdb, tmp_ctx, res->msgs[0], "serverReference");
+       if (hostname != NULL && computer_dn != NULL) {
                char *local_principal;
 
                /*
@@ -234,7 +219,7 @@ NTSTATUS dreplsrv_get_target_principal(struct dreplsrv_service *s,
                local_principal = talloc_asprintf(mem_ctx, "GC/%s/%s",
                                                    hostname,
                                                    samdb_dn_to_dns_domain(tmp_ctx, forest_dn));
-               if (dreplsrv_spn_exists(s->samdb, ntds_dn, local_principal)) {
+               if (dreplsrv_spn_exists(s->samdb, computer_dn, local_principal)) {
                        *target_principal = local_principal;
                        talloc_free(tmp_ctx);
                        return NT_STATUS_OK;