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";
13 helper
("../librpc/ndr/ndr_nbt.h"),
14 headerhelper
("lib/util/time.h"),
15 helpstring("NBT messages"),
16 uuid("6def41b6-86e4-4c32-997c-ed33af7bcd8e")
20 const int NBT_NAME_SERVICE_PORT
= 137;
21 const int NBT_DGRAM_SERVICE_PORT
= 138;
23 typedef [bitmap16bit
] bitmap
{
25 NBT_FLAG_BROADCAST
= 0x0010,
26 NBT_FLAG_RECURSION_AVAIL
= 0x0080,
27 NBT_FLAG_RECURSION_DESIRED
= 0x0100,
28 NBT_FLAG_TRUNCATION
= 0x0200,
29 NBT_FLAG_AUTHORITATIVE
= 0x0400,
31 NBT_FLAG_REPLY
= 0x8000
34 /* the opcodes are in the operation field, masked with
37 NBT_OPCODE_QUERY
= (0x0<<11),
38 NBT_OPCODE_REGISTER
= (0x5<<11),
39 NBT_OPCODE_RELEASE
= (0x6<<11),
40 NBT_OPCODE_WACK
= (0x7<<11),
41 NBT_OPCODE_REFRESH
= (0x8<<11),
42 NBT_OPCODE_REFRESH2
= (0x9<<11),
43 NBT_OPCODE_MULTI_HOME_REG
= (0xf<<11)
58 /* we support any 8bit name type, but by defining the common
59 ones here we get better debug displays */
60 typedef [enum8bit
] enum {
61 NBT_NAME_CLIENT
= 0x00,
64 NBT_NAME_SERVER
= 0x20,
66 NBT_NAME_LOGON
= 0x1C,
67 NBT_NAME_MASTER
= 0x1D,
68 NBT_NAME_BROWSER
= 0x1E
71 /* the ndr parser for nbt_name is separately defined in
72 nbtname.c (along with the parsers for nbt_string) */
73 typedef [public,nopull
,nopush
] struct {
79 typedef [public,enum16bit
] enum {
83 typedef [public,enum16bit
,nopush
] enum {
84 NBT_QTYPE_ADDRESS
= 0x0001,
85 NBT_QTYPE_NAMESERVICE
= 0x0002,
86 NBT_QTYPE_NULL
= 0x000A,
87 NBT_QTYPE_NETBIOS
= 0x0020,
88 NBT_QTYPE_STATUS
= 0x0021,
90 * Indicates that this is a WACK packet. As long as the size of
91 * ‘int’ is larger than 16 bits, this value cannot appear on the
92 * wire. We’ll encode it instead as NBT_QTYPE_NETBIOS.
99 nbt_qtype question_type
;
100 nbt_qclass question_class
;
103 /* these are the possible values of the NBT_NM_OWNER_TYPE
112 typedef [bitmap16bit
] bitmap
{
113 NBT_NM_PERMANENT
= 0x0200,
114 NBT_NM_ACTIVE
= 0x0400,
115 NBT_NM_CONFLICT
= 0x0800,
116 NBT_NM_DEREGISTER
= 0x1000,
117 NBT_NM_OWNER_TYPE
= 0x6000,
118 NBT_NM_GROUP
= 0x8000
128 nbt_rdata_address addresses
[length
/6];
135 uint16 version_number
;
136 uint16 period_of_statistics
;
137 uint16 number_of_crcs
;
138 uint16 number_alignment_errors
;
139 uint16 number_of_collisions
;
140 uint16 number_send_aborts
;
141 uint32 number_good_sends
;
142 uint32 number_good_receives
;
143 uint16 number_retransmits
;
144 uint16 number_no_resource_conditions
;
145 uint16 number_free_command_blocks
;
146 uint16 total_number_command_blocks
;
147 uint16 max_total_number_command_blocks
;
148 uint16 number_pending_sessions
;
149 uint16 max_number_pending_sessions
;
150 uint16 max_total_sessions_possible
;
151 uint16 session_data_packet_size
;
155 [charset
(DOS
)] uint8 name
[15];
161 [value
(num_names
* 18 + 47)] uint16 length
;
163 nbt_status_name names
[num_names
];
164 nbt_statistics statistics
;
172 typedef [nodiscriminant
,public] union {
173 [case(NBT_QTYPE_NETBIOS
)] nbt_rdata_netbios netbios
;
174 [case(NBT_QTYPE_STATUS
)] nbt_rdata_status status
;
175 [default] nbt_rdata_data data
;
178 typedef [flag
(LIBNDR_PRINT_ARRAY_HEX
)] struct {
183 [switch_is(rr_type
)] nbt_rdata rdata
;
186 typedef [flag
(NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX
),public] struct {
188 nbt_operation operation
;
193 nbt_name_question questions
[qdcount
];
194 nbt_res_rec answers
[ancount
];
195 nbt_res_rec nsrecs
[nscount
];
196 nbt_res_rec additional
[arcount
];
197 [flag
(NDR_REMAINING
)] DATA_BLOB padding
;
202 NBT DGRAM packets (UDP/138)
205 typedef [enum8bit
] enum {
206 DGRAM_DIRECT_UNIQUE
= 0x10,
207 DGRAM_DIRECT_GROUP
= 0x11,
211 DGRAM_QUERY_POSITIVE
= 0x15,
212 DGRAM_QUERY_NEGATIVE
= 0x16
215 typedef [bitmap8bit
] bitmap
{
216 DGRAM_FLAG_MORE
= 0x01,
217 DGRAM_FLAG_FIRST
= 0x02,
218 DGRAM_FLAG_NODE_TYPE
= 0x0C
221 typedef [enum8bit
] enum {
225 DGRAM_NODE_NBDD
= 0x0C
228 /* a dgram_message is the main dgram body in general use */
230 /* the most common datagram type is a SMB_TRANSACTION
231 operation, where a SMB packet is used in the data section
232 of a dgram_message to hold a trans request, which in turn
233 holds a small command structure. It's a very strange beast
234 indeed. To make the code cleaner we define a basic SMB
235 packet in IDL here. This is not a general purpose SMB
236 packet, and won't be used in the core SMB client/server
237 code, but it does make working with these types of dgrams
240 const string NBT_MAILSLOT_NETLOGON
= "\\MAILSLOT\\NET\\NETLOGON";
241 const string NBT_MAILSLOT_NTLOGON
= "\\MAILSLOT\\NET\\NTLOGON";
242 const string NBT_MAILSLOT_GETDC
= "\\MAILSLOT\\NET\\GETDC";
243 const string NBT_MAILSLOT_BROWSE
= "\\MAILSLOT\\BROWSE";
245 typedef [enum8bit
] enum {
246 SMB_TRANSACTION
= 0x25
250 [range(17,17),value
(17)] uint8 wct
;
251 uint16 total_param_count
;
252 uint16 total_data_count
;
253 uint16 max_param_count
;
254 uint16 max_data_count
;
255 uint8 max_setup_count
;
264 [range(3,3),value
(3)] uint8 setup_count
;
269 [value
(strlen
(mailslot_name
)+1+data.length
)]
271 astring mailslot_name
;
272 [flag
(NDR_REMAINING
)] DATA_BLOB data
;
275 typedef [nodiscriminant
] union {
276 [case(SMB_TRANSACTION
)] smb_trans_body trans
;
280 typedef [flag
(NDR_NOALIGN|NDR_LITTLE_ENDIAN|NDR_PAHEX
),public] struct {
281 smb_command smb_command
;
294 [switch_is(smb_command
)] smb_body body
;
297 const uint32 DGRAM_SMB
= 0xff534d42; /* 0xffSMB */
299 typedef [nodiscriminant
] union {
300 [case(DGRAM_SMB
)] dgram_smb_packet smb
;
301 } dgram_message_body
;
306 nbt_name source_name
;
308 uint32 dgram_body_type
;
309 [switch_is(dgram_body_type
)] dgram_message_body body
;
312 typedef [enum8bit
] enum {
313 DGRAM_ERROR_NAME_NOT_PRESENT
= 0x82,
314 DGRAM_ERROR_INVALID_SOURCE
= 0x83,
315 DGRAM_ERROR_INVALID_DEST
= 0x84
318 typedef [nodiscriminant
] union {
319 [case(DGRAM_DIRECT_UNIQUE
)] dgram_message msg
;
320 [case(DGRAM_DIRECT_GROUP
)] dgram_message msg
;
321 [case(DGRAM_BCAST
)] dgram_message msg
;
322 [case(DGRAM_ERROR
)] dgram_err_code error
;
323 [case(DGRAM_QUERY
)] nbt_name dest_name
;
324 [case(DGRAM_QUERY_POSITIVE
)] nbt_name dest_name
;
325 [case(DGRAM_QUERY_NEGATIVE
)] nbt_name dest_name
;
328 typedef [flag
(NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX
),public] struct {
329 dgram_msg_type msg_type
;
332 ipv4address src_addr
;
334 [switch_is(msg_type
)] dgram_data data
;
338 /******************************************
339 * \MAILSLOT\NET\NETLOGON mailslot requests
341 * \MAILSLOT\NET\NTLOGON mailslot requests
344 typedef [public,gensize
] struct {
345 uint32 sockaddr_family
;
346 [flag
(NDR_BIG_ENDIAN
)] ipv4address pdc_ip
;
347 [flag
(NDR_REMAINING
)] DATA_BLOB remaining
;
350 typedef [bitmap32bit
,public] bitmap
{
351 NBT_SERVER_PDC
= 0x00000001,
352 NBT_SERVER_GC
= 0x00000004,
353 NBT_SERVER_LDAP
= 0x00000008,
354 NBT_SERVER_DS
= 0x00000010,
355 NBT_SERVER_KDC
= 0x00000020,
356 NBT_SERVER_TIMESERV
= 0x00000040,
357 NBT_SERVER_CLOSEST
= 0x00000080,
358 NBT_SERVER_WRITABLE
= 0x00000100,
359 NBT_SERVER_GOOD_TIMESERV
= 0x00000200,
360 NBT_SERVER_NDNC
= 0x00000400,
361 NBT_SERVER_SELECT_SECRET_DOMAIN_6
= 0x00000800, /* 2008 / RODC */
362 NBT_SERVER_FULL_SECRET_DOMAIN_6
= 0x00001000, /* 2008 */
363 NBT_SERVER_ADS_WEB_SERVICE
= 0x00002000,
364 NBT_SERVER_DS_8
= 0x00004000, /* 2012 */
365 NBT_SERVER_DS_9
= 0x00008000, /* 2012R2 */
366 NBT_SERVER_DS_10
= 0x00010000, /* 2016 */
367 NBT_SERVER_HAS_DNS_NAME
= 0x20000000,
368 NBT_SERVER_IS_DEFAULT_NC
= 0x40000000,
369 NBT_SERVER_FOREST_ROOT
= 0x80000000
372 typedef [bitmap32bit
,public] bitmap
{
373 NETLOGON_NT_VERSION_1
= 0x00000001,
374 NETLOGON_NT_VERSION_5
= 0x00000002,
375 NETLOGON_NT_VERSION_5EX
= 0x00000004,
376 NETLOGON_NT_VERSION_5EX_WITH_IP
= 0x00000008,
377 NETLOGON_NT_VERSION_WITH_CLOSEST_SITE
= 0x00000010,
378 NETLOGON_NT_VERSION_AVOID_NT4EMUL
= 0x01000000,
379 NETLOGON_NT_VERSION_PDC
= 0x10000000,
380 NETLOGON_NT_VERSION_IP
= 0x20000000,
381 NETLOGON_NT_VERSION_LOCAL
= 0x40000000,
382 NETLOGON_NT_VERSION_GC
= 0x80000000
383 } netlogon_nt_version_flags
;
385 typedef [enum16bit
,public] enum {
388 LOGON_PRIMARY_QUERY
= 7, /* Was also NETLOGON_QUERY_FOR_PDC */
389 NETLOGON_ANNOUNCE_UAS
= 10,
390 NETLOGON_RESPONSE_FROM_PDC
= 12,
391 LOGON_SAM_LOGON_REQUEST
= 18, /* Was also NETLOGON_QUERY_FOR_PDC2, NTLOGON_SAM_LOGON */
392 LOGON_SAM_LOGON_RESPONSE
= 19, /* Was also NTLOGON_SAM_LOGON_REPLY */
393 LOGON_SAM_LOGON_PAUSE_RESPONSE
= 20,
394 LOGON_SAM_LOGON_USER_UNKNOWN
= 21, /* Was also NTLOGON_SAM_LOGON_REPLY15 */
395 LOGON_SAM_LOGON_RESPONSE_EX
= 23, /* was NETLOGON_RESPONSE_FROM_PDC2 */
396 LOGON_SAM_LOGON_PAUSE_RESPONSE_EX
= 24,
397 LOGON_SAM_LOGON_USER_UNKNOWN_EX
= 25 /* was NETLOGON_RESPONSE_FROM_PDC_USER */
400 /* query to dc hand marshaled, as it has 'optional'
402 typedef [nopull
,nopush
] struct {
403 uint16 request_count
;
404 nstring computer_name
;
406 astring mailslot_name
;
408 /* samr_AcctFlags acct_control; */
409 [value
(ndr_size_dom_sid0
(&sid
, ndr
->flags
))] uint32 sid_size
;
410 /* The manual alignment is required because this
411 * structure is marked flag(NDR_NOALIGN) via the
412 * nbt_netlogon_packet below.
414 * However, both MUST only be present if sid_size > 0
416 [flag
(NDR_ALIGN4
)] DATA_BLOB _pad
;
417 [subcontext
(0),subcontext_size
(sid_size
)] dom_sid0 sid
;
418 netlogon_nt_version_flags nt_version
;
421 } NETLOGON_SAM_LOGON_REQUEST
;
424 astring computer_name
;
426 astring mailslot_name
;
430 } NETLOGON_LOGON_REQUEST
;
432 typedef [flag
(NDR_NOALIGN
),public] struct {
433 netlogon_command command
;
437 netlogon_nt_version_flags nt_version
;
440 } NETLOGON_SAM_LOGON_RESPONSE_NT40
;
442 typedef [flag
(NDR_NOALIGN
),public] struct {
443 netlogon_command command
;
450 nbt_string dns_domain
;
451 nbt_string pdc_dns_name
;
453 nbt_server_type server_type
;
454 netlogon_nt_version_flags nt_version
;
457 } NETLOGON_SAM_LOGON_RESPONSE
;
459 /* response from pdc hand marshaled (we have an additional
460 * function that uses this structure), as it has 'optional'
462 typedef [flag
(NDR_NOALIGN
),public] struct {
463 netlogon_command command
;
464 uint16 sbz
; /* From the docs */
465 nbt_server_type server_type
;
468 nbt_string dns_domain
;
469 nbt_string pdc_dns_name
;
470 nbt_string domain_name
;
472 nbt_string user_name
;
473 nbt_string server_site
;
474 nbt_string client_site
;
476 /* Optional on NETLOGON_NT_VERSION_5EX_WITH_IP */
477 [value
(ndr_size_nbt_sockaddr
(&sockaddr
, ndr
->flags
))] uint8 sockaddr_size
;
478 [subcontext
(0),subcontext_size
(sockaddr_size
)] nbt_sockaddr sockaddr
;
480 /* Optional on NETLOGON_NT_VERSION_WITH_CLOSEST_SITE */
481 nbt_string next_closest_site
;
483 netlogon_nt_version_flags nt_version
;
486 } NETLOGON_SAM_LOGON_RESPONSE_EX
;
488 typedef [nopush
,nopull
] union {
489 [case(NETLOGON_NT_VERSION_1
)] NETLOGON_SAM_LOGON_RESPONSE_NT40 nt4
;
490 [case(NETLOGON_NT_VERSION_5
)] NETLOGON_SAM_LOGON_RESPONSE nt5
;
491 [case(NETLOGON_NT_VERSION_5EX
)] NETLOGON_SAM_LOGON_RESPONSE_EX nt5_ex
;
492 } netlogon_samlogon_response_union
;
494 typedef [nopush
,nopull
,noprint
,public] struct {
496 [switch_is(ntver
)] netlogon_samlogon_response_union data
;
497 } netlogon_samlogon_response
;
499 /* query for pdc request */
501 astring computer_name
;
502 astring mailslot_name
;
503 [flag
(NDR_ALIGN2
)] DATA_BLOB _pad
;
504 nstring unicode_name
;
505 netlogon_nt_version_flags nt_version
;
508 } nbt_netlogon_query_for_pdc
;
510 /* response from pdc */
511 typedef [public] struct {
512 netlogon_command command
;
514 [flag
(NDR_ALIGN2
)] DATA_BLOB _pad
;
515 nstring unicode_pdc_name
;
517 netlogon_nt_version_flags nt_version
;
520 } nbt_netlogon_response_from_pdc
;
522 typedef [flag
(NDR_NOALIGN
),public] struct {
523 netlogon_command command
;
526 } nbt_netlogon_response2
;
528 /* used to announce SAM changes - MS-NRPC 2.2.1.5.1 */
530 netr_SamDatabaseID db_index
;
533 } nbt_db_change_info
;
542 [flag
(NDR_ALIGN2
)] DATA_BLOB _pad
;
543 nstring unicode_pdc_name
;
544 nstring unicode_domain
;
546 nbt_db_change_info dbchange
[db_count
];
547 [value
(ndr_size_dom_sid0
(&sid
, ndr
->flags
))] uint32 sid_size
;
548 [subcontext
(0),subcontext_size
(sid_size
)] dom_sid0 sid
;
549 uint32 message_format_version
;
550 uint32 message_token
;
551 } NETLOGON_DB_CHANGE
;
553 typedef [nodiscriminant
] union {
554 [case(LOGON_REQUEST
)] NETLOGON_LOGON_REQUEST logon0
;
555 [case(LOGON_SAM_LOGON_REQUEST
)] NETLOGON_SAM_LOGON_REQUEST logon
;
556 [case(LOGON_PRIMARY_QUERY
)] nbt_netlogon_query_for_pdc pdc
;
557 [case(NETLOGON_ANNOUNCE_UAS
)] NETLOGON_DB_CHANGE uas
;
558 } nbt_netlogon_request
;
561 /* These responses are all handled manually, as they cannot be encoded in IDL fully
563 See push_nbt_netlogon_response()
565 [case(NETLOGON_RESPONSE_FROM_PDC
)] nbt_netlogon_response_from_pdc response
;
566 [case(NETLOGON_RESPONSE_FROM_PDC_USER
)] nbt_netlogon_response_from_pdc2 response2
;
568 [case(LOGON_SAM_LOGON_PAUSE_RESPONSE
)] NETLOGON_SAM_LOGON_RESPONSE reply
;
569 [case(LOGON_SAM_LOGON_RESPONSE
)] NETLOGON_SAM_LOGON_RESPONSE reply
;
570 [case(LOGON_SAM_LOGON_USER_UNKNOWN
)] NETLOGON_SAM_LOGON_RESPONSE reply
;
571 [case(LOGON_SAM_LOGON_RESPONSE_EX
)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex
;
572 [case(LOGON_SAM_LOGON_PAUSE_RESPONSE_EX
)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex
;
573 [case(LOGON_SAM_LOGON_USER_UNKNOWN_EX
)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex
;
576 typedef [flag
(NDR_NOALIGN
),public] struct {
577 netlogon_command command
;
578 [switch_is(command
)] nbt_netlogon_request req
;
579 } nbt_netlogon_packet
;
581 /********************************************************/
582 /* \MAILSLOT\BROWSE mailslot requests */
583 /* for details see http://ubiqx.org/cifs/Browsing.html */
584 /********************************************************/
585 typedef bitmap svcctl_ServerType svcctl_ServerType
;
587 typedef [enum8bit
] enum {
588 HostAnnouncement
= 1,
589 AnnouncementRequest
= 2,
591 GetBackupListReq
= 9,
592 GetBackupListResp
= 10,
594 DomainAnnouncement
= 12,
595 MasterAnnouncement
= 13,
596 ResetBrowserState
= 14,
597 LocalMasterAnnouncement
= 15
603 [charset
(DOS
)] uint8 ServerName
[16];
606 svcctl_ServerType ServerType
;
611 } nbt_browse_host_announcement
;
615 astring ResponseName
;
616 } nbt_browse_announcement_request
;
621 uint32 UpTime
; /* In milliseconds */
622 uint32 Reserved
; /* Must be zero */
624 } nbt_browse_election_request
;
629 } nbt_browse_backup_list_request
;
634 nbt_name BackupServerList
[BackupCount
];/* TODO: this is wrong */
635 } nbt_browse_backup_list_response
;
639 } nbt_browse_become_backup
;
644 [charset
(DOS
)] uint8 ServerName
[16];
647 svcctl_ServerType ServerType
;
648 uint32 MysteriousField
;
650 } nbt_browse_domain_announcement
;
654 } nbt_browse_master_announcement
;
658 } nbt_browse_reset_state
;
663 [charset
(DOS
)] uint8 ServerName
[16];
666 svcctl_ServerType ServerType
;
671 } nbt_browse_local_master_announcement
;
673 typedef [nodiscriminant
] union {
674 [case(HostAnnouncement
)] nbt_browse_host_announcement host_annoucement
;
675 [case(AnnouncementRequest
)] nbt_browse_announcement_request announcement_request
;
676 [case(Election
)] nbt_browse_election_request election_request
;
677 [case(GetBackupListReq
)] nbt_browse_backup_list_request backup_list_request
;
678 [case(GetBackupListResp
)] nbt_browse_backup_list_response backup_list_response
;
679 [case(BecomeBackup
)] nbt_browse_become_backup become_backup
;
680 [case(DomainAnnouncement
)] nbt_browse_domain_announcement domain_announcement
;
681 [case(MasterAnnouncement
)] nbt_browse_master_announcement master_announcement
;
682 [case(ResetBrowserState
)] nbt_browse_reset_state reset_browser_state
;
683 [case(LocalMasterAnnouncement
)] nbt_browse_local_master_announcement local_master_announcement
;
684 } nbt_browse_payload
;
686 typedef [public,flag
(NDR_NOALIGN
)] struct {
687 nbt_browse_opcode opcode
;
688 [switch_is(opcode
)] nbt_browse_payload payload
;