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:
parent
9a8f3e3c4c
commit
bd27e626c2
@ -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)));
|
||||
|
@ -127,7 +127,7 @@ struct cldap_netlogon {
|
||||
uint8_t version;
|
||||
} in;
|
||||
struct {
|
||||
struct nbt_cldap_netlogon netlogon;
|
||||
union nbt_cldap_netlogon netlogon;
|
||||
} out;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
/*******************************************/
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user