diff options
author | Andrew Bartlett <abartlet@samba.org> | 2008-05-17 20:53:29 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2008-05-17 20:53:29 +1000 |
commit | fd0d47b746be322b60fca29c1daa13e72b360e62 (patch) | |
tree | 4f8cb55d4a4a001001b2397284800f7cfe8e0645 | |
parent | 24264e9acb12938f666bcdfc92ee4f9ed6409112 (diff) | |
download | samba-fd0d47b746be322b60fca29c1daa13e72b360e62.tar.gz samba-fd0d47b746be322b60fca29c1daa13e72b360e62.tar.bz2 samba-fd0d47b746be322b60fca29c1daa13e72b360e62.zip |
Handle netbios domains in the CLDAP server too.
This commit also fixes a number of issues found by the NBT-DGRAM and
LDAP-CLDAP tests.
Andrew Bartlett
(This used to be commit 8f99a4b94e95f8bde0f80f92d4e57020c62cfaab)
-rw-r--r-- | source4/cldap_server/netlogon.c | 72 | ||||
-rw-r--r-- | source4/nbt_server/dgram/netlogon.c | 17 |
2 files changed, 78 insertions, 11 deletions
diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index b59a54ade7..b2a034d5a4 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -42,6 +42,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, const char *domain, + const char *netbios_domain, struct dom_sid *domain_sid, const char *domain_guid, const char *user, @@ -114,6 +115,45 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, } } + if (netbios_domain) { + struct ldb_dn *dom_dn; + /* try and find the domain */ + + ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &ref_res, + partitions_basedn, LDB_SCOPE_ONELEVEL, + ref_attrs, + "(&(objectClass=crossRef)(ncName=*)(nETBIOSName=%s))", + netbios_domain); + + if (ret != LDB_SUCCESS) { + DEBUG(2,("Unable to find referece to '%s' in sam: %s\n", + netbios_domain, + ldb_errstring(sam_ctx))); + return NT_STATUS_NO_SUCH_DOMAIN; + } else if (ref_res->count == 1) { + talloc_steal(mem_ctx, dom_res); + 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, dom_dn, + LDB_SCOPE_BASE, "objectClass=domain", + dom_attrs, &dom_res); + 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; + } + talloc_steal(mem_ctx, dom_res); + 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 ((dom_res == NULL || dom_res->count == 0) && (domain_guid || domain_sid)) { ref_res = NULL; @@ -211,11 +251,16 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, ZERO_STRUCTP(netlogon); if (version & NETLOGON_NT_VERSION_5EX) { - uint32_t extra_flags; + uint32_t extra_flags = 0; netlogon->ntver = NETLOGON_NT_VERSION_5EX; /* could check if the user exists */ - netlogon->nt5_ex.command = LOGON_SAM_LOGON_RESPONSE_EX; + if (!user) { + user = ""; + netlogon->nt5_ex.command = LOGON_SAM_LOGON_RESPONSE_EX; + } else { + netlogon->nt5_ex.command = LOGON_SAM_LOGON_USER_UNKNOWN_EX; + } netlogon->nt5_ex.server_type = server_type; netlogon->nt5_ex.domain_uuid = domain_uuid; netlogon->nt5_ex.forest = realm; @@ -232,8 +277,9 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, extra_flags = NETLOGON_NT_VERSION_5EX_WITH_IP; netlogon->nt5_ex.sockaddr.sa_family = 2; netlogon->nt5_ex.sockaddr.pdc_ip = pdc_ip; + netlogon->nt5_ex.sockaddr.remaining = data_blob(NULL, 4); } - netlogon->nt5_ex.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5|extra_flags; + netlogon->nt5_ex.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5EX|extra_flags; netlogon->nt5_ex.lmnt_token = 0xFFFF; netlogon->nt5_ex.lm20_token = 0xFFFF; @@ -241,7 +287,12 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, netlogon->ntver = NETLOGON_NT_VERSION_5; /* could check if the user exists */ - netlogon->nt5.command = LOGON_SAM_LOGON_RESPONSE; + if (!user) { + user = ""; + netlogon->nt5.command = LOGON_SAM_LOGON_RESPONSE; + } else { + netlogon->nt5.command = LOGON_SAM_LOGON_USER_UNKNOWN; + } netlogon->nt5.pdc_name = pdc_name; netlogon->nt5.user_name = user; netlogon->nt5.domain_name = flatname; @@ -254,17 +305,22 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, netlogon->nt5.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5; netlogon->nt5.lmnt_token = 0xFFFF; netlogon->nt5.lm20_token = 0xFFFF; - } else { + + } else /* (version & NETLOGON_NT_VERSION_1) and all other cases */ { netlogon->ntver = NETLOGON_NT_VERSION_1; /* could check if the user exists */ - netlogon->nt4.command = LOGON_SAM_LOGON_RESPONSE; + if (!user) { + user = ""; + netlogon->nt4.command = LOGON_SAM_LOGON_RESPONSE; + } else { + netlogon->nt4.command = LOGON_SAM_LOGON_USER_UNKNOWN; + } netlogon->nt4.server = pdc_name; netlogon->nt4.user_name = user; netlogon->nt4.domain = flatname; netlogon->nt4.nt_version = NETLOGON_NT_VERSION_1; netlogon->nt4.lmnt_token = 0xFFFF; netlogon->nt4.lm20_token = 0xFFFF; - } return NT_STATUS_OK; @@ -349,7 +405,7 @@ void cldapd_netlogon_request(struct cldap_socket *cldap, DEBUG(5,("cldap netlogon query domain=%s host=%s user=%s version=%d guid=%s\n", domain, host, user, version, domain_guid)); - status = fill_netlogon_samlogon_response(cldapd->samctx, tmp_ctx, domain, NULL, domain_guid, + status = fill_netlogon_samlogon_response(cldapd->samctx, tmp_ctx, domain, NULL, NULL, domain_guid, user, src->addr, version, cldapd->task->lp_ctx, &netlogon); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/nbt_server/dgram/netlogon.c b/source4/nbt_server/dgram/netlogon.c index ae24a7cd2b..c66089523b 100644 --- a/source4/nbt_server/dgram/netlogon.c +++ b/source4/nbt_server/dgram/netlogon.c @@ -30,6 +30,7 @@ #include "param/param.h" #include "smbd/service_task.h" #include "cldap_server/cldap_server.h" +#include "libcli/security/security.h" /* reply to a GETDC request @@ -51,8 +52,8 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, struct nbt_netlogon_response netlogon_response; int ret; - /* only answer getdc requests on the PDC name */ - if (name->type != NBT_NAME_PDC) { + /* only answer getdc requests on the PDC or LOGON names */ + if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) { return; } @@ -62,6 +63,11 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, return; } + if (!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, @@ -130,6 +136,7 @@ static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot, if (netlogon->req.logon.sid_size) { if (strcasecmp(mailslot_name, NBT_MAILSLOT_NTLOGON) == 0) { + DEBUG(2,("NBT netlogon query failed because SID specified in request to NTLOGON\n")); /* SID not permitted on NTLOGON (for some reason...) */ return; } @@ -138,13 +145,17 @@ static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot, sid = NULL; } - status = fill_netlogon_samlogon_response(samctx, packet, name->name, sid, NULL, + status = fill_netlogon_samlogon_response(samctx, packet, NULL, name->name, sid, NULL, netlogon->req.logon.user_name, src->addr, netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.samlogon); if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("NBT netlogon query failed domain=%s sid=%s version=%d - %s\n", + name->name, dom_sid_string(packet, sid), netlogon->req.logon.nt_version, nt_errstr(status))); return; } + netlogon_response.response_type = NETLOGON_SAMLOGON; + packet->data.msg.dest_name.type = 0; dgram_mailslot_netlogon_reply(reply_iface->dgmsock, |