2 Unix SMB/CIFS implementation.
4 CLDAP server structures
6 Copyright (C) Andrew Tridgell 2005
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /* parser auto-generated by pidl, then hand-modified by abartlet */
26 #include "../libcli/nbt/libnbt.h"
27 #include "../libcli/netlogon/netlogon.h"
28 #include "ndr_dns_utils.h"
31 /* don't allow an unlimited number of name components */
32 #define MAX_COMPONENTS 128
37 _PUBLIC_
void ndr_print_nbt_string(struct ndr_print
*ndr
, const char *name
, const char *s
)
39 ndr_print_string(ndr
, name
, s
);
43 pull one component of a nbt_string
45 static enum ndr_err_code
ndr_pull_component(struct ndr_pull
*ndr
,
51 unsigned int loops
= 0;
53 if (*offset
>= ndr
->data_size
) {
54 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
55 "BAD NBT NAME component");
57 len
= ndr
->data
[*offset
];
60 *max_offset
= MAX(*max_offset
, *offset
);
62 return NDR_ERR_SUCCESS
;
64 if ((len
& 0xC0) == 0xC0) {
65 /* its a label pointer */
66 if (1 + *offset
>= ndr
->data_size
) {
67 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
68 "BAD NBT NAME component");
70 *max_offset
= MAX(*max_offset
, *offset
+ 2);
71 *offset
= ((len
&0x3F)<<8) | ndr
->data
[1 + *offset
];
72 *max_offset
= MAX(*max_offset
, *offset
);
76 if ((len
& 0xC0) != 0) {
77 /* its a reserved length field */
78 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
79 "BAD NBT NAME component");
81 if (*offset
+ len
+ 1 > ndr
->data_size
) {
82 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
83 "BAD NBT NAME component");
85 *component
= (uint8_t*)talloc_strndup(
87 (const char *)&ndr
->data
[1 + *offset
], len
);
88 NDR_ERR_HAVE_NO_MEMORY(*component
);
90 *max_offset
= MAX(*max_offset
, *offset
);
91 return NDR_ERR_SUCCESS
;
94 /* too many pointers */
95 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "BAD NBT NAME component");
99 pull a nbt_string from the wire
101 _PUBLIC_
enum ndr_err_code
ndr_pull_nbt_string(struct ndr_pull
*ndr
, int ndr_flags
, const char **s
)
103 uint32_t offset
= ndr
->offset
;
104 uint32_t max_offset
= offset
;
105 unsigned num_components
;
108 if (!(ndr_flags
& NDR_SCALARS
)) {
109 return NDR_ERR_SUCCESS
;
114 /* break up name into a list of components */
115 for (num_components
=0;num_components
<MAX_COMPONENTS
;num_components
++) {
116 uint8_t *component
= NULL
;
117 NDR_CHECK(ndr_pull_component(ndr
, &component
, &offset
, &max_offset
));
118 if (component
== NULL
) break;
120 name
= talloc_asprintf_append_buffer(name
, ".%s", component
);
121 NDR_ERR_HAVE_NO_MEMORY(name
);
123 name
= (char *)component
;
126 if (num_components
== MAX_COMPONENTS
) {
127 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
128 "BAD NBT NAME too many components");
130 if (num_components
== 0) {
131 name
= talloc_strdup(ndr
->current_mem_ctx
, "");
132 NDR_ERR_HAVE_NO_MEMORY(name
);
136 ndr
->offset
= max_offset
;
138 return NDR_ERR_SUCCESS
;
142 push a nbt string to the wire
144 _PUBLIC_
enum ndr_err_code
ndr_push_nbt_string(struct ndr_push
*ndr
, int ndr_flags
, const char *s
)
146 return ndr_push_dns_string_list(ndr
,
147 &ndr
->dns_string_list
,
154 /* Manually modified to handle the dom_sid being optional based on if it is present or all zero */
155 enum ndr_err_code
ndr_push_NETLOGON_SAM_LOGON_REQUEST(struct ndr_push
*ndr
, int ndr_flags
, const struct NETLOGON_SAM_LOGON_REQUEST
*r
)
157 if (ndr_flags
& NDR_SCALARS
) {
158 NDR_CHECK(ndr_push_align(ndr
, 4));
159 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->request_count
));
161 uint32_t _flags_save_string
= ndr
->flags
;
162 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
163 NDR_CHECK(ndr_push_string(ndr
, NDR_SCALARS
, r
->computer_name
));
164 ndr
->flags
= _flags_save_string
;
167 uint32_t _flags_save_string
= ndr
->flags
;
168 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
169 NDR_CHECK(ndr_push_string(ndr
, NDR_SCALARS
, r
->user_name
));
170 ndr
->flags
= _flags_save_string
;
173 uint32_t _flags_save_string
= ndr
->flags
;
174 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_ASCII
|LIBNDR_FLAG_STR_NULLTERM
);
175 NDR_CHECK(ndr_push_string(ndr
, NDR_SCALARS
, r
->mailslot_name
));
176 ndr
->flags
= _flags_save_string
;
178 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, r
->acct_control
));
179 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)));
180 if (ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)) {
181 struct ndr_push
*_ndr_sid
;
182 uint32_t _flags_save_DATA_BLOB
= ndr
->flags
;
183 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_ALIGN4
);
184 NDR_CHECK(ndr_push_DATA_BLOB(ndr
, NDR_SCALARS
, r
->_pad
));
185 ndr
->flags
= _flags_save_DATA_BLOB
;
186 NDR_CHECK(ndr_push_subcontext_start(ndr
, &_ndr_sid
, 0, ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)));
187 NDR_CHECK(ndr_push_dom_sid0(_ndr_sid
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sid
));
188 NDR_CHECK(ndr_push_subcontext_end(ndr
, _ndr_sid
, 0, ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)));
190 NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, r
->nt_version
));
191 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lmnt_token
));
192 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lm20_token
));
194 if (ndr_flags
& NDR_BUFFERS
) {
196 return NDR_ERR_SUCCESS
;
199 /* Manually modified to handle the dom_sid being optional based on if it is present (size is non-zero) or not */
200 enum ndr_err_code
ndr_pull_NETLOGON_SAM_LOGON_REQUEST(struct ndr_pull
*ndr
, int ndr_flags
, struct NETLOGON_SAM_LOGON_REQUEST
*r
)
202 if (ndr_flags
& NDR_SCALARS
) {
203 NDR_CHECK(ndr_pull_align(ndr
, 4));
204 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->request_count
));
206 uint32_t _flags_save_string
= ndr
->flags
;
207 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
208 NDR_CHECK(ndr_pull_string(ndr
, NDR_SCALARS
, &r
->computer_name
));
209 ndr
->flags
= _flags_save_string
;
212 uint32_t _flags_save_string
= ndr
->flags
;
213 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
214 NDR_CHECK(ndr_pull_string(ndr
, NDR_SCALARS
, &r
->user_name
));
215 ndr
->flags
= _flags_save_string
;
218 uint32_t _flags_save_string
= ndr
->flags
;
219 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_ASCII
|LIBNDR_FLAG_STR_NULLTERM
);
220 NDR_CHECK(ndr_pull_string(ndr
, NDR_SCALARS
, &r
->mailslot_name
));
221 ndr
->flags
= _flags_save_string
;
223 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &r
->acct_control
));
224 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &r
->sid_size
));
226 uint32_t _flags_save_DATA_BLOB
= ndr
->flags
;
227 struct ndr_pull
*_ndr_sid
;
228 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_ALIGN4
);
229 NDR_CHECK(ndr_pull_DATA_BLOB(ndr
, NDR_SCALARS
, &r
->_pad
));
230 ndr
->flags
= _flags_save_DATA_BLOB
;
231 NDR_CHECK(ndr_pull_subcontext_start(ndr
, &_ndr_sid
, 0, r
->sid_size
));
232 NDR_CHECK(ndr_pull_dom_sid0(_ndr_sid
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sid
));
233 NDR_CHECK(ndr_pull_subcontext_end(ndr
, _ndr_sid
, 0, r
->sid_size
));
237 NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, &r
->nt_version
));
238 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lmnt_token
));
239 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lm20_token
));
241 if (ndr_flags
& NDR_BUFFERS
) {
243 return NDR_ERR_SUCCESS
;
246 /* Manually modified to only push some parts of the structure if certain flags are set */
247 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
)
250 uint32_t _flags_save_STRUCT
= ndr
->flags
;
251 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_NOALIGN
);
252 if (ndr_flags
& NDR_SCALARS
) {
253 NDR_CHECK(ndr_push_align(ndr
, 4));
254 NDR_CHECK(ndr_push_netlogon_command(ndr
, NDR_SCALARS
, r
->command
));
255 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->sbz
));
256 NDR_CHECK(ndr_push_nbt_server_type(ndr
, NDR_SCALARS
, r
->server_type
));
257 NDR_CHECK(ndr_push_GUID(ndr
, NDR_SCALARS
, &r
->domain_uuid
));
258 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->forest
));
259 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->dns_domain
));
260 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->pdc_dns_name
));
261 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->domain_name
));
262 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->pdc_name
));
263 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->user_name
));
264 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->server_site
));
265 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->client_site
));
266 if (r
->nt_version
& NETLOGON_NT_VERSION_5EX_WITH_IP
) {
267 NDR_CHECK(ndr_push_uint8(ndr
, NDR_SCALARS
, ndr_size_nbt_sockaddr(&r
->sockaddr
, ndr
->flags
)));
269 struct ndr_push
*_ndr_sockaddr
;
270 NDR_CHECK(ndr_push_subcontext_start(ndr
, &_ndr_sockaddr
, 0, ndr_size_nbt_sockaddr(&r
->sockaddr
, ndr
->flags
)));
271 NDR_CHECK(ndr_push_nbt_sockaddr(_ndr_sockaddr
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sockaddr
));
272 NDR_CHECK(ndr_push_subcontext_end(ndr
, _ndr_sockaddr
, 0, ndr_size_nbt_sockaddr(&r
->sockaddr
, ndr
->flags
)));
275 if (r
->nt_version
& NETLOGON_NT_VERSION_WITH_CLOSEST_SITE
) {
276 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->next_closest_site
));
278 NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, r
->nt_version
));
279 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lmnt_token
));
280 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lm20_token
));
282 if (ndr_flags
& NDR_BUFFERS
) {
283 NDR_CHECK(ndr_push_GUID(ndr
, NDR_BUFFERS
, &r
->domain_uuid
));
285 ndr
->flags
= _flags_save_STRUCT
;
287 return NDR_ERR_SUCCESS
;
290 /* Manually modified to only pull some parts of the structure if certain flags provided */
291 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
,
292 uint32_t nt_version_flags
)
295 uint32_t _flags_save_STRUCT
= ndr
->flags
;
297 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_NOALIGN
);
298 if (ndr_flags
& NDR_SCALARS
) {
299 NDR_CHECK(ndr_pull_align(ndr
, 4));
300 NDR_CHECK(ndr_pull_netlogon_command(ndr
, NDR_SCALARS
, &r
->command
));
301 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->sbz
));
302 NDR_CHECK(ndr_pull_nbt_server_type(ndr
, NDR_SCALARS
, &r
->server_type
));
303 NDR_CHECK(ndr_pull_GUID(ndr
, NDR_SCALARS
, &r
->domain_uuid
));
304 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->forest
));
305 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->dns_domain
));
306 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->pdc_dns_name
));
307 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->domain_name
));
308 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->pdc_name
));
309 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->user_name
));
310 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->server_site
));
311 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->client_site
));
312 if (nt_version_flags
& NETLOGON_NT_VERSION_5EX_WITH_IP
) {
313 NDR_CHECK(ndr_pull_uint8(ndr
, NDR_SCALARS
, &r
->sockaddr_size
));
315 struct ndr_pull
*_ndr_sockaddr
;
316 NDR_CHECK(ndr_pull_subcontext_start(ndr
, &_ndr_sockaddr
, 0, r
->sockaddr_size
));
317 NDR_CHECK(ndr_pull_nbt_sockaddr(_ndr_sockaddr
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sockaddr
));
318 NDR_CHECK(ndr_pull_subcontext_end(ndr
, _ndr_sockaddr
, 0, r
->sockaddr_size
));
321 if (nt_version_flags
& NETLOGON_NT_VERSION_WITH_CLOSEST_SITE
) {
322 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->next_closest_site
));
324 NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, &r
->nt_version
));
325 if (r
->nt_version
!= nt_version_flags
) {
326 return NDR_ERR_VALIDATE
;
328 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lmnt_token
));
329 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lm20_token
));
331 if (ndr_flags
& NDR_BUFFERS
) {
332 NDR_CHECK(ndr_pull_GUID(ndr
, NDR_BUFFERS
, &r
->domain_uuid
));
334 ndr
->flags
= _flags_save_STRUCT
;
336 return NDR_ERR_SUCCESS
;
339 _PUBLIC_
enum ndr_err_code
ndr_push_netlogon_samlogon_response(struct ndr_push
*ndr
, int ndr_flags
, const struct netlogon_samlogon_response
*r
)
341 if (r
->ntver
== NETLOGON_NT_VERSION_1
) {
342 NDR_CHECK(ndr_push_NETLOGON_SAM_LOGON_RESPONSE_NT40(
343 ndr
, ndr_flags
, &r
->data
.nt4
));
344 } else if (r
->ntver
& NETLOGON_NT_VERSION_5EX
) {
345 NDR_CHECK(ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(
346 ndr
, ndr_flags
, &r
->data
.nt5_ex
));
347 } else if (r
->ntver
& NETLOGON_NT_VERSION_5
) {
348 NDR_CHECK(ndr_push_NETLOGON_SAM_LOGON_RESPONSE(
349 ndr
, ndr_flags
, &r
->data
.nt5
));
351 return NDR_ERR_BAD_SWITCH
;
354 return NDR_ERR_SUCCESS
;
357 _PUBLIC_
enum ndr_err_code
ndr_pull_netlogon_samlogon_response(struct ndr_pull
*ndr
, int ndr_flags
, struct netlogon_samlogon_response
*r
)
359 if (ndr
->data_size
< 8) {
360 return NDR_ERR_BUFSIZE
;
364 if (SVAL(ndr
->data
, ndr
->data_size
- 4) != 0xffff) {
365 return NDR_ERR_TOKEN
;
368 if (SVAL(ndr
->data
, ndr
->data_size
- 2) != 0xffff) {
369 return NDR_ERR_TOKEN
;
372 r
->ntver
= IVAL(ndr
->data
, ndr
->data_size
- 8);
374 if (r
->ntver
== NETLOGON_NT_VERSION_1
) {
375 NDR_CHECK(ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_NT40(
376 ndr
, ndr_flags
, &r
->data
.nt4
));
377 } else if (r
->ntver
& NETLOGON_NT_VERSION_5EX
) {
378 NDR_CHECK(ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(
379 ndr
, ndr_flags
, &r
->data
.nt5_ex
, r
->ntver
));
380 if (ndr
->offset
< ndr
->data_size
) {
381 return ndr_pull_error(ndr
, NDR_ERR_UNREAD_BYTES
,
382 "not all bytes consumed ofs[%u] size[%u]",
383 ndr
->offset
, ndr
->data_size
);
385 } else if (r
->ntver
& NETLOGON_NT_VERSION_5
) {
386 NDR_CHECK(ndr_pull_NETLOGON_SAM_LOGON_RESPONSE(
387 ndr
, ndr_flags
, &r
->data
.nt5
));
389 return NDR_ERR_BAD_SWITCH
;
392 return NDR_ERR_SUCCESS
;
395 _PUBLIC_
void ndr_print_netlogon_samlogon_response(struct ndr_print
*ndr
, const char *name
, struct netlogon_samlogon_response
*r
)
397 ndr_print_struct(ndr
, name
, "netlogon_samlogon_response");
398 if (r
== NULL
) { ndr_print_null(ndr
); return; }
399 if (r
->ntver
== NETLOGON_NT_VERSION_1
) {
400 ndr_print_NETLOGON_SAM_LOGON_RESPONSE_NT40(ndr
, "data.nt4", &r
->data
.nt4
);
401 } else if (r
->ntver
& NETLOGON_NT_VERSION_5EX
) {
402 ndr_print_NETLOGON_SAM_LOGON_RESPONSE_EX(ndr
, "data.nt5_ex", &r
->data
.nt5_ex
);
403 } else if (r
->ntver
& NETLOGON_NT_VERSION_5
) {
404 ndr_print_NETLOGON_SAM_LOGON_RESPONSE(ndr
, "data.nt5", &r
->data
.nt5
);