4
IDL structures for NBT operations
6
NBT is not traditionally encoded using IDL/NDR. This is a bit of an
7
experiment, and I may well switch us back to a more traditional
8
encoding if it doesn't work out
11
import "misc.idl", "security.idl", "svcctl.idl", "samr.idl";
13
helper("../libcli/netlogon.h", "../libcli/nbt/libnbt.h")
17
const int NBT_NAME_SERVICE_PORT = 137;
18
const int NBT_DGRAM_SERVICE_PORT = 138;
20
typedef [bitmap16bit] bitmap {
22
NBT_FLAG_BROADCAST = 0x0010,
23
NBT_FLAG_RECURSION_AVAIL = 0x0080,
24
NBT_FLAG_RECURSION_DESIRED = 0x0100,
25
NBT_FLAG_TRUNCATION = 0x0200,
26
NBT_FLAG_AUTHORITIVE = 0x0400,
28
NBT_FLAG_REPLY = 0x8000
31
/* the opcodes are in the operation field, masked with
34
NBT_OPCODE_QUERY = (0x0<<11),
35
NBT_OPCODE_REGISTER = (0x5<<11),
36
NBT_OPCODE_RELEASE = (0x6<<11),
37
NBT_OPCODE_WACK = (0x7<<11),
38
NBT_OPCODE_REFRESH = (0x8<<11),
39
NBT_OPCODE_REFRESH2 = (0x9<<11),
40
NBT_OPCODE_MULTI_HOME_REG = (0xf<<11)
55
/* we support any 8bit name type, but by defining the common
56
ones here we get better debug displays */
57
typedef [enum8bit] enum {
58
NBT_NAME_CLIENT = 0x00,
61
NBT_NAME_SERVER = 0x20,
63
NBT_NAME_LOGON = 0x1C,
64
NBT_NAME_MASTER = 0x1D,
65
NBT_NAME_BROWSER = 0x1E
68
/* the ndr parser for nbt_name is separately defined in
69
nbtname.c (along with the parsers for nbt_string) */
70
typedef [public,nopull,nopush] struct {
76
typedef [public,enum16bit] enum {
80
typedef [public,enum16bit] enum {
81
NBT_QTYPE_ADDRESS = 0x0001,
82
NBT_QTYPE_NAMESERVICE = 0x0002,
83
NBT_QTYPE_NULL = 0x000A,
84
NBT_QTYPE_NETBIOS = 0x0020,
85
NBT_QTYPE_STATUS = 0x0021
90
nbt_qtype question_type;
91
nbt_qclass question_class;
94
/* these are the possible values of the NBT_NM_OWNER_TYPE
103
typedef [bitmap16bit] bitmap {
104
NBT_NM_PERMANENT = 0x0200,
105
NBT_NM_ACTIVE = 0x0400,
106
NBT_NM_CONFLICT = 0x0800,
107
NBT_NM_DEREGISTER = 0x1000,
108
NBT_NM_OWNER_TYPE = 0x6000,
109
NBT_NM_GROUP = 0x8000
119
nbt_rdata_address addresses[length/6];
126
uint16 version_number;
127
uint16 period_of_statistics;
128
uint16 number_of_crcs;
129
uint16 number_alignment_errors;
130
uint16 number_of_collisions;
131
uint16 number_send_aborts;
132
uint32 number_good_sends;
133
uint32 number_good_receives;
134
uint16 number_retransmits;
135
uint16 number_no_resource_conditions;
136
uint16 number_free_command_blocks;
137
uint16 total_number_command_blocks;
138
uint16 max_total_number_command_blocks;
139
uint16 number_pending_sessions;
140
uint16 max_number_pending_sessions;
141
uint16 max_total_sessions_possible;
142
uint16 session_data_packet_size;
146
[charset(DOS)] uint8 name[15];
152
[value(num_names * 18 + 47)] uint16 length;
154
nbt_status_name names[num_names];
155
nbt_statistics statistics;
163
typedef [nodiscriminant,public] union {
164
[case(NBT_QTYPE_NETBIOS)] nbt_rdata_netbios netbios;
165
[case(NBT_QTYPE_STATUS)] nbt_rdata_status status;
166
[default] nbt_rdata_data data;
170
* this macro works around the problem
171
* that we need to use nbt_rdata_data
172
* together with NBT_QTYPE_NETBIOS
175
typedef [flag(LIBNDR_PRINT_ARRAY_HEX),nopush] struct {
180
[switch_is(rr_type)] nbt_rdata rdata;
183
typedef [flag(NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX),public] struct {
185
nbt_operation operation;
190
nbt_name_question questions[qdcount];
191
nbt_res_rec answers[ancount];
192
nbt_res_rec nsrecs[nscount];
193
nbt_res_rec additional[arcount];
194
[flag(NDR_REMAINING)] DATA_BLOB padding;
199
NBT DGRAM packets (UDP/138)
202
typedef [enum8bit] enum {
203
DGRAM_DIRECT_UNIQUE = 0x10,
204
DGRAM_DIRECT_GROUP = 0x11,
208
DGRAM_QUERY_POSITIVE = 0x15,
209
DGRAM_QUERY_NEGATIVE = 0x16
212
typedef [bitmap8bit] bitmap {
213
DGRAM_FLAG_MORE = 0x01,
214
DGRAM_FLAG_FIRST = 0x02,
215
DGRAM_FLAG_NODE_TYPE = 0x0C
218
typedef [enum8bit] enum {
222
DGRAM_NODE_NBDD = 0x0C
225
/* a dgram_message is the main dgram body in general use */
227
/* the most common datagram type is a SMB_TRANSACTION
228
operation, where a SMB packet is used in the data section
229
of a dgram_message to hold a trans request, which in turn
230
holds a small command structure. It's a very strange beast
231
indeed. To make the code cleaner we define a basic SMB
232
packet in IDL here. This is not a general purpose SMB
233
packet, and won't be used in the core SMB client/server
234
code, but it does make working with these types of dgrams
237
const string NBT_MAILSLOT_NETLOGON = "\\MAILSLOT\\NET\\NETLOGON";
238
const string NBT_MAILSLOT_NTLOGON = "\\MAILSLOT\\NET\\NTLOGON";
239
const string NBT_MAILSLOT_GETDC = "\\MAILSLOT\\NET\\GETDC";
240
const string NBT_MAILSLOT_BROWSE = "\\MAILSLOT\\BROWSE";
242
typedef [enum8bit] enum {
243
SMB_TRANSACTION = 0x25
247
[range(17,17),value(17)] uint8 wct;
248
uint16 total_param_count;
249
uint16 total_data_count;
250
uint16 max_param_count;
251
uint16 max_data_count;
252
uint8 max_setup_count;
261
[range(3,3),value(3)] uint8 setup_count;
266
[value(strlen(mailslot_name)+1+data.length)]
268
astring mailslot_name;
269
[flag(NDR_REMAINING)] DATA_BLOB data;
272
typedef [nodiscriminant] union {
273
[case(SMB_TRANSACTION)] smb_trans_body trans;
277
typedef [flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN|NDR_PAHEX),public] struct {
278
smb_command smb_command;
291
[switch_is(smb_command)] smb_body body;
294
const uint32 DGRAM_SMB = 0xff534d42; /* 0xffSMB */
296
typedef [nodiscriminant] union {
297
[case(DGRAM_SMB)] dgram_smb_packet smb;
298
} dgram_message_body;
303
nbt_name source_name;
305
uint32 dgram_body_type;
306
[switch_is(dgram_body_type)] dgram_message_body body;
309
typedef [enum8bit] enum {
310
DGRAM_ERROR_NAME_NOT_PRESENT = 0x82,
311
DGRAM_ERROR_INVALID_SOURCE = 0x83,
312
DGRAM_ERROR_INVALID_DEST = 0x84
315
typedef [nodiscriminant] union {
316
[case(DGRAM_DIRECT_UNIQUE)] dgram_message msg;
317
[case(DGRAM_DIRECT_GROUP)] dgram_message msg;
318
[case(DGRAM_BCAST)] dgram_message msg;
319
[case(DGRAM_ERROR)] dgram_err_code error;
320
[case(DGRAM_QUERY)] nbt_name dest_name;
321
[case(DGRAM_QUERY_POSITIVE)] nbt_name dest_name;
322
[case(DGRAM_QUERY_NEGATIVE)] nbt_name dest_name;
325
typedef [flag(NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX),public] struct {
326
dgram_msg_type msg_type;
329
ipv4address src_addr;
331
[switch_is(msg_type)] dgram_data data;
335
/******************************************
336
* \MAILSLOT\NET\NETLOGON mailslot requests
338
* \MAILSLOT\NET\NTLOGON mailslot requests
341
typedef [public,gensize] struct {
342
uint32 sockaddr_family;
343
[flag(NDR_BIG_ENDIAN)] ipv4address pdc_ip;
344
[flag(NDR_REMAINING)] DATA_BLOB remaining;
347
typedef [bitmap32bit,public] bitmap {
348
NBT_SERVER_PDC = 0x00000001,
349
NBT_SERVER_GC = 0x00000004,
350
NBT_SERVER_LDAP = 0x00000008,
351
NBT_SERVER_DS = 0x00000010,
352
NBT_SERVER_KDC = 0x00000020,
353
NBT_SERVER_TIMESERV = 0x00000040,
354
NBT_SERVER_CLOSEST = 0x00000080,
355
NBT_SERVER_WRITABLE = 0x00000100,
356
NBT_SERVER_GOOD_TIMESERV = 0x00000200,
357
NBT_SERVER_NDNC = 0x00000400,
358
NBT_SERVER_SELECT_SECRET_DOMAIN_6 = 0x00000800,
359
NBT_SERVER_FULL_SECRET_DOMAIN_6 = 0x00001000
362
typedef [bitmap32bit,public] bitmap {
363
NETLOGON_NT_VERSION_1 = 0x00000001,
364
NETLOGON_NT_VERSION_5 = 0x00000002,
365
NETLOGON_NT_VERSION_5EX = 0x00000004,
366
NETLOGON_NT_VERSION_5EX_WITH_IP = 0x00000008,
367
NETLOGON_NT_VERSION_WITH_CLOSEST_SITE = 0x00000010,
368
NETLOGON_NT_VERSION_AVIOD_NT4EMUL = 0x01000000,
369
NETLOGON_NT_VERSION_PDC = 0x10000000,
370
NETLOGON_NT_VERSION_IP = 0x20000000,
371
NETLOGON_NT_VERSION_LOCAL = 0x40000000,
372
NETLOGON_NT_VERSION_GC = 0x80000000
373
} netlogon_nt_version_flags;
375
typedef [enum16bit,public] enum {
376
LOGON_PRIMARY_QUERY = 7, /* Was also NETLOGON_QUERY_FOR_PDC */
377
NETLOGON_ANNOUNCE_UAS = 10,
378
NETLOGON_RESPONSE_FROM_PDC = 12,
379
LOGON_SAM_LOGON_REQUEST = 18, /* Was also NETLOGON_QUERY_FOR_PDC2, NTLOGON_SAM_LOGON */
380
LOGON_SAM_LOGON_RESPONSE = 19, /* Was also NTLOGON_SAM_LOGON_REPLY */
381
LOGON_SAM_LOGON_PAUSE_RESPONSE = 20,
382
LOGON_SAM_LOGON_USER_UNKNOWN = 21, /* Was also NTLOGON_SAM_LOGON_REPLY15 */
383
LOGON_SAM_LOGON_RESPONSE_EX = 23, /* was NETLOGON_RESPONSE_FROM_PDC2 */
384
LOGON_SAM_LOGON_PAUSE_RESPONSE_EX = 24,
385
LOGON_SAM_LOGON_USER_UNKNOWN_EX = 25 /* was NETLOGON_RESPONSE_FROM_PDC_USER */
388
typedef bitmap samr_AcctFlags samr_AcctFlags;
390
/* query to dc hand marshaled, as it has 'optional'
392
typedef [nopull,nopush] struct {
393
uint16 request_count;
394
nstring computer_name;
396
astring mailslot_name;
397
samr_AcctFlags acct_control;
398
[value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size;
399
/* The manual alignment is required because this
400
* structure is marked flag(NDR_NOALIGN) via the
401
* nbt_netlogon_packet below.
403
* However, both MUST only be present if sid_size > 0
405
[flag(NDR_ALIGN4)] DATA_BLOB _pad;
406
[subcontext(0),subcontext_size(sid_size)] dom_sid0 sid;
407
netlogon_nt_version_flags nt_version;
410
} NETLOGON_SAM_LOGON_REQUEST;
412
typedef [flag(NDR_NOALIGN),public] struct {
413
netlogon_command command;
417
netlogon_nt_version_flags nt_version;
420
} NETLOGON_SAM_LOGON_RESPONSE_NT40;
422
typedef [flag(NDR_NOALIGN),public] struct {
423
netlogon_command command;
430
nbt_string dns_domain;
431
nbt_string pdc_dns_name;
433
nbt_server_type server_type;
434
netlogon_nt_version_flags nt_version;
437
} NETLOGON_SAM_LOGON_RESPONSE;
439
/* response from pdc hand marshaled (we have an additional
440
* function that uses this structure), as it has 'optional'
442
typedef [flag(NDR_NOALIGN),public] struct {
443
netlogon_command command;
444
uint16 sbz; /* From the docs */
445
nbt_server_type server_type;
448
nbt_string dns_domain;
449
nbt_string pdc_dns_name;
452
nbt_string user_name;
453
nbt_string server_site;
454
nbt_string client_site;
456
/* Optional on NETLOGON_NT_VERSION_5EX_WITH_IP */
457
[value(ndr_size_nbt_sockaddr(&sockaddr, ndr->iconv_convenience, ndr->flags))] uint8 sockaddr_size;
458
[subcontext(0),subcontext_size(sockaddr_size)] nbt_sockaddr sockaddr;
460
/* Optional on NETLOGON_NT_VERSION_WITH_CLOSEST_SITE */
461
nbt_string next_closest_site;
463
netlogon_nt_version_flags nt_version;
466
} NETLOGON_SAM_LOGON_RESPONSE_EX;
468
/* query for pdc request */
470
astring computer_name;
471
astring mailslot_name;
472
[flag(NDR_ALIGN2)] DATA_BLOB _pad;
473
nstring unicode_name;
474
netlogon_nt_version_flags nt_version;
477
} nbt_netlogon_query_for_pdc;
479
/* response from pdc */
480
typedef [flag(NDR_NOALIGN),public] struct {
481
netlogon_command command;
483
[flag(NDR_ALIGN2)] DATA_BLOB _pad;
484
nstring unicode_pdc_name;
486
netlogon_nt_version_flags nt_version;
489
} nbt_netlogon_response_from_pdc;
491
typedef enum netr_SamDatabaseID netr_SamDatabaseID;
493
/* used to announce SAM changes - MS-NRPC 2.2.1.5.1 */
495
netr_SamDatabaseID db_index;
498
} nbt_db_change_info;
507
[flag(NDR_ALIGN2)] DATA_BLOB _pad;
508
nstring unicode_pdc_name;
509
nstring unicode_domain;
511
nbt_db_change_info dbchange[db_count];
512
[value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size;
513
[subcontext(0),subcontext_size(sid_size)] dom_sid0 sid;
514
uint32 message_format_version;
515
uint32 message_token;
516
} NETLOGON_DB_CHANGE;
518
typedef [nodiscriminant] union {
519
[case(LOGON_SAM_LOGON_REQUEST)] NETLOGON_SAM_LOGON_REQUEST logon;
520
[case(LOGON_PRIMARY_QUERY)] nbt_netlogon_query_for_pdc pdc;
521
[case(NETLOGON_ANNOUNCE_UAS)] NETLOGON_DB_CHANGE uas;
522
} nbt_netlogon_request;
525
[case(NETLOGON_RESPONSE_FROM_PDC)] nbt_netlogon_response_from_pdc response;
526
[case(NETLOGON_RESPONSE_FROM_PDC_USER)] nbt_netlogon_response_from_pdc2 response2;
528
[case(LOGON_SAM_LOGON_PAUSE_RESPONSE)] NETLOGON_SAM_LOGON_RESPONSE reply;
529
[case(LOGON_SAM_LOGON_RESPONSE)] NETLOGON_SAM_LOGON_RESPONSE reply;
530
[case(LOGON_SAM_LOGON_USER_UNKNOWN)] NETLOGON_SAM_LOGON_RESPONSE reply;
531
[case(LOGON_SAM_LOGON_RESPONSE_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex;
532
[case(LOGON_SAM_LOGON_PAUSE_RESPONSE_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex;
533
[case(LOGON_SAM_LOGON_USER_UNKNOWN_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex;
536
typedef [flag(NDR_NOALIGN),public] struct {
537
netlogon_command command;
538
[switch_is(command)] nbt_netlogon_request req;
539
} nbt_netlogon_packet;
541
/********************************************************/
542
/* \MAILSLOT\BROWSE mailslot requests */
543
/* for details see http://ubiqx.org/cifs/Browsing.html */
544
/********************************************************/
545
typedef bitmap svcctl_ServerType svcctl_ServerType;
547
typedef [enum8bit] enum {
548
HostAnnouncement = 1,
549
AnnouncementRequest = 2,
551
GetBackupListReq = 9,
552
GetBackupListResp = 10,
554
DomainAnnouncement = 12,
555
MasterAnnouncement = 13,
556
ResetBrowserState = 14,
557
LocalMasterAnnouncement = 15
563
[charset(DOS)] uint8 ServerName[16];
566
svcctl_ServerType ServerType;
571
} nbt_browse_host_announcement;
575
astring ResponseName;
576
} nbt_browse_announcement_request;
581
uint32 UpTime; /* In milliseconds */
582
uint32 Reserved; /* Must be zero */
584
} nbt_browse_election_request;
589
} nbt_browse_backup_list_request;
594
nbt_name BackupServerList[BackupCount];/* TODO: this is wrong */
595
} nbt_browse_backup_list_response;
599
} nbt_browse_become_backup;
604
[charset(DOS)] uint8 ServerName[16];
607
svcctl_ServerType ServerType;
608
uint32 MysteriousField;
610
} nbt_browse_domain_announcement;
614
} nbt_browse_master_announcement;
618
} nbt_browse_reset_state;
623
[charset(DOS)] uint8 ServerName[16];
626
svcctl_ServerType ServerType;
631
} nbt_browse_local_master_announcement;
633
typedef [nodiscriminant] union {
634
[case(HostAnnouncement)] nbt_browse_host_announcement host_annoucement;
635
[case(AnnouncementRequest)] nbt_browse_announcement_request announcement_request;
636
[case(Election)] nbt_browse_election_request election_request;
637
[case(GetBackupListReq)] nbt_browse_backup_list_request backup_list_request;
638
[case(GetBackupListResp)] nbt_browse_backup_list_response backup_list_response;
639
[case(BecomeBackup)] nbt_browse_become_backup become_backup;
640
[case(DomainAnnouncement)] nbt_browse_domain_announcement domain_announcement;
641
[case(MasterAnnouncement)] nbt_browse_master_announcement master_announcement;
642
[case(ResetBrowserState)] nbt_browse_reset_state reset_browser_state;
643
[case(LocalMasterAnnouncement)] nbt_browse_local_master_announcement local_master_announcement;
644
} nbt_browse_payload;
646
typedef [public,flag(NDR_NOALIGN)] struct {
647
nbt_browse_opcode opcode;
648
[switch_is(opcode)] nbt_browse_payload payload;