summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/cldap_server/netlogon.c249
-rw-r--r--source4/lib/ldb/tools/ad2oLschema.c4
-rw-r--r--source4/libcli/cldap/cldap.c35
-rw-r--r--source4/libcli/cldap/cldap.h7
-rw-r--r--source4/libcli/config.mk13
-rw-r--r--source4/libcli/dgram/dgramsocket.c2
-rw-r--r--source4/libcli/dgram/libdgram.h35
-rw-r--r--source4/libcli/dgram/netlogon.c45
-rw-r--r--source4/libcli/dgram/ntlogon.c128
-rw-r--r--source4/libnet/libnet_become_dc.c24
-rw-r--r--source4/libnet/libnet_site.c7
-rw-r--r--source4/libnet/libnet_unbecome_dc.c21
-rw-r--r--source4/librpc/config.mk2
-rw-r--r--source4/librpc/idl/nbt.idl326
-rw-r--r--source4/nbt_server/config.mk2
-rw-r--r--source4/nbt_server/dgram/browse.c1
-rw-r--r--source4/nbt_server/dgram/netlogon.c153
-rw-r--r--source4/nbt_server/dgram/request.c4
-rw-r--r--source4/nbt_server/irpc.c82
-rw-r--r--source4/setup/provision-backend.js188
-rw-r--r--source4/torture/ldap/cldap.c75
-rw-r--r--source4/torture/nbt/dgram.c146
-rw-r--r--source4/torture/rpc/dssync.c7
23 files changed, 635 insertions, 921 deletions
diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c
index a524a6f8bd..b2a034d5a4 100644
--- a/source4/cldap_server/netlogon.c
+++ b/source4/cldap_server/netlogon.c
@@ -4,6 +4,7 @@
CLDAP server - netlogon handling
Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
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
@@ -28,25 +29,27 @@
#include "cldap_server/cldap_server.h"
#include "librpc/gen_ndr/ndr_misc.h"
#include "libcli/ldap/ldap_ndr.h"
+#include "libcli/security/security.h"
#include "dsdb/samdb/samdb.h"
#include "auth/auth.h"
#include "ldb_wrap.h"
#include "system/network.h"
#include "lib/socket/netif.h"
#include "param/param.h"
-
/*
fill in the cldap netlogon union for a given version
*/
-static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd,
- TALLOC_CTX *mem_ctx,
- const char *domain,
- const char *domain_guid,
- const char *user,
- const char *src_address,
- uint32_t version,
- struct loadparm_context *lp_ctx,
- union nbt_cldap_netlogon *netlogon)
+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,
+ const char *src_address,
+ uint32_t version,
+ struct loadparm_context *lp_ctx,
+ struct netlogon_samlogon_response *netlogon)
{
const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL};
const char *dom_attrs[] = {"objectGUID", NULL};
@@ -66,7 +69,7 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd,
struct ldb_dn *partitions_basedn;
struct interface *ifaces;
- partitions_basedn = samdb_partitions_dn(cldapd->samctx, mem_ctx);
+ partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
/* the domain has an optional trailing . */
if (domain && domain[strlen(domain)-1] == '.') {
@@ -77,7 +80,7 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd,
struct ldb_dn *dom_dn;
/* try and find the domain */
- ret = ldb_search_exp_fmt(cldapd->samctx, mem_ctx, &ref_res,
+ ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &ref_res,
partitions_basedn, LDB_SCOPE_ONELEVEL,
ref_attrs,
"(&(&(objectClass=crossRef)(dnsRoot=%s))(nETBIOSName=*))",
@@ -86,19 +89,19 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd,
if (ret != LDB_SUCCESS) {
DEBUG(2,("Unable to find referece to '%s' in sam: %s\n",
domain,
- ldb_errstring(cldapd->samctx)));
+ 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(cldapd->samctx, mem_ctx, ref_res->msgs[0], "ncName");
+ 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(cldapd->samctx, dom_dn,
+ 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(cldapd->samctx)));
+ 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);
@@ -112,23 +115,70 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd,
}
}
- if ((dom_res == NULL || dom_res->count == 0) && domain_guid) {
+ 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;
- ret = ldb_search_exp_fmt(cldapd->samctx, mem_ctx, &dom_res,
- NULL, LDB_SCOPE_SUBTREE,
- dom_attrs,
- "(&(objectClass=domainDNS)(objectGUID=%s))",
- domain_guid);
+ if (domain_guid) {
+ ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &dom_res,
+ NULL, LDB_SCOPE_SUBTREE,
+ dom_attrs,
+ "(&(objectClass=domainDNS)(objectGUID=%s))",
+ domain_guid);
+ } else { /* domain_sid case */
+ ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &dom_res,
+ NULL, LDB_SCOPE_SUBTREE,
+ dom_attrs,
+ "(&(objectClass=domainDNS)(objectSID=%s))",
+ dom_sid_string(mem_ctx, domain_sid));
+ }
if (ret != LDB_SUCCESS) {
- DEBUG(2,("Unable to find referece to GUID '%s' in sam: %s\n",
- domain_guid,
- ldb_errstring(cldapd->samctx)));
+ DEBUG(2,("Unable to find referece to GUID '%s' or SID %s in sam: %s\n",
+ domain_guid, dom_sid_string(mem_ctx, domain_sid),
+ ldb_errstring(sam_ctx)));
return NT_STATUS_NO_SUCH_DOMAIN;
} else if (dom_res->count == 1) {
/* try and find the domain */
- ret = ldb_search_exp_fmt(cldapd->samctx, mem_ctx, &ref_res,
+ ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &ref_res,
partitions_basedn, LDB_SCOPE_ONELEVEL,
ref_attrs,
"(&(objectClass=crossRef)(ncName=%s))",
@@ -137,7 +187,7 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd,
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(cldapd->samctx)));
+ ldb_errstring(sam_ctx)));
return NT_STATUS_NO_SUCH_DOMAIN;
} else if (ref_res->count != 1) {
@@ -166,11 +216,11 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd,
NBT_SERVER_CLOSEST | NBT_SERVER_WRITABLE |
NBT_SERVER_GOOD_TIMESERV;
- if (samdb_is_pdc(cldapd->samctx)) {
+ if (samdb_is_pdc(sam_ctx)) {
server_type |= NBT_SERVER_PDC;
}
- if (samdb_is_gc(cldapd->samctx)) {
+ if (samdb_is_gc(sam_ctx)) {
server_type |= NBT_SERVER_GC;
}
@@ -200,68 +250,77 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd,
ZERO_STRUCTP(netlogon);
- switch (version & 0xF) {
- case 0:
- case 1:
- netlogon->logon1.type = (user?19+2:19);
- netlogon->logon1.pdc_name = pdc_name;
- netlogon->logon1.user_name = user;
- netlogon->logon1.domain_name = flatname;
- netlogon->logon1.nt_version = 1;
- netlogon->logon1.lmnt_token = 0xFFFF;
- netlogon->logon1.lm20_token = 0xFFFF;
- break;
- case 2:
- case 3:
- netlogon->logon3.type = (user?19+2:19);
- netlogon->logon3.pdc_name = pdc_name;
- netlogon->logon3.user_name = user;
- netlogon->logon3.domain_name = flatname;
- netlogon->logon3.domain_uuid = domain_uuid;
- netlogon->logon3.forest = realm;
- netlogon->logon3.dns_domain = dns_domain;
- netlogon->logon3.pdc_dns_name = pdc_dns_name;
- netlogon->logon3.pdc_ip = pdc_ip;
- netlogon->logon3.server_type = server_type;
- netlogon->logon3.lmnt_token = 0xFFFF;
- netlogon->logon3.lm20_token = 0xFFFF;
- break;
- case 4:
- case 5:
- case 6:
- case 7:
- netlogon->logon5.type = (user?NETLOGON_RESPONSE_FROM_PDC_USER:NETLOGON_RESPONSE_FROM_PDC2);
- netlogon->logon5.server_type = server_type;
- netlogon->logon5.domain_uuid = domain_uuid;
- netlogon->logon5.forest = realm;
- netlogon->logon5.dns_domain = dns_domain;
- netlogon->logon5.pdc_dns_name = pdc_dns_name;
- netlogon->logon5.domain = flatname;
- netlogon->logon5.pdc_name = lp_netbios_name(lp_ctx);
- netlogon->logon5.user_name = user;
- netlogon->logon5.server_site = server_site;
- netlogon->logon5.client_site = client_site;
- netlogon->logon5.lmnt_token = 0xFFFF;
- netlogon->logon5.lm20_token = 0xFFFF;
- break;
- default:
- netlogon->logon13.type = (user?NETLOGON_RESPONSE_FROM_PDC_USER:NETLOGON_RESPONSE_FROM_PDC2);
- netlogon->logon13.server_type = server_type;
- netlogon->logon13.domain_uuid = domain_uuid;
- netlogon->logon13.forest = realm;
- netlogon->logon13.dns_domain = dns_domain;
- netlogon->logon13.pdc_dns_name = pdc_dns_name;
- netlogon->logon13.domain = flatname;
- netlogon->logon13.pdc_name = lp_netbios_name(lp_ctx);
- netlogon->logon13.user_name = user;
- netlogon->logon13.server_site = server_site;
- netlogon->logon13.client_site = client_site;
- netlogon->logon13.unknown = 10;
- netlogon->logon13.unknown2 = 2;
- netlogon->logon13.pdc_ip = pdc_ip;
- netlogon->logon13.lmnt_token = 0xFFFF;
- netlogon->logon13.lm20_token = 0xFFFF;
- break;
+ if (version & NETLOGON_NT_VERSION_5EX) {
+ uint32_t extra_flags = 0;
+ netlogon->ntver = NETLOGON_NT_VERSION_5EX;
+
+ /* could check if the user exists */
+ 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;
+ netlogon->nt5_ex.dns_domain = dns_domain;
+ netlogon->nt5_ex.pdc_dns_name = pdc_dns_name;
+ netlogon->nt5_ex.domain = flatname;
+ netlogon->nt5_ex.pdc_name = lp_netbios_name(lp_ctx);
+ netlogon->nt5_ex.user_name = user;
+ netlogon->nt5_ex.server_site = server_site;
+ netlogon->nt5_ex.client_site = client_site;
+
+ if (version & NETLOGON_NT_VERSION_5EX_WITH_IP) {
+ /* Clearly this needs to be fixed up for IPv6 */
+ 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_5EX|extra_flags;
+ netlogon->nt5_ex.lmnt_token = 0xFFFF;
+ netlogon->nt5_ex.lm20_token = 0xFFFF;
+
+ } else if (version & NETLOGON_NT_VERSION_5) {
+ netlogon->ntver = NETLOGON_NT_VERSION_5;
+
+ /* could check if the user exists */
+ 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;
+ netlogon->nt5.domain_uuid = domain_uuid;
+ netlogon->nt5.forest = realm;
+ netlogon->nt5.dns_domain = dns_domain;
+ netlogon->nt5.pdc_dns_name = pdc_dns_name;
+ netlogon->nt5.pdc_ip = pdc_ip;
+ netlogon->nt5.server_type = server_type;
+ netlogon->nt5.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5;
+ netlogon->nt5.lmnt_token = 0xFFFF;
+ netlogon->nt5.lm20_token = 0xFFFF;
+
+ } else /* (version & NETLOGON_NT_VERSION_1) and all other cases */ {
+ netlogon->ntver = NETLOGON_NT_VERSION_1;
+ /* could check if the user exists */
+ 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;
@@ -285,7 +344,7 @@ void cldapd_netlogon_request(struct cldap_socket *cldap,
const char *domain_sid = NULL;
int acct_control = -1;
int version = -1;
- union nbt_cldap_netlogon netlogon;
+ struct netlogon_samlogon_response netlogon;
NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
TALLOC_CTX *tmp_ctx = talloc_new(cldap);
@@ -346,9 +405,9 @@ 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 = cldapd_netlogon_fill(cldapd, tmp_ctx, domain, domain_guid,
- user, src->addr,
- version, cldapd->task->lp_ctx, &netlogon);
+ 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)) {
goto failed;
}
diff --git a/source4/lib/ldb/tools/ad2oLschema.c b/source4/lib/ldb/tools/ad2oLschema.c
index 67b16dd06e..0a89656fa2 100644
--- a/source4/lib/ldb/tools/ad2oLschema.c
+++ b/source4/lib/ldb/tools/ad2oLschema.c
@@ -429,7 +429,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
/* We might have been asked to remap this oid,
* due to a conflict, or lack of
* implementation */
- for (j=0; syntax_oid && oid_map[j].old_oid; j++) {
+ for (j=0; syntax_oid && oid_map && oid_map[j].old_oid; j++) {
if (strcasecmp(syntax_oid, oid_map[j].old_oid) == 0) {
syntax_oid = oid_map[j].new_oid;
break;
@@ -494,7 +494,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
}
/* We might have been asked to remap this oid, due to a conflict */
- for (j=0; oid_map[j].old_oid; j++) {
+ for (j=0; oid_map && oid_map[j].old_oid; j++) {
if (strcasecmp(oid, oid_map[j].old_oid) == 0) {
oid = oid_map[j].new_oid;
break;
diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c
index 614bd51d2a..3867f3d3fd 100644
--- a/source4/libcli/cldap/cldap.c
+++ b/source4/libcli/cldap/cldap.c
@@ -595,7 +595,6 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req,
struct cldap_netlogon *io)
{
NTSTATUS status;
- enum ndr_err_code ndr_err;
struct cldap_search search;
struct cldap_socket *cldap;
DATA_BLOB *data;
@@ -618,18 +617,15 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req,
}
data = search.out.response->attributes[0].values;
- ndr_err = ndr_pull_union_blob_all(data, mem_ctx,
- cldap->iconv_convenience,
- &io->out.netlogon,
- io->in.version & 0xF,
- (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(2,("cldap failed to parse netlogon response of type 0x%02x\n",
- SVAL(data->data, 0)));
- dump_data(10, data->data, data->length);
- return ndr_map_error2ntstatus(ndr_err);
+ status = pull_netlogon_samlogon_response(data, mem_ctx, req->cldap->iconv_convenience,
+ &io->out.netlogon);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (io->in.map_response) {
+ map_netlogon_samlogon_response(&io->out.netlogon);
}
-
return NT_STATUS_OK;
}
@@ -704,25 +700,20 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap,
uint32_t message_id,
struct socket_address *src,
uint32_t version,
- union nbt_cldap_netlogon *netlogon)
+ struct netlogon_samlogon_response *netlogon)
{
NTSTATUS status;
- enum ndr_err_code ndr_err;
struct cldap_reply reply;
struct ldap_SearchResEntry response;
struct ldap_Result result;
TALLOC_CTX *tmp_ctx = talloc_new(cldap);
DATA_BLOB blob;
- ndr_err = ndr_push_union_blob(&blob, tmp_ctx,
- cldap->iconv_convenience,
- netlogon, version & 0xF,
- (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(tmp_ctx);
- return ndr_map_error2ntstatus(ndr_err);
- }
+ status = push_netlogon_samlogon_response(&blob, tmp_ctx, cldap->iconv_convenience,
+ netlogon);
+ if (!NT_STATUS_IS_OK(status)) {
+ }
reply.messageid = message_id;
reply.dest = src;
reply.response = &response;
diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h
index eb0191d0f4..7c2daf0ca2 100644
--- a/source4/libcli/cldap/cldap.h
+++ b/source4/libcli/cldap/cldap.h
@@ -20,7 +20,7 @@
*/
#include "lib/util/asn1.h"
-#include "librpc/gen_ndr/nbt.h"
+#include "libcli/netlogon.h"
struct ldap_message;
@@ -161,9 +161,10 @@ struct cldap_netlogon {
const char *domain_sid;
int acct_control;
uint32_t version;
+ bool map_response;
} in;
struct {
- union nbt_cldap_netlogon netlogon;
+ struct netlogon_samlogon_response netlogon;
} out;
};
@@ -178,4 +179,4 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap,
uint32_t message_id,
struct socket_address *src,
uint32_t version,
- union nbt_cldap_netlogon *netlogon);
+ struct netlogon_samlogon_response *netlogon);
diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk
index 95b45003be..08c08043a6 100644
--- a/source4/libcli/config.mk
+++ b/source4/libcli/config.mk
@@ -53,6 +53,14 @@ LIBCLI_NBT_OBJ_FILES = $(addprefix libcli/nbt/, \
namerefresh.o \
namerelease.o)
+[SUBSYSTEM::LIBCLI_NETLOGON]
+PRIVATE_PROTO_HEADER = netlogon_proto.h
+PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT \
+ NDR_SECURITY LIBSAMBA-UTIL
+
+LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \
+ netlogon.o)
+
[PYTHON::python_libcli_nbt]
SWIG_FILE = swig/libcli_nbt.i
PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG
@@ -66,18 +74,17 @@ PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG
python_libcli_smb_OBJ_FILES = libcli/swig/libcli_smb_wrap.o
[SUBSYSTEM::LIBCLI_DGRAM]
-PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE
+PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE LIBCLI_NETLOGON
LIBCLI_DGRAM_OBJ_FILES = $(addprefix libcli/dgram/, \
dgramsocket.o \
mailslot.o \
netlogon.o \
- ntlogon.o \
browse.o)
[SUBSYSTEM::LIBCLI_CLDAP]
PUBLIC_DEPENDENCIES = LIBCLI_LDAP
-PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB
+PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB LIBCLI_NETLOGON
LIBCLI_CLDAP_OBJ_FILES = libcli/cldap/cldap.o
# PUBLIC_HEADERS += libcli/cldap/cldap.h
diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c
index 06b7bd5771..2cdda654ef 100644
--- a/source4/libcli/dgram/dgramsocket.c
+++ b/source4/libcli/dgram/dgramsocket.c
@@ -88,7 +88,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock)
struct dgram_mailslot_handler *dgmslot;
dgmslot = dgram_mailslot_find(dgmsock, mailslot_name);
if (dgmslot) {
- dgmslot->handler(dgmslot, packet, src);
+ dgmslot->handler(dgmslot, packet, mailslot_name, src);
} else {
DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name));
}
diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h
index 707cca8cc5..51408d029e 100644
--- a/source4/libcli/dgram/libdgram.h
+++ b/source4/libcli/dgram/libdgram.h
@@ -19,7 +19,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "librpc/gen_ndr/nbt.h"
+#include "libcli/netlogon.h"
/*
a datagram name request
@@ -70,6 +70,7 @@ struct nbt_dgram_socket {
typedef void (*dgram_mailslot_handler_t)(struct dgram_mailslot_handler *,
struct nbt_dgram_packet *,
+ const char *mailslot_name,
struct socket_address *src);
struct dgram_mailslot_handler {
@@ -121,33 +122,23 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock,
NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock,
struct nbt_name *dest_name,
struct socket_address *dest,
+ const char *mailslot_name,
struct nbt_name *src_name,
struct nbt_netlogon_packet *request);
NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock,
struct nbt_dgram_packet *request,
const char *my_netbios_name,
const char *mailslot_name,
- struct nbt_netlogon_packet *reply);
-NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot,
- TALLOC_CTX *mem_ctx,
- struct nbt_dgram_packet *dgram,
- struct nbt_netlogon_packet *netlogon);
-
-NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock,
- enum dgram_msg_type msg_type,
- struct nbt_name *dest_name,
- struct socket_address *dest,
- struct nbt_name *src_name,
- struct nbt_ntlogon_packet *request);
-NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock,
- struct nbt_dgram_packet *request,
- const char *my_netbios_name,
- const char *mailslot_name,
- struct nbt_ntlogon_packet *reply);
-NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot,
- TALLOC_CTX *mem_ctx,
- struct nbt_dgram_packet *dgram,
- struct nbt_ntlogon_packet *ntlogon);
+ struct nbt_netlogon_response *reply);
+NTSTATUS dgram_mailslot_netlogon_parse_request(struct dgram_mailslot_handler *dgmslot,
+ TALLOC_CTX *mem_ctx,
+ struct nbt_dgram_packet *dgram,
+ struct nbt_netlogon_packet *netlogon);
+
+NTSTATUS dgram_mailslot_netlogon_parse_response(struct dgram_mailslot_handler *dgmslot,
+ TALLOC_CTX *mem_ctx,
+ struct nbt_dgram_packet *dgram,
+ struct nbt_netlogon_response *netlogon);
NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock,
struct nbt_name *dest_name,
diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c
index 5c7dedc7bb..b37d4a2ee6 100644
--- a/source4/libcli/dgram/netlogon.c
+++ b/source4/libcli/dgram/netlogon.c
@@ -32,6 +32,7 @@
NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock,
struct nbt_name *dest_name,
struct socket_address *dest,
+ const char *mailslot,
struct nbt_name *src_name,
struct nbt_netlogon_packet *request)
{
@@ -51,7 +52,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock,
status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE,
- NBT_MAILSLOT_NETLOGON,
+ mailslot,
dest_name, dest,
src_name, &blob);
talloc_free(tmp_ctx);
@@ -66,22 +67,18 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock,
struct nbt_dgram_packet *request,
const char *my_netbios_name,
const char *mailslot_name,
- struct nbt_netlogon_packet *reply)
+ struct nbt_netlogon_response *reply)
{
NTSTATUS status;
- enum ndr_err_code ndr_err;
DATA_BLOB blob;
TALLOC_CTX *tmp_ctx = talloc_new(dgmsock);
struct nbt_name myname;
struct socket_address *dest;
- ndr_err = ndr_push_struct_blob(&blob, tmp_ctx,
- dgmsock->iconv_convenience,
- reply,
- (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(tmp_ctx);
- return ndr_map_error2ntstatus(ndr_err);
+ status = push_nbt_netlogon_response(&blob, tmp_ctx, dgmsock->iconv_convenience,
+ reply);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
make_nbt_name_client(&myname, my_netbios_name);
@@ -106,10 +103,10 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock,
/*
parse a netlogon response. The packet must be a valid mailslot packet
*/
-NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot,
- TALLOC_CTX *mem_ctx,
- struct nbt_dgram_packet *dgram,
- struct nbt_netlogon_packet *netlogon)
+NTSTATUS dgram_mailslot_netlogon_parse_request(struct dgram_mailslot_handler *dgmslot,
+ TALLOC_CTX *mem_ctx,
+ struct nbt_dgram_packet *dgram,
+ struct nbt_netlogon_packet *netlogon)
{
DATA_BLOB data = dgram_mailslot_data(dgram);
enum ndr_err_code ndr_err;
@@ -127,3 +124,23 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot,
}
return NT_STATUS_OK;
}
+
+/*
+ parse a netlogon response. The packet must be a valid mailslot packet
+*/
+NTSTATUS dgram_mailslot_netlogon_parse_response(struct dgram_mailslot_handler *dgmslot,
+ TALLOC_CTX *mem_ctx,
+ struct nbt_dgram_packet *dgram,
+ struct nbt_netlogon_response *netlogon)
+{
+ NTSTATUS status;
+ DATA_BLOB data = dgram_mailslot_data(dgram);
+
+ status = pull_nbt_netlogon_response(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ return NT_STATUS_OK;
+}
+
diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c
deleted file mode 100644
index 7b26ed7c00..0000000000
--- a/source4/libcli/dgram/ntlogon.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- handling for ntlogon dgram requests
-
- Copyright (C) Andrew Tridgell 2005
-
- 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
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "libcli/dgram/libdgram.h"
-#include "lib/socket/socket.h"
-#include "libcli/resolve/resolve.h"
-#include "librpc/gen_ndr/ndr_nbt.h"
-#include "param/param.h"
-
-/*
- send a ntlogon mailslot request
-*/
-NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock,
- enum dgram_msg_type msg_type,
- struct nbt_name *dest_name,
- struct socket_address *dest,
- struct nbt_name *src_name,
- struct nbt_ntlogon_packet *request)
-{
- NTSTATUS status;
- enum ndr_err_code ndr_err;
- DATA_BLOB blob;
- TALLOC_CTX *tmp_ctx = talloc_new(dgmsock);
-
- ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience,
- request,
- (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(tmp_ctx);
- return ndr_map_error2ntstatus(ndr_err);
- }
-
-
- status = dgram_mailslot_send(dgmsock, msg_type,
- NBT_MAILSLOT_NTLOGON,
- dest_name, dest,
- src_name, &blob);
- talloc_free(tmp_ctx);
- return status;
-}
-
-
-/*
- send a ntlogon mailslot reply
-*/
-NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock,
- struct nbt_dgram_packet *request,
- const char *my_netbios_name,
- const char *mailslot_name,
- struct nbt_ntlogon_packet *reply)
-{
- NTSTATUS status;
- enum ndr_err_code ndr_err;
- DATA_BLOB blob;
- TALLOC_CTX *tmp_ctx = talloc_new(dgmsock);
- struct nbt_name myname;
- struct socket_address *dest;
-
- ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, reply,
- (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(tmp_ctx);
- return ndr_map_error2ntstatus(ndr_err);
- }
-
- make_nbt_name_client(&myname, my_netbios_name);
-
- dest = socket_address_from_strings(tmp_ctx,
- dgmsock->sock->backend_name,
- request->src_addr, request->src_port);
- if (!dest) {
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE,
- mailslot_name,
- &request->data.msg.source_name,
- dest,
- &myname, &blob);
- talloc_free(tmp_ctx);
- return status;
-}
-
-
-/*
- parse a ntlogon response. The packet must be a valid mailslot packet
-*/
-NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot,
- TALLOC_CTX *mem_ctx,
- struct nbt_dgram_packet *dgram,
- struct nbt_ntlogon_packet *ntlogon)
-{
- DATA_BLOB data = dgram_mailslot_data(dgram);
- enum ndr_err_code ndr_err;
-
- ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, ntlogon,
- (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
- DEBUG(0,("Failed to parse ntlogon packet of length %d: %s\n",
- (int)data.length, nt_errstr(status)));
- if (DEBUGLVL(10)) {
- file_save("ntlogon.dat", data.data, data.length);
- }
- return status;
- }
- return NT_STATUS_OK;
-}
diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c
index e8a5329985..1c4c1d0732 100644
--- a/source4/libnet/libnet_become_dc.c
+++ b/source4/libnet/libnet_become_dc.c
@@ -30,6 +30,7 @@
#include "libcli/security/security.h"
#include "librpc/gen_ndr/ndr_misc.h"
#include "librpc/gen_ndr/ndr_security.h"
+#include "librpc/gen_ndr/ndr_nbt.h"
#include "librpc/gen_ndr/ndr_drsuapi.h"
#include "auth/gensec/gensec.h"
#include "param/param.h"
@@ -687,7 +688,7 @@ struct libnet_BecomeDC_state {
struct {
struct cldap_socket *sock;
struct cldap_netlogon io;
- struct nbt_cldap_netlogon_5 netlogon5;
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX netlogon;
} cldap;
struct becomeDC_ldap {
@@ -745,7 +746,8 @@ static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
s->cldap.io.in.domain_guid = NULL;
s->cldap.io.in.domain_sid = NULL;
s->cldap.io.in.acct_control = -1;
- s->cldap.io.in.version = 6;
+ s->cldap.io.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
+ s->cldap.io.in.map_response = true;
s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx,
lp_iconv_convenience(s->libnet->lp_ctx));
@@ -768,19 +770,19 @@ static void becomeDC_recv_cldap(struct cldap_request *req)
c->status = cldap_netlogon_recv(req, s, &s->cldap.io);
if (!composite_is_ok(c)) return;
- s->cldap.netlogon5 = s->cldap.io.out.netlogon.logon5;
+ s->cldap.netlogon = s->cldap.io.out.netlogon.nt5_ex;
- s->domain.dns_name = s->cldap.netlogon5.dns_domain;
- s->domain.netbios_name = s->cldap.netlogon5.domain;
- s->domain.guid = s->cldap.netlogon5.domain_uuid;
+ s->domain.dns_name = s->cldap.netlogon.dns_domain;
+ s->domain.netbios_name = s->cldap.netlogon.domain;
+ s->domain.guid = s->cldap.netlogon.domain_uuid;
- s->forest.dns_name = s->cldap.netlogon5.forest;
+ s->forest.dns_name = s->cldap.netlogon.forest;
- s->source_dsa.dns_name = s->cldap.netlogon5.pdc_dns_name;
- s->source_dsa.netbios_name = s->cldap.netlogon5.pdc_name;
- s->source_dsa.site_name = s->cldap.netlogon5.server_site;
+ s->source_dsa.dns_name = s->cldap.netlogon.pdc_dns_name;
+ s->source_dsa.netbios_name = s->cldap.netlogon.pdc_name;
+ s->source_dsa.site_name = s->cldap.netlogon.server_site;
- s->dest_dsa.site_name = s->cldap.netlogon5.client_site;
+ s->dest_dsa.site_name = s->cldap.netlogon.client_site;
becomeDC_connect_ldap1(s);
}
diff --git a/source4/libnet/libnet_site.c b/source4/libnet/libnet_site.c
index f39d9e039c..bb65de1f54 100644
--- a/source4/libnet/libnet_site.c
+++ b/source4/libnet/libnet_site.c
@@ -53,11 +53,12 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_context *lctx, struct li
search.in.dest_address = r->in.dest_address;
search.in.dest_port = r->in.cldap_port;
search.in.acct_control = -1;
- search.in.version = 6;
+ search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
+ search.in.map_response = true;
cldap = cldap_socket_init(tmp_ctx, lctx->event_ctx, lp_iconv_convenience(global_loadparm));
status = cldap_netlogon(cldap, tmp_ctx, &search);
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(status) || !search.out.netlogon.nt5_ex.client_site) {
/*
If cldap_netlogon() returns in error,
default to using Default-First-Site-Name.
@@ -71,7 +72,7 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_context *lctx, struct li
}
} else {
site_name_str = talloc_asprintf(tmp_ctx, "%s",
- search.out.netlogon.logon5.client_site);
+ search.out.netlogon.nt5_ex.client_site);
if (!site_name_str) {
r->out.error_string = NULL;
talloc_free(tmp_ctx);
diff --git a/source4/libnet/libnet_unbecome_dc.c b/source4/libnet/libnet_unbecome_dc.c
index 6f06585880..cff919018a 100644
--- a/source4/libnet/libnet_unbecome_dc.c
+++ b/source4/libnet/libnet_unbecome_dc.c
@@ -193,7 +193,7 @@ struct libnet_UnbecomeDC_state {
struct {
struct cldap_socket *sock;
struct cldap_netlogon io;
- struct nbt_cldap_netlogon_5 netlogon5;
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX netlogon;
} cldap;
struct {
@@ -265,7 +265,8 @@ static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s)
s->cldap.io.in.domain_guid = NULL;
s->cldap.io.in.domain_sid = NULL;
s->cldap.io.in.acct_control = -1;
- s->cldap.io.in.version = 6;
+ s->cldap.io.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
+ s->cldap.io.in.map_response = true;
s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx,
lp_iconv_convenience(s->libnet->lp_ctx));
@@ -288,17 +289,17 @@ static void unbecomeDC_recv_cldap(struct cldap_request *req)
c->status = cldap_netlogon_recv(req, s, &s->cldap.io);
if (!composite_is_ok(c)) return;
- s->cldap.netlogon5 = s->cldap.io.out.netlogon.logon5;
+ s->cldap.netlogon = s->cldap.io.out.netlogon.nt5_ex;
- s->domain.dns_name = s->cldap.netlogon5.dns_domain;
- s->domain.netbios_name = s->cldap.netlogon5.domain;
- s->domain.guid = s->cldap.netlogon5.domain_uuid;
+ s->domain.dns_name = s->cldap.netlogon.dns_domain;
+ s->domain.netbios_name = s->cldap.netlogon.domain;
+ s->domain.guid = s->cldap.netlogon.domain_uuid;
- s->source_dsa.dns_name = s->cldap.netlogon5.pdc_dns_name;
- s->source_dsa.netbios_name = s->cldap.netlogon5.pdc_name;
- s->source_dsa.site_name = s->cldap.netlogon5.server_site;
+ s->source_dsa.dns_name = s->cldap.netlogon.pdc_dns_name;
+ s->source_dsa.netbios_name = s->cldap.netlogon.pdc_name;
+ s->source_dsa.site_name = s->cldap.netlogon.server_site;
- s->dest_dsa.site_name = s->cldap.netlogon5.client_site;
+ s->dest_dsa.site_name = s->cldap.netlogon.client_site;
unbecomeDC_connect_ldap(s);
}
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index 24fad8c9c4..0b136644d8 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -325,7 +325,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT
NDR_SCHANNEL_OBJ_FILES = librpc/gen_ndr/ndr_schannel.o
[SUBSYSTEM::NDR_NBT]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY
+PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR
NDR_NBT_OBJ_FILES = librpc/gen_ndr/ndr_nbt.o
diff --git a/source4/librpc/idl/nbt.idl b/source4/librpc/idl/nbt.idl
index dddfa4e1ce..e6af2cd035 100644
--- a/source4/librpc/idl/nbt.idl
+++ b/source4/librpc/idl/nbt.idl
@@ -8,7 +8,7 @@
encoding if it doesn't work out
*/
-import "misc.idl", "security.idl", "svcctl.idl";
+import "misc.idl", "security.idl", "svcctl.idl", "samr.idl";
[
helper("libcli/nbt/libnbt.h")
]
@@ -338,52 +338,19 @@ interface nbt
} nbt_dgram_packet;
- /*******************************************/
- /* \MAILSLOT\NET\NETLOGON mailslot requests */
- typedef enum {
- NETLOGON_QUERY_FOR_PDC = 0x7,
- NETLOGON_ANNOUNCE_UAS = 0xa,
- NETLOGON_RESPONSE_FROM_PDC = 0xc,
- NETLOGON_QUERY_FOR_PDC2 = 0x12,
- NETLOGON_RESPONSE_FROM_PDC2 = 0x17,
- NETLOGON_RESPONSE_FROM_PDC_USER = 0x19
- } nbt_netlogon_command;
-
- /* query for pdc request */
- typedef struct {
- astring computer_name;
- astring mailslot_name;
- [flag(NDR_ALIGN2)] DATA_BLOB _pad;
- nstring unicode_name;
- uint32 nt_version;
- uint16 lmnt_token;
- uint16 lm20_token;
- } nbt_netlogon_query_for_pdc;
-
- /* query for pdc request - new style */
- typedef struct {
- uint16 request_count;
- nstring computer_name;
- nstring user_name;
- astring mailslot_name;
- uint32 unknown[2];
- uint32 nt_version;
- uint16 lmnt_token;
- uint16 lm20_token;
- } nbt_netlogon_query_for_pdc2;
+ /******************************************
+ * \MAILSLOT\NET\NETLOGON mailslot requests
+ * and
+ * \MAILSLOT\NET\NTLOGON mailslot requests
+ */
- /* response from pdc */
- typedef struct {
- astring pdc_name;
- [flag(NDR_ALIGN2)] DATA_BLOB _pad;
- nstring unicode_pdc_name;
- nstring domain_name;
- uint32 nt_version;
- uint16 lmnt_token;
- uint16 lm20_token;
- } nbt_netlogon_response_from_pdc;
+ typedef [public,gensize] struct {
+ uint32 sa_family;
+ [flag(NDR_BIG_ENDIAN)] ipv4address pdc_ip;
+ [flag(NDR_REMAINING)] DATA_BLOB remaining;
+ } nbt_sockaddr;
- typedef [bitmap32bit] bitmap {
+ typedef [bitmap32bit,public] bitmap {
NBT_SERVER_PDC = 0x00000001,
NBT_SERVER_GC = 0x00000004,
NBT_SERVER_LDAP = 0x00000008,
@@ -395,107 +362,82 @@ interface nbt
NBT_SERVER_GOOD_TIMESERV = 0x00000200
} nbt_server_type;
- /* response from pdc - type2 */
- typedef struct {
- [flag(NDR_ALIGN4)] DATA_BLOB _pad;
- nbt_server_type server_type;
- GUID domain_uuid;
- nbt_string forest;
- nbt_string dns_domain;
- nbt_string pdc_dns_name;
- nbt_string domain;
- nbt_string pdc_name;
- nbt_string user_name;
- nbt_string server_site;
- nbt_string client_site;
- uint8 unknown;
- uint32 unknown2;
- [flag(NDR_BIG_ENDIAN)]
- ipv4address pdc_ip;
- uint32 unknown3[2];
- uint32 nt_version;
- uint16 lmnt_token;
- uint16 lm20_token;
- } nbt_netlogon_response_from_pdc2;
-
- typedef enum netr_SamDatabaseID netr_SamDatabaseID;
-
- /* announce change to UAS or SAM */
- typedef struct {
- netr_SamDatabaseID db_index;
- hyper serial;
- NTTIME timestamp;
- } nbt_db_change;
+ typedef [bitmap32bit,public] bitmap {
+ NETLOGON_NT_VERSION_1 = 0x00000001,
+ NETLOGON_NT_VERSION_5 = 0x00000002,
+ NETLOGON_NT_VERSION_5EX = 0x00000004,
+ NETLOGON_NT_VERSION_5EX_WITH_IP = 0x00000008,
+ NETLOGON_NT_VERSION_WITH_CLOSEST_SITE = 0x00000010,
+ NETLOGON_NT_VERSION_AVIOD_NT4EMUL = 0x01000000,
+ NETLOGON_NT_VERSION_PDC = 0x10000000,
+ NETLOGON_NT_VERSION_IP = 0x20000000,
+ NETLOGON_NT_VERSION_LOCAL = 0x40000000,
+ NETLOGON_NT_VERSION_GC = 0x80000000
+ } netlogon_nt_version_flags;
+
+
+ typedef [enum16bit,public] enum {
+ LOGON_PRIMARY_QUERY = 7, /* Was also NETLOGON_QUERY_FOR_PDC */
+ NETLOGON_ANNOUNCE_UAS = 10,
+ NETLOGON_RESPONSE_FROM_PDC = 12,
+ LOGON_SAM_LOGON_REQUEST = 18, /* Was also NETLOGON_QUERY_FOR_PDC2, NTLOGON_SAM_LOGON */
+ LOGON_SAM_LOGON_RESPONSE = 19, /* Was also NTLOGON_SAM_LOGON_REPLY */
+ LOGON_SAM_LOGON_PAUSE_RESPONSE = 20,
+ LOGON_SAM_LOGON_USER_UNKNOWN = 21, /* Was also NTLOGON_SAM_LOGON_REPLY15 */
+ LOGON_SAM_LOGON_RESPONSE_EX = 23, /* was NETLOGON_RESPONSE_FROM_PDC2 */
+ LOGON_SAM_LOGON_PAUSE_RESPONSE_EX = 24,
+ LOGON_SAM_LOGON_USER_UNKNOWN_EX = 25 /* was NETLOGON_RESPONSE_FROM_PDC_USER */
+ } netlogon_command;
+
+ typedef bitmap samr_AcctFlags samr_AcctFlags;
- /* used to announce SAM changes */
typedef struct {
- uint32 serial_lo;
- time_t timestamp;
- uint32 pulse;
- uint32 random;
- astring pdc_name;
- astring domain;
- [flag(NDR_ALIGN2)] DATA_BLOB _pad;
- nstring unicode_pdc_name;
- nstring unicode_domain;
- uint32 db_count;
- nbt_db_change dbchange[db_count];
+ uint16 request_count;
+ nstring computer_name;
+ nstring user_name;
+ astring mailslot_name;
+ samr_AcctFlags acct_control;
[value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size;
+ /* Must not be present (ie, zero size, in request to \MAILSLOT\NET\NTLOGON */
[subcontext(0),subcontext_size(sid_size)] dom_sid0 sid;
- uint32 nt_version;
- uint16 lmnt_token;
- uint16 lm20_token;
- } nbt_netlogon_announce_uas;
-
- typedef [nodiscriminant] union {
- [case(NETLOGON_QUERY_FOR_PDC)] nbt_netlogon_query_for_pdc pdc;
- [case(NETLOGON_QUERY_FOR_PDC2)] nbt_netlogon_query_for_pdc2 pdc2;
- [case(NETLOGON_ANNOUNCE_UAS)] nbt_netlogon_announce_uas uas;
- [case(NETLOGON_RESPONSE_FROM_PDC)] nbt_netlogon_response_from_pdc response;
- [case(NETLOGON_RESPONSE_FROM_PDC2)] nbt_netlogon_response_from_pdc2 response2;
- [case(NETLOGON_RESPONSE_FROM_PDC_USER)] nbt_netlogon_response_from_pdc2 response2;
- } nbt_netlogon_request;
+ netlogon_nt_version_flags nt_version;
+ uint16 lmnt_token;
+ uint16 lm20_token;
+ } NETLOGON_SAM_LOGON_REQUEST;
typedef [flag(NDR_NOALIGN),public] struct {
- nbt_netlogon_command command;
- [switch_is(command)] nbt_netlogon_request req;
- } nbt_netlogon_packet;
-
- /*******************************************/
- /* CLDAP netlogon response */
-
- /* note that these structures are very similar to, but not
- quite identical to, the netlogon structures above */
-
- typedef struct {
- uint16 type;
- nstring pdc_name;
+ netlogon_command command;
+ nstring server;
nstring user_name;
- nstring domain_name;
- [value(1)] uint32 nt_version;
+ nstring domain;
+ netlogon_nt_version_flags nt_version;
uint16 lmnt_token;
- uint16 lm20_token;
- } nbt_cldap_netlogon_1;
+ uint16 lm20_token;
+ } NETLOGON_SAM_LOGON_RESPONSE_NT40;
- typedef struct {
- uint16 type;
+ typedef [flag(NDR_NOALIGN),public] struct {
+ netlogon_command command;
nstring pdc_name;
nstring user_name;
nstring domain_name;
GUID domain_uuid;
- GUID unknown_uuid;
+ GUID zero_uuid;
nbt_string forest;
nbt_string dns_domain;
nbt_string pdc_dns_name;
ipv4address pdc_ip;
nbt_server_type server_type;
- [value(3)] uint32 nt_version;
+ netlogon_nt_version_flags nt_version;
uint16 lmnt_token;
uint16 lm20_token;
- } nbt_cldap_netlogon_3;
+ } NETLOGON_SAM_LOGON_RESPONSE;
- typedef struct {
- uint32 type;
+ /* response from pdc hand marshaled (we have an additional
+ * function that uses this structure), as it has 'optional'
+ * parts */
+ typedef [flag(NDR_NOALIGN),public] struct {
+ netlogon_command command;
+ uint16 sbz; /* From the docs */
nbt_server_type server_type;
GUID domain_uuid;
nbt_string forest;
@@ -506,85 +448,91 @@ interface nbt
nbt_string user_name;
nbt_string server_site;
nbt_string client_site;
- [value(5)] uint32 nt_version;
- uint16 lmnt_token;
- uint16 lm20_token;
- } nbt_cldap_netlogon_5;
- typedef struct {
- uint32 type;
- nbt_server_type server_type;
- GUID domain_uuid;
- nbt_string forest;
- nbt_string dns_domain;
- nbt_string pdc_dns_name;
- nbt_string domain;
- nbt_string pdc_name;
- nbt_string user_name;
- nbt_string server_site;
- nbt_string client_site;
- uint8 unknown;
- uint32 unknown2;
- [flag(NDR_BIG_ENDIAN)]
- ipv4address pdc_ip;
- uint32 unknown3[2];
- [value(13)] uint32 nt_version;
+ /* Optional on NETLOGON_NT_VERSION_5EX_WITH_IP */
+ [value(ndr_size_nbt_sockaddr(&sockaddr, ndr->flags))] uint8 sockaddr_size;
+ [subcontext(0),subcontext_size(sockaddr_size)] nbt_sockaddr sockaddr;
+
+ /* Optional on NETLOGON_NT_VERSION_WITH_CLOSEST_SITE */
+ nbt_string next_closest_site;
+
+ netlogon_nt_version_flags nt_version;
uint16 lmnt_token;
uint16 lm20_token;
- } nbt_cldap_netlogon_13;
-
- typedef [flag(NDR_NOALIGN),public,nodiscriminant] union {
- [case(0)] nbt_cldap_netlogon_1 logon1;
- [case(1)] nbt_cldap_netlogon_1 logon1;
- [case(2)] nbt_cldap_netlogon_3 logon3;
- [case(3)] nbt_cldap_netlogon_3 logon3;
- [case(4)] nbt_cldap_netlogon_5 logon5;
- [case(5)] nbt_cldap_netlogon_5 logon5;
- [case(6)] nbt_cldap_netlogon_5 logon5;
- [case(7)] nbt_cldap_netlogon_5 logon5;
- [default] nbt_cldap_netlogon_13 logon13;
- } nbt_cldap_netlogon;
-
- /*******************************************/
- /* \MAILSLOT\NET\NTLOGON mailslot requests */
- typedef enum {
- NTLOGON_SAM_LOGON = 0x12,
- NTLOGON_SAM_LOGON_REPLY = 0x13,
- NTLOGON_SAM_LOGON_REPLY15 = 0x15
- } nbt_ntlogon_command;
+ } NETLOGON_SAM_LOGON_RESPONSE_EX;
+ /* query for pdc request */
typedef struct {
- uint16 request_count;
- nstring computer_name;
- nstring user_name;
+ astring computer_name;
astring mailslot_name;
- uint32 acct_control;
- [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size;
- [subcontext(0),subcontext_size(sid_size)] dom_sid0 sid;
- uint32 nt_version;
+ [flag(NDR_ALIGN2)] DATA_BLOB _pad;
+ nstring unicode_name;
+ netlogon_nt_version_flags nt_version;
uint16 lmnt_token;
uint16 lm20_token;
- } nbt_ntlogon_sam_logon;
+ } nbt_netlogon_query_for_pdc;
- typedef struct {
- nstring server;
- nstring user_name;
- nstring domain;
- uint32 nt_version;
+ /* response from pdc */
+ typedef [flag(NDR_NOALIGN),public] struct {
+ netlogon_command command;
+ astring pdc_name;
+ [flag(NDR_ALIGN2)] DATA_BLOB _pad;
+ nstring unicode_pdc_name;
+ nstring domain_name;
+ netlogon_nt_version_flags nt_version;
uint16 lmnt_token;
uint16 lm20_token;
- } nbt_ntlogon_sam_logon_reply;
+ } nbt_netlogon_response_from_pdc;
+
+ typedef enum netr_SamDatabaseID netr_SamDatabaseID;
+
+ /* used to announce SAM changes - MS-NRPC 2.2.1.5.1 */
+ typedef struct {
+ netr_SamDatabaseID db_index;
+ hyper serial;
+ NTTIME timestamp;
+ } nbt_db_change_info;
+
+ typedef struct {
+ uint32 serial_lo;
+ time_t timestamp;
+ uint32 pulse;
+ uint32 random;
+ astring pdc_name;
+ astring domain;
+ [flag(NDR_ALIGN2)] DATA_BLOB _pad;
+ nstring unicode_pdc_name;
+ nstring unicode_domain;
+ uint32 db_count;
+ nbt_db_change_info dbchange[db_count];
+ [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size;
+ [subcontext(0),subcontext_size(sid_size)] dom_sid0 sid;
+ uint32 message_format_version;
+ uint32 message_token;
+ } NETLOGON_DB_CHANGE;
typedef [nodiscriminant] union {
- [case(NTLOGON_SAM_LOGON)] nbt_ntlogon_sam_logon logon;
- [case(NTLOGON_SAM_LOGON_REPLY)] nbt_ntlogon_sam_logon_reply reply;
- [case(NTLOGON_SAM_LOGON_REPLY15)] nbt_ntlogon_sam_logon_reply reply;
- } nbt_ntlogon_request;
+ [case(LOGON_SAM_LOGON_REQUEST)] NETLOGON_SAM_LOGON_REQUEST logon;
+ [case(LOGON_PRIMARY_QUERY)] nbt_netlogon_query_for_pdc pdc;
+ [case(NETLOGON_ANNOUNCE_UAS)] NETLOGON_DB_CHANGE uas;
+ } nbt_netlogon_request;
+
+#if 0
+ [case(NETLOGON_RESPONSE_FROM_PDC)] nbt_netlogon_response_from_pdc response;
+ [case(NETLOGON_RESPONSE_FROM_PDC_USER)] nbt_netlogon_response_from_pdc2 response2;
+
+ [case(LOGON_SAM_LOGON_PAUSE_RESPONSE)] NETLOGON_SAM_LOGON_RESPONSE reply;
+ [case(LOGON_SAM_LOGON_RESPONSE)] NETLOGON_SAM_LOGON_RESPONSE reply;
+ [case(LOGON_SAM_LOGON_USER_UNKNOWN)] NETLOGON_SAM_LOGON_RESPONSE reply;
+ [case(LOGON_SAM_LOGON_RESPONSE_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex;
+ [case(LOGON_SAM_LOGON_PAUSE_RESPONSE_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex;
+ [case(LOGON_SAM_LOGON_USER_UNKNOWN_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex;
+#endif
typedef [flag(NDR_NOALIGN),public] struct {
- nbt_ntlogon_command command;
- [switch_is(command)] nbt_ntlogon_request req;
- } nbt_ntlogon_packet;
+ netlogon_command command;
+ [switch_is(command)] nbt_netlogon_request req;
+ } nbt_netlogon_packet;
/********************************************************/
/* \MAILSLOT\BROWSE mailslot requests */
diff --git a/source4/nbt_server/config.mk b/source4/nbt_server/config.mk
index 84e6b661bf..eb1aea65d7 100644
--- a/source4/nbt_server/config.mk
+++ b/source4/nbt_server/config.mk
@@ -44,7 +44,7 @@ PRIVATE_DEPENDENCIES = \
# End SUBSYSTEM NBTD_DGRAM
#######################
-NBTD_DGRAM_OBJ_FILES = $(addprefix nbt_server/dgram/, request.o netlogon.o ntlogon.o browse.o)
+NBTD_DGRAM_OBJ_FILES = $(addprefix nbt_server/dgram/, request.o netlogon.o browse.o)
#######################
# Start SUBSYSTEM NBTD
diff --git a/source4/nbt_server/dgram/browse.c b/source4/nbt_server/dgram/browse.c
index 2e12fa114a..36f0160e1b 100644
--- a/source4/nbt_server/dgram/browse.c
+++ b/source4/nbt_server/dgram/browse.c
@@ -49,6 +49,7 @@ static const char *nbt_browse_opcode_string(enum nbt_browse_opcode r)
*/
void nbtd_mailslot_browse_handler(struct dgram_mailslot_handler *dgmslot,
struct nbt_dgram_packet *packet,
+ const char *mailslot_name,
struct socket_address *src)
{
struct nbt_browse_packet *browse = talloc(dgmslot, struct nbt_browse_packet);
diff --git a/source4/nbt_server/dgram/netlogon.c b/source4/nbt_server/dgram/netlogon.c
index 7fae6bc1f6..c66089523b 100644
--- a/source4/nbt_server/dgram/netlogon.c
+++ b/source4/nbt_server/dgram/netlogon.c
@@ -4,7 +4,8 @@
NBT datagram netlogon server
Copyright (C) Andrew Tridgell 2005
-
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
+
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
the Free Software Foundation; either version 3 of the License, or
@@ -26,9 +27,10 @@
#include "dsdb/samdb/samdb.h"
#include "auth/auth.h"
#include "util/util_ldb.h"
-#include "librpc/gen_ndr/ndr_nbt.h"
#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
@@ -36,17 +38,18 @@
static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
struct nbtd_interface *iface,
struct nbt_dgram_packet *packet,
+ const char *mailslot_name,
const struct socket_address *src,
struct nbt_netlogon_packet *netlogon)
{
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_packet reply;
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 */
@@ -60,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,
@@ -72,10 +80,11 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
}
/* setup a GETDC reply */
- ZERO_STRUCT(reply);
- reply.command = NETLOGON_RESPONSE_FROM_PDC;
- pdc = &reply.req.response;
+ ZERO_STRUCT(netlogon_response);
+ netlogon_response.response_type = NETLOGON_GET_PDC;
+ pdc = &netlogon_response.get_pdc;
+ 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);;
@@ -83,38 +92,32 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
pdc->lmnt_token = 0xFFFF;
pdc->lm20_token = 0xFFFF;
-
- packet->data.msg.dest_name.type = 0;
-
dgram_mailslot_netlogon_reply(reply_iface->dgmsock,
packet,
lp_netbios_name(iface->nbtsrv->task->lp_ctx),
netlogon->req.pdc.mailslot_name,
- &reply);
+ &netlogon_response);
}
/*
reply to a ADS style GETDC request
*/
-static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot,
- struct nbtd_interface *iface,
- struct nbt_dgram_packet *packet,
- const struct socket_address *src,
- struct nbt_netlogon_packet *netlogon)
+static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot,
+ struct nbtd_interface *iface,
+ struct nbt_dgram_packet *packet,
+ const char *mailslot_name,
+ const struct socket_address *src,
+ struct nbt_netlogon_packet *netlogon)
{
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_packet reply;
- struct nbt_netlogon_response_from_pdc2 *pdc;
struct ldb_context *samctx;
- const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL};
- const char *dom_attrs[] = {"objectGUID", NULL};
- struct ldb_message **ref_res, **dom_res;
- int ret;
- const char **services = lp_server_services(iface->nbtsrv->task->lp_ctx);
const char *my_ip = reply_iface->ip_address;
- struct ldb_dn *partitions_basedn;
+ struct dom_sid *sid;
+ struct nbt_netlogon_response netlogon_response;
+ NTSTATUS status;
+
if (!my_ip) {
DEBUG(0, ("Could not obtain own IP address for datagram socket\n"));
return;
@@ -131,90 +134,35 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot,
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));
- return;
+ 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;
+ }
+ sid = &netlogon->req.logon.sid;
+ } else {
+ sid = NULL;
}
- /* try and find the domain */
- ret = gendb_search_dn(samctx, packet,
- samdb_result_dn(samctx, samctx, ref_res[0], "ncName", NULL),
- &dom_res, dom_attrs);
- if (ret != 1) {
- DEBUG(2,("Unable to find domain from reference '%s' in sam\n",
- ldb_dn_get_linearized(ref_res[0]->dn)));
+ 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;
}
- /* setup a GETDC reply */
- ZERO_STRUCT(reply);
- reply.command = NETLOGON_RESPONSE_FROM_PDC2;
-
-#if 0
- /* newer testing shows that the reply command type is not
- changed based on whether a username is given in the
- reply. This was what was causing the w2k join to be so
- slow */
- if (netlogon->req.pdc2.user_name[0]) {
- reply.command = NETLOGON_RESPONSE_FROM_PDC_USER;
- }
-#endif
-
- pdc = &reply.req.response2;
-
- /* TODO: accurately depict which services we are running */
- pdc->server_type =
- NBT_SERVER_PDC | NBT_SERVER_GC |
- NBT_SERVER_DS | NBT_SERVER_TIMESERV |
- NBT_SERVER_CLOSEST | NBT_SERVER_WRITABLE |
- NBT_SERVER_GOOD_TIMESERV;
-
- /* hmm, probably a better way to do this */
- if (str_list_check(services, "ldap")) {
- pdc->server_type |= NBT_SERVER_LDAP;
- }
-
- if (str_list_check(services, "kdc")) {
- pdc->server_type |= NBT_SERVER_KDC;
- }
-
- pdc->domain_uuid = samdb_result_guid(dom_res[0], "objectGUID");
- pdc->forest = samdb_result_string(ref_res[0], "dnsRoot",
- lp_realm(iface->nbtsrv->task->lp_ctx));
- pdc->dns_domain = samdb_result_string(ref_res[0], "dnsRoot",
- lp_realm(iface->nbtsrv->task->lp_ctx));
-
- /* TODO: get our full DNS name from somewhere else */
- pdc->pdc_dns_name = talloc_asprintf(packet, "%s.%s",
- strlower_talloc(packet,
- lp_netbios_name(iface->nbtsrv->task->lp_ctx)),
- pdc->dns_domain);
- pdc->domain = samdb_result_string(ref_res[0], "nETBIOSName", name->name);;
- pdc->pdc_name = lp_netbios_name(iface->nbtsrv->task->lp_ctx);
- pdc->user_name = netlogon->req.pdc2.user_name;
- /* TODO: we need to make sure these are in our DNS zone */
- pdc->server_site = "Default-First-Site-Name";
- pdc->client_site = "Default-First-Site-Name";
- pdc->unknown = 0x10; /* what is this? */
- pdc->unknown2 = 2; /* and this ... */
- pdc->pdc_ip = my_ip;
- pdc->nt_version = 13;
- pdc->lmnt_token = 0xFFFF;
- pdc->lm20_token = 0xFFFF;
+ netlogon_response.response_type = NETLOGON_SAMLOGON;
packet->data.msg.dest_name.type = 0;
dgram_mailslot_netlogon_reply(reply_iface->dgmsock,
packet,
lp_netbios_name(iface->nbtsrv->task->lp_ctx),
- netlogon->req.pdc2.mailslot_name,
- &reply);
+ netlogon->req.logon.mailslot_name,
+ &netlogon_response);
}
@@ -223,6 +171,7 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot,
*/
void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot,
struct nbt_dgram_packet *packet,
+ const char *mailslot_name,
struct socket_address *src)
{
NTSTATUS status = NT_STATUS_NO_MEMORY;
@@ -246,15 +195,17 @@ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot,
DEBUG(2,("netlogon request to %s from %s:%d\n",
nbt_name_string(netlogon, name), src->addr, src->port));
- status = dgram_mailslot_netlogon_parse(dgmslot, netlogon, packet, netlogon);
+ status = dgram_mailslot_netlogon_parse_request(dgmslot, netlogon, packet, netlogon);
if (!NT_STATUS_IS_OK(status)) goto failed;
switch (netlogon->command) {
- case NETLOGON_QUERY_FOR_PDC:
- nbtd_netlogon_getdc(dgmslot, iface, packet, src, netlogon);
+ case LOGON_PRIMARY_QUERY:
+ nbtd_netlogon_getdc(dgmslot, iface, packet, mailslot_name,
+ src, netlogon);
break;
- case NETLOGON_QUERY_FOR_PDC2:
- nbtd_netlogon_getdc2(dgmslot, iface, packet, src, netlogon);
+ case LOGON_SAM_LOGON_REQUEST:
+ nbtd_netlogon_samlogon(dgmslot, iface, packet, mailslot_name,
+ src, netlogon);
break;
default:
DEBUG(2,("unknown netlogon op %d from %s:%d\n",
diff --git a/source4/nbt_server/dgram/request.c b/source4/nbt_server/dgram/request.c
index 205a544209..277b64741d 100644
--- a/source4/nbt_server/dgram/request.c
+++ b/source4/nbt_server/dgram/request.c
@@ -35,8 +35,10 @@ static const struct {
const char *mailslot_name;
dgram_mailslot_handler_t handler;
} mailslot_handlers[] = {
+ /* Handle both NTLOGON and NETLOGON in the same function, as
+ * they are very similar */
{ NBT_MAILSLOT_NETLOGON, nbtd_mailslot_netlogon_handler },
- { NBT_MAILSLOT_NTLOGON, nbtd_mailslot_ntlogon_handler },
+ { NBT_MAILSLOT_NTLOGON, nbtd_mailslot_netlogon_handler },
{ NBT_MAILSLOT_BROWSE, nbtd_mailslot_browse_handler }
};
diff --git a/source4/nbt_server/irpc.c b/source4/nbt_server/irpc.c
index 8f2f7fc2c2..3a70c98041 100644
--- a/source4/nbt_server/irpc.c
+++ b/source4/nbt_server/irpc.c
@@ -49,7 +49,7 @@ static NTSTATUS nbtd_information(struct irpc_message *msg,
/*
- winbind needs to be able to do a getdc request, but some windows
+ winbind needs to be able to do a getdc request, but most (all?) windows
servers always send the reply to port 138, regardless of the request
port. To cope with this we use a irpc request to the NBT server
which has port 138 open, and thus can receive the replies
@@ -59,55 +59,48 @@ struct getdc_state {
struct nbtd_getdcname *req;
};
-static void getdc_recv_ntlogon_reply(struct dgram_mailslot_handler *dgmslot,
- struct nbt_dgram_packet *packet,
- struct socket_address *src)
+static void getdc_recv_netlogon_reply(struct dgram_mailslot_handler *dgmslot,
+ struct nbt_dgram_packet *packet,
+ const char *mailslot_name,
+ struct socket_address *src)
{
struct getdc_state *s =
talloc_get_type(dgmslot->private, struct getdc_state);
-
- struct nbt_ntlogon_packet ntlogon;
+ const char *p;
+ struct nbt_netlogon_response netlogon;
NTSTATUS status;
- status = dgram_mailslot_ntlogon_parse(dgmslot, packet, packet,
- &ntlogon);
+ status = dgram_mailslot_netlogon_parse_response(dgmslot, packet, packet,
+ &netlogon);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("dgram_mailslot_ntlogon_parse failed: %s\n",
nt_errstr(status)));
goto done;
}
+ /* We asked for version 1 only */
+ if (netlogon.response_type == NETLOGON_SAMLOGON
+ && netlogon.samlogon.ntver != NETLOGON_NT_VERSION_1) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto done;
+ }
+
status = NT_STATUS_NO_LOGON_SERVERS;
- DEBUG(10, ("reply: command=%d\n", ntlogon.command));
+ p = netlogon.samlogon.nt4.server;
- switch (ntlogon.command) {
- case NTLOGON_SAM_LOGON:
- DEBUG(0, ("Huh -- got NTLOGON_SAM_LOGON as reply\n"));
- break;
- case NTLOGON_SAM_LOGON_REPLY:
- case NTLOGON_SAM_LOGON_REPLY15: {
- const char *p = ntlogon.req.reply.server;
-
- DEBUG(10, ("NTLOGON_SAM_LOGON_REPLY: server: %s, user: %s, "
- "domain: %s\n", p, ntlogon.req.reply.user_name,
- ntlogon.req.reply.domain));
-
- if (*p == '\\') p += 1;
- if (*p == '\\') p += 1;
-
- s->req->out.dcname = talloc_strdup(s->req, p);
- if (s->req->out.dcname == NULL) {
- DEBUG(0, ("talloc failed\n"));
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
- status = NT_STATUS_OK;
- break;
- }
- default:
- DEBUG(0, ("Got unknown packet: %d\n", ntlogon.command));
- break;
+ DEBUG(10, ("NTLOGON_SAM_LOGON_REPLY: server: %s, user: %s, "
+ "domain: %s\n", p, netlogon.samlogon.nt4.user_name,
+ netlogon.samlogon.nt4.domain));
+
+ if (*p == '\\') p += 1;
+ if (*p == '\\') p += 1;
+
+ s->req->out.dcname = talloc_strdup(s->req, p);
+ if (s->req->out.dcname == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
}
done:
@@ -121,8 +114,8 @@ static NTSTATUS nbtd_getdcname(struct irpc_message *msg,
talloc_get_type(msg->private, struct nbtd_server);
struct nbtd_interface *iface = nbtd_find_request_iface(server, req->in.ip_address, true);
struct getdc_state *s;
- struct nbt_ntlogon_packet p;
- struct nbt_ntlogon_sam_logon *r;
+ struct nbt_netlogon_packet p;
+ struct NETLOGON_SAM_LOGON_REQUEST *r;
struct nbt_name src, dst;
struct socket_address *dest;
struct dgram_mailslot_handler *handler;
@@ -137,11 +130,11 @@ static NTSTATUS nbtd_getdcname(struct irpc_message *msg,
s->req = req;
handler = dgram_mailslot_temp(iface->dgmsock, NBT_MAILSLOT_GETDC,
- getdc_recv_ntlogon_reply, s);
+ getdc_recv_netlogon_reply, s);
NT_STATUS_HAVE_NO_MEMORY(handler);
ZERO_STRUCT(p);
- p.command = NTLOGON_SAM_LOGON;
+ p.command = LOGON_SAM_LOGON_REQUEST;
r = &p.req.logon;
r->request_count = 0;
r->computer_name = req->in.my_computername;
@@ -149,7 +142,7 @@ static NTSTATUS nbtd_getdcname(struct irpc_message *msg,
r->mailslot_name = handler->mailslot_name;
r->acct_control = req->in.account_control;
r->sid = *req->in.domain_sid;
- r->nt_version = 1;
+ r->nt_version = NETLOGON_NT_VERSION_1;
r->lmnt_token = 0xffff;
r->lm20_token = 0xffff;
@@ -160,9 +153,10 @@ static NTSTATUS nbtd_getdcname(struct irpc_message *msg,
req->in.ip_address, 138);
NT_STATUS_HAVE_NO_MEMORY(dest);
- status = dgram_mailslot_ntlogon_send(iface->dgmsock, DGRAM_DIRECT_GROUP,
- &dst, dest,
- &src, &p);
+ status = dgram_mailslot_netlogon_send(iface->dgmsock,
+ &dst, dest,
+ NBT_MAILSLOT_NETLOGON,
+ &src, &p);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("dgram_mailslot_ntlogon_send failed: %s\n",
nt_errstr(status)));
diff --git a/source4/setup/provision-backend.js b/source4/setup/provision-backend.js
deleted file mode 100644
index 9482d8c435..0000000000
--- a/source4/setup/provision-backend.js
+++ /dev/null
@@ -1,188 +0,0 @@
-#!/bin/sh
-exec smbscript "$0" ${1+"$@"}
-/*
- provision a Samba4 server
- Copyright Andrew Tridgell 2005
- Released under the GNU GPL version 3 or later
-*/
-
-options = GetOptions(ARGV,
- "POPT_AUTOHELP",
- "POPT_COMMON_SAMBA",
- "POPT_COMMON_VERSION",
- "POPT_COMMON_CREDENTIALS",
- 'realm=s',
- 'host-name=s',
- 'ldap-manager-pass=s',
- 'root=s',
- 'quiet',
- 'ldap-backend-type=s',
- 'ldap-backend-port=i');
-
-if (options == undefined) {
- println("Failed to parse options");
- return -1;
-}
-
-sys = sys_init();
-
-libinclude("base.js");
-libinclude("provision.js");
-
-/*
- print a message if quiet is not set
-*/
-function message()
-{
- if (options["quiet"] == undefined) {
- print(vsprintf(arguments));
- }
-}
-
-/*
- show some help
-*/
-function ShowHelp()
-{
- print("
-Samba4 provisioning
-
-provision [options]
- --realm REALM set realm
- --host-name HOSTNAME set hostname
- --ldap-manager-pass PASSWORD choose LDAP Manager password (otherwise random)
- --root USERNAME choose 'root' unix username
- --quiet Be quiet
- --ldap-backend-type LDAPSERVER Select either \"openldap\" or \"fedora-ds\" as a target to configure
- --ldap-backend-port PORT Select the TCP port (if any) that the LDAP backend should listen on (Fedora DS only)
-You must provide at least a realm and ldap-backend-type
-
-");
- exit(1);
-}
-
-if (options['host-name'] == undefined) {
- options['host-name'] = hostname();
-}
-
-/*
- main program
-*/
-if (options["realm"] == undefined ||
- options["ldap-backend-type"] == undefined ||
- options["host-name"] == undefined) {
- ShowHelp();
-}
-
-/* cope with an initially blank smb.conf */
-var lp = loadparm_init();
-lp.set("realm", options.realm);
-lp.reload();
-
-var subobj = provision_guess();
-for (r in options) {
- var key = strupper(join("", split("-", r)));
- subobj[key] = options[r];
-}
-
-
-
-var paths = provision_default_paths(subobj);
-provision_fix_subobj(subobj, paths);
-message("Provisioning LDAP backend for %s in realm %s into %s\n", subobj.HOSTNAME, subobj.REALM, subobj.LDAPDIR);
-message("Using %s password: %s\n", subobj.LDAPMANAGERDN, subobj.LDAPMANAGERPASS);
-var tmp_schema_ldb = subobj.LDAPDIR + "/schema-tmp.ldb";
-sys.mkdir(subobj.LDAPDIR, 0700);
-
-provision_schema(subobj, message, tmp_schema_ldb, paths);
-
-var mapping;
-var backend_schema;
-var slapd_command;
-if (options["ldap-backend-type"] == "fedora-ds") {
- mapping = "schema-map-fedora-ds-1.0";
- backend_schema = "99_ad.ldif";
- if (options["ldap-backend-port"] != undefined) {
- message("Will listen on TCP port " + options["ldap-backend-port"] + "\n");
- subobj.SERVERPORT="ServerPort = " + options["ldap-backend-port"];
- } else {
- message("Will listen on LDAPI only\n");
- subobj.SERVERPORT="";
- }
- setup_file("fedorads.inf", message, subobj.LDAPDIR + "/fedorads.inf", subobj);
- setup_file("fedorads-partitions.ldif", message, subobj.LDAPDIR + "/fedorads-partitions.ldif", subobj);
-
- slapd_command = "(see documentation)";
-} else if (options["ldap-backend-type"] == "openldap") {
- mapping = "schema-map-openldap-2.3";
- backend_schema = "backend-schema.schema";
- setup_file("slapd.conf", message, subobj.LDAPDIR + "/slapd.conf", subobj);
- setup_file("modules.conf", message, subobj.LDAPDIR + "/modules.conf", subobj);
- sys.mkdir(subobj.LDAPDIR + "/db", 0700);
- subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/user";
- sys.mkdir(subobj.LDAPDBDIR, 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700);
- setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj);
- subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/config";
- sys.mkdir(subobj.LDAPDBDIR, 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700);
- setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj);
- subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/schema";
- sys.mkdir(subobj.LDAPDBDIR, 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700);
- setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj);
- if (options["ldap-backend-port"] != undefined) {
- message("\nStart slapd with: \n");
- slapd_command = "slapd -f " + subobj.LDAPDIR + "/slapd.conf -h \"ldap://0.0.0.0:" + options["ldap-backend-port"] + " " + subobj.LDAPI_URI "\"";
- } else {
- slapd_command = "slapd -f " + subobj.LDAPDIR + "/slapd.conf -h " + subobj.LDAPI_URI;
- }
-
- var ldb = ldb_init();
- ldb.filename = tmp_schema_ldb;
-
- var connect_ok = ldb.connect(ldb.filename);
- assert(connect_ok);
- var attrs = new Array("linkID", "lDAPDisplayName");
- var res = ldb.search("(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", subobj.SCHEMADN, ldb.SCOPE_SUBTREE, attrs);
- assert(res.error == 0);
- var memberof_config = "";
- var refint_attributes = "";
- for (i=0; i < res.msgs.length; i++) {
- var target = searchone(ldb, subobj.SCHEMADN, "(&(objectclass=attributeSchema)(linkID=" + (res.msgs[i].linkID + 1) + "))", "lDAPDisplayName");
- if (target != undefined) {
- refint_attributes = refint_attributes + " " + target + " " + res.msgs[i].lDAPDisplayName;
- memberof_config = memberof_config + "overlay memberof
-memberof-dangling error
-memberof-refint TRUE
-memberof-group-oc top
-memberof-member-ad " + res.msgs[i].lDAPDisplayName + "
-memberof-memberof-ad " + target + "
-memberof-dangling-error 32
-
-";
- }
- }
-
- memberof_config = memberof_config + "
-overlay refint
-refint_attributes" + refint_attributes + "
-";
-
- ok = sys.file_save(subobj.LDAPDIR + "/memberof.conf", memberof_config);
- if (!ok) {
- message("failed to create file: " + f + "\n");
- assert(ok);
- }
-
-}
-var schema_command = "ad2oLschema --option=convert:target=" + options["ldap-backend-type"] + " -I " + lp.get("setup directory") + "/" + mapping + " -H tdb://" + tmp_schema_ldb + " -O " + subobj.LDAPDIR + "/" + backend_schema;
-
-message("\nCreate a suitable schema file with:\n%s\n", schema_command);
-message("\nStart slapd with: \n%s\n", slapd_command);
-
-message("All OK\n");
-return 0;
diff --git a/source4/torture/ldap/cldap.c b/source4/torture/ldap/cldap.c
index ca4d9b7705..a77920d4e6 100644
--- a/source4/torture/ldap/cldap.c
+++ b/source4/torture/ldap/cldap.c
@@ -41,7 +41,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
struct cldap_socket *cldap;
NTSTATUS status;
struct cldap_netlogon search, empty_search;
- union nbt_cldap_netlogon n1;
+ struct netlogon_samlogon_response n1;
struct GUID guid;
int i;
@@ -51,7 +51,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
search.in.dest_address = dest;
search.in.dest_port = lp_cldap_port(tctx->lp_ctx);
search.in.acct_control = -1;
- search.in.version = 6;
+ search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
+ search.in.map_response = true;
empty_search = search;
@@ -63,7 +64,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
n1 = search.out.netlogon;
search.in.user = "Administrator";
- search.in.realm = n1.logon5.dns_domain;
+ search.in.realm = n1.nt5_ex.dns_domain;
search.in.host = "__cldap_torture__";
printf("Scanning for netlogon levels\n");
@@ -82,7 +83,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
CHECK_STATUS(status, NT_STATUS_OK);
}
- search.in.version = 0x20000006;
+ search.in.version = NETLOGON_NT_VERSION_5|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_IP;
+
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
@@ -91,8 +93,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
search.in.user = NULL;
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
- CHECK_STRING(search.out.netlogon.logon5.user_name, "");
- CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2);
+ CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
+ CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
printf("Trying with User=Administrator\n");
@@ -100,10 +102,10 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
- CHECK_STRING(search.out.netlogon.logon5.user_name, search.in.user);
- CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC_USER);
+ CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user);
+ CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
- search.in.version = 6;
+ search.in.version = NETLOGON_NT_VERSION_5;
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
@@ -112,8 +114,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
search.in.user = NULL;
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
- CHECK_STRING(search.out.netlogon.logon5.user_name, "");
- CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2);
+ CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
+ CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE);
printf("Trying with User=Administrator\n");
@@ -121,16 +123,18 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
- CHECK_STRING(search.out.netlogon.logon5.user_name, search.in.user);
- CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC_USER);
+ CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user);
+ CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN);
+
+ search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
printf("Trying with a GUID\n");
search.in.realm = NULL;
- search.in.domain_guid = GUID_string(tctx, &n1.logon5.domain_uuid);
+ search.in.domain_guid = GUID_string(tctx, &n1.nt5_ex.domain_uuid);
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
- CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC_USER);
- CHECK_STRING(GUID_string(tctx, &search.out.netlogon.logon5.domain_uuid), search.in.domain_guid);
+ CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
+ CHECK_STRING(GUID_string(tctx, &search.out.netlogon.nt5_ex.domain_uuid), search.in.domain_guid);
printf("Trying with a incorrect GUID\n");
guid = GUID_random();
@@ -141,15 +145,15 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
printf("Trying with a AAC\n");
search.in.acct_control = 0x180;
- search.in.realm = n1.logon5.dns_domain;
+ search.in.realm = n1.nt5_ex.dns_domain;
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
- CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2);
- CHECK_STRING(search.out.netlogon.logon5.user_name, "");
+ CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
+ CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
printf("Trying with a bad AAC\n");
search.in.acct_control = 0xFF00FF00;
- search.in.realm = n1.logon5.dns_domain;
+ search.in.realm = n1.nt5_ex.dns_domain;
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
@@ -158,15 +162,16 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
search.in.user = "Administrator";
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
- CHECK_STRING(search.out.netlogon.logon5.dns_domain, n1.logon5.dns_domain);
- CHECK_STRING(search.out.netlogon.logon5.user_name, search.in.user);
+ CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain);
+ CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user);
printf("Trying with just a bad username\n");
search.in.user = "___no_such_user___";
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
- CHECK_STRING(search.out.netlogon.logon5.user_name, search.in.user);
- CHECK_STRING(search.out.netlogon.logon5.dns_domain, n1.logon5.dns_domain);
+ CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user);
+ CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain);
+ CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
printf("Trying with just a bad domain\n");
search = empty_search;
@@ -175,29 +180,29 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
printf("Trying with a incorrect domain and correct guid\n");
- search.in.domain_guid = GUID_string(tctx, &n1.logon5.domain_uuid);
+ search.in.domain_guid = GUID_string(tctx, &n1.nt5_ex.domain_uuid);
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
- CHECK_STRING(search.out.netlogon.logon5.dns_domain, n1.logon5.dns_domain);
- CHECK_STRING(search.out.netlogon.logon5.user_name, "");
- CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2);
+ CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain);
+ CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
+ CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
printf("Trying with a incorrect domain and incorrect guid\n");
search.in.domain_guid = GUID_string(tctx, &guid);
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
- CHECK_STRING(search.out.netlogon.logon5.dns_domain, n1.logon5.dns_domain);
- CHECK_STRING(search.out.netlogon.logon5.user_name, "");
- CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2);
+ CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain);
+ CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
+ CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
printf("Trying with a incorrect GUID and correct domain\n");
search.in.domain_guid = GUID_string(tctx, &guid);
- search.in.realm = n1.logon5.dns_domain;
+ search.in.realm = n1.nt5_ex.dns_domain;
status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
- CHECK_STRING(search.out.netlogon.logon5.dns_domain, n1.logon5.dns_domain);
- CHECK_STRING(search.out.netlogon.logon5.user_name, "");
- CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2);
+ CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain);
+ CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
+ CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
return true;
}
diff --git a/source4/torture/nbt/dgram.c b/source4/torture/nbt/dgram.c
index a3585896eb..ce5758977d 100644
--- a/source4/torture/nbt/dgram.c
+++ b/source4/torture/nbt/dgram.c
@@ -39,23 +39,22 @@
*/
static void netlogon_handler(struct dgram_mailslot_handler *dgmslot,
struct nbt_dgram_packet *packet,
+ const char *mailslot_name,
struct socket_address *src)
{
NTSTATUS status;
- struct nbt_netlogon_packet netlogon;
+ struct nbt_netlogon_response netlogon;
int *replies = (int *)dgmslot->private;
printf("netlogon reply from %s:%d\n", src->addr, src->port);
- status = dgram_mailslot_netlogon_parse(dgmslot, dgmslot, packet, &netlogon);
+ status = dgram_mailslot_netlogon_parse_response(dgmslot, dgmslot, packet, &netlogon);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to parse netlogon packet from %s:%d\n",
src->addr, src->port);
return;
}
- NDR_PRINT_DEBUG(nbt_netlogon_packet, &netlogon);
-
(*replies)++;
}
@@ -101,7 +100,7 @@ static bool nbt_test_netlogon(struct torture_context *tctx)
/* try receiving replies on port 138 first, which will only
work if we are root and smbd/nmbd are not running - fall
back to listening on any port, which means replies from
- some windows versions won't be seen */
+ most windows versions won't be seen */
status = socket_listen(dgmsock->sock, socket_address, 0, 0);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(socket_address);
@@ -117,7 +116,7 @@ static bool nbt_test_netlogon(struct torture_context *tctx)
netlogon_handler, &replies);
ZERO_STRUCT(logon);
- logon.command = NETLOGON_QUERY_FOR_PDC;
+ logon.command = LOGON_PRIMARY_QUERY;
logon.req.pdc.computer_name = TEST_NAME;
logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
logon.req.pdc.unicode_name = TEST_NAME;
@@ -132,6 +131,7 @@ static bool nbt_test_netlogon(struct torture_context *tctx)
torture_assert(tctx, dest != NULL, "Error getting address");
status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
+ NBT_MAILSLOT_NETLOGON,
&myname, &logon);
torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
@@ -163,6 +163,9 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
struct nbt_name name;
struct interface *ifaces;
+ struct test_join *join_ctx;
+ struct cli_credentials *machine_credentials;
+ const struct dom_sid *dom_sid;
name.name = lp_workgroup(tctx->lp_ctx);
name.type = NBT_NAME_LOGON;
@@ -200,14 +203,14 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
ZERO_STRUCT(logon);
- logon.command = NETLOGON_QUERY_FOR_PDC2;
- logon.req.pdc2.request_count = 0;
- logon.req.pdc2.computer_name = TEST_NAME;
- logon.req.pdc2.user_name = "";
- logon.req.pdc2.mailslot_name = dgmslot->mailslot_name;
- logon.req.pdc2.nt_version = 11;
- logon.req.pdc2.lmnt_token = 0xFFFF;
- logon.req.pdc2.lm20_token = 0xFFFF;
+ logon.command = LOGON_SAM_LOGON_REQUEST;
+ logon.req.logon.request_count = 0;
+ logon.req.logon.computer_name = TEST_NAME;
+ logon.req.logon.user_name = "";
+ logon.req.logon.mailslot_name = dgmslot->mailslot_name;
+ logon.req.logon.nt_version = 11;
+ logon.req.logon.lmnt_token = 0xFFFF;
+ logon.req.logon.lm20_token = 0xFFFF;
make_nbt_name_client(&myname, TEST_NAME);
@@ -216,6 +219,7 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
torture_assert(tctx, dest != NULL, "Error getting address");
status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
+ NBT_MAILSLOT_NETLOGON,
&myname, &logon);
torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
@@ -223,33 +227,64 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
event_loop_once(dgmsock->event_ctx);
}
- return true;
-}
+ ZERO_STRUCT(logon);
+ logon.command = LOGON_SAM_LOGON_REQUEST;
+ logon.req.logon.request_count = 0;
+ logon.req.logon.computer_name = TEST_NAME;
+ logon.req.logon.user_name = TEST_NAME"$";
+ logon.req.logon.mailslot_name = dgmslot->mailslot_name;
+ logon.req.logon.nt_version = 1;
+ logon.req.logon.lmnt_token = 0xFFFF;
+ logon.req.logon.lm20_token = 0xFFFF;
+ make_nbt_name_client(&myname, TEST_NAME);
-/*
- reply handler for ntlogon request
-*/
-static void ntlogon_handler(struct dgram_mailslot_handler *dgmslot,
- struct nbt_dgram_packet *packet,
- struct socket_address *src)
-{
- NTSTATUS status;
- struct nbt_ntlogon_packet ntlogon;
- int *replies = (int *)dgmslot->private;
+ dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
+ address, lp_dgram_port(tctx->lp_ctx));
- printf("ntlogon reply from %s:%d\n", src->addr, src->port);
+ torture_assert(tctx, dest != NULL, "Error getting address");
+ status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
+ NBT_MAILSLOT_NETLOGON,
+ &myname, &logon);
+ torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
- status = dgram_mailslot_ntlogon_parse(dgmslot, dgmslot, packet, &ntlogon);
- if (!NT_STATUS_IS_OK(status)) {
- printf("Failed to parse ntlogon packet from %s:%d\n",
- src->addr, src->port);
- return;
+ while (timeval_elapsed(&tv) < 5 && replies == 0) {
+ event_loop_once(dgmsock->event_ctx);
}
- NDR_PRINT_DEBUG(nbt_ntlogon_packet, &ntlogon);
+ join_ctx = torture_join_domain(tctx, TEST_NAME,
+ ACB_WSTRUST, &machine_credentials);
- (*replies)++;
+ dom_sid = torture_join_sid(join_ctx);
+
+ ZERO_STRUCT(logon);
+ logon.command = LOGON_SAM_LOGON_REQUEST;
+ logon.req.logon.request_count = 0;
+ logon.req.logon.computer_name = TEST_NAME;
+ logon.req.logon.user_name = TEST_NAME"$";
+ logon.req.logon.mailslot_name = dgmslot->mailslot_name;
+ logon.req.logon.sid = *dom_sid;
+ logon.req.logon.nt_version = 1;
+ logon.req.logon.lmnt_token = 0xFFFF;
+ logon.req.logon.lm20_token = 0xFFFF;
+
+ make_nbt_name_client(&myname, TEST_NAME);
+
+ dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
+ address, lp_dgram_port(tctx->lp_ctx));
+
+ torture_assert(tctx, dest != NULL, "Error getting address");
+ status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
+ NBT_MAILSLOT_NETLOGON,
+ &myname, &logon);
+ torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
+
+ while (timeval_elapsed(&tv) < 5 && replies == 0) {
+ event_loop_once(dgmsock->event_ctx);
+ }
+
+ torture_leave_domain(join_ctx);
+ return true;
}
@@ -262,10 +297,9 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
struct socket_address *dest;
struct test_join *join_ctx;
struct cli_credentials *machine_credentials;
- const struct dom_sid *dom_sid;
const char *myaddress;
- struct nbt_ntlogon_packet logon;
+ struct nbt_netlogon_packet logon;
struct nbt_name myname;
NTSTATUS status;
struct timeval tv = timeval_current();
@@ -296,7 +330,7 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
/* try receiving replies on port 138 first, which will only
work if we are root and smbd/nmbd are not running - fall
back to listening on any port, which means replies from
- some windows versions won't be seen */
+ most windows versions won't be seen */
status = socket_listen(dgmsock->sock, socket_address, 0, 0);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(socket_address);
@@ -313,21 +347,19 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
talloc_asprintf(tctx, "Failed to join domain %s as %s\n",
lp_workgroup(tctx->lp_ctx), TEST_NAME));
- dom_sid = torture_join_sid(join_ctx);
-
/* setup a temporary mailslot listener for replies */
dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
- ntlogon_handler, &replies);
+ netlogon_handler, &replies);
ZERO_STRUCT(logon);
- logon.command = NTLOGON_SAM_LOGON;
+ logon.command = LOGON_SAM_LOGON_REQUEST;
logon.req.logon.request_count = 0;
logon.req.logon.computer_name = TEST_NAME;
logon.req.logon.user_name = TEST_NAME"$";
logon.req.logon.mailslot_name = dgmslot->mailslot_name;
logon.req.logon.acct_control = ACB_WSTRUST;
- logon.req.logon.sid = *dom_sid;
+ /* Leave sid as all zero */
logon.req.logon.nt_version = 1;
logon.req.logon.lmnt_token = 0xFFFF;
logon.req.logon.lm20_token = 0xFFFF;
@@ -337,8 +369,34 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
address, lp_dgram_port(tctx->lp_ctx));
torture_assert(tctx, dest != NULL, "Error getting address");
- status = dgram_mailslot_ntlogon_send(dgmsock, DGRAM_DIRECT_UNIQUE,
- &name, dest, &myname, &logon);
+ status = dgram_mailslot_netlogon_send(dgmsock,
+ &name, dest,
+ NBT_MAILSLOT_NTLOGON,
+ &myname, &logon);
+ torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
+
+ while (timeval_elapsed(&tv) < 5 && replies == 0) {
+ event_loop_once(dgmsock->event_ctx);
+ }
+
+ ZERO_STRUCT(logon);
+ logon.command = LOGON_PRIMARY_QUERY;
+ logon.req.pdc.computer_name = TEST_NAME;
+ logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
+ logon.req.pdc.unicode_name = TEST_NAME;
+ logon.req.pdc.nt_version = 1;
+ logon.req.pdc.lmnt_token = 0xFFFF;
+ logon.req.pdc.lm20_token = 0xFFFF;
+
+ make_nbt_name_client(&myname, TEST_NAME);
+
+ dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
+ address, lp_dgram_port(tctx->lp_ctx));
+ torture_assert(tctx, dest != NULL, "Error getting address");
+ status = dgram_mailslot_netlogon_send(dgmsock,
+ &name, dest,
+ NBT_MAILSLOT_NTLOGON,
+ &myname, &logon);
torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
while (timeval_elapsed(&tv) < 5 && replies == 0) {
diff --git a/source4/torture/rpc/dssync.c b/source4/torture/rpc/dssync.c
index 00617f4072..989a1faf27 100644
--- a/source4/torture/rpc/dssync.c
+++ b/source4/torture/rpc/dssync.c
@@ -288,16 +288,17 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx)
search.in.dest_address = ctx->drsuapi_binding->host;
search.in.dest_port = lp_cldap_port(tctx->lp_ctx);
search.in.acct_control = -1;
- search.in.version = 6;
+ search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
+ search.in.map_response = true;
status = cldap_netlogon(cldap, ctx, &search);
if (!NT_STATUS_IS_OK(status)) {
const char *errstr = nt_errstr(status);
ctx->site_name = talloc_asprintf(ctx, "%s", "Default-First-Site-Name");
printf("cldap_netlogon() returned %s. Defaulting to Site-Name: %s\n", errstr, ctx->site_name);
} else {
- ctx->site_name = talloc_steal(ctx, search.out.netlogon.logon5.client_site);
+ ctx->site_name = talloc_steal(ctx, search.out.netlogon.nt5_ex.client_site);
printf("cldap_netlogon() returned Client Site-Name: %s.\n",ctx->site_name);
- printf("cldap_netlogon() returned Server Site-Name: %s.\n",search.out.netlogon.logon5.server_site);
+ printf("cldap_netlogon() returned Server Site-Name: %s.\n",search.out.netlogon.nt5_ex.server_site);
}
return ret;