1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-29 21:47:30 +03:00

r6720: added support for the remaining 2 types of CLDAP netlogon

response.

To work around the fact that the type of the returned data is not
encoded in the packet, this required adding ndr_pull_union_blob()
which allows us to pull a blob into a union with a specified switch
value, in this case the switch value comes from the calling NtVer field.
This commit is contained in:
Andrew Tridgell 2005-05-10 23:33:56 +00:00 committed by Gerald (Jerry) Carter
parent 9a8f3e3c4c
commit bd27e626c2
6 changed files with 105 additions and 32 deletions

View File

@ -451,8 +451,9 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req,
}
data = search.out.response->attributes[0].values;
status = ndr_pull_struct_blob_all(data, mem_ctx, &io->out.netlogon,
(ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon);
status = ndr_pull_union_blob(data, mem_ctx, &io->out.netlogon,
io->in.version & 0xF,
(ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(2,("cldap failed to parse netlogon response of type 0x%02x\n",
SVAL(data->data, 0)));

View File

@ -127,7 +127,7 @@ struct cldap_netlogon {
uint8_t version;
} in;
struct {
struct nbt_cldap_netlogon netlogon;
union nbt_cldap_netlogon netlogon;
} out;
};

View File

@ -452,24 +452,38 @@
/*******************************************/
/* CLDAP netlogon response */
typedef enum {
CLDAP_NETLOGON_19 = 0x13,
CLDAP_NETLOGON_23 = 0x17
} nbt_cldap_netlogon_command;
/* note that these structures are very similar to, but not
quite identical to, the netlogon structures above */
/* cldap type 19 netlogon response */
typedef struct {
[value(19)] uint16 type;
nstring pdc_name;
nstring unknown;
nstring domain_name;
uint32 nt_version;
uint16 lmnt_token;
uint16 lm20_token;
} nbt_cldap_netlogon_19;
} nbt_cldap_netlogon_1;
/* cldap type 23 netlogon response */
typedef struct {
[flag(NDR_ALIGN4)] DATA_BLOB _pad;
[value(19)] uint16 type;
nstring pdc_name;
nstring unknown;
nstring domain_name;
GUID domain_uuid;
GUID unknown_uuid;
nbt_string forest;
nbt_string dns_domain;
nbt_string pdc_dns_name;
ipv4address pdc_ip;
nbt_server_type server_type;
uint32 nt_version;
uint16 lmnt_token;
uint16 lm20_token;
} nbt_cldap_netlogon_2;
typedef struct {
[value(23)] uint32 type;
nbt_server_type server_type;
GUID domain_uuid;
nbt_string forest;
@ -483,16 +497,40 @@
uint32 nt_version;
uint16 lmnt_token;
uint16 lm20_token;
} nbt_cldap_netlogon_23;
} nbt_cldap_netlogon_3;
typedef [nodiscriminant] union {
[case(CLDAP_NETLOGON_19)] nbt_cldap_netlogon_19 logon19;
[case(CLDAP_NETLOGON_23)] nbt_cldap_netlogon_23 logon23;
} nbt_cldap_netlogon_info;
typedef struct {
[value(23)] 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 site_name;
nbt_string site_name2;
uint8 unknown;
uint32 unknown2;
[flag(NDR_BIG_ENDIAN)]
ipv4address pdc_ip;
uint32 unknown3[2];
uint32 nt_version;
uint16 lmnt_token;
uint16 lm20_token;
} nbt_cldap_netlogon_4;
typedef [flag(NDR_NOALIGN),public] struct {
nbt_cldap_netlogon_command command;
[switch_is(command)] nbt_cldap_netlogon_info info;
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_2 logon2;
[case(3)] nbt_cldap_netlogon_2 logon2;
[case(4)] nbt_cldap_netlogon_3 logon3;
[case(5)] nbt_cldap_netlogon_3 logon3;
[case(6)] nbt_cldap_netlogon_3 logon3;
[case(7)] nbt_cldap_netlogon_3 logon3;
[default] nbt_cldap_netlogon_4 logon4;
} nbt_cldap_netlogon;
/*******************************************/

View File

@ -138,6 +138,7 @@ struct ndr_print {
/* useful macro for debugging */
#define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p)
#define NDR_PRINT_UNION_DEBUG(type, level, p) ndr_print_union_debug((ndr_print_fn_t)ndr_print_ ##type, #p, level, p)
#define NDR_PRINT_FUNCTION_DEBUG(type, flags, p) ndr_print_function_debug((ndr_print_function_t)ndr_print_ ##type, #type, flags, p)
#define NDR_PRINT_BOTH_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_BOTH, p)
#define NDR_PRINT_OUT_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_OUT, p)

View File

@ -324,6 +324,23 @@ void ndr_print_debug(ndr_print_fn_t fn, const char *name, void *ptr)
talloc_free(ndr);
}
/*
a useful helper function for printing idl unions via DEBUG()
*/
void ndr_print_union_debug(ndr_print_fn_t fn, const char *name, uint32_t level, void *ptr)
{
struct ndr_print *ndr;
ndr = talloc_zero(NULL, struct ndr_print);
if (!ndr) return;
ndr->print = ndr_print_debug_helper;
ndr->depth = 1;
ndr->flags = 0;
ndr_print_set_switch_value(ndr, ptr, level);
fn(ndr, name, ptr);
talloc_free(ndr);
}
/*
a useful helper function for printing idl function calls via DEBUG()
*/
@ -780,6 +797,28 @@ NTSTATUS ndr_pull_struct_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, vo
return status;
}
/*
pull a union from a blob using NDR, given the union discriminator
*/
NTSTATUS ndr_pull_union_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,
uint32_t level, ndr_pull_flags_fn_t fn)
{
struct ndr_pull *ndr;
NTSTATUS status;
ndr = ndr_pull_init_blob(blob, mem_ctx);
if (!ndr) {
return NT_STATUS_NO_MEMORY;
}
ndr_pull_set_switch_value(ndr, p, level);
status = fn(ndr, NDR_SCALARS|NDR_BUFFERS, p);
if (!NT_STATUS_IS_OK(status)) return status;
if (ndr->offset != ndr->data_size) {
return NT_STATUS_BUFFER_TOO_SMALL;
}
return status;
}
/*
push a struct to a blob using NDR
*/

View File

@ -37,25 +37,19 @@ static BOOL test_cldap_netlogon(TALLOC_CTX *mem_ctx, const char *dest)
struct cldap_netlogon search;
int i;
search.in.dest_address = dest;
search.in.realm = lp_realm();
search.in.host = lp_netbios_name();
search.in.version = 6;
status = cldap_netlogon(cldap, mem_ctx, &search);
search.in.dest_address = dest;
search.in.realm = lp_realm();
search.in.host = lp_netbios_name();
if (!NT_STATUS_IS_OK(status)) {
printf("netlogon failed - %s\n", nt_errstr(status));
} else {
NDR_PRINT_DEBUG(nbt_cldap_netlogon, &search.out.netlogon);
}
for (i=0;i<20;i++) {
for (i=0;i<256;i++) {
search.in.version = i;
printf("Trying netlogon level %d\n", i);
status = cldap_netlogon(cldap, mem_ctx, &search);
if (!NT_STATUS_IS_OK(status)) {
printf("netlogon[%d] failed - %s\n", i, nt_errstr(status));
} else {
NDR_PRINT_DEBUG(nbt_cldap_netlogon, &search.out.netlogon);
NDR_PRINT_UNION_DEBUG(nbt_cldap_netlogon, i & 0xF,
&search.out.netlogon);
}
}