2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Luke Leighton 1996 - 1997 Paul Ashton 1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern int DEBUGLEVEL;
27 /*******************************************************************
28 reads or writes a UTIME type.
29 ********************************************************************/
30 char* smb_io_utime(BOOL io, UTIME *t, char *q, char *base, int align, int depth)
32 if (t == NULL) return NULL;
34 DEBUG(5,("%s%04x smb_io_utime\n", tab_depth(depth), PTR_DIFF(q, base)));
37 q = align_offset(q, base, align);
39 DBG_RW_IVAL ("time", depth, base, io, q, t->time); q += 4;
44 /*******************************************************************
45 reads or writes an NTTIME structure.
46 ********************************************************************/
47 char* smb_io_time(BOOL io, NTTIME *nttime, char *q, char *base, int align, int depth)
49 if (nttime == NULL) return NULL;
51 DEBUG(5,("%s%04x smb_io_time\n", tab_depth(depth), PTR_DIFF(q, base)));
54 q = align_offset(q, base, align);
56 DBG_RW_IVAL("low", depth, base, io, q, nttime->low ); q += 4; /* low part */
57 DBG_RW_IVAL("high", depth, base, io, q, nttime->high); q += 4; /* high part */
62 /*******************************************************************
63 reads or writes a DOM_SID structure.
64 ********************************************************************/
65 char* smb_io_dom_sid(BOOL io, DOM_SID *sid, char *q, char *base, int align, int depth)
69 if (sid == NULL) return NULL;
71 DEBUG(5,("%s%04x smb_io_dom_sid\n", tab_depth(depth), PTR_DIFF(q, base)));
74 q = align_offset(q, base, align);
76 DBG_RW_CVAL("sid_no", depth, base, io, q, sid->sid_no); q++;
77 DBG_RW_CVAL("num_auths", depth, base, io, q, sid->num_auths); q++;
79 for (i = 0; i < 6; i++)
82 sprintf(tmp, "id_auth[%d] ", i);
83 DBG_RW_CVAL(tmp, depth, base, io, q, sid->id_auth[i]); q++;
86 /* oops! XXXX should really issue a warning here... */
87 if (sid->num_auths > MAXSUBAUTHS) sid->num_auths = MAXSUBAUTHS;
89 DBG_RW_PSVAL("num_auths", depth, base, io, q, sid->sub_auths, sid->num_auths); q += sid->num_auths * 2;
94 /*******************************************************************
95 reads or writes a UNIHDR structure.
96 ********************************************************************/
97 char* smb_io_unihdr(BOOL io, UNIHDR *hdr, char *q, char *base, int align, int depth)
99 if (hdr == NULL) return NULL;
101 DEBUG(5,("%s%04x smb_io_unihdr\n", tab_depth(depth), PTR_DIFF(q, base)));
104 /* should be value 4, so enforce it. */
107 q = align_offset(q, base, align);
109 DBG_RW_IVAL("uni_max_len", depth, base, io, q, hdr->uni_max_len); q += 4;
110 DBG_RW_IVAL("uni_str_len", depth, base, io, q, hdr->uni_str_len); q += 4;
111 DBG_RW_IVAL("undoc", depth, base, io, q, hdr->undoc ); q += 4;
116 /*******************************************************************
117 reads or writes a UNIHDR2 structure.
118 ********************************************************************/
119 char* smb_io_unihdr2(BOOL io, UNIHDR2 *hdr2, char *q, char *base, int align, int depth)
121 if (hdr2 == NULL) return NULL;
123 DEBUG(5,("%s%04x smb_io_unihdr2\n", tab_depth(depth), PTR_DIFF(q, base)));
126 q = align_offset(q, base, align);
128 q = smb_io_unihdr(io, &(hdr2->unihdr), q, base, align, depth);
129 DBG_RW_IVAL("undoc_buffer", depth, base, io, q, hdr2->undoc_buffer); q += 4;
134 /*******************************************************************
135 reads or writes a UNISTR structure.
136 XXXX NOTE: UNISTR structures NEED to be null-terminated.
137 ********************************************************************/
138 char* smb_io_unistr(BOOL io, UNISTR *uni, char *q, char *base, int align, int depth)
140 if (uni == NULL) return NULL;
142 DEBUG(5,("%s%04x smb_io_unistr\n", tab_depth(depth), PTR_DIFF(q, base)));
145 q = align_offset(q, base, align);
149 /* io True indicates read _from_ the SMB buffer into the string */
150 q += 2 * unistrcpy((char*)uni->buffer, q);
154 /* io True indicates copy _from_ the string into SMB buffer */
155 q += 2 * unistrcpy(q, (char*)uni->buffer);
160 /*******************************************************************
161 reads or writes a UNISTR2 structure.
162 XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
163 the uni_str_len member tells you how long the string is;
164 the uni_max_len member tells you how large the buffer is.
165 ********************************************************************/
166 char* smb_io_unistr2(BOOL io, UNISTR2 *uni2, char *q, char *base, int align, int depth)
168 if (uni2 == NULL) return NULL;
170 DEBUG(5,("%s%04x smb_io_unistr2\n", tab_depth(depth), PTR_DIFF(q, base)));
173 q = align_offset(q, base, align);
175 /* should be value 0, so enforce it. */
178 DBG_RW_IVAL("uni_max_len", depth, base, io, q, uni2->uni_max_len); q += 4;
179 DBG_RW_IVAL("undoc", depth, base, io, q, uni2->undoc ); q += 4;
180 DBG_RW_IVAL("uni_str_len", depth, base, io, q, uni2->uni_str_len); q += 4;
182 /* oops! XXXX maybe issue a warning that this is happening... */
183 if (uni2->uni_max_len > MAX_UNISTRLEN) uni2->uni_max_len = MAX_UNISTRLEN;
184 if (uni2->uni_str_len > MAX_UNISTRLEN) uni2->uni_str_len = MAX_UNISTRLEN;
186 /* buffer advanced by indicated length of string
187 NOT by searching for null-termination */
188 DBG_RW_PSVAL("", depth, base, io, q, uni2->buffer, uni2->uni_max_len); q += uni2->uni_max_len * 2;
193 /*******************************************************************
194 reads or writes a DOM_SID2 structure.
195 ********************************************************************/
196 char* smb_io_dom_sid2(BOOL io, DOM_SID2 *sid2, char *q, char *base, int align, int depth)
198 if (sid2 == NULL) return NULL;
200 DEBUG(5,("%s%04x smb_io_dom_sid2\n", tab_depth(depth), PTR_DIFF(q, base)));
203 q = align_offset(q, base, align);
205 /* should be value 5, so enforce it */
208 /* should be value 0, so enforce it */
211 DBG_RW_IVAL("type", depth, base, io, q, sid2->type ); q += 4;
212 DBG_RW_IVAL("undoc", depth, base, io, q, sid2->undoc); q += 4;
214 q = smb_io_unihdr2(io, &(sid2->hdr), q, base, align, depth);
215 q = smb_io_unistr (io, &(sid2->str), q, base, align, depth);
220 /*******************************************************************
221 reads or writes a DOM_RID2 structure.
222 ********************************************************************/
223 char* smb_io_dom_rid2(BOOL io, DOM_RID2 *rid2, char *q, char *base, int align, int depth)
225 if (rid2 == NULL) return NULL;
227 DEBUG(5,("%s%04x smb_io_dom_rid2\n", tab_depth(depth), PTR_DIFF(q, base)));
230 q = align_offset(q, base, align);
232 /* should be value 5, so enforce it */
235 /* should be value 5, so enforce it */
238 DBG_RW_IVAL("type", depth, base, io, q, rid2->type); q += 4;
239 DBG_RW_IVAL("undoc", depth, base, io, q, rid2->undoc ); q += 4;
240 DBG_RW_IVAL("rid", depth, base, io, q, rid2->rid ); q += 4;
241 DBG_RW_IVAL("rid_idx", depth, base, io, q, rid2->rid_idx ); q += 4;
246 /*******************************************************************
247 reads or writes a DOM_LOG_INFO structure.
248 ********************************************************************/
249 char* smb_io_log_info(BOOL io, DOM_LOG_INFO *log, char *q, char *base, int align, int depth)
251 if (log == NULL) return NULL;
253 DEBUG(5,("%s%04x smb_io_log_info\n", tab_depth(depth), PTR_DIFF(q, base)));
256 q = align_offset(q, base, align);
258 DBG_RW_IVAL("undoc_buffer", depth, base, io, q, log->undoc_buffer); q += 4;
260 q = smb_io_unistr2(io, &(log->uni_logon_srv), q, base, align, depth);
261 q = smb_io_unistr2(io, &(log->uni_acct_name), q, base, align, depth);
263 DBG_RW_SVAL("sec_chan", depth, base, io, q, log->sec_chan); q += 2;
265 /* XXXX no alignment required between sec_chan and uni_comp_name */
266 q = smb_io_unistr2(io, &(log->uni_comp_name), q, base, 0, depth);
271 /*******************************************************************
272 reads or writes a DOM_CHAL structure.
273 ********************************************************************/
274 char* smb_io_chal(BOOL io, DOM_CHAL *chal, char *q, char *base, int align, int depth)
276 if (chal == NULL) return NULL;
278 DEBUG(5,("%s%04x smb_io_chal\n", tab_depth(depth), PTR_DIFF(q, base)));
281 q = align_offset(q, base, align);
283 DBG_RW_PCVAL("data", depth, base, io, q, chal->data, 8); q += 8;
288 /*******************************************************************
289 reads or writes a DOM_CRED structure.
290 ********************************************************************/
291 char* smb_io_cred(BOOL io, DOM_CRED *cred, char *q, char *base, int align, int depth)
293 if (cred == NULL) return NULL;
295 DEBUG(5,("%s%04x smb_io_cred\n", tab_depth(depth), PTR_DIFF(q, base)));
298 q = align_offset(q, base, align);
300 q = smb_io_chal (io, &(cred->challenge), q, base, align, depth);
301 q = smb_io_utime(io, &(cred->timestamp), q, base, align, depth);
306 /*******************************************************************
307 reads or writes a DOM_CLNT_INFO structure.
308 ********************************************************************/
309 char* smb_io_clnt_info(BOOL io, DOM_CLNT_INFO *clnt, char *q, char *base, int align, int depth)
311 if (clnt == NULL) return NULL;
313 DEBUG(5,("%s%04x smb_io_clnt_info\n", tab_depth(depth), PTR_DIFF(q, base)));
316 q = align_offset(q, base, align);
318 q = smb_io_log_info(io, &(clnt->login), q, base, align, depth);
319 q = smb_io_cred (io, &(clnt->cred ), q, base, align, depth);
324 /*******************************************************************
325 reads or writes a DOM_LOGON_ID structure.
326 ********************************************************************/
327 char* smb_io_logon_id(BOOL io, DOM_LOGON_ID *log, char *q, char *base, int align, int depth)
329 if (log == NULL) return NULL;
331 DEBUG(5,("%s%04x smb_io_logon_id\n", tab_depth(depth), PTR_DIFF(q, base)));
334 q = align_offset(q, base, align);
336 DBG_RW_IVAL("low", depth, base, io, q, log->low ); q += 4;
337 DBG_RW_IVAL("high", depth, base, io, q, log->high); q += 4;
342 /*******************************************************************
343 reads or writes an ARC4_OWF structure.
344 ********************************************************************/
345 char* smb_io_arc4_owf(BOOL io, ARC4_OWF *hash, char *q, char *base, int align, int depth)
347 if (hash == NULL) return NULL;
349 DEBUG(5,("%s%04x smb_io_arc4_owf\n", tab_depth(depth), PTR_DIFF(q, base)));
352 q = align_offset(q, base, align);
354 DBG_RW_PCVAL("data", depth, base, io, q, hash->data, 16); q += 16;
359 /*******************************************************************
360 reads or writes an DOM_ID_INFO_1 structure.
361 ********************************************************************/
362 char* smb_io_id_info1(BOOL io, DOM_ID_INFO_1 *id, char *q, char *base, int align, int depth)
364 if (id == NULL) return NULL;
366 DEBUG(5,("%s%04x smb_io_id_info1\n", tab_depth(depth), PTR_DIFF(q, base)));
369 q = align_offset(q, base, align);
371 q = smb_io_unihdr(io, &(id->hdr_domain_name ), q, base, align, depth);
373 DBG_RW_IVAL("param", depth, base, io, q, id->param); q += 4;
374 q = smb_io_logon_id(io, &(id->logon_id), q, base, align, depth);
376 q = smb_io_unihdr(io, &(id->hdr_user_name ), q, base, align, depth);
377 q = smb_io_unihdr(io, &(id->hdr_workgroup_name), q, base, align, depth);
379 q = smb_io_arc4_owf(io, &(id->arc4_lm_owf), q, base, align, depth);
380 q = smb_io_arc4_owf(io, &(id->arc4_nt_owf), q, base, align, depth);
382 q = smb_io_unistr2(io, &(id->uni_domain_name ), q, base, align, depth);
383 q = smb_io_unistr2(io, &(id->uni_user_name ), q, base, align, depth);
384 q = smb_io_unistr2(io, &(id->uni_workgroup_name), q, base, align, depth);
389 /*******************************************************************
390 reads or writes a DOM_SAM_INFO structure.
391 ********************************************************************/
392 char* smb_io_sam_info(BOOL io, DOM_SAM_INFO *sam, char *q, char *base, int align, int depth)
394 if (sam == NULL) return NULL;
396 DEBUG(5,("%s%04x smb_io_sam_info\n", tab_depth(depth), PTR_DIFF(q, base)));
399 q = align_offset(q, base, align);
401 q = smb_io_clnt_info(io, &(sam->client ), q, base, align, depth);
402 q = smb_io_cred (io, &(sam->rtn_cred), q, base, align, depth);
404 DBG_RW_IVAL("logon_level", depth, base, io, q, sam->logon_level); q += 4;
405 DBG_RW_SVAL("auth_level", depth, base, io, q, sam->auth_level ); q += 4;
407 switch (sam->auth_level)
411 q = smb_io_id_info1(io, &(sam->auth.id1), q, base, align, depth);
423 /*******************************************************************
424 reads or writes a DOM_GID structure.
425 ********************************************************************/
426 char* smb_io_gid(BOOL io, DOM_GID *gid, char *q, char *base, int align, int depth)
428 if (gid == NULL) return NULL;
430 DEBUG(5,("%s%04x smb_io_gid\n", tab_depth(depth), PTR_DIFF(q, base)));
433 q = align_offset(q, base, align);
435 DBG_RW_IVAL("gid", depth, base, io, q, gid->gid ); q += 4;
436 DBG_RW_IVAL("attr", depth, base, io, q, gid->attr); q += 4;
441 /*******************************************************************
442 reads or writes an RPC_HDR structure.
443 ********************************************************************/
444 char* smb_io_rpc_hdr(BOOL io, RPC_HDR *rpc, char *q, char *base, int align, int depth)
446 if (rpc == NULL) return NULL;
448 DEBUG(5,("%s%04x smb_io_rpc_hdr\n", tab_depth(depth), PTR_DIFF(q, base)));
451 /* reserved should be zero: enforce it */
454 DBG_RW_CVAL("major", depth, base, io, q, rpc->major); q++;
455 DBG_RW_CVAL("minor", depth, base, io, q, rpc->minor); q++;
456 DBG_RW_CVAL("pkt_type", depth, base, io, q, rpc->pkt_type); q++;
457 DBG_RW_CVAL("frag", depth, base, io, q, rpc->frag); q++;
458 DBG_RW_IVAL("pack_type", depth, base, io, q, rpc->pack_type); q += 4;
459 DBG_RW_SVAL("frag_len", depth, base, io, q, rpc->frag_len); q += 2;
460 DBG_RW_SVAL("auth_len", depth, base, io, q, rpc->auth_len); q += 2;
461 DBG_RW_IVAL("call_id", depth, base, io, q, rpc->call_id); q += 4;
462 DBG_RW_IVAL("alloc_hint", depth, base, io, q, rpc->alloc_hint); q += 4;
463 DBG_RW_CVAL("context_id", depth, base, io, q, rpc->context_id); q++;
464 DBG_RW_CVAL("reserved", depth, base, io, q, rpc->reserved); q++;
469 /*******************************************************************
470 reads or writes an LSA_POL_HND structure.
471 ********************************************************************/
472 char* smb_io_pol_hnd(BOOL io, LSA_POL_HND *pol, char *q, char *base, int align, int depth)
474 if (pol == NULL) return NULL;
476 DEBUG(5,("%s%04x smb_io_pol_hnd\n", tab_depth(depth), PTR_DIFF(q, base)));
479 q = align_offset(q, base, align);
481 DBG_RW_PCVAL("data", depth, base, io, q, pol->data, POL_HND_SIZE); q += POL_HND_SIZE;
486 /*******************************************************************
487 reads or writes a dom query structure.
488 ********************************************************************/
489 char* smb_io_dom_query_3(BOOL io, DOM_QUERY_3 *d_q, char *q, char *base, int align, int depth)
491 return smb_io_dom_query(io, d_q, q, base, align, depth);
494 /*******************************************************************
495 reads or writes a dom query structure.
496 ********************************************************************/
497 char* smb_io_dom_query_5(BOOL io, DOM_QUERY_3 *d_q, char *q, char *base, int align, int depth)
499 return smb_io_dom_query(io, d_q, q, base, align, depth);
502 /*******************************************************************
503 reads or writes a dom query structure.
504 ********************************************************************/
505 char* smb_io_dom_query(BOOL io, DOM_QUERY *d_q, char *q, char *base, int align, int depth)
507 if (d_q == NULL) return NULL;
509 DEBUG(5,("%s%04x smb_io_dom_query\n", tab_depth(depth), PTR_DIFF(q, base)));
512 q = align_offset(q, base, align);
515 DBG_RW_SVAL("uni_dom_max_len", depth, base, io, q, d_q->uni_dom_max_len); q += 2; /* domain name string length * 2 */
516 DBG_RW_SVAL("padding", depth, base, io, q, d_q->padding ); q += 2; /* 2 padding bytes */
517 DBG_RW_SVAL("uni_dom_str_len", depth, base, io, q, d_q->uni_dom_str_len); q += 2; /* domain name string length * 2 */
519 DBG_RW_IVAL("buffer_dom_name", depth, base, io, q, d_q->buffer_dom_name); q += 4; /* undocumented domain name string buffer pointer */
520 DBG_RW_IVAL("buffer_dom_sid", depth, base, io, q, d_q->buffer_dom_sid ); q += 4; /* undocumented domain SID string buffer pointer */
522 if (d_q->buffer_dom_name != 0)
524 q = smb_io_unistr2(io, &(d_q->uni_domain_name), q, base, align, depth); /* domain name (unicode string) */
526 if (d_q->buffer_dom_sid != 0)
528 q = smb_io_dom_sid(io, &(d_q->dom_sid), q, base, align, depth); /* domain SID */
534 /*******************************************************************
535 reads or writes a DOM_R_REF structure.
536 ********************************************************************/
537 char* smb_io_dom_r_ref(BOOL io, DOM_R_REF *r_r, char *q, char *base, int align, int depth)
541 DEBUG(5,("%s%04x smb_io_dom_r_ref\n", tab_depth(depth), PTR_DIFF(q, base)));
544 if (r_r == NULL) return NULL;
546 q = align_offset(q, base, align);
548 DBG_RW_IVAL("undoc_buffer", depth, base, io, q, r_r->undoc_buffer); q += 4; /* undocumented buffer pointer. */
549 DBG_RW_IVAL("num_ref_doms_1", depth, base, io, q, r_r->num_ref_doms_1); q += 4; /* num referenced domains? */
550 DBG_RW_IVAL("buffer_dom_name", depth, base, io, q, r_r->buffer_dom_name); q += 4; /* undocumented domain name buffer pointer. */
551 DBG_RW_IVAL("max_entries", depth, base, io, q, r_r->max_entries); q += 4; /* 32 - max number of entries */
552 DBG_RW_IVAL("num_ref_doms_2", depth, base, io, q, r_r->num_ref_doms_2); q += 4; /* 4 - num referenced domains? */
554 q = smb_io_unihdr2(io, &(r_r->hdr_dom_name), q, base, align, depth); /* domain name unicode string header */
556 for (i = 0; i < r_r->num_ref_doms_1-1; i++)
558 q = smb_io_unihdr2(io, &(r_r->hdr_ref_dom[i]), q, base, align, depth);
561 q = smb_io_unistr(io, &(r_r->uni_dom_name), q, base, align, depth); /* domain name unicode string */
563 for (i = 0; i < r_r->num_ref_doms_2; i++)
565 q = smb_io_dom_sid(io, &(r_r->ref_dom[i]), q, base, align, depth); /* referenced domain SIDs */
570 /*******************************************************************
571 reads or writes a DOM_NAME structure.
572 ********************************************************************/
573 char* smb_io_dom_name(BOOL io, DOM_NAME *name, char *q, char *base, int align, int depth)
575 if (name == NULL) return NULL;
577 DEBUG(5,("%s%04x smb_io_dom_name\n", tab_depth(depth), PTR_DIFF(q, base)));
580 q = align_offset(q, base, align);
582 DBG_RW_IVAL("uni_str_len", depth, base, io, q, name->uni_str_len); q += 4;
584 /* don't know if len is specified by uni_str_len member... */
585 /* assume unicode string is unicode-null-terminated, instead */
587 q = smb_io_unistr(io, &(name->str), q, base, align, depth);
593 /*******************************************************************
594 reads or writes a structure.
595 ********************************************************************/
596 char* smb_io_neg_flags(BOOL io, NEG_FLAGS *neg, char *q, char *base, int align, int depth)
598 if (neg == NULL) return NULL;
600 DEBUG(5,("%s%04x smb_io_neg_flags\n", tab_depth(depth), PTR_DIFF(q, base)));
603 q = align_offset(q, base, align);
605 DBG_RW_IVAL("neg_flags", depth, base, io, q, neg->neg_flags); q += 4;
612 /*******************************************************************
613 reads or writes a structure.
614 ********************************************************************/
615 char* smb_io_(BOOL io, *, char *q, char *base, int align, int depth)
617 if (== NULL) return NULL;
619 q = align_offset(q, base, align);
621 DBG_RW_IVAL("", depth, base, io, q, ); q += 4;