summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2008-05-17 20:53:29 +1000
committerAndrew Bartlett <abartlet@samba.org>2008-05-17 20:53:29 +1000
commitfd0d47b746be322b60fca29c1daa13e72b360e62 (patch)
tree4f8cb55d4a4a001001b2397284800f7cfe8e0645
parent24264e9acb12938f666bcdfc92ee4f9ed6409112 (diff)
downloadsamba-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.c72
-rw-r--r--source4/nbt_server/dgram/netlogon.c17
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,