1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-04 17:47:26 +03:00

Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into nosmbpython

(This used to be commit 5c56464a6c2f29a039ba3152de83d34778ca0615)
This commit is contained in:
Jelmer Vernooij 2008-05-21 12:22:05 +02:00
commit d17b9c4509
15 changed files with 719 additions and 170 deletions

View File

@ -27,7 +27,7 @@ There are 2 methods of doing this:
method 1: "rsync -avz samba.org::ftp/unpacked/samba_4_0_test/ samba4" method 1: "rsync -avz samba.org::ftp/unpacked/samba_4_0_test/ samba4"
method 2: "git clone git://git.samba.org/samba.git samba4; cd samba4; git checkout v4-0-test; cd .." method 2: "git clone git://git.samba.org/samba.git samba4; cd samba4 && git checkout -b v4-0-test origin/v4-0-test; cd .."
both methods will create a directory called "samba4" in the current both methods will create a directory called "samba4" in the current
directory. If you don't have rsync or git then install one of them. directory. If you don't have rsync or git then install one of them.

View File

@ -46,6 +46,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
struct dom_sid *domain_sid, struct dom_sid *domain_sid,
const char *domain_guid, const char *domain_guid,
const char *user, const char *user,
uint32_t acct_control,
const char *src_address, const char *src_address,
uint32_t version, uint32_t version,
struct loadparm_context *lp_ctx, struct loadparm_context *lp_ctx,
@ -53,7 +54,8 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
{ {
const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL}; const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL};
const char *dom_attrs[] = {"objectGUID", NULL}; const char *dom_attrs[] = {"objectGUID", NULL};
struct ldb_result *ref_res = NULL, *dom_res = NULL; const char *none_attrs[] = {NULL};
struct ldb_result *ref_res = NULL, *dom_res = NULL, *user_res = NULL;
int ret; int ret;
const char **services = lp_server_services(lp_ctx); const char **services = lp_server_services(lp_ctx);
uint32_t server_type; uint32_t server_type;
@ -68,6 +70,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
const char *pdc_ip; const char *pdc_ip;
struct ldb_dn *partitions_basedn; struct ldb_dn *partitions_basedn;
struct interface *ifaces; struct interface *ifaces;
bool user_known;
partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx); partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
@ -201,6 +204,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
} }
} }
if ((ref_res == NULL || ref_res->count == 0)) { if ((ref_res == NULL || ref_res->count == 0)) {
DEBUG(2,("Unable to find domain reference with name %s or GUID {%s}\n", domain, domain_guid)); DEBUG(2,("Unable to find domain reference with name %s or GUID {%s}\n", domain, domain_guid));
return NT_STATUS_NO_SUCH_DOMAIN; return NT_STATUS_NO_SUCH_DOMAIN;
@ -211,6 +215,44 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
return NT_STATUS_NO_SUCH_DOMAIN; return NT_STATUS_NO_SUCH_DOMAIN;
} }
/* work around different inputs for not-specified users */
if (!user) {
user = "";
}
/* Enquire about any valid username with just a CLDAP packet -
* if kerberos didn't also do this, the security folks would
* scream... */
if (user[0]) { \
/* Only allow some bits to be enquired: [MS-ATDS] 7.3.3.2 */
if (acct_control == (uint32_t)-1) {
acct_control = 0;
}
acct_control = acct_control & (ACB_TEMPDUP | ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST);
/* We must exclude disabled accounts, but otherwise do the bitwise match the client asked for */
ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &user_res,
dom_res->msgs[0]->dn, LDB_SCOPE_SUBTREE,
none_attrs,
"(&(objectClass=user)(samAccountName=%s)"
"(!(userAccountControl:" LDB_OID_COMPARATOR_AND ":=%u))"
"(userAccountControl:" LDB_OID_COMPARATOR_OR ":=%u))",
user, UF_ACCOUNTDISABLE, samdb_acb2uf(acct_control));
if (ret != LDB_SUCCESS) {
DEBUG(2,("Unable to find referece to user '%s' with ACB 0x%8x under %s: %s\n",
user, acct_control, ldb_dn_get_linearized(dom_res->msgs[0]->dn),
ldb_errstring(sam_ctx)));
return NT_STATUS_NO_SUCH_USER;
} else if (user_res->count == 1) {
user_known = true;
} else {
user_known = false;
}
} else {
user_known = true;
}
server_type = server_type =
NBT_SERVER_DS | NBT_SERVER_TIMESERV | NBT_SERVER_DS | NBT_SERVER_TIMESERV |
NBT_SERVER_CLOSEST | NBT_SERVER_WRITABLE | NBT_SERVER_CLOSEST | NBT_SERVER_WRITABLE |
@ -250,13 +292,13 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
ZERO_STRUCTP(netlogon); ZERO_STRUCTP(netlogon);
if (version & NETLOGON_NT_VERSION_5EX) { /* check if either of these bits is present */
if (version & (NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_5EX_WITH_IP)) {
uint32_t extra_flags = 0; uint32_t extra_flags = 0;
netlogon->ntver = NETLOGON_NT_VERSION_5EX; netlogon->ntver = NETLOGON_NT_VERSION_5EX;
/* could check if the user exists */ /* could check if the user exists */
if (!user) { if (user_known) {
user = "";
netlogon->nt5_ex.command = LOGON_SAM_LOGON_RESPONSE_EX; netlogon->nt5_ex.command = LOGON_SAM_LOGON_RESPONSE_EX;
} else { } else {
netlogon->nt5_ex.command = LOGON_SAM_LOGON_USER_UNKNOWN_EX; netlogon->nt5_ex.command = LOGON_SAM_LOGON_USER_UNKNOWN_EX;
@ -277,7 +319,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
extra_flags = NETLOGON_NT_VERSION_5EX_WITH_IP; extra_flags = NETLOGON_NT_VERSION_5EX_WITH_IP;
netlogon->nt5_ex.sockaddr.sa_family = 2; netlogon->nt5_ex.sockaddr.sa_family = 2;
netlogon->nt5_ex.sockaddr.pdc_ip = pdc_ip; netlogon->nt5_ex.sockaddr.pdc_ip = pdc_ip;
netlogon->nt5_ex.sockaddr.remaining = data_blob(NULL, 4); netlogon->nt5_ex.sockaddr.remaining = data_blob_talloc_zero(mem_ctx, 8);
} }
netlogon->nt5_ex.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5EX|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.lmnt_token = 0xFFFF;
@ -287,8 +329,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
netlogon->ntver = NETLOGON_NT_VERSION_5; netlogon->ntver = NETLOGON_NT_VERSION_5;
/* could check if the user exists */ /* could check if the user exists */
if (!user) { if (user_known) {
user = "";
netlogon->nt5.command = LOGON_SAM_LOGON_RESPONSE; netlogon->nt5.command = LOGON_SAM_LOGON_RESPONSE;
} else { } else {
netlogon->nt5.command = LOGON_SAM_LOGON_USER_UNKNOWN; netlogon->nt5.command = LOGON_SAM_LOGON_USER_UNKNOWN;
@ -309,8 +350,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
} else /* (version & NETLOGON_NT_VERSION_1) and all other cases */ { } else /* (version & NETLOGON_NT_VERSION_1) and all other cases */ {
netlogon->ntver = NETLOGON_NT_VERSION_1; netlogon->ntver = NETLOGON_NT_VERSION_1;
/* could check if the user exists */ /* could check if the user exists */
if (!user) { if (user_known) {
user = "";
netlogon->nt4.command = LOGON_SAM_LOGON_RESPONSE; netlogon->nt4.command = LOGON_SAM_LOGON_RESPONSE;
} else { } else {
netlogon->nt4.command = LOGON_SAM_LOGON_USER_UNKNOWN; netlogon->nt4.command = LOGON_SAM_LOGON_USER_UNKNOWN;
@ -406,7 +446,7 @@ void cldapd_netlogon_request(struct cldap_socket *cldap,
domain, host, user, version, domain_guid)); domain, host, user, version, domain_guid));
status = fill_netlogon_samlogon_response(cldapd->samctx, tmp_ctx, domain, NULL, NULL, domain_guid, status = fill_netlogon_samlogon_response(cldapd->samctx, tmp_ctx, domain, NULL, NULL, domain_guid,
user, src->addr, user, acct_control, src->addr,
version, cldapd->task->lp_ctx, &netlogon); version, cldapd->task->lp_ctx, &netlogon);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
goto failed; goto failed;

View File

@ -37,6 +37,7 @@ struct event_context;
#include "dsdb/schema/schema.h" #include "dsdb/schema/schema.h"
#include "dsdb/samdb/samdb_proto.h" #include "dsdb/samdb/samdb_proto.h"
#include "dsdb/common/proto.h" #include "dsdb/common/proto.h"
#include "dsdb/common/flags.h"
#define DSDB_CONTROL_CURRENT_PARTITION_OID "1.3.6.1.4.1.7165.4.3.2" #define DSDB_CONTROL_CURRENT_PARTITION_OID "1.3.6.1.4.1.7165.4.3.2"
struct dsdb_control_current_partition { struct dsdb_control_current_partition {

View File

@ -57,9 +57,17 @@ LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclisrcdir)/nbt/, \
$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c))) $(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c)))
[SUBSYSTEM::LIBCLI_NDR_NETLOGON]
PUBLIC_DEPENDENCIES = LIBNDR \
NDR_SECURITY
LIBCLI_NDR_NETLOGON_OBJ_FILES = $(addprefix libcli/, \
ndr_netlogon.o)
$(eval $(call proto_header_template,$(libclisrcdir)/ndr_netlogon_proto.h,$(LIBCLI_NDR_NETLOGON_OBJ_FILES:.o=.c)))
[SUBSYSTEM::LIBCLI_NETLOGON] [SUBSYSTEM::LIBCLI_NETLOGON]
PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT \ PUBLIC_DEPENDENCIES = LIBSAMBA-UTIL LIBCLI_NDR_NETLOGON
NDR_SECURITY LIBSAMBA-UTIL
LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \ LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \
netlogon.o) netlogon.o)

View File

@ -0,0 +1,209 @@
/*
Unix SMB/CIFS implementation.
CLDAP server structures
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
(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/>.
*/
/* parser auto-generated by pidl, then hand-modified by abartlet */
#include "includes.h"
#include "libcli/netlogon.h"
/* Manually modified to handle the dom_sid being optional based on if it is present or all zero */
enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_REQUEST(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_REQUEST *r)
{
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 4));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->request_count));
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->computer_name));
ndr->flags = _flags_save_string;
}
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->user_name));
ndr->flags = _flags_save_string;
}
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM);
NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->mailslot_name));
ndr->flags = _flags_save_string;
}
NDR_CHECK(ndr_push_samr_AcctFlags(ndr, NDR_SCALARS, r->acct_control));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_dom_sid0(&r->sid, ndr->flags)));
if (ndr_size_dom_sid0(&r->sid, ndr->flags)) {
struct ndr_push *_ndr_sid;
uint32_t _flags_save_DATA_BLOB = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4);
NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad));
ndr->flags = _flags_save_DATA_BLOB;
NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sid, 0, ndr_size_dom_sid0(&r->sid, ndr->flags)));
NDR_CHECK(ndr_push_dom_sid0(_ndr_sid, NDR_SCALARS|NDR_BUFFERS, &r->sid));
NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sid, 0, ndr_size_dom_sid0(&r->sid, ndr->flags)));
}
NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr, NDR_SCALARS, r->nt_version));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lmnt_token));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lm20_token));
}
if (ndr_flags & NDR_BUFFERS) {
}
return NDR_ERR_SUCCESS;
}
/* Manually modified to handle the dom_sid being optional based on if it is present (size is non-zero) or not */
enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_REQUEST(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_REQUEST *r)
{
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->request_count));
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->computer_name));
ndr->flags = _flags_save_string;
}
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->user_name));
ndr->flags = _flags_save_string;
}
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM);
NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->mailslot_name));
ndr->flags = _flags_save_string;
}
NDR_CHECK(ndr_pull_samr_AcctFlags(ndr, NDR_SCALARS, &r->acct_control));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sid_size));
if (r->sid_size) {
uint32_t _flags_save_DATA_BLOB = ndr->flags;
struct ndr_pull *_ndr_sid;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4);
NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad));
ndr->flags = _flags_save_DATA_BLOB;
NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sid, 0, r->sid_size));
NDR_CHECK(ndr_pull_dom_sid0(_ndr_sid, NDR_SCALARS|NDR_BUFFERS, &r->sid));
NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sid, 0, r->sid_size));
} else {
ZERO_STRUCT(r->sid);
}
NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr, NDR_SCALARS, &r->nt_version));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lmnt_token));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lm20_token));
}
if (ndr_flags & NDR_BUFFERS) {
}
return NDR_ERR_SUCCESS;
}
/* Manually modified to only push some parts of the structure if certain flags are set */
enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_RESPONSE_EX *r)
{
{
uint32_t _flags_save_STRUCT = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 4));
NDR_CHECK(ndr_push_netlogon_command(ndr, NDR_SCALARS, r->command));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->sbz));
NDR_CHECK(ndr_push_nbt_server_type(ndr, NDR_SCALARS, r->server_type));
NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->domain_uuid));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->forest));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->dns_domain));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_dns_name));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->domain));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_name));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->user_name));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->server_site));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->client_site));
if (r->nt_version & NETLOGON_NT_VERSION_5EX_WITH_IP) {
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags)));
{
struct ndr_push *_ndr_sockaddr;
NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags)));
NDR_CHECK(ndr_push_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr));
NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags)));
}
}
if (r->nt_version & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) {
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->next_closest_site));
}
NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr, NDR_SCALARS, r->nt_version));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lmnt_token));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lm20_token));
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_push_GUID(ndr, NDR_BUFFERS, &r->domain_uuid));
}
ndr->flags = _flags_save_STRUCT;
}
return NDR_ERR_SUCCESS;
}
/* Manually modified to only pull some parts of the structure if certain flags provided */
enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_RESPONSE_EX *r,
uint32_t nt_version_flags)
{
{
uint32_t _flags_save_STRUCT = ndr->flags;
ZERO_STRUCTP(r);
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
NDR_CHECK(ndr_pull_netlogon_command(ndr, NDR_SCALARS, &r->command));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->sbz));
NDR_CHECK(ndr_pull_nbt_server_type(ndr, NDR_SCALARS, &r->server_type));
NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->domain_uuid));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->forest));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->dns_domain));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_dns_name));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->domain));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_name));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->user_name));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->server_site));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->client_site));
if (nt_version_flags & NETLOGON_NT_VERSION_5EX_WITH_IP) {
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sockaddr_size));
{
struct ndr_pull *_ndr_sockaddr;
NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sockaddr, 0, r->sockaddr_size));
NDR_CHECK(ndr_pull_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr));
NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sockaddr, 0, r->sockaddr_size));
}
}
if (nt_version_flags & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) {
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->next_closest_site));
}
NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr, NDR_SCALARS, &r->nt_version));
if (r->nt_version != nt_version_flags) {
return NDR_ERR_VALIDATE;
}
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lmnt_token));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lm20_token));
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_pull_GUID(ndr, NDR_BUFFERS, &r->domain_uuid));
}
ndr->flags = _flags_save_STRUCT;
}
return NDR_ERR_SUCCESS;
}

View File

@ -1,99 +1,27 @@
/* parser auto-generated by pidl, then hand-modified by abartlet */ /*
Unix SMB/CIFS implementation.
CLDAP server structures
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
(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 "includes.h"
#include "libcli/netlogon.h" #include "libcli/netlogon.h"
_PUBLIC_ enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_RESPONSE_EX *r)
{
{
uint32_t _flags_save_STRUCT = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 4));
NDR_CHECK(ndr_push_netlogon_command(ndr, NDR_SCALARS, r->command));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->sbz));
NDR_CHECK(ndr_push_nbt_server_type(ndr, NDR_SCALARS, r->server_type));
NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->domain_uuid));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->forest));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->dns_domain));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_dns_name));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->domain));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_name));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->user_name));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->server_site));
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->client_site));
if (r->nt_version & NETLOGON_NT_VERSION_5EX_WITH_IP) {
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags)));
{
struct ndr_push *_ndr_sockaddr;
NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags)));
NDR_CHECK(ndr_push_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr));
NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags)));
}
}
if (r->nt_version & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) {
NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->next_closest_site));
}
NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr, NDR_SCALARS, r->nt_version));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lmnt_token));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lm20_token));
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_push_GUID(ndr, NDR_BUFFERS, &r->domain_uuid));
}
ndr->flags = _flags_save_STRUCT;
}
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_RESPONSE_EX *r,
uint32_t nt_version_flags)
{
{
uint32_t _flags_save_STRUCT = ndr->flags;
ZERO_STRUCTP(r);
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
NDR_CHECK(ndr_pull_netlogon_command(ndr, NDR_SCALARS, &r->command));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->sbz));
NDR_CHECK(ndr_pull_nbt_server_type(ndr, NDR_SCALARS, &r->server_type));
NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->domain_uuid));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->forest));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->dns_domain));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_dns_name));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->domain));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_name));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->user_name));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->server_site));
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->client_site));
if (nt_version_flags & NETLOGON_NT_VERSION_5EX_WITH_IP) {
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sockaddr_size));
{
struct ndr_pull *_ndr_sockaddr;
NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sockaddr, 0, r->sockaddr_size));
NDR_CHECK(ndr_pull_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr));
NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sockaddr, 0, r->sockaddr_size));
}
}
if (nt_version_flags & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) {
NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->next_closest_site));
}
NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr, NDR_SCALARS, &r->nt_version));
if (r->nt_version != nt_version_flags) {
return NDR_ERR_VALIDATE;
}
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lmnt_token));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lm20_token));
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_pull_GUID(ndr, NDR_BUFFERS, &r->domain_uuid));
}
ndr->flags = _flags_save_STRUCT;
}
return NDR_ERR_SUCCESS;
}
NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
struct smb_iconv_convenience *iconv_convenience, struct smb_iconv_convenience *iconv_convenience,
struct netlogon_samlogon_response *response) struct netlogon_samlogon_response *response)

View File

@ -50,4 +50,5 @@ struct nbt_netlogon_response
}; };
#include "libcli/netlogon_proto.h" #include "libcli/netlogon_proto.h"
#include "libcli/ndr_netlogon_proto.h"
#endif /* __CLDAP_SERVER_PROTO_H__ */ #endif /* __CLDAP_SERVER_PROTO_H__ */

View File

@ -332,7 +332,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT
NDR_SCHANNEL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_schannel.o NDR_SCHANNEL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_schannel.o
[SUBSYSTEM::NDR_NBT] [SUBSYSTEM::NDR_NBT]
PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR LIBCLI_NDR_NETLOGON
NDR_NBT_OBJ_FILES = $(gen_ndrsrcdir)/ndr_nbt.o NDR_NBT_OBJ_FILES = $(gen_ndrsrcdir)/ndr_nbt.o

View File

@ -10,7 +10,7 @@
import "misc.idl", "security.idl", "svcctl.idl", "samr.idl"; import "misc.idl", "security.idl", "svcctl.idl", "samr.idl";
[ [
helper("libcli/nbt/libnbt.h") helper("libcli/netlogon.h", "libcli/nbt/libnbt.h")
] ]
interface nbt interface nbt
{ {
@ -391,15 +391,23 @@ interface nbt
typedef bitmap samr_AcctFlags samr_AcctFlags; typedef bitmap samr_AcctFlags samr_AcctFlags;
typedef struct { /* query to dc hand marshaled, as it has 'optional'
* parts */
typedef [nopull,nopush] struct {
uint16 request_count; uint16 request_count;
nstring computer_name; nstring computer_name;
nstring user_name; nstring user_name;
astring mailslot_name; astring mailslot_name;
samr_AcctFlags acct_control; samr_AcctFlags acct_control;
[value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size; [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size;
/* Must not be present (ie, zero size, in request to \MAILSLOT\NET\NTLOGON */ /* The manual alignment is required because this
[subcontext(0),subcontext_size(sid_size)] dom_sid0 sid; * structure is marked flag(NDR_NOALIGN) via the
* nbt_netlogon_packet below.
*
* However, both MUST only be present if sid_size > 0
*/
[flag(NDR_ALIGN4)] DATA_BLOB _pad;
[subcontext(0),subcontext_size(sid_size)] dom_sid0 sid;
netlogon_nt_version_flags nt_version; netlogon_nt_version_flags nt_version;
uint16 lmnt_token; uint16 lmnt_token;
uint16 lm20_token; uint16 lm20_token;

View File

@ -133,18 +133,13 @@ static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot,
} }
if (netlogon->req.logon.sid_size) { if (netlogon->req.logon.sid_size) {
if (strcasecmp(dgmslot->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; sid = &netlogon->req.logon.sid;
} else { } else {
sid = NULL; sid = NULL;
} }
status = fill_netlogon_samlogon_response(samctx, packet, NULL, 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.user_name, netlogon->req.logon.acct_control, src->addr,
netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.samlogon); netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.samlogon);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
DEBUG(2,("NBT netlogon query failed domain=%s sid=%s version=%d - %s\n", DEBUG(2,("NBT netlogon query failed domain=%s sid=%s version=%d - %s\n",

View File

@ -236,6 +236,7 @@ def provision_paths_from_lp(lp, dnsdomain):
paths.secrets = os.path.join(paths.private_dir, lp.get("secrets database") or "secrets.ldb") paths.secrets = os.path.join(paths.private_dir, lp.get("secrets database") or "secrets.ldb")
paths.templates = os.path.join(paths.private_dir, "templates.ldb") paths.templates = os.path.join(paths.private_dir, "templates.ldb")
paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone")
paths.namedconf = os.path.join(paths.private_dir, "named.conf")
paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") paths.winsdb = os.path.join(paths.private_dir, "wins.ldb")
paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi")
paths.phpldapadminconfig = os.path.join(paths.private_dir, paths.phpldapadminconfig = os.path.join(paths.private_dir,
@ -1059,12 +1060,14 @@ def provision(setup_dir, message, session_info,
scope=SCOPE_SUBTREE) scope=SCOPE_SUBTREE)
assert isinstance(hostguid, str) assert isinstance(hostguid, str)
create_zone_file(paths.dns, setup_path, samdb, create_zone_file(paths.dns, paths.namedconf, setup_path, samdb,
hostname=names.hostname, hostip=hostip, hostname=names.hostname, hostip=hostip,
hostip6=hostip6, dnsdomain=names.dnsdomain, hostip6=hostip6, dnsdomain=names.dnsdomain,
domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, domaindn=names.domaindn, dnspass=dnspass, realm=names.realm,
domainguid=domainguid, hostguid=hostguid) domainguid=domainguid, hostguid=hostguid,
private_dir=paths.private_dir, keytab_name=paths.dns_keytab)
message("Please install the zone located in %s into your DNS server" % paths.dns) message("Please install the zone located in %s into your DNS server" % paths.dns)
message("See %s if you want to use secure GSS-TSIG updates" % paths.namedconf)
create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, create_phpldapadmin_config(paths.phpldapadminconfig, setup_path,
ldapi_url) ldapi_url)
@ -1281,12 +1284,18 @@ def create_phpldapadmin_config(path, setup_path, ldapi_uri):
{"S4_LDAPI_URI": ldapi_uri}) {"S4_LDAPI_URI": ldapi_uri})
def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, def create_zone_file(path_zone, path_conf, setup_path, samdb, dnsdomain, domaindn,
hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid): hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid,
private_dir, keytab_name):
"""Write out a DNS zone file, from the info in the current database. """Write out a DNS zone file, from the info in the current database.
Also writes a file with stubs appropriate for a DNS configuration file
(including GSS-TSIG configuration), and details as to some of the other
configuration changes that may be necessary.
:param path: Path of the new file. :param path_zone: Path of the new zone file.
:param setup_path": Setup path function. :param path_conf: Path of the config stubs file.
:param setup_path: Setup path function.
:param samdb: SamDB object :param samdb: SamDB object
:param dnsdomain: DNS Domain name :param dnsdomain: DNS Domain name
:param domaindn: DN of the Domain :param domaindn: DN of the Domain
@ -1307,7 +1316,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,
hostip6_base_line = " IN AAAA " + hostip6 hostip6_base_line = " IN AAAA " + hostip6
hostip6_host_line = hostname + " IN AAAA " + hostip6 hostip6_host_line = hostname + " IN AAAA " + hostip6
setup_file(setup_path("provision.zone"), path, { setup_file(setup_path("provision.zone"), path_zone, {
"DNSPASS_B64": b64encode(dnspass), "DNSPASS_B64": b64encode(dnspass),
"HOSTNAME": hostname, "HOSTNAME": hostname,
"DNSDOMAIN": dnsdomain, "DNSDOMAIN": dnsdomain,
@ -1321,6 +1330,15 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,
"HOSTIP6_HOST_LINE": hostip6_host_line, "HOSTIP6_HOST_LINE": hostip6_host_line,
}) })
setup_file(setup_path("named.conf"), path_conf, {
"DNSDOMAIN": dnsdomain,
"REALM": realm,
"REALM_WC": "*." + ".".join(realm.split(".")[1:]),
"HOSTNAME": hostname,
"DNS_KEYTAB": keytab_name,
"DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name),
})
def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename):
"""Load schema for the SamDB. """Load schema for the SamDB.

View File

@ -3,35 +3,116 @@
# the BIND nameserver. # the BIND nameserver.
# #
# If you have a very recent BIND, supporting GSS-TSIG, # You should always include the actual forward zone configuration:
# insert this into options {} (otherwise omit, it is not required if we don't accept updates)
tkey-gssapi-credential "DNS/${DNSDOMAIN}";
tkey-domain "${REALM}";
# You should always include the actual zone configuration reference:
zone "${DNSDOMAIN}." IN { zone "${DNSDOMAIN}." IN {
type master; type master;
file "${DNSDOMAIN}.zone"; file "${DNSDOMAIN}.zone";
update-policy { update-policy {
/* use ANY only for Domain controllers for now */ /*
/* for normal machines A AAAA PTR is probbaly all is needed */ * A rather long description here, as the "ms-self" option does
grant ${HOSTNAME}.${DNSDOMAIN}@${REALM} name ${HOSTNAME}.${DNSDOMAIN} ANY; * not appear in any docs yet (it can only be found in the
* source code).
*
* The short of it is that each host is allowed to update its
* own A and AAAA records, when the update request is properly
* signed by the host itself.
*
* The long description is (look at the
* dst_gssapi_identitymatchesrealmms() call in lib/dns/ssu.c and
* its definition in lib/dns/gssapictx.c for details):
*
* A GSS-TSIG update request will be signed by a given signer
* (e.g. machine-name$@${REALM}). The signer name is split into
* the machine component (e.g. "machine-name") and the realm
* component (e.g. "${REALM}"). The update is allowed if the
* following conditions are met:
*
* 1) The machine component of the signer name matches the first
* (host) component of the FQDN that is being updated.
*
* 2) The realm component of the signer name matches the realm
* in the grant statement below (${REALM}).
*
* 3) The domain component of the FQDN that is being updated
* matches the realm in the grant statement below.
*
* If the 3 conditions above are satisfied, the update succeeds.
*/
grant ${REALM} ms-self * A AAAA;
}; };
}; };
# Also, you need to change your init scripts to set this environment variable # The reverse zone configuration is optional. The following example assumes a
# for named: KRB5_KTNAME so that it points to the keytab generated. # subnet of 192.168.123.0/24:
# In RedHat derived systems such RHEL/CentOS/Fedora you can add the following zone "123.168.192.in-addr.arpa" in {
# line to the /etc/sysconfig/named file: type master;
# export KRB5_KTNAME=${DNS_KEYTAB_ABS} file "123.168.192.in-addr.arpa.zone";
# update-policy {
# Please note that most distributions have BIND configured to run under grant ${REALM_WC} wildcard *.123.168.192.in-addr.arpa. PTR;
# a non-root user account. For example, Fedora Core 6 (FC6) runs BIND as };
# the user "named" once the daemon relinquishes its rights. Therefore, };
# the file "${DNS_KEYTAB}" must be readable by the user that BIND run as. # Note that the reverse zone file is not created during the provision process.
# If BIND is running as a non-root user, the "${DNS_KEYTAB}" file must have its
# permissions altered to allow the daemon to read it. In the FC6 # The most recent BIND version (9.5.0a5 or later) supports secure GSS-TSIG
# example, execute the commands: # updates. If you are running an earlier version of BIND, or if you do not wish
# # to use secure GSS-TSIG updates, you may remove the update-policy sections in
# chgrp named ${DNS_KEYTAB_ABS} # both examples above.
# chmod g+r ${DNS_KEYTAB_ABS}
# If you are running a capable version of BIND and you wish to support secure
# GSS-TSIG updates, you must make the following configuration changes:
# - Insert the following lines into the options {} section of your named.conf
# file:
tkey-gssapi-credential "DNS/${DNSDOMAIN}";
tkey-domain "${REALM}";
# - Add settings for the ${REALM} realm to the Kerberos configuration on the DNS
# server. The easiest way is to add the following blocks to the appropriate
# sections in /etc/krb5.conf:
[realms]
${REALM} = {
kdc = ${HOSTNAME}.${DNSDOMAIN}:88
admin_server = ${HOSTNAME}.${DNSDOMAIN}:749
default_domain = ${DNSDOMAIN}
}
[domain_realm]
.${DNSDOMAIN} = ${REALM}
${DNSDOMAIN} = ${REALM}
# - Modify BIND init scripts to pass the location of the generated keytab file.
# Fedora 8 & later provide a variable named KEYTAB_FILE in /etc/sysconfig/named
# for this purpose:
KEYTAB_FILE="${DNS_KEYTAB_ABS}"
# Note that the Fedora scripts translate KEYTAB_FILE behind the scenes into a
# variable named KRB5_KTNAME, which is ultimately passed to the BIND daemon. If
# your distribution does not provide a variable like KEYTAB_FILE to pass a
# keytab file to the BIND daemon, a workaround is to place the following line in
# BIND's sysconfig file or in the init script for BIND:
export KRB5_KTNAME="${DNS_KEYTAB_ABS}"
# - Set appropriate ownership and permissions on the ${DNS_KEYTAB} file. Note
# that most distributions have BIND configured to run under a non-root user
# account. For example, Fedora 9 runs BIND as the user "named" once the daemon
# relinquishes its rights. Therefore, the file ${DNS_KEYTAB} must be readable
# by the user that BIND run as. If BIND is running as a non-root user, the
# "${DNS_KEYTAB}" file must have its permissions altered to allow the daemon to
# read it. Under Fedora 9, execute the following commands:
chgrp named ${DNS_KEYTAB_ABS}
chmod g+r ${DNS_KEYTAB_ABS}
# - Ensure the BIND zone file(s) that will be dynamically updated are in a
# directory where the BIND daemon can write. When BIND performs dynamic
# updates, it not only needs to update the zone file itself but it must also
# create a journal (.jnl) file to track the dynamic updates as they occur.
# Under Fedora 9, the /var/named directory can not be written to by the "named"
# user. However, the directory /var/named/dynamic directory does provide write
# access. Therefore the zone files were placed under the /var/named/dynamic
# directory. The file directives in both example zone statements at the
# beginning of this file were changed by prepending the directory "dynamic/".
# - If SELinux is enabled, ensure that all files have the appropriate SELinux
# file contexts. The ${DNS_KEYTAB} file must be accessible by the BIND daemon
# and should have a SELinux type of named_conf_t. This can be set with the
# following command:
chcon -t named_conf_t ${DNS_KEYTAB_ABS}

View File

@ -33,6 +33,7 @@ objectClass: secret
objectClass: kerberosSecret objectClass: kerberosSecret
realm: ${REALM} realm: ${REALM}
servicePrincipalName: DNS/${DNSDOMAIN} servicePrincipalName: DNS/${DNSDOMAIN}
msDS-KeyVersionNumber: 1
privateKeytab: ${DNS_KEYTAB} privateKeytab: ${DNS_KEYTAB}
secret:: ${DNSPASS_B64} secret:: ${DNSPASS_B64}

View File

@ -144,18 +144,38 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
CHECK_STATUS(status, NT_STATUS_NOT_FOUND); CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
printf("Trying with a AAC\n"); printf("Trying with a AAC\n");
search.in.acct_control = 0x180; search.in.acct_control = ACB_WSTRUST|ACB_SVRTRUST;
search.in.realm = n1.nt5_ex.dns_domain; search.in.realm = n1.nt5_ex.dns_domain;
status = cldap_netlogon(cldap, tctx, &search); status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK); CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
CHECK_STRING(search.out.netlogon.nt5_ex.user_name, ""); CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
printf("Trying with a zero AAC\n");
search.in.acct_control = 0x0;
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.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
printf("Trying with a zero AAC and user=Administrator\n");
search.in.acct_control = 0x0;
search.in.user = "Administrator";
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.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "Administrator");
printf("Trying with a bad AAC\n"); printf("Trying with a bad AAC\n");
search.in.user = NULL;
search.in.acct_control = 0xFF00FF00; search.in.acct_control = 0xFF00FF00;
search.in.realm = n1.nt5_ex.dns_domain; search.in.realm = n1.nt5_ex.dns_domain;
status = cldap_netlogon(cldap, tctx, &search); status = cldap_netlogon(cldap, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK); CHECK_STATUS(status, NT_STATUS_OK);
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 user only\n"); printf("Trying with a user only\n");
search = empty_search; search = empty_search;

View File

@ -42,19 +42,24 @@ static void netlogon_handler(struct dgram_mailslot_handler *dgmslot,
struct socket_address *src) struct socket_address *src)
{ {
NTSTATUS status; NTSTATUS status;
struct nbt_netlogon_response netlogon; struct nbt_netlogon_response *netlogon = dgmslot->private;
int *replies = (int *)dgmslot->private;
dgmslot->private = netlogon = talloc(dgmslot, struct nbt_netlogon_response);
if (!dgmslot->private) {
return;
}
printf("netlogon reply from %s:%d\n", src->addr, src->port); printf("netlogon reply from %s:%d\n", src->addr, src->port);
status = dgram_mailslot_netlogon_parse_response(dgmslot, dgmslot, packet, &netlogon); /* Fills in the netlogon pointer */
status = dgram_mailslot_netlogon_parse_response(dgmslot, netlogon, packet, netlogon);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
printf("Failed to parse netlogon packet from %s:%d\n", printf("Failed to parse netlogon packet from %s:%d\n",
src->addr, src->port); src->addr, src->port);
return; return;
} }
(*replies)++;
} }
@ -67,10 +72,10 @@ static bool nbt_test_netlogon(struct torture_context *tctx)
struct socket_address *dest; struct socket_address *dest;
const char *myaddress; const char *myaddress;
struct nbt_netlogon_packet logon; struct nbt_netlogon_packet logon;
struct nbt_netlogon_response *response;
struct nbt_name myname; struct nbt_name myname;
NTSTATUS status; NTSTATUS status;
struct timeval tv = timeval_current(); struct timeval tv = timeval_current();
int replies = 0;
struct socket_address *socket_address; struct socket_address *socket_address;
@ -78,7 +83,7 @@ static bool nbt_test_netlogon(struct torture_context *tctx)
struct nbt_name name; struct nbt_name name;
struct interface *ifaces; struct interface *ifaces;
name.name = lp_workgroup(tctx->lp_ctx); name.name = lp_workgroup(tctx->lp_ctx);
name.type = NBT_NAME_LOGON; name.type = NBT_NAME_LOGON;
name.scope = NULL; name.scope = NULL;
@ -112,7 +117,7 @@ static bool nbt_test_netlogon(struct torture_context *tctx)
/* setup a temporary mailslot listener for replies */ /* setup a temporary mailslot listener for replies */
dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC, dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
netlogon_handler, &replies); netlogon_handler, NULL);
ZERO_STRUCT(logon); ZERO_STRUCT(logon);
logon.command = LOGON_PRIMARY_QUERY; logon.command = LOGON_PRIMARY_QUERY;
@ -134,10 +139,17 @@ static bool nbt_test_netlogon(struct torture_context *tctx)
&myname, &logon); &myname, &logon);
torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request"); torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
while (timeval_elapsed(&tv) < 5 && replies == 0) { while (timeval_elapsed(&tv) < 5 && !dgmslot->private) {
event_loop_once(dgmsock->event_ctx); event_loop_once(dgmsock->event_ctx);
} }
response = talloc_get_type(dgmslot->private, struct nbt_netlogon_response);
torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
torture_assert(tctx, response->response_type == NETLOGON_GET_PDC, "Got incorrect type of netlogon response");
torture_assert(tctx, response->get_pdc.command == NETLOGON_RESPONSE_FROM_PDC, "Got incorrect netlogon response command");
return true; return true;
} }
@ -151,10 +163,10 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
struct socket_address *dest; struct socket_address *dest;
const char *myaddress; const char *myaddress;
struct nbt_netlogon_packet logon; struct nbt_netlogon_packet logon;
struct nbt_netlogon_response *response;
struct nbt_name myname; struct nbt_name myname;
NTSTATUS status; NTSTATUS status;
struct timeval tv = timeval_current(); struct timeval tv = timeval_current();
int replies = 0;
struct socket_address *socket_address; struct socket_address *socket_address;
@ -198,7 +210,7 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
/* setup a temporary mailslot listener for replies */ /* setup a temporary mailslot listener for replies */
dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC, dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
netlogon_handler, &replies); netlogon_handler, NULL);
ZERO_STRUCT(logon); ZERO_STRUCT(logon);
@ -207,7 +219,7 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
logon.req.logon.computer_name = TEST_NAME; logon.req.logon.computer_name = TEST_NAME;
logon.req.logon.user_name = ""; logon.req.logon.user_name = "";
logon.req.logon.mailslot_name = dgmslot->mailslot_name; logon.req.logon.mailslot_name = dgmslot->mailslot_name;
logon.req.logon.nt_version = 11; logon.req.logon.nt_version = NETLOGON_NT_VERSION_5EX_WITH_IP|NETLOGON_NT_VERSION_5|NETLOGON_NT_VERSION_1;
logon.req.logon.lmnt_token = 0xFFFF; logon.req.logon.lmnt_token = 0xFFFF;
logon.req.logon.lm20_token = 0xFFFF; logon.req.logon.lm20_token = 0xFFFF;
@ -222,10 +234,24 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
&myname, &logon); &myname, &logon);
torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request"); torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
while (timeval_elapsed(&tv) < 5 && replies == 0) { while (timeval_elapsed(&tv) < 5 && dgmslot->private == NULL) {
event_loop_once(dgmsock->event_ctx); event_loop_once(dgmsock->event_ctx);
} }
response = talloc_get_type(dgmslot->private, struct nbt_netlogon_response);
torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
map_netlogon_samlogon_response(&response->samlogon);
torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX, "Got incorrect netlogon response command");
torture_assert_int_equal(tctx, response->samlogon.nt5_ex.nt_version, NETLOGON_NT_VERSION_5EX_WITH_IP|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_1, "Got incorrect netlogon response command");
/* setup (another) temporary mailslot listener for replies */
dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
netlogon_handler, NULL);
ZERO_STRUCT(logon); ZERO_STRUCT(logon);
logon.command = LOGON_SAM_LOGON_REQUEST; logon.command = LOGON_SAM_LOGON_REQUEST;
logon.req.logon.request_count = 0; logon.req.logon.request_count = 0;
@ -247,15 +273,30 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
&myname, &logon); &myname, &logon);
torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request"); torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
while (timeval_elapsed(&tv) < 5 && replies == 0) { while (timeval_elapsed(&tv) < 5 && dgmslot->private == NULL) {
event_loop_once(dgmsock->event_ctx); event_loop_once(dgmsock->event_ctx);
} }
response = talloc_get_type(dgmslot->private, struct nbt_netlogon_response);
torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
map_netlogon_samlogon_response(&response->samlogon);
torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
torture_assert_str_equal(tctx, response->samlogon.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
join_ctx = torture_join_domain(tctx, TEST_NAME, join_ctx = torture_join_domain(tctx, TEST_NAME,
ACB_WSTRUST, &machine_credentials); ACB_WSTRUST, &machine_credentials);
dom_sid = torture_join_sid(join_ctx); dom_sid = torture_join_sid(join_ctx);
/* setup (another) temporary mailslot listener for replies */
dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
netlogon_handler, NULL);
ZERO_STRUCT(logon); ZERO_STRUCT(logon);
logon.command = LOGON_SAM_LOGON_REQUEST; logon.command = LOGON_SAM_LOGON_REQUEST;
logon.req.logon.request_count = 0; logon.req.logon.request_count = 0;
@ -278,10 +319,100 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
&myname, &logon); &myname, &logon);
torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request"); torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
while (timeval_elapsed(&tv) < 5 && replies == 0) {
while (timeval_elapsed(&tv) < 5 && dgmslot->private == NULL) {
event_loop_once(dgmsock->event_ctx); event_loop_once(dgmsock->event_ctx);
} }
response = talloc_get_type(dgmslot->private, struct nbt_netlogon_response);
torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
map_netlogon_samlogon_response(&response->samlogon);
torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
/* setup (another) temporary mailslot listener for replies */
dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
netlogon_handler, NULL);
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.acct_control = ACB_WSTRUST;
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 && dgmslot->private == NULL) {
event_loop_once(dgmsock->event_ctx);
}
response = talloc_get_type(dgmslot->private, struct nbt_netlogon_response);
torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
map_netlogon_samlogon_response(&response->samlogon);
torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
dgmslot->private = NULL;
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.acct_control = ACB_NORMAL;
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 && dgmslot->private == NULL) {
event_loop_once(dgmsock->event_ctx);
}
response = talloc_get_type(dgmslot->private, struct nbt_netlogon_response);
torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
map_netlogon_samlogon_response(&response->samlogon);
torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
torture_leave_domain(join_ctx); torture_leave_domain(join_ctx);
return true; return true;
} }
@ -295,14 +426,15 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
lp_iconv_convenience(tctx->lp_ctx)); lp_iconv_convenience(tctx->lp_ctx));
struct socket_address *dest; struct socket_address *dest;
struct test_join *join_ctx; struct test_join *join_ctx;
const struct dom_sid *dom_sid;
struct cli_credentials *machine_credentials; struct cli_credentials *machine_credentials;
const char *myaddress; const char *myaddress;
struct nbt_netlogon_packet logon; struct nbt_netlogon_packet logon;
struct nbt_netlogon_response *response;
struct nbt_name myname; struct nbt_name myname;
NTSTATUS status; NTSTATUS status;
struct timeval tv = timeval_current(); struct timeval tv = timeval_current();
int replies = 0;
struct socket_address *socket_address; struct socket_address *socket_address;
const char *address; const char *address;
@ -342,13 +474,60 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
join_ctx = torture_join_domain(tctx, TEST_NAME, join_ctx = torture_join_domain(tctx, TEST_NAME,
ACB_WSTRUST, &machine_credentials); ACB_WSTRUST, &machine_credentials);
dom_sid = torture_join_sid(join_ctx);
torture_assert(tctx, join_ctx != NULL, torture_assert(tctx, join_ctx != NULL,
talloc_asprintf(tctx, "Failed to join domain %s as %s\n", talloc_asprintf(tctx, "Failed to join domain %s as %s\n",
lp_workgroup(tctx->lp_ctx), TEST_NAME)); lp_workgroup(tctx->lp_ctx), TEST_NAME));
/* setup a temporary mailslot listener for replies */ /* setup a temporary mailslot listener for replies */
dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC, dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
netlogon_handler, &replies); netlogon_handler, NULL);
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.acct_control = ACB_WSTRUST;
/* Try with a SID this time */
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_NTLOGON,
&myname, &logon);
torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
while (timeval_elapsed(&tv) < 5 && dgmslot->private == NULL) {
event_loop_once(dgmsock->event_ctx);
}
response = talloc_get_type(dgmslot->private, struct nbt_netlogon_response);
torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
map_netlogon_samlogon_response(&response->samlogon);
torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
torture_assert_str_equal(tctx, response->samlogon.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
/* setup a temporary mailslot listener for replies */
dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
netlogon_handler, NULL);
ZERO_STRUCT(logon); ZERO_STRUCT(logon);
@ -374,10 +553,26 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
&myname, &logon); &myname, &logon);
torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request"); torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
while (timeval_elapsed(&tv) < 5 && replies == 0) { while (timeval_elapsed(&tv) < 5 && dgmslot->private == NULL) {
event_loop_once(dgmsock->event_ctx); event_loop_once(dgmsock->event_ctx);
} }
response = talloc_get_type(dgmslot->private, struct nbt_netlogon_response);
torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
map_netlogon_samlogon_response(&response->samlogon);
torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
torture_assert_str_equal(tctx, response->samlogon.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
/* setup (another) temporary mailslot listener for replies */
dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
netlogon_handler, NULL);
ZERO_STRUCT(logon); ZERO_STRUCT(logon);
logon.command = LOGON_PRIMARY_QUERY; logon.command = LOGON_PRIMARY_QUERY;
logon.req.pdc.computer_name = TEST_NAME; logon.req.pdc.computer_name = TEST_NAME;
@ -398,11 +593,55 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
&myname, &logon); &myname, &logon);
torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request"); torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
while (timeval_elapsed(&tv) < 5 && replies == 0) { while (timeval_elapsed(&tv) < 5 && !dgmslot->private) {
event_loop_once(dgmsock->event_ctx); event_loop_once(dgmsock->event_ctx);
} }
response = talloc_get_type(dgmslot->private, struct nbt_netlogon_response);
torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response");
torture_assert_int_equal(tctx, response->get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");
torture_leave_domain(join_ctx); torture_leave_domain(join_ctx);
/* setup (another) temporary mailslot listener for replies */
dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
netlogon_handler, NULL);
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 && !dgmslot->private) {
event_loop_once(dgmsock->event_ctx);
}
response = talloc_get_type(dgmslot->private, struct nbt_netlogon_response);
torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response");
torture_assert_int_equal(tctx, response->get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");
return true; return true;
} }