Don't use crossRef records to find our own domain
authorAndrew Bartlett <abartlet@samba.org>
Tue, 26 May 2009 02:31:39 +0000 (12:31 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 26 May 2009 02:37:09 +0000 (12:37 +1000)
A single AD server can only host a single domain, so don't stuff about
with looking up our crossRef record in the cn=Partitions container.
We instead trust that lp_realm() and lp_workgroup() works correctly.

Andrew Bartlett

16 files changed:
source4/auth/auth.h
source4/auth/ntlm/auth_sam.c
source4/auth/sam.c
source4/cldap_server/netlogon.c
source4/kdc/config.mk
source4/kdc/hdb-samba4.c
source4/kdc/kdc.h
source4/kdc/pac-glue.c
source4/nbt_server/dgram/netlogon.c
source4/param/loadparm.c
source4/param/param.h
source4/param/util.c
source4/rpc_server/config.mk
source4/rpc_server/lsa/lsa_init.c
source4/rpc_server/netlogon/dcerpc_netlogon.c
source4/rpc_server/samr/dcesrv_samr.c

index 973102d842be635ee3ed61e340d5e20145418fed..f6d739325da54f2901924912c76aa32f405fefd6 100644 (file)
@@ -221,24 +221,26 @@ struct auth_critical_sizes {
 
 struct ldb_message;
 struct ldb_context;
+struct ldb_dn;
 struct gensec_security;
 
 NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_t **_chal);
 NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
                            struct ldb_context *sam_ctx,
                            uint32_t logon_parameters,
+                           struct ldb_dn *domain_dn,
                            struct ldb_message *msg,
-                           struct ldb_message *msg_domain_ref,
                            const char *logon_workstation,
                            const char *name_for_logs,
                            bool allow_domain_trust);
 struct auth_session_info *system_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx);
 NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
                                           const char *netbios_name,
+                                          const char *domain_name,
+                                          struct ldb_dn *domain_dn, 
                                           struct ldb_message *msg,
-                                          struct ldb_message *msg_domain_ref,
                                           DATA_BLOB user_sess_key, DATA_BLOB lm_sess_key,
-                                          struct auth_serversupplied_info **_server_info);
+                                 struct auth_serversupplied_info **_server_info);
 NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, 
                                           struct loadparm_context *lp_ctx,
                                           struct auth_session_info **_session_info) ;
index e99d0e1f51bf24a7058dba36f56bd1cb121506a0..75ed3243d44911a9d7a0294ba0bc31812feeab4e 100644 (file)
@@ -42,26 +42,12 @@ extern const char *domain_ref_attrs[];
 
 static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
                                       const char *account_name,
-                                      const char *domain_name,
-                                      struct ldb_message ***ret_msgs,
-                                      struct ldb_message ***ret_msgs_domain_ref)
+                                      struct ldb_dn *domain_dn,
+                                      struct ldb_message ***ret_msgs)
 {
-       struct ldb_message **msgs_tmp;
        struct ldb_message **msgs;
-       struct ldb_message **msgs_domain_ref;
-       struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
 
        int ret;
-       int ret_domain;
-
-       struct ldb_dn *domain_dn = NULL;
-
-       if (domain_name) {
-               domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx, domain_name);
-               if (!domain_dn) {
-                       return NT_STATUS_INTERNAL_DB_CORRUPTION;
-               }
-       }
 
        /* pull the user attributes */
        ret = gendb_search(sam_ctx, mem_ctx, domain_dn, &msgs, user_attrs,
@@ -72,8 +58,8 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *
        }
 
        if (ret == 0) {
-               DEBUG(3,("sam_search_user: Couldn't find user [%s\\%s] in samdb, under %s\n", 
-                        domain_name, account_name, ldb_dn_get_linearized(domain_dn)));
+               DEBUG(3,("sam_search_user: Couldn't find user [%s] in samdb, under %s\n", 
+                        account_name, ldb_dn_get_linearized(domain_dn)));
                return NT_STATUS_NO_SUCH_USER;
        }
 
@@ -82,57 +68,7 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
-       if (!domain_dn) {
-               struct dom_sid *domain_sid;
-
-               domain_sid = samdb_result_sid_prefix(mem_ctx, msgs[0], "objectSid");
-               if (!domain_sid) {
-                       return NT_STATUS_INTERNAL_DB_CORRUPTION;
-               }
-
-               /* find the domain's DN */
-               ret = gendb_search(sam_ctx, mem_ctx, NULL, &msgs_tmp, NULL,
-                                  "(&(objectSid=%s)(objectClass=domain))", 
-                                  ldap_encode_ndr_dom_sid(mem_ctx, domain_sid));
-               if (ret == -1) {
-                       return NT_STATUS_INTERNAL_DB_CORRUPTION;
-               }
-               
-               if (ret == 0) {
-                       DEBUG(3,("check_sam_security: Couldn't find domain_sid [%s] in passdb file.\n",
-                                dom_sid_string(mem_ctx, domain_sid)));
-                       return NT_STATUS_NO_SUCH_USER;
-               }
-               
-               if (ret > 1) {
-                       DEBUG(0,("Found %d records matching domain_sid [%s]\n", 
-                                ret, dom_sid_string(mem_ctx, domain_sid)));
-                       return NT_STATUS_INTERNAL_DB_CORRUPTION;
-               }
-
-               domain_dn = msgs_tmp[0]->dn;
-       }
-
-       ret_domain = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &msgs_domain_ref, domain_ref_attrs,
-                                 "(nCName=%s)", ldb_dn_get_linearized(domain_dn));
-       if (ret_domain == -1) {
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       }
-               
-       if (ret_domain == 0) {
-               DEBUG(3,("check_sam_security: Couldn't find domain [%s] in passdb file.\n",
-                        ldb_dn_get_linearized(msgs_tmp[0]->dn)));
-               return NT_STATUS_NO_SUCH_USER;
-       }
-               
-       if (ret_domain > 1) {
-               DEBUG(0,("Found %d records matching domain [%s]\n", 
-                        ret_domain, ldb_dn_get_linearized(msgs_tmp[0]->dn)));
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       }
-
        *ret_msgs = msgs;
-       *ret_msgs_domain_ref = msgs_domain_ref;
        
        return NT_STATUS_OK;
 }
@@ -210,14 +146,13 @@ static NTSTATUS authsam_password_ok(struct auth_context *auth_context,
 
 static NTSTATUS authsam_authenticate(struct auth_context *auth_context, 
                                     TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, 
+                                    struct ldb_dn *domain_dn,
                                     struct ldb_message **msgs,
-                                    struct ldb_message **msgs_domain_ref,
                                     const struct auth_usersupplied_info *user_info, 
                                     DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) 
 {
        struct samr_Password *lm_pwd, *nt_pwd;
        NTSTATUS nt_status;
-       struct ldb_dn *domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msgs_domain_ref[0], "nCName", NULL);
 
        uint16_t acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msgs[0], domain_dn);
        
@@ -245,8 +180,8 @@ static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
 
        nt_status = authsam_account_ok(mem_ctx, sam_ctx, 
                                       user_info->logon_parameters,
+                                      domain_dn,
                                       msgs[0],
-                                      msgs_domain_ref[0],
                                       user_info->workstation_name,
                                       user_info->mapped.account_name,
                                       false);
@@ -258,15 +193,14 @@ static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
 
 static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx,
                                                 TALLOC_CTX *mem_ctx,
-                                                const char *domain,
                                                 const struct auth_usersupplied_info *user_info, 
                                                 struct auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status;
        const char *account_name = user_info->mapped.account_name;
        struct ldb_message **msgs;
-       struct ldb_message **domain_ref_msgs;
        struct ldb_context *sam_ctx;
+       struct ldb_dn *domain_dn;
        DATA_BLOB user_sess_key, lm_sess_key;
        TALLOC_CTX *tmp_ctx;
 
@@ -286,13 +220,19 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
                return NT_STATUS_INVALID_SYSTEM_SERVICE;
        }
 
-       nt_status = authsam_search_account(tmp_ctx, sam_ctx, account_name, domain, &msgs, &domain_ref_msgs);
+       domain_dn = ldb_get_default_basedn(sam_ctx);
+       if (domain_dn == NULL) {
+               talloc_free(tmp_ctx);
+               return NT_STATUS_NO_SUCH_DOMAIN;
+       }
+
+       nt_status = authsam_search_account(tmp_ctx, sam_ctx, account_name, domain_dn, &msgs);
        if (!NT_STATUS_IS_OK(nt_status)) {
                talloc_free(tmp_ctx);
                return nt_status;
        }
 
-       nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, sam_ctx, msgs, domain_ref_msgs, user_info,
+       nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, sam_ctx, domain_dn, msgs, user_info,
                                         &user_sess_key, &lm_sess_key);
        if (!NT_STATUS_IS_OK(nt_status)) {
                talloc_free(tmp_ctx);
@@ -300,7 +240,9 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
        }
 
        nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx), 
-                                            msgs[0], domain_ref_msgs[0],
+                                            lp_sam_name(ctx->auth_ctx->lp_ctx),
+                                            domain_dn,
+                                            msgs[0],
                                             user_sess_key, lm_sess_key,
                                             server_info);
        if (!NT_STATUS_IS_OK(nt_status)) {
@@ -325,14 +267,6 @@ static NTSTATUS authsam_ignoredomain_want_check(struct auth_method_context *ctx,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS authsam_ignoredomain_check_password(struct auth_method_context *ctx,
-                                                   TALLOC_CTX *mem_ctx,
-                                                   const struct auth_usersupplied_info *user_info, 
-                                                   struct auth_serversupplied_info **server_info)
-{
-       return authsam_check_password_internals(ctx, mem_ctx, NULL, user_info, server_info);
-}
-
 /****************************************************************************
 Check SAM security (above) but with a few extra checks.
 ****************************************************************************/
@@ -377,34 +311,6 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx,
        return NT_STATUS_NOT_IMPLEMENTED;
 }
 
-/****************************************************************************
-Check SAM security (above) but with a few extra checks.
-****************************************************************************/
-static NTSTATUS authsam_check_password(struct auth_method_context *ctx,
-                                      TALLOC_CTX *mem_ctx,
-                                      const struct auth_usersupplied_info *user_info, 
-                                      struct auth_serversupplied_info **server_info)
-{
-       const char *domain;
-
-       /* check whether or not we service this domain/workgroup name */
-       switch (lp_server_role(ctx->auth_ctx->lp_ctx)) {
-               case ROLE_STANDALONE:
-               case ROLE_DOMAIN_MEMBER:
-                       domain = lp_netbios_name(ctx->auth_ctx->lp_ctx);
-                       break;
-
-               case ROLE_DOMAIN_CONTROLLER:
-                       domain = lp_workgroup(ctx->auth_ctx->lp_ctx);
-                       break;
-
-               default:
-                       return NT_STATUS_NO_SUCH_USER;
-       }
-
-       return authsam_check_password_internals(ctx, mem_ctx, domain, user_info, server_info);
-}
-
                                   
 /* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available */
 NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx, 
@@ -417,9 +323,9 @@ NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx,
        DATA_BLOB lm_sess_key = data_blob(NULL, 0);
 
        struct ldb_message **msgs;
-       struct ldb_message **msgs_domain_ref;
        struct ldb_context *sam_ctx;
-
+       struct ldb_dn *domain_dn;
+       
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
        if (!tmp_ctx) {
                return NT_STATUS_NO_MEMORY;
@@ -433,14 +339,16 @@ NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx,
        }
 
        nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal, 
-                                             &msgs, &msgs_domain_ref);
+                                             &domain_dn, &msgs);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
 
        nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, 
                                             lp_netbios_name(auth_context->lp_ctx),
-                                            msgs[0], msgs_domain_ref[0],
+                                            lp_workgroup(auth_context->lp_ctx),
+                                            domain_dn, 
+                                            msgs[0],
                                             user_sess_key, lm_sess_key,
                                             server_info);
        if (NT_STATUS_IS_OK(nt_status)) {
@@ -454,7 +362,7 @@ static const struct auth_operations sam_ignoredomain_ops = {
        .name                      = "sam_ignoredomain",
        .get_challenge             = auth_get_challenge_not_implemented,
        .want_check                = authsam_ignoredomain_want_check,
-       .check_password            = authsam_ignoredomain_check_password,
+       .check_password            = authsam_check_password_internals,
        .get_server_info_principal = authsam_get_server_info_principal
 };
 
@@ -462,7 +370,7 @@ static const struct auth_operations sam_ops = {
        .name                      = "sam",
        .get_challenge             = auth_get_challenge_not_implemented,
        .want_check                = authsam_want_check,
-       .check_password            = authsam_check_password,
+       .check_password            = authsam_check_password_internals,
        .get_server_info_principal = authsam_get_server_info_principal
 };
 
index 819bca0db0422b5eae77ec555db1163e5a254e89..ebdf1932af403c70f3e658566b96fb0e96c99a83 100644 (file)
@@ -139,21 +139,19 @@ static bool logon_hours_ok(struct ldb_message *msg, const char *name_for_logs)
  (ie not disabled, expired and the like).
 ****************************************************************************/
 _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
-                           struct ldb_context *sam_ctx,
-                           uint32_t logon_parameters,
-                           struct ldb_message *msg,
-                           struct ldb_message *msg_domain_ref,
-                           const char *logon_workstation,
-                           const char *name_for_logs,
-                           bool allow_domain_trust)
+                                    struct ldb_context *sam_ctx,
+                                    uint32_t logon_parameters,
+                                    struct ldb_dn *domain_dn,
+                                    struct ldb_message *msg,
+                                    const char *logon_workstation,
+                                    const char *name_for_logs,
+                                    bool allow_domain_trust)
 {
        uint16_t acct_flags;
        const char *workstation_list;
        NTTIME acct_expiry;
        NTTIME must_change_time;
 
-       struct ldb_dn *domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", ldb_dn_new(mem_ctx, sam_ctx, NULL));
-
        NTTIME now;
        DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", name_for_logs));
 
@@ -256,8 +254,9 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
 
 _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
                                           const char *netbios_name,
+                                          const char *domain_name,
+                                          struct ldb_dn *domain_dn, 
                                           struct ldb_message *msg,
-                                          struct ldb_message *msg_domain_ref,
                                           DATA_BLOB user_sess_key, DATA_BLOB lm_sess_key,
                                           struct auth_serversupplied_info **_server_info)
 {
@@ -269,7 +268,6 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
        struct dom_sid **groupSIDs = NULL;
        struct dom_sid *account_sid;
        struct dom_sid *primary_group_sid;
-       struct ldb_dn *domain_dn;
        const char *str;
        struct ldb_dn *ncname;
        int i;
@@ -327,7 +325,8 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
 
        server_info->account_name = talloc_steal(server_info, samdb_result_string(msg, "sAMAccountName", NULL));
 
-       server_info->domain_name = talloc_steal(server_info, samdb_result_string(msg_domain_ref, "nETBIOSName", NULL));
+       server_info->domain_name = talloc_strdup(server_info, domain_name);
+       NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
 
        str = samdb_result_string(msg, "displayName", "");
        server_info->full_name = talloc_strdup(server_info, str);
@@ -357,10 +356,6 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
        server_info->acct_expiry = samdb_result_account_expires(msg);
        server_info->last_password_change = samdb_result_nttime(msg, "pwdLastSet", 0);
 
-       ncname = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", NULL);
-       if (!ncname) {
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       }
        server_info->allow_password_change
                = samdb_result_allow_password_change(sam_ctx, mem_ctx, 
                                                     ncname, msg, "pwdLastSet");
@@ -371,8 +366,6 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
        server_info->logon_count = samdb_result_uint(msg, "logonCount", 0);
        server_info->bad_password_count = samdb_result_uint(msg, "badPwdCount", 0);
 
-       domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", NULL);
-
        server_info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, 
                                                          msg, domain_dn);
 
@@ -388,34 +381,24 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
 
 NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx,
                                   TALLOC_CTX *mem_ctx, const char *principal,
-                                  struct ldb_message ***msgs,
-                                  struct ldb_message ***msgs_domain_ref)
+                                  struct ldb_dn **domain_dn,
+                                  struct ldb_message ***msgs)
 {                         
-       struct ldb_dn *user_dn, *domain_dn;
+       struct ldb_dn *user_dn;
        NTSTATUS nt_status;
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
        int ret;
-       struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
 
        if (!tmp_ctx) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       nt_status = crack_user_principal_name(sam_ctx, tmp_ctx, principal, &user_dn, &domain_dn);
+       nt_status = crack_user_principal_name(sam_ctx, tmp_ctx, principal, &user_dn, domain_dn);
        if (!NT_STATUS_IS_OK(nt_status)) {
                talloc_free(tmp_ctx);
                return nt_status;
        }
        
-       /* grab domain info from the reference */
-       ret = gendb_search(sam_ctx, tmp_ctx, partitions_basedn, msgs_domain_ref, domain_ref_attrs,
-                          "(ncName=%s)", ldb_dn_get_linearized(domain_dn));
-
-       if (ret != 1) {
-               talloc_free(tmp_ctx);
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       }
-       
        /* pull the user attributes */
        ret = gendb_search_dn(sam_ctx, tmp_ctx, user_dn, msgs, user_attrs);
        if (ret != 1) {
@@ -423,7 +406,7 @@ NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx,
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
        talloc_steal(mem_ctx, *msgs);
-       talloc_steal(mem_ctx, *msgs_domain_ref);
+       talloc_steal(mem_ctx, *domain_dn);
        talloc_free(tmp_ctx);
        
        return NT_STATUS_OK;
index 33c0adc3b18b6d34a2f8abfe968d91124282cefb..8a21ea55c9ad727a1a1ea79a108de0495a4456f3 100644 (file)
@@ -53,10 +53,9 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
                                         struct loadparm_context *lp_ctx,
                                         struct netlogon_samlogon_response *netlogon)
 {
-       const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL};
        const char *dom_attrs[] = {"objectGUID", NULL};
        const char *none_attrs[] = {NULL};
-       struct ldb_result *ref_res = NULL, *dom_res = NULL, *user_res = NULL;
+       struct ldb_result *dom_res = NULL, *user_res = NULL;
        int ret;
        const char **services = lp_server_services(lp_ctx);
        uint32_t server_type;
@@ -69,94 +68,39 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
        const char *server_site;
        const char *client_site;
        const char *pdc_ip;
-       struct ldb_dn *partitions_basedn;
+       struct ldb_dn *domain_dn = NULL;
        struct interface *ifaces;
        bool user_known;
        NTSTATUS status;
 
-       partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
-
        /* the domain has an optional trailing . */
        if (domain && domain[strlen(domain)-1] == '.') {
                domain = talloc_strndup(mem_ctx, domain, strlen(domain)-1);
        }
 
-       if (domain) {
-               struct ldb_dn *dom_dn;
-               /* try and find the domain */
-
-               ret = ldb_search(sam_ctx, mem_ctx, &ref_res,
-                                partitions_basedn, LDB_SCOPE_ONELEVEL,
-                                ref_attrs,
-                                "(&(&(objectClass=crossRef)(dnsRoot=%s))(nETBIOSName=*))",
-                                ldb_binary_encode_string(mem_ctx, domain));
-       
-               if (ret != LDB_SUCCESS) {
-                       DEBUG(2,("Unable to find referece to '%s' in sam: %s\n",
-                                domain, 
-                                ldb_errstring(sam_ctx)));
-                       return NT_STATUS_NO_SUCH_DOMAIN;
-               } else if (ref_res->count == 1) {
-                       dom_dn = ldb_msg_find_attr_as_dn(sam_ctx, mem_ctx, ref_res->msgs[0], "ncName");
-                       if (!dom_dn) {
-                               return NT_STATUS_NO_SUCH_DOMAIN;
-                       }
-                       ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
-                                        dom_dn, LDB_SCOPE_BASE, dom_attrs,
-                                        "objectClass=domain");
-                       if (ret != LDB_SUCCESS) {
-                               DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(dom_dn), ldb_errstring(sam_ctx)));
-                               return NT_STATUS_NO_SUCH_DOMAIN;
-                       }
-                       if (dom_res->count != 1) {
-                               DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain, ldb_dn_get_linearized(dom_dn)));
-                               return NT_STATUS_NO_SUCH_DOMAIN;
-                       }
-               } else if (ref_res->count > 1) {
-                       talloc_free(ref_res);
-                       return NT_STATUS_NO_SUCH_DOMAIN;
-               }
+       if (domain && strcasecmp_m(domain, lp_realm(lp_ctx)) == 0) {
+               domain_dn = ldb_get_default_basedn(sam_ctx);
        }
 
-       if (netbios_domain) {
-               struct ldb_dn *dom_dn;
-               /* try and find the domain */
+       if (netbios_domain && strcasecmp_m(domain, lp_sam_name(lp_ctx))) {
+               domain_dn = ldb_get_default_basedn(sam_ctx);
+       }
 
-               ret = ldb_search(sam_ctx, mem_ctx, &ref_res,
-                                partitions_basedn, LDB_SCOPE_ONELEVEL,
-                                ref_attrs,
-                                "(&(objectClass=crossRef)(ncName=*)(nETBIOSName=%s))",
-                                ldb_binary_encode_string(mem_ctx, netbios_domain));
-       
+       if (domain_dn) {
+               ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
+                                domain_dn, LDB_SCOPE_BASE, dom_attrs,
+                                "objectClass=domain");
                if (ret != LDB_SUCCESS) {
-                       DEBUG(2,("Unable to find referece to '%s' in sam: %s\n",
-                                netbios_domain, 
-                                ldb_errstring(sam_ctx)));
+                       DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(domain_dn), ldb_errstring(sam_ctx)));
                        return NT_STATUS_NO_SUCH_DOMAIN;
-               } else if (ref_res->count == 1) {
-                       dom_dn = ldb_msg_find_attr_as_dn(sam_ctx, mem_ctx, ref_res->msgs[0], "ncName");
-                       if (!dom_dn) {
-                               return NT_STATUS_NO_SUCH_DOMAIN;
-                       }
-                       ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
-                                        dom_dn, LDB_SCOPE_BASE, dom_attrs,
-                                        "objectClass=domain");
-                       if (ret != LDB_SUCCESS) {
-                               DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(dom_dn), ldb_errstring(sam_ctx)));
-                               return NT_STATUS_NO_SUCH_DOMAIN;
-                       }
-                       if (dom_res->count != 1) {
-                               DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain, ldb_dn_get_linearized(dom_dn)));
-                               return NT_STATUS_NO_SUCH_DOMAIN;
-                       }
-               } else if (ref_res->count > 1) {
-                       talloc_free(ref_res);
+               }
+               if (dom_res->count != 1) {
+                       DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain, ldb_dn_get_linearized(domain_dn)));
                        return NT_STATUS_NO_SUCH_DOMAIN;
                }
        }
 
        if ((dom_res == NULL || dom_res->count == 0) && (domain_guid || domain_sid)) {
-               ref_res = NULL;
 
                if (domain_guid) {
                        struct GUID binary_guid;
@@ -206,36 +150,17 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
                                 ldb_errstring(sam_ctx)));
                        return NT_STATUS_NO_SUCH_DOMAIN;
                } else if (dom_res->count == 1) {
-                       /* try and find the domain */
-                       ret = ldb_search(sam_ctx, mem_ctx, &ref_res,
-                                                partitions_basedn, LDB_SCOPE_ONELEVEL, 
-                                                ref_attrs, 
-                                                "(&(objectClass=crossRef)(ncName=%s))", 
-                                                ldb_dn_get_linearized(dom_res->msgs[0]->dn));
+                       /* Ok, now just check it is our domain */
                        
-                       if (ret != LDB_SUCCESS) {
-                               DEBUG(2,("Unable to find referece to '%s' in sam: %s\n",
-                                        ldb_dn_get_linearized(dom_res->msgs[0]->dn), 
-                                        ldb_errstring(sam_ctx)));
-                               return NT_STATUS_NO_SUCH_DOMAIN;
-                               
-                       } else if (ref_res->count != 1) {
-                               DEBUG(2,("Unable to find referece to '%s' in sam\n",
-                                        ldb_dn_get_linearized(dom_res->msgs[0]->dn)));
+                       if (ldb_dn_compare(ldb_get_default_basedn(sam_ctx), dom_res->msgs[0]->dn) != 0) {
                                return NT_STATUS_NO_SUCH_DOMAIN;
                        }
                } else if (dom_res->count > 1) {
-                       talloc_free(ref_res);
                        return NT_STATUS_NO_SUCH_DOMAIN;
                }
        }
 
 
-       if ((ref_res == NULL || ref_res->count == 0)) {
-               DEBUG(2,("Unable to find domain reference with name %s or GUID {%s}\n", domain, domain_guid));
-               return NT_STATUS_NO_SUCH_DOMAIN;
-       }
-
        if ((dom_res == NULL || dom_res->count == 0)) {
                DEBUG(2,("Unable to find domain with name %s or GUID {%s}\n", domain, domain_guid));
                return NT_STATUS_NO_SUCH_DOMAIN;
@@ -308,15 +233,14 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
 
        pdc_name         = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name(lp_ctx));
        domain_uuid      = samdb_result_guid(dom_res->msgs[0], "objectGUID");
-       realm            = samdb_result_string(ref_res->msgs[0], "dnsRoot", lp_realm(lp_ctx));
-       dns_domain       = samdb_result_string(ref_res->msgs[0], "dnsRoot", lp_realm(lp_ctx));
+       realm            = lp_realm(lp_ctx);
+       dns_domain       = lp_realm(lp_ctx);
        pdc_dns_name     = talloc_asprintf(mem_ctx, "%s.%s", 
                                           strlower_talloc(mem_ctx, 
                                                           lp_netbios_name(lp_ctx)), 
                                           dns_domain);
 
-       flatname         = samdb_result_string(ref_res->msgs[0], "nETBIOSName", 
-                                              lp_workgroup(lp_ctx));
+       flatname         = lp_sam_name(lp_ctx);
        /* FIXME: Hardcoded site names */
        server_site      = "Default-First-Site-Name";
        client_site      = "Default-First-Site-Name";
index bd8a3133168edf0b50b2a96564465715a3285c18..03fa2db295c77f92c903668173c49fdea2187613 100644 (file)
@@ -6,7 +6,7 @@
 INIT_FUNCTION = server_service_kdc_init
 SUBSYSTEM = service
 PRIVATE_DEPENDENCIES = \
-               HEIMDAL_KDC HDB_SAMBA4
+               HEIMDAL_KDC HDB_SAMBA4 LIBSAMBA-HOSTCONFIG
 # End SUBSYSTEM KDC
 #######################
 
@@ -18,7 +18,7 @@ KDC_OBJ_FILES = $(addprefix $(kdcsrcdir)/, kdc.o kpasswdd.o)
 CFLAGS = -Iheimdal/kdc -Iheimdal/lib/hdb
 PRIVATE_DEPENDENCIES = \
                LIBLDB auth_sam auth_sam_reply CREDENTIALS \
-               HEIMDAL_HDB
+               HEIMDAL_HDB LIBSAMBA-HOSTCONFIG
 # End SUBSYSTEM KDC
 #######################
 
index daeed77975b46d788fe61f85afdf70c9db7009cd..1fdb744a84a2f01a639848c68bb753fb67fca7d9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1999-2001, 2003, PADL Software Pty Ltd.
- * Copyright (c) 2004, Andrew Bartlett <abartlet@samba.org>.
+ * Copyright (c) 2004-2009, Andrew Bartlett <abartlet@samba.org>.
  * Copyright (c) 2004, Stefan Metzmacher <metze@samba.org>
  * All rights reserved.
  *
@@ -62,12 +62,6 @@ enum trust_direction {
        OUTBOUND = LSA_TRUST_DIRECTION_OUTBOUND
 };
 
-static const char *realm_ref_attrs[] = {
-       "nCName", 
-       "dnsRoot", 
-       NULL
-};
-
 static const char *trust_attrs[] = {
        "trustPartner",
        "trustAuthIncoming",
@@ -491,32 +485,33 @@ out:
  */
 static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, 
                                         TALLOC_CTX *mem_ctx, krb5_const_principal principal,
-                                        enum hdb_ldb_ent_type ent_type, 
+                                        enum hdb_ldb_ent_type ent_type,
+                                        struct ldb_dn *realm_dn,
                                         struct ldb_message *msg,
-                                        struct ldb_message *realm_ref_msg,
                                         hdb_entry_ex *entry_ex)
 {
        unsigned int userAccountControl;
        int i;
        krb5_error_code ret = 0;
        krb5_boolean is_computer = FALSE;
-       const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg, "dnsRoot", NULL);
-       char *realm = strupper_talloc(mem_ctx, dnsdomain);
        struct loadparm_context *lp_ctx = ldb_get_opaque((struct ldb_context *)db->hdb_db, "loadparm");
-       struct ldb_dn *domain_dn = samdb_result_dn((struct ldb_context *)db->hdb_db,
-                                                       mem_ctx,
-                                                       realm_ref_msg,
-                                                       "nCName",
-                                                       ldb_dn_new(mem_ctx, (struct ldb_context *)db->hdb_db, NULL));
+       char *realm = strupper_talloc(mem_ctx, lp_realm(lp_ctx));
 
        struct hdb_ldb_private *p;
        NTTIME acct_expiry;
 
        struct ldb_message_element *objectclasses;
        struct ldb_val computer_val;
+       const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
        computer_val.data = discard_const_p(uint8_t,"computer");
        computer_val.length = strlen((const char *)computer_val.data);
        
+       if (!samAccountName) {
+               krb5_set_error_string(context, "LDB_message2entry: no samAccountName present");
+               ret = ENOENT;
+               goto out;
+       }
+
        objectclasses = ldb_msg_find_element(msg, "objectClass");
        
        if (objectclasses && ldb_msg_find_val(objectclasses, &computer_val)) {
@@ -539,7 +534,12 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
 
        p->entry_ex = entry_ex;
        p->iconv_convenience = lp_iconv_convenience(lp_ctx);
-       p->netbios_name = lp_netbios_name(lp_ctx);
+       p->lp_ctx = lp_ctx;
+       p->realm_dn = talloc_reference(p, realm_dn);
+       if (!p->realm_dn) {
+               ret = ENOMEM;
+               goto out;
+       }
 
        talloc_set_destructor(p, hdb_ldb_destructor);
 
@@ -551,13 +551,6 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
        
        entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal)));
        if (ent_type == HDB_SAMBA4_ENT_TYPE_ANY && principal == NULL) {
-               const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
-               if (!samAccountName) {
-                       krb5_set_error_string(context, "LDB_message2entry: no samAccountName present");
-                       ret = ENOENT;
-                       goto out;
-               }
-               samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
                krb5_make_principal(context, &entry_ex->entry.principal, realm, samAccountName, NULL);
        } else {
                char *strdup_realm;
@@ -584,6 +577,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
                krb5_princ_set_realm(context, entry_ex->entry.principal, &strdup_realm);
        }
 
+       /* First try and figure out the flags based on the userAccountControl */
        entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type);
 
        if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT) {
@@ -593,6 +587,11 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
                entry_ex->entry.flags.ok_as_delegate = 1;
        }
 
+       /* Windows 2008 seems to enforce this (very sensible) rule by
+        * default - don't allow offline attacks on a user's password
+        * by asking for a ticket to them as a service (encrypted with
+        * their probably patheticly insecure password) */
+
        if (lp_parm_bool(lp_ctx, NULL, "kdc", "require spn for service", true)) {
                if (!is_computer && !ldb_msg_find_attr_as_string(msg, "servicePrincipalName", NULL)) {
                        entry_ex->entry.flags.server = 0;
@@ -618,22 +617,19 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
 
        entry_ex->entry.valid_start = NULL;
 
-       acct_expiry = samdb_result_account_expires(msg);
-       if (acct_expiry == 0x7FFFFFFFFFFFFFFFULL) {
+       /* The account/password expiry only applies when the account is used as a
+        * client (ie password login), not when used as a server */
+       if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT || ent_type == HDB_SAMBA4_ENT_TYPE_SERVER) {
+               /* Make very well sure we don't use this for a client,
+                * it could bypass the above password restrictions */
+               entry_ex->entry.flags.client = 0;
                entry_ex->entry.valid_end = NULL;
-       } else {
-               entry_ex->entry.valid_end = malloc(sizeof(*entry_ex->entry.valid_end));
-               if (entry_ex->entry.valid_end == NULL) {
-                       ret = ENOMEM;
-                       goto out;
-               }
-               *entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry);
-       }
+               entry_ex->entry.pw_end = NULL;
 
-       if (ent_type != HDB_SAMBA4_ENT_TYPE_KRBTGT) {
+       } else {
                NTTIME must_change_time
                        = samdb_result_force_password_change((struct ldb_context *)db->hdb_db, mem_ctx, 
-                                                            domain_dn, msg);
+                                                            realm_dn, msg);
                if (must_change_time == 0x7FFFFFFFFFFFFFFFULL) {
                        entry_ex->entry.pw_end = NULL;
                } else {
@@ -644,8 +640,18 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
                        }
                        *entry_ex->entry.pw_end = nt_time_to_unix(must_change_time);
                }
-       } else {
-               entry_ex->entry.pw_end = NULL;
+
+               acct_expiry = samdb_result_account_expires(msg);
+               if (acct_expiry == 0x7FFFFFFFFFFFFFFFULL) {
+                       entry_ex->entry.valid_end = NULL;
+               } else {
+                       entry_ex->entry.valid_end = malloc(sizeof(*entry_ex->entry.valid_end));
+                       if (entry_ex->entry.valid_end == NULL) {
+                               ret = ENOMEM;
+                               goto out;
+                       }
+                       *entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry);
+               }
        }
                        
        entry_ex->entry.max_life = NULL;
@@ -680,7 +686,6 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
 
 
        p->msg = talloc_steal(p, msg);
-       p->realm_ref_msg = talloc_steal(p, realm_ref_msg);
        p->samdb = (struct ldb_context *)db->hdb_db;
        
 out:
@@ -701,6 +706,7 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
                                               struct loadparm_context *lp_ctx,
                                               TALLOC_CTX *mem_ctx, krb5_const_principal principal,
                                               enum trust_direction direction,
+                                              struct ldb_dn *realm_dn,
                                               struct ldb_message *msg,
                                               hdb_entry_ex *entry_ex)
 {
@@ -725,7 +731,8 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
 
        p->entry_ex = entry_ex;
        p->iconv_convenience = lp_iconv_convenience(lp_ctx);
-       p->netbios_name = lp_netbios_name(lp_ctx);
+       p->lp_ctx = lp_ctx;
+       p->realm_dn = realm_dn;
 
        talloc_set_destructor(p, hdb_ldb_destructor);
 
@@ -869,7 +876,6 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
 
 
        p->msg = talloc_steal(p, msg);
-       p->realm_ref_msg = NULL;
        p->samdb = (struct ldb_context *)db->hdb_db;
        
 out:
@@ -988,40 +994,6 @@ static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context
        return 0;
 }
 
-static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context *ldb_ctx, 
-                                       TALLOC_CTX *mem_ctx,
-                                       const char *realm,
-                                       struct ldb_message ***pmsg)
-{
-       int ret;
-       struct ldb_result *cross_ref_res;
-       struct ldb_dn *partitions_basedn = samdb_partitions_dn(ldb_ctx, mem_ctx);
-
-       ret = ldb_search(ldb_ctx, mem_ctx, &cross_ref_res,
-                       partitions_basedn, LDB_SCOPE_SUBTREE, realm_ref_attrs,
-                       "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
-                       realm, realm);
-
-       if (ret != LDB_SUCCESS) {
-               DEBUG(3, ("Failed to search to lookup realm(%s): %s\n", realm, ldb_errstring(ldb_ctx)));
-               talloc_free(cross_ref_res);
-               return HDB_ERR_NOENTRY;
-       } else if (cross_ref_res->count == 0 || cross_ref_res->count > 1) {
-               DEBUG(3, ("Failed find a single entry for realm %s: got %d\n", realm, cross_ref_res->count));
-               talloc_free(cross_ref_res);
-               return HDB_ERR_NOENTRY;
-       }
-
-       if (pmsg) {
-               *pmsg = cross_ref_res->msgs;
-               talloc_steal(mem_ctx, cross_ref_res->msgs);
-       }
-       talloc_free(cross_ref_res);
-
-       return 0;
-}
-
-
 static krb5_error_code LDB_open(krb5_context context, HDB *db, int flags, mode_t mode)
 {
        if (db->hdb_master_key_set) {
@@ -1060,9 +1032,9 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
                                        hdb_entry_ex *entry_ex) {
        NTSTATUS nt_status;
        char *principal_string;
+       struct ldb_dn *realm_dn;
        krb5_error_code ret;
        struct ldb_message **msg = NULL;
-       struct ldb_message **realm_ref_msg = NULL;
 
        ret = krb5_unparse_name(context, principal, &principal_string);
        
@@ -1072,7 +1044,7 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
        
        nt_status = sam_get_results_principal((struct ldb_context *)db->hdb_db,
                                              mem_ctx, principal_string, 
-                                             &msg, &realm_ref_msg);
+                                             &realm_dn, &msg);
        free(principal_string);
        if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
                return HDB_ERR_NOENTRY;
@@ -1084,7 +1056,7 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
        
        ret = LDB_message2entry(context, db, mem_ctx, 
                                principal, HDB_SAMBA4_ENT_TYPE_CLIENT,
-                               msg[0], realm_ref_msg[0], entry_ex);
+                               realm_dn, msg[0], entry_ex);
        return ret;
 }
 
@@ -1096,10 +1068,9 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
 {
        krb5_error_code ret;
        struct ldb_message **msg = NULL;
-       struct ldb_message **realm_ref_msg_1 = NULL;
-       struct ldb_message **realm_ref_msg_2 = NULL;
-       struct ldb_dn *realm_dn;
+       struct ldb_dn *realm_dn = ldb_get_default_basedn(db->hdb_db);
        const char *realm;
+       struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context);
 
        krb5_principal alloc_principal = NULL;
        if (principal->name.name_string.len != 2
@@ -1110,18 +1081,14 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
 
        /* krbtgt case.  Either us or a trusted realm */
 
-       if ((LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db,
-                             mem_ctx, principal->realm, &realm_ref_msg_1) == 0)
-           && (LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db,
-                                mem_ctx, principal->name.name_string.val[1], &realm_ref_msg_2) == 0)
-           && (ldb_dn_compare(realm_ref_msg_1[0]->dn, realm_ref_msg_1[0]->dn) == 0)) {
+       if (lp_is_my_domain_or_realm(lp_ctx, principal->realm)
+           && lp_is_my_domain_or_realm(lp_ctx, principal->name.name_string.val[1])) {
                /* us */                
                /* Cludge, cludge cludge.  If the realm part of krbtgt/realm,
                 * is in our db, then direct the caller at our primary
                 * krbtgt */
                
-               const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg_1[0], "dnsRoot", NULL);
-               char *realm_fixed = strupper_talloc(mem_ctx, dnsdomain);
+               char *realm_fixed = strupper_talloc(mem_ctx, lp_realm(lp_ctx));
                if (!realm_fixed) {
                        krb5_set_error_string(context, "strupper_talloc: out of memory");
                        return ENOMEM;
@@ -1140,8 +1107,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
                        return ENOMEM;
                }
                principal = alloc_principal;
-               realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg_1[0], "nCName", NULL);
-               
+
                ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, 
                                           mem_ctx, 
                                           principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, realm_dn, &msg);
@@ -1154,7 +1120,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
                
                ret = LDB_message2entry(context, db, mem_ctx, 
                                        principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, 
-                                       msg[0], realm_ref_msg_1[0], entry_ex);
+                                       realm_dn, msg[0], entry_ex);
                if (ret != 0) {
                        krb5_warnx(context, "LDB_fetch: self krbtgt message2entry failed");     
                }
@@ -1163,7 +1129,6 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
        } else {
                enum trust_direction direction = UNKNOWN;
 
-               struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context);
                /* Either an inbound or outbound trust */
 
                if (strcasecmp(lp_realm(lp_ctx), principal->realm) == 0) {
@@ -1192,7 +1157,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
                
                ret = LDB_trust_message2entry(context, db, lp_ctx, mem_ctx, 
                                              principal, direction, 
-                                             msg[0], entry_ex);
+                                             realm_dn, msg[0], entry_ex);
                if (ret != 0) {
                        krb5_warnx(context, "LDB_fetch: trust_message2entry failed");   
                }
@@ -1214,13 +1179,12 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
        krb5_error_code ret;
        const char *realm;
        struct ldb_message **msg = NULL;
-       struct ldb_message **realm_ref_msg = NULL;
-       struct ldb_dn *partitions_basedn = samdb_partitions_dn(db->hdb_db, mem_ctx);
+       struct ldb_dn *realm_dn;
        if (principal->name.name_string.len >= 2) {
                /* 'normal server' case */
                int ldb_ret;
                NTSTATUS nt_status;
-               struct ldb_dn *user_dn, *domain_dn;
+               struct ldb_dn *user_dn;
                char *principal_string;
                
                ret = krb5_unparse_name_flags(context, principal, 
@@ -1235,7 +1199,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
                 * referral instead */
                nt_status = crack_service_principal_name((struct ldb_context *)db->hdb_db,
                                                         mem_ctx, principal_string, 
-                                                        &user_dn, &domain_dn);
+                                                        &user_dn, &realm_dn);
                free(principal_string);
                
                if (!NT_STATUS_IS_OK(nt_status)) {
@@ -1249,28 +1213,13 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
                        return HDB_ERR_NOENTRY;
                }
                
-               ldb_ret = gendb_search((struct ldb_context *)db->hdb_db,
-                                      mem_ctx, partitions_basedn, &realm_ref_msg, realm_ref_attrs, 
-                                      "ncName=%s", ldb_dn_get_linearized(domain_dn));
-               
-               if (ldb_ret != 1) {
-                       return HDB_ERR_NOENTRY;
-               }
-               
        } else {
-               struct ldb_dn *realm_dn;
                /* server as client principal case, but we must not lookup userPrincipalNames */
-
+               realm_dn = ldb_get_default_basedn((struct ldb_context *)db->hdb_db);
                realm = krb5_principal_get_realm(context, principal);
                
-               ret = LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, 
-                                      mem_ctx, realm, &realm_ref_msg);
-               if (ret != 0) {
-                       return HDB_ERR_NOENTRY;
-               }
-               
-               realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL);
-               
+               /* Check if it is our realm, otherwise give referall */
+
                ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, 
                                           mem_ctx, 
                                           principal, HDB_SAMBA4_ENT_TYPE_SERVER, realm_dn, &msg);
@@ -1282,7 +1231,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
 
        ret = LDB_message2entry(context, db, mem_ctx, 
                                principal, HDB_SAMBA4_ENT_TYPE_SERVER,
-                               msg[0], realm_ref_msg[0], entry_ex);
+                               realm_dn, msg[0], entry_ex);
        if (ret != 0) {
                krb5_warnx(context, "LDB_fetch: message2entry failed"); 
        }
@@ -1342,7 +1291,7 @@ struct hdb_ldb_seq {
        int index;
        int count;
        struct ldb_message **msgs;
-       struct ldb_message **realm_ref_msgs;
+       struct ldb_dn *realm_dn;
 };
 
 static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
@@ -1367,8 +1316,7 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd
        if (priv->index < priv->count) {
                ret = LDB_message2entry(context, db, mem_ctx, 
                                        NULL, HDB_SAMBA4_ENT_TYPE_ANY, 
-                                       priv->msgs[priv->index++], 
-                                       priv->realm_ref_msgs[0], entry);
+                                       priv->realm_dn, priv->msgs[priv->index++], entry);
        } else {
                ret = HDB_ERR_NOENTRY;
        }
@@ -1389,9 +1337,7 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
        struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db;
        struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc;
        char *realm;
-       struct ldb_dn *realm_dn = NULL;
        struct ldb_result *res = NULL;
-       struct ldb_message **realm_ref_msgs = NULL;
        krb5_error_code ret;
        TALLOC_CTX *mem_ctx;
        int lret;
@@ -1410,7 +1356,7 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
        priv->ctx = ldb_ctx;
        priv->index = 0;
        priv->msgs = NULL;
-       priv->realm_ref_msgs = NULL;
+       priv->realm_dn = ldb_get_default_basedn(ldb_ctx);
        priv->count = 0;
 
        mem_ctx = talloc_named(priv, 0, "LDB_firstkey context");
@@ -1426,23 +1372,8 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
                return ret;
        }
                
-       ret = LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, 
-                              mem_ctx, realm, &realm_ref_msgs);
-
-       free(realm);
-
-       if (ret != 0) {
-               talloc_free(priv);
-               krb5_warnx(context, "LDB_firstkey: could not find realm\n");
-               return HDB_ERR_NOENTRY;
-       }
-
-       realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msgs[0], "nCName", NULL);
-
-       priv->realm_ref_msgs = talloc_steal(priv, realm_ref_msgs);
-
        lret = ldb_search(ldb_ctx, priv, &res,
-                         realm_dn, LDB_SCOPE_SUBTREE, user_attrs,
+                         priv->realm_dn, LDB_SCOPE_SUBTREE, user_attrs,
                          "(objectClass=user)");
 
        if (lret != LDB_SUCCESS) {
index 417f327a57e19d718cf1b77896b4bd4a6b195d4f..a281e1d9c9ebea47fead2a448c16bb6df630394d 100644 (file)
@@ -55,8 +55,8 @@ struct kdc_server {
 struct hdb_ldb_private {
        struct ldb_context *samdb;
        struct smb_iconv_convenience *iconv_convenience;
+       struct loadparm_context *lp_ctx;
        struct ldb_message *msg;
-       struct ldb_message *realm_ref_msg;
+       struct ldb_dn *realm_dn;
        hdb_entry_ex *entry_ex;
-       const char *netbios_name;
 };
index 1a0df8e4a1b5cd09d45c8e6bb326716a6da0d1e8..411e752c04c2281b769af30ab1d455d81e1c2ab2 100644 (file)
@@ -3,7 +3,7 @@
 
    PAC Glue between Samba and the KDC
    
-   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2009
 
    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
@@ -29,6 +29,7 @@
 #include "auth/auth_sam.h"
 #include "auth/auth_sam_reply.h"
 #include "kdc/kdc.h"
+#include "param/param.h"
 
 struct krb5_dh_moduli;
 struct _krb5_krb_auth_data;
@@ -127,9 +128,10 @@ krb5_error_code samba_kdc_get_pac(void *priv,
        }
 
        nt_status = authsam_make_server_info(mem_ctx, p->samdb,
-                                            p->netbios_name,
+                                            lp_netbios_name(p->lp_ctx),
+                                            lp_sam_name(p->lp_ctx),
+                                            p->realm_dn,
                                             p->msg,
-                                            p->realm_ref_msg,
                                             data_blob(NULL, 0),
                                             data_blob(NULL, 0),
                                             &server_info);
@@ -274,8 +276,8 @@ krb5_error_code samba_kdc_check_client_access(void *priv,
        nt_status = authsam_account_ok(tmp_ctx, 
                                       p->samdb,
                                       MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT,
+                                      p->realm_dn,
                                       p->msg,
-                                      p->realm_ref_msg,
                                       workstation,
                                       name, true);
        free(name);
index e5c82280e3afa49f2c3791b0d3086e7f0cc4dfad..2ed37fde59dcae385c8524ff368f217c29b72fef 100644 (file)
@@ -45,33 +45,22 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
        struct nbt_name *name = &packet->data.msg.dest_name;
        struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false);
        struct nbt_netlogon_response_from_pdc *pdc;
-       const char *ref_attrs[] = {"nETBIOSName", NULL};
-       struct ldb_message **ref_res;
        struct ldb_context *samctx;
-       struct ldb_dn *partitions_basedn;
        struct nbt_netlogon_response netlogon_response;
-       int ret;
 
        /* only answer getdc requests on the PDC or LOGON names */
        if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) {
                return;
        }
 
-       samctx = iface->nbtsrv->sam_ctx;
-
-       if (!samdb_is_pdc(samctx)) {
+       if (lp_server_role(iface->nbtsrv->task->lp_ctx) != ROLE_DOMAIN_CONTROLLER
+           || !samdb_is_pdc(samctx)) {
                DEBUG(2, ("Not a PDC, so not processing LOGON_PRIMARY_QUERY\n"));
                return;         
        }
 
-       partitions_basedn = samdb_partitions_dn(samctx, packet);
-
-       ret = gendb_search(samctx, packet, partitions_basedn, &ref_res, ref_attrs,
-                          "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))", 
-                          name->name);
-       
-       if (ret != 1) {
-               DEBUG(2,("Unable to find domain reference '%s' in sam\n", name->name));
+       if (strcasecmp_m(name->name, lp_workgroup(iface->nbtsrv->task->lp_ctx)) != 0) {
+               DEBUG(5,("GetDC requested for a domian %s that we don't host\n", name->name));
                return;
        }
 
@@ -83,7 +72,7 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
        pdc->command = NETLOGON_RESPONSE_FROM_PDC;
        pdc->pdc_name         = lp_netbios_name(iface->nbtsrv->task->lp_ctx);
        pdc->unicode_pdc_name = pdc->pdc_name;
-       pdc->domain_name      = samdb_result_string(ref_res[0], "nETBIOSName", name->name);;
+       pdc->domain_name      = lp_workgroup(iface->nbtsrv->task->lp_ctx);
        pdc->nt_version       = 1;
        pdc->lmnt_token       = 0xFFFF;
        pdc->lm20_token       = 0xFFFF;
index d6f418e56815e7ac1bfffe305c06dd686cd69992..eeffe9874fa631d83a7a497aa3a3703139b7a574 100644 (file)
@@ -2725,3 +2725,4 @@ struct gensec_settings *lp_gensec_settings(TALLOC_CTX *mem_ctx, struct loadparm_
        settings->target_hostname = lp_parm_string(lp_ctx, NULL, "gensec", "target_hostname");
        return settings;
 }
+
index 3d257be062815a5079a27a81adfdf77eb1ae7e37..27bc32f9b959fd971eceb71ce2d3289bbf8683fa 100644 (file)
@@ -362,6 +362,9 @@ int param_write(struct param_context *ctx, const char *fn);
 bool lp_is_mydomain(struct loadparm_context *lp_ctx, 
                             const char *domain);
 
+bool lp_is_my_domain_or_realm(struct loadparm_context *lp_ctx, 
+                             const char *domain);
+
 /**
   see if a string matches either our primary or one of our secondary 
   netbios aliases. do a case insensitive match
@@ -434,6 +437,8 @@ const char *lp_messaging_path(TALLOC_CTX *mem_ctx,
 struct smb_iconv_convenience *smb_iconv_convenience_init_lp(TALLOC_CTX *mem_ctx,
                                                         struct loadparm_context *lp_ctx);
 
+const char *lp_sam_name(struct loadparm_context *lp_ctx);
+
 /* The following definitions come from lib/version.c  */
 
 const char *samba_version_string(void);
index 3881107cbcfed97a6cbf8e5d006ba23d90aef150..366c3f1d784cfd3926adc7c931ec67dc68b32ca9 100644 (file)
@@ -41,6 +41,13 @@ bool lp_is_mydomain(struct loadparm_context *lp_ctx,
        return strequal(lp_workgroup(lp_ctx), domain);
 }
 
+bool lp_is_my_domain_or_realm(struct loadparm_context *lp_ctx, 
+                            const char *domain)
+{
+       return strequal(lp_workgroup(lp_ctx), domain) || 
+               strequal(lp_realm(lp_ctx), domain);
+}
+
 /**
   see if a string matches either our primary or one of our secondary 
   netbios aliases. do a case insensitive match
@@ -296,3 +303,13 @@ struct smb_iconv_convenience *smb_iconv_convenience_init_lp(TALLOC_CTX *mem_ctx,
 }
 
 
+const char *lp_sam_name(struct loadparm_context *lp_ctx) 
+{
+       switch (lp_server_role(lp_ctx)) {
+       case ROLE_DOMAIN_CONTROLLER:
+               return lp_workgroup(lp_ctx);
+       default:
+               return lp_netbios_name(lp_ctx);
+       }
+}
+
index d05b0a0c0d2c332b43197c1f27ced2bfde355a88..dfc3d17bedef67a44f0dada4a11c3daf5f8ef24a 100644 (file)
@@ -129,7 +129,8 @@ PRIVATE_DEPENDENCIES = \
                DCERPC_COMMON \
                SCHANNELDB \
                NDR_NETLOGON \
-               auth_sam
+               auth_sam \
+               LIBSAMBA-HOSTCONFIG
 # End MODULE dcerpc_netlogon
 ################################################
 
index 8d8417109f8de0b008bf82494e7f3842abfc98b1..ae565a3ff16df0ff7c64ba0a9296b09d30fcfe35 100644 (file)
@@ -26,7 +26,6 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
                                     struct lsa_policy_state **_state)
 {
        struct lsa_policy_state *state;
-       struct ldb_dn *partitions_basedn;
        struct ldb_result *dom_res;
        const char *dom_attrs[] = {
                "objectSid", 
@@ -35,13 +34,7 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
                "fSMORoleOwner",
                NULL
        };
-       struct ldb_result *ref_res;
-       struct ldb_result *forest_ref_res;
-       const char *ref_attrs[] = {
-               "nETBIOSName",
-               "dnsRoot",
-               NULL
-       };
+       char *p;
        int ret;
 
        state = talloc(mem_ctx, struct lsa_policy_state);
@@ -55,11 +48,9 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
                return NT_STATUS_INVALID_SYSTEM_SERVICE;
        }
 
-       partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
-
        /* work out the domain_dn - useful for so many calls its worth
           fetching here */
-       state->domain_dn = samdb_base_dn(state->sam_ldb);
+       state->domain_dn = ldb_get_default_basedn(state->sam_ldb);
        if (!state->domain_dn) {
                return NT_STATUS_NO_MEMORY;             
        }
@@ -86,66 +77,30 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
        }
 
        state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
-       if (!state->domain_sid) {
-               return NT_STATUS_NO_SUCH_DOMAIN;                
-       }
 
        state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
        
        talloc_free(dom_res);
 
-       ret = ldb_search(state->sam_ldb, state, &ref_res,
-                                partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
-                                "(&(objectclass=crossRef)(ncName=%s))",
-                                ldb_dn_get_linearized(state->domain_dn));
-       
-       if (ret != LDB_SUCCESS) {
-               talloc_free(ref_res);
-               return NT_STATUS_INVALID_SYSTEM_SERVICE;
-       }
-       if (ref_res->count != 1) {
-               talloc_free(ref_res);
-               return NT_STATUS_NO_SUCH_DOMAIN;                
-       }
-
-       state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
-       if (!state->domain_name) {
-               talloc_free(ref_res);
-               return NT_STATUS_NO_SUCH_DOMAIN;                
-       }
-       talloc_steal(state, state->domain_name);
+       state->domain_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
 
-       state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
+       state->domain_dns = ldb_dn_canonical_string(state, state->domain_dn);
        if (!state->domain_dns) {
-               talloc_free(ref_res);
                return NT_STATUS_NO_SUCH_DOMAIN;                
        }
-       talloc_steal(state, state->domain_dns);
-
-       talloc_free(ref_res);
-
-       ret = ldb_search(state->sam_ldb, state, &forest_ref_res,
-                                partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
-                                "(&(objectclass=crossRef)(ncName=%s))",
-                                ldb_dn_get_linearized(state->forest_dn));
-       
-       if (ret != LDB_SUCCESS) {
-               talloc_free(forest_ref_res);
-               return NT_STATUS_INVALID_SYSTEM_SERVICE;
-       }
-       if (forest_ref_res->count != 1) {
-               talloc_free(forest_ref_res);
-               return NT_STATUS_NO_SUCH_DOMAIN;                
+       p = strchr(state->domain_dns, '/');
+       if (p) {
+               *p = '\0';
        }
 
-       state->forest_dns = ldb_msg_find_attr_as_string(forest_ref_res->msgs[0], "dnsRoot", NULL);
+       state->forest_dns = ldb_dn_canonical_string(state, state->forest_dn);
        if (!state->forest_dns) {
-               talloc_free(forest_ref_res);
                return NT_STATUS_NO_SUCH_DOMAIN;                
        }
-       talloc_steal(state, state->forest_dns);
-
-       talloc_free(forest_ref_res);
+       p = strchr(state->forest_dns, '/');
+       if (p) {
+               *p = '\0';
+       }
 
        /* work out the builtin_dn - useful for so many calls its worth
           fetching here */
index b17ab86e264fe496d465dd7432efef98c1835904..51849fc52e1ab36fc1d10dfa45851b2c8819f187 100644 (file)
@@ -1010,8 +1010,9 @@ static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TAL
   fill in a netr_DomainTrustInfo from a ldb search result
 */
 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
+                                      struct loadparm_context *lp_ctx,
+                                      struct ldb_context *sam_ctx,
                                       struct ldb_message *res,
-                                      struct ldb_message *ref_res,
                                       struct netr_DomainTrustInfo *info, 
                                       bool is_local, bool is_trust_list)
 {
@@ -1020,9 +1021,10 @@ static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
        info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
        info->trust_extension.length = 16;
        info->trust_extension.info->flags = 
-               NETR_TRUST_FLAG_TREEROOT | 
+               NETR_TRUST_FLAG_TREEROOT |
                NETR_TRUST_FLAG_IN_FOREST | 
                NETR_TRUST_FLAG_PRIMARY;
+
        info->trust_extension.info->parent_index = 0; /* should be index into array
                                                         of parent */
        info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
@@ -1032,13 +1034,21 @@ static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
                /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
                info->forest.string = NULL;
        } else {
+               char *p;
                /* TODO: we need a common function for pulling the forest */
-               info->forest.string = samdb_result_string(ref_res, "dnsRoot", NULL);
+               info->forest.string = ldb_dn_canonical_string(info, ldb_get_root_basedn(sam_ctx));
+               if (!info->forest.string) {
+                       return NT_STATUS_NO_SUCH_DOMAIN;                
+               }
+               p = strchr(info->forest.string, '/');
+               if (p) {
+                       *p = '\0';
+               }
        }
 
        if (is_local) {
-               info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
-               info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
+               info->domainname.string = lp_sam_name(lp_ctx);
+               info->fulldomainname.string = lp_realm(lp_ctx);
                info->guid = samdb_result_guid(res, "objectGUID");
                info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
        } else {
@@ -1064,13 +1074,11 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
        const char * const attrs[] = { "objectSid", 
                                       "objectGUID", "flatName", "securityIdentifier",
                                       "trustPartner", NULL };
-       const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
        struct ldb_context *sam_ctx;
-       struct ldb_message **res1, **res2, **ref_res;
+       struct ldb_message **res1, **res2;
        struct netr_DomainInfo1 *info1;
-       int ret, ret1, ret2, i;
+       int ret1, ret2, i;
        NTSTATUS status;
-       struct ldb_dn *partitions_basedn;
 
        const char *local_domain;
 
@@ -1090,8 +1098,6 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
                return NT_STATUS_INVALID_SYSTEM_SERVICE;
        }
 
-       partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
-
        /* we need to do two searches. The first will pull our primary
           domain and the second will pull any trusted domains. Our
           primary domain is also a "trusted" domain, so we need to
@@ -1103,15 +1109,7 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
        }
 
        /* try and find the domain */
-       ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, 
-                          &ref_res, ref_attrs, 
-                          "(&(objectClass=crossRef)(ncName=%s))", 
-                          ldb_dn_get_linearized(res1[0]->dn));
-       if (ret != 1) {
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       }
-
-       local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
+       local_domain = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
 
        ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
        if (ret2 == -1) {
@@ -1128,21 +1126,21 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
                                       info1->num_trusts);
        NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
 
-       status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, 
+       status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res1[0], &info1->domaininfo, 
                                        true, false);
        NT_STATUS_NOT_OK_RETURN(status);
 
        for (i=0;i<ret2;i++) {
-               status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], 
+               status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[i], &info1->trusts[i], 
                                                false, true);
                NT_STATUS_NOT_OK_RETURN(status);
        }
 
-       status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], 
+       status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res1[0], &info1->trusts[i], 
                                        true, true);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       info1->dns_hostname.string = samdb_result_string(ref_res[0], "dnsRoot", NULL);
+       info1->dns_hostname.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
        info1->workstation_flags = 
                NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | NETR_WS_FLAG_HANDLES_SPN_UPDATE;
        info1->supported_enc_types = 0; /* w2008 gives this 0 */
@@ -1191,7 +1189,7 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA
                                   struct netr_DsRGetDCNameEx2 *r)
 {
        const char * const attrs[] = { "objectGUID", NULL };
-       void *sam_ctx;
+       struct ldb_context *sam_ctx;
        struct ldb_message **res;
        struct ldb_dn *domain_dn;
        int ret;
@@ -1206,21 +1204,19 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA
 
        /* Win7-beta will send the domain name in the form the user typed, so we have to cope
           with both the short and long form here */
-       if (r->in.domain_name == NULL || strcasecmp(r->in.domain_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)) == 0) {
-               r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
+       if (r->in.domain_name != NULL && !lp_is_my_domain_or_realm(dce_call->conn->dce_ctx->lp_ctx, 
+                                                               r->in.domain_name)) {
+               return WERR_NO_SUCH_DOMAIN;
        }
 
-       domain_dn = samdb_dns_domain_to_dn((struct ldb_context *)sam_ctx,
-                                          mem_ctx,
-                                          r->in.domain_name);   
+       domain_dn = ldb_get_default_basedn(sam_ctx);
        if (domain_dn == NULL) {
                return WERR_DS_SERVICE_UNAVAILABLE;
        }
 
-       ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx,
+       ret = gendb_search_dn(sam_ctx, mem_ctx,
                              domain_dn, &res, attrs);
        if (ret != 1) {
-               return WERR_NO_SUCH_DOMAIN;
        }
 
        info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
@@ -1359,10 +1355,8 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
        struct netr_DomainTrustList *trusts;
        void *sam_ctx;
        int ret;
-       struct ldb_message **dom_res, **ref_res;
+       struct ldb_message **dom_res;
        const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
-       const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
-       struct ldb_dn *partitions_basedn;
 
        ZERO_STRUCT(r->out);
 
@@ -1371,9 +1365,6 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
                return WERR_GENERAL_FAILURE;
        }
 
-       partitions_basedn = samdb_partitions_dn((struct ldb_context *)sam_ctx,
-                                               mem_ctx);
-
        ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL,
                              &dom_res, dom_attrs);
        if (ret == -1) {
@@ -1383,17 +1374,6 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
                return WERR_GENERAL_FAILURE;
        }
 
-       ret = gendb_search((struct ldb_context *)sam_ctx, mem_ctx,
-                          partitions_basedn, &ref_res, ref_attrs,
-                          "(&(objectClass=crossRef)(ncName=%s))",
-                          ldb_dn_get_linearized(dom_res[0]->dn));
-       if (ret == -1) {
-               return WERR_GENERAL_FAILURE;
-       }
-       if (ret != 1) {
-               return WERR_GENERAL_FAILURE;
-       }
-
        trusts = talloc(mem_ctx, struct netr_DomainTrustList);
        W_ERROR_HAVE_NO_MEMORY(trusts);
 
@@ -1406,8 +1386,8 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
 
        /* TODO: add filtering by trust_flags, and correct trust_type
           and attributes */
-       trusts->array[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
-       trusts->array[0].dns_name     = samdb_result_string(ref_res[0], "dnsRoot", NULL);
+       trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
+       trusts->array[0].dns_name     = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
        trusts->array[0].trust_flags =
                NETR_TRUST_FLAG_TREEROOT | 
                NETR_TRUST_FLAG_IN_FOREST | 
index df23e11a67b553ae2f5d3217797a507d8981047a..fabc88d02df00418b3e8b8e27f5abb4fc6ee9a5e 100644 (file)
@@ -273,11 +273,8 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
        struct dcesrv_handle *h;
        struct dom_sid *sid;
        const char * const dom_attrs[] = { "objectSid", NULL};
-       const char * const ref_attrs[] = { "ncName", NULL};
        struct ldb_message **dom_msgs;
-       struct ldb_message **ref_msgs;
        int ret;
-       struct ldb_dn *partitions_basedn;
 
        *r->out.sid = NULL;
 
@@ -289,27 +286,17 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
-
        if (strcasecmp(r->in.domain_name->string, "BUILTIN") == 0) {
                ret = gendb_search(c_state->sam_ctx,
                                   mem_ctx, NULL, &dom_msgs, dom_attrs,
                                   "(objectClass=builtinDomain)");
-       } else {
-               ret = gendb_search(c_state->sam_ctx,
-                                  mem_ctx, partitions_basedn, &ref_msgs, ref_attrs,
-                                  "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))", 
-                                  ldb_binary_encode_string(mem_ctx, r->in.domain_name->string));
-               if (ret != 1) {
-                       return NT_STATUS_NO_SUCH_DOMAIN;
-               }
-               
-               ret = gendb_search_dn(c_state->sam_ctx, mem_ctx, 
-                                     samdb_result_dn(c_state->sam_ctx, mem_ctx,
-                                                     ref_msgs[0], "ncName", NULL), 
+       } else if (strcasecmp_m(r->in.domain_name->string, lp_sam_name(dce_call->conn->dce_ctx->lp_ctx)) == 0) {
+               ret = gendb_search_dn(c_state->sam_ctx,
+                                     mem_ctx, ldb_get_default_basedn(c_state->sam_ctx), 
                                      &dom_msgs, dom_attrs);
+       } else {
+               return NT_STATUS_NO_SUCH_DOMAIN;
        }
-
        if (ret != 1) {
                return NT_STATUS_NO_SUCH_DOMAIN;
        }
@@ -338,12 +325,7 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
        struct samr_connect_state *c_state;
        struct dcesrv_handle *h;
        struct samr_SamArray *array;
-       int i, start_i, ret;
-       const char * const dom_attrs[] = { "cn", NULL};
-       const char * const ref_attrs[] = { "nETBIOSName", NULL};
-       struct ldb_result *dom_res;
-       struct ldb_result *ref_res;
-       struct ldb_dn *partitions_basedn;
+       int i, start_i;
 
        *r->out.resume_handle = 0;
        *r->out.sam = NULL;
@@ -353,20 +335,11 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
 
        c_state = h->data;
 
-       partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
-
-       ret = ldb_search(c_state->sam_ctx, mem_ctx, &dom_res, ldb_get_default_basedn(c_state->sam_ctx),
-                                LDB_SCOPE_SUBTREE, dom_attrs, "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))");
-       if (ret != LDB_SUCCESS) {
-               DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       }
-
-       *r->out.resume_handle = dom_res->count;
+       *r->out.resume_handle = 2;
 
        start_i = *r->in.resume_handle;
 
-       if (start_i >= dom_res->count) {
+       if (start_i >= 2) {
                /* search past end of list is not an error for this call */
                return NT_STATUS_OK;
        }
@@ -379,27 +352,17 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
        array->count = 0;
        array->entries = NULL;
 
-       array->entries = talloc_array(mem_ctx, struct samr_SamEntry, dom_res->count - start_i);
+       array->entries = talloc_array(mem_ctx, struct samr_SamEntry, 2 - start_i);
        if (array->entries == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       for (i=0;i<dom_res->count-start_i;i++) {
+       for (i=0;i<2-start_i;i++) {
                array->entries[i].idx = start_i + i;
-               /* try and find the domain */
-               ret = ldb_search(c_state->sam_ctx, mem_ctx, &ref_res, partitions_basedn,
-                                        LDB_SCOPE_SUBTREE, ref_attrs, "(&(objectClass=crossRef)(ncName=%s))", 
-                                        ldb_dn_get_linearized(dom_res->msgs[i]->dn));
-
-               if (ret != LDB_SUCCESS) {
-                       DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
-                       return NT_STATUS_INTERNAL_DB_CORRUPTION;
-               }
-
-               if (ref_res->count == 1) {
-                       array->entries[i].name.string = samdb_result_string(ref_res->msgs[0], "nETBIOSName", NULL);
+               if (i == 0) {
+                       array->entries[i].name.string = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
                } else {
-                       array->entries[i].name.string = samdb_result_string(dom_res->msgs[i], "cn", NULL);
+                       array->entries[i].name.string = "BUILTIN";
                }
        }
 
@@ -418,15 +381,11 @@ static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLO
                                struct samr_OpenDomain *r)
 {
        struct dcesrv_handle *h_conn, *h_domain;
-       const char *domain_name;
        struct samr_connect_state *c_state;
        struct samr_domain_state *d_state;
        const char * const dom_attrs[] = { "cn", NULL};
-       const char * const ref_attrs[] = { "nETBIOSName", NULL};
        struct ldb_message **dom_msgs;
-       struct ldb_message **ref_msgs;
        int ret;
-       struct ldb_dn *partitions_basedn;
 
        ZERO_STRUCTP(r->out.domain_handle);
 
@@ -438,63 +397,44 @@ static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLO
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
+       d_state = talloc(c_state, struct samr_domain_state);
+       if (!d_state) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       d_state->domain_sid = talloc_steal(d_state, r->in.sid);
+
+       if (dom_sid_equal(d_state->domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
+               d_state->builtin = true;
+               d_state->domain_name = "BUILTIN";
+       } else {
+               d_state->builtin = false;
+               d_state->domain_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
+       }
 
        ret = gendb_search(c_state->sam_ctx,
-                          mem_ctx, NULL, &dom_msgs, dom_attrs,
-                          "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))", 
+                          mem_ctx, ldb_get_default_basedn(c_state->sam_ctx), &dom_msgs, dom_attrs,
+                          "(objectSid=%s)", 
                           ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid));
+       
        if (ret == 0) {
+               talloc_free(d_state);
                return NT_STATUS_NO_SUCH_DOMAIN;
        } else if (ret > 1) {
+               talloc_free(d_state);
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        } else if (ret == -1) {
+               talloc_free(d_state);
                DEBUG(1, ("Failed to open domain %s: %s\n", dom_sid_string(mem_ctx, r->in.sid), ldb_errstring(c_state->sam_ctx)));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       } else {
-               ret = gendb_search(c_state->sam_ctx,
-                                  mem_ctx, partitions_basedn, &ref_msgs, ref_attrs,
-                                  "(&(&(nETBIOSName=*)(objectclass=crossRef))(ncName=%s))", 
-                                  ldb_dn_get_linearized(dom_msgs[0]->dn));
-               if (ret == 0) {
-                       domain_name = ldb_msg_find_attr_as_string(dom_msgs[0], "cn", NULL);
-                       if (domain_name == NULL) {
-                               return NT_STATUS_NO_SUCH_DOMAIN;
-                       }
-               } else if (ret == 1) {
-               
-                       domain_name = ldb_msg_find_attr_as_string(ref_msgs[0], "nETBIOSName", NULL);
-                       if (domain_name == NULL) {
-                               return NT_STATUS_NO_SUCH_DOMAIN;
-                       }
-               } else {
-                       return NT_STATUS_NO_SUCH_DOMAIN;
-               }
-       }
-
-       d_state = talloc(c_state, struct samr_domain_state);
-       if (!d_state) {
-               return NT_STATUS_NO_MEMORY;
        }
 
+       d_state->domain_dn = talloc_steal(d_state, dom_msgs[0]->dn);
        d_state->role = lp_server_role(dce_call->conn->dce_ctx->lp_ctx);
        d_state->connect_state = talloc_reference(d_state, c_state);
        d_state->sam_ctx = c_state->sam_ctx;
-       d_state->domain_sid = dom_sid_dup(d_state, r->in.sid);
-       d_state->domain_name = talloc_strdup(d_state, domain_name);
-       d_state->domain_dn = ldb_dn_copy(d_state, dom_msgs[0]->dn);
-       if (!d_state->domain_sid || !d_state->domain_name || !d_state->domain_dn) {
-               talloc_free(d_state);
-               return NT_STATUS_NO_MEMORY;             
-       }
        d_state->access_mask = r->in.access_mask;
 
-       if (dom_sid_equal(d_state->domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
-               d_state->builtin = true;
-       } else {
-               d_state->builtin = false;
-       }
-
        d_state->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
 
        h_domain = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_DOMAIN);