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)
32 if (t == NULL) return NULL;
34 q = align_offset(q, base, align);
36 RW_IVAL (io, q, t->time, 0); q += 4;
41 /*******************************************************************
42 reads or writes an NTTIME structure.
43 ********************************************************************/
44 char* smb_io_time(BOOL io, NTTIME *nttime, char *q, char *base, int align)
46 if (nttime == NULL) return NULL;
48 q = align_offset(q, base, align);
50 RW_IVAL(io, q, nttime->low , 0); q += 4; /* low part */
51 RW_IVAL(io, q, nttime->high, 0); q += 4; /* high part */
56 /*******************************************************************
57 reads or writes a DOM_SID structure.
58 ********************************************************************/
59 char* smb_io_dom_sid(BOOL io, DOM_SID *sid, char *q, char *base, int align)
63 if (sid == NULL) return NULL;
65 q = align_offset(q, base, align);
67 RW_CVAL(io, q, sid->sid_no, 0); q++;
68 RW_CVAL(io, q, sid->num_auths, 0); q++;
70 for (i = 0; i < 6; i++)
72 RW_CVAL(io, q, sid->id_auth[i], 0); q++;
75 /* oops! XXXX should really issue a warning here... */
76 if (sid->num_auths > MAXSUBAUTHS) sid->num_auths = MAXSUBAUTHS;
78 RW_PSVAL(io, q, sid->sub_auths, sid->num_auths); q += sid->num_auths * 2;
83 /*******************************************************************
84 reads or writes a UNIHDR structure.
85 ********************************************************************/
86 char* smb_io_unihdr(BOOL io, UNIHDR *hdr, char *q, char *base, int align)
88 if (hdr == NULL) return NULL;
90 /* should be value 4, so enforce it. */
93 q = align_offset(q, base, align);
95 RW_IVAL(io, q, hdr->uni_max_len, 0); q += 4;
96 RW_IVAL(io, q, hdr->uni_str_len, 0); q += 4;
97 RW_IVAL(io, q, hdr->undoc , 0); q += 4;
102 /*******************************************************************
103 reads or writes a UNIHDR2 structure.
104 ********************************************************************/
105 char* smb_io_unihdr2(BOOL io, UNIHDR2 *hdr2, char *q, char *base, int align)
107 if (hdr2 == NULL) return NULL;
109 q = align_offset(q, base, align);
111 q = smb_io_unihdr(io, &(hdr2->unihdr), q, base, align);
112 RW_IVAL(io, q, hdr2->undoc_buffer, 0); q += 4;
117 /*******************************************************************
118 reads or writes a UNISTR structure.
119 XXXX NOTE: UNISTR structures NEED to be null-terminated.
120 ********************************************************************/
121 char* smb_io_unistr(BOOL io, UNISTR *uni, char *q, char *base, int align)
123 if (uni == NULL) return NULL;
125 q = align_offset(q, base, align);
129 /* io True indicates read _from_ the SMB buffer into the string */
130 q += 2 * unistrcpy((char*)uni->buffer, q);
134 /* io True indicates copy _from_ the string into SMB buffer */
135 q += 2 * unistrcpy(q, (char*)uni->buffer);
140 /*******************************************************************
141 reads or writes a UNISTR2 structure.
142 XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
143 the uni_str_len member tells you how long the string is;
144 the uni_max_len member tells you how large the buffer is.
145 ********************************************************************/
146 char* smb_io_unistr2(BOOL io, UNISTR2 *uni2, char *q, char *base, int align)
148 if (uni2 == NULL) return NULL;
150 q = align_offset(q, base, align);
152 /* should be value 0, so enforce it. */
155 RW_IVAL(io, q, uni2->uni_max_len, 0); q += 4;
156 RW_IVAL(io, q, uni2->undoc , 0); q += 4;
157 RW_IVAL(io, q, uni2->uni_str_len, 0); q += 4;
159 /* oops! XXXX maybe issue a warning that this is happening... */
160 if (uni2->uni_max_len > MAX_UNISTRLEN) uni2->uni_max_len = MAX_UNISTRLEN;
161 if (uni2->uni_str_len > MAX_UNISTRLEN) uni2->uni_str_len = MAX_UNISTRLEN;
163 /* buffer advanced by indicated length of string
164 NOT by searching for null-termination */
165 RW_PSVAL(io, q, uni2->buffer, uni2->uni_max_len); q += uni2->uni_max_len * 2;
170 /*******************************************************************
171 reads or writes a DOM_SID2 structure.
172 ********************************************************************/
173 char* smb_io_dom_sid2(BOOL io, DOM_SID2 *sid2, char *q, char *base, int align)
175 if (sid2 == NULL) return NULL;
177 q = align_offset(q, base, align);
179 /* should be value 5, so enforce it */
182 /* should be value 0, so enforce it */
185 RW_IVAL(io, q, sid2->type , 0); q += 4;
186 RW_IVAL(io, q, sid2->undoc, 0); q += 4;
188 q = smb_io_unihdr2(io, &(sid2->hdr), q, base, align);
189 q = smb_io_unistr (io, &(sid2->str), q, base, align);
194 /*******************************************************************
195 reads or writes a DOM_RID2 structure.
196 ********************************************************************/
197 char* smb_io_dom_rid2(BOOL io, DOM_RID2 *rid2, char *q, char *base, int align)
199 if (rid2 == NULL) return NULL;
201 q = align_offset(q, base, align);
203 /* should be value 5, so enforce it */
206 /* should be value 5, so enforce it */
209 RW_IVAL(io, q, rid2->type, 0); q += 4;
210 RW_IVAL(io, q, rid2->undoc , 0); q += 4;
211 RW_IVAL(io, q, rid2->rid , 0); q += 4;
212 RW_IVAL(io, q, rid2->rid_idx , 0); q += 4;
217 /*******************************************************************
218 reads or writes a DOM_LOG_INFO structure.
219 ********************************************************************/
220 char* smb_io_log_info(BOOL io, DOM_LOG_INFO *log, char *q, char *base, int align)
222 if (log == NULL) return NULL;
224 q = align_offset(q, base, align);
226 RW_IVAL(io, q, log->undoc_buffer, 0); q += 4;
228 q = smb_io_unistr2(io, &(log->uni_logon_srv), q, base, align);
229 q = smb_io_unistr2(io, &(log->uni_acct_name), q, base, align);
231 RW_SVAL(io, q, log->sec_chan, 0); q += 2;
233 /* XXXX no alignment required between sec_chan and uni_comp_name */
234 q = smb_io_unistr2(io, &(log->uni_comp_name), q, base, 0);
239 /*******************************************************************
240 reads or writes a DOM_CHAL structure.
241 ********************************************************************/
242 char* smb_io_chal(BOOL io, DOM_CHAL *chal, char *q, char *base, int align)
244 if (chal == NULL) return NULL;
246 q = align_offset(q, base, align);
248 RW_PCVAL(io, q, chal->data, 8); q += 8;
253 /*******************************************************************
254 reads or writes a DOM_CRED structure.
255 ********************************************************************/
256 char* smb_io_cred(BOOL io, DOM_CRED *cred, char *q, char *base, int align)
258 if (cred == NULL) return NULL;
260 q = align_offset(q, base, align);
262 q = smb_io_chal (io, &(cred->challenge), q, base, align);
263 q = smb_io_utime(io, &(cred->timestamp), q, base, align);
268 /*******************************************************************
269 reads or writes a DOM_CLNT_INFO structure.
270 ********************************************************************/
271 char* smb_io_clnt_info(BOOL io, DOM_CLNT_INFO *clnt, char *q, char *base, int align)
273 if (clnt == NULL) return NULL;
275 q = align_offset(q, base, align);
277 q = smb_io_log_info(io, &(clnt->login), q, base, align);
278 q = smb_io_cred (io, &(clnt->cred ), q, base, align);
283 /*******************************************************************
284 reads or writes a DOM_LOGON_ID structure.
285 ********************************************************************/
286 char* smb_io_logon_id(BOOL io, DOM_LOGON_ID *log, char *q, char *base, int align)
288 if (log == NULL) return NULL;
290 q = align_offset(q, base, align);
292 RW_IVAL(io, q, log->low , 0); q += 4;
293 RW_IVAL(io, q, log->high, 0); q += 4;
298 /*******************************************************************
299 reads or writes an ARC4_OWF structure.
300 ********************************************************************/
301 char* smb_io_arc4_owf(BOOL io, ARC4_OWF *hash, char *q, char *base, int align)
303 if (hash == NULL) return NULL;
305 q = align_offset(q, base, align);
307 RW_PCVAL(io, q, hash->data, 16); q += 16;
312 /*******************************************************************
313 reads or writes an DOM_ID_INFO_1 structure.
314 ********************************************************************/
315 char* smb_io_id_info1(BOOL io, DOM_ID_INFO_1 *id, char *q, char *base, int align)
317 if (id == NULL) return NULL;
319 q = align_offset(q, base, align);
321 q = smb_io_unihdr(io, &(id->hdr_domain_name ), q, base, align);
323 RW_IVAL(io, q, id->param, 0); q += 4;
324 q = smb_io_logon_id(io, &(id->logon_id), q, base, align);
326 q = smb_io_unihdr(io, &(id->hdr_user_name ), q, base, align);
327 q = smb_io_unihdr(io, &(id->hdr_workgroup_name), q, base, align);
329 q = smb_io_arc4_owf(io, &(id->arc4_lm_owf), q, base, align);
330 q = smb_io_arc4_owf(io, &(id->arc4_nt_owf), q, base, align);
332 q = smb_io_unistr2(io, &(id->uni_domain_name ), q, base, align);
333 q = smb_io_unistr2(io, &(id->uni_user_name ), q, base, align);
334 q = smb_io_unistr2(io, &(id->uni_workgroup_name), q, base, align);
339 /*******************************************************************
340 reads or writes a DOM_SAM_INFO structure.
341 ********************************************************************/
342 char* smb_io_sam_info(BOOL io, DOM_SAM_INFO *sam, char *q, char *base, int align)
344 if (sam == NULL) return NULL;
346 q = align_offset(q, base, align);
348 q = smb_io_clnt_info(io, &(sam->client ), q, base, align);
349 q = smb_io_cred (io, &(sam->rtn_cred), q, base, align);
351 RW_IVAL(io, q, sam->logon_level, 0); q += 4;
352 RW_SVAL(io, q, sam->auth_level , 0); q += 4;
354 switch (sam->auth_level)
358 q = smb_io_id_info1(io, &(sam->auth.id1), q, base, align);
370 /*******************************************************************
371 reads or writes a DOM_GID structure.
372 ********************************************************************/
373 char* smb_io_gid(BOOL io, DOM_GID *gid, char *q, char *base, int align)
375 if (gid == NULL) return NULL;
377 q = align_offset(q, base, align);
379 RW_IVAL(io, q, gid->gid , 0); q += 4;
380 RW_IVAL(io, q, gid->attr, 0); q += 4;
385 /*******************************************************************
386 reads or writes an RPC_HDR structure.
387 ********************************************************************/
388 char* smb_io_rpc_hdr(BOOL io, RPC_HDR *rpc, char *q, char *base, int align)
390 if (rpc == NULL) return NULL;
392 /* reserved should be zero: enforce it */
395 RW_CVAL(io, q, rpc->major, 0); q++;
396 RW_CVAL(io, q, rpc->minor, 0); q++;
397 RW_CVAL(io, q, rpc->pkt_type, 0); q++;
398 RW_CVAL(io, q, rpc->frag, 0); q++;
399 RW_IVAL(io, q, rpc->pack_type, 0); q += 4;
400 RW_SVAL(io, q, rpc->frag_len, 0); q += 2;
401 RW_SVAL(io, q, rpc->auth_len, 0); q += 2;
402 RW_IVAL(io, q, rpc->call_id, 0); q += 4;
403 RW_SVAL(io, q, rpc->alloc_hint, 0); q += 2;
404 RW_CVAL(io, q, rpc->context_id, 0); q++;
405 RW_CVAL(io, q, rpc->reserved, 0); q++;
410 /*******************************************************************
411 reads or writes an LSA_POL_HND structure.
412 ********************************************************************/
413 char* smb_io_pol_hnd(BOOL io, LSA_POL_HND *pol, char *q, char *base, int align, int depth)
415 if (pol == NULL) return NULL;
417 DEBUG(5,("%ssmb_io_pol_hnd\n", tab_depth(depth)));
420 q = align_offset(q, base, align);
422 DBG_RW_PCVAL("data", depth, base, io, q, pol->data, POL_HND_SIZE); q += POL_HND_SIZE;
427 /*******************************************************************
428 reads or writes a dom query structure.
429 ********************************************************************/
430 char* smb_io_dom_query_3(BOOL io, DOM_QUERY_3 *d_q, char *q, char *base, int align)
432 return smb_io_dom_query(io, d_q, q, base, align);
435 /*******************************************************************
436 reads or writes a dom query structure.
437 ********************************************************************/
438 char* smb_io_dom_query_5(BOOL io, DOM_QUERY_3 *d_q, char *q, char *base, int align)
440 return smb_io_dom_query(io, d_q, q, base, align);
443 /*******************************************************************
444 reads or writes a dom query structure.
445 ********************************************************************/
446 char* smb_io_dom_query(BOOL io, DOM_QUERY *d_q, char *q, char *base, int align)
448 if (d_q == NULL) return NULL;
450 q = align_offset(q, base, align);
453 RW_SVAL(io, q, d_q->uni_dom_max_len, 0); q += 2; /* domain name string length * 2 */
454 RW_SVAL(io, q, d_q->padding , 0); q += 2; /* 2 padding bytes */
455 RW_SVAL(io, q, d_q->uni_dom_str_len, 0); q += 2; /* domain name string length * 2 */
457 RW_IVAL(io, q, d_q->buffer_dom_name, 0); q += 4; /* undocumented domain name string buffer pointer */
458 RW_IVAL(io, q, d_q->buffer_dom_sid , 0); q += 4; /* undocumented domain SID string buffer pointer */
460 if (d_q->buffer_dom_name != 0)
462 q = smb_io_unistr2(io, &(d_q->uni_domain_name), q, base, align); /* domain name (unicode string) */
464 if (d_q->buffer_dom_sid != 0)
466 q = smb_io_dom_sid(io, &(d_q->dom_sid), q, base, align); /* domain SID */
472 /*******************************************************************
473 reads or writes a DOM_R_REF structure.
474 ********************************************************************/
475 char* smb_io_dom_r_ref(BOOL io, DOM_R_REF *r_r, char *q, char *base, int align)
479 if (r_r == NULL) return NULL;
481 q = align_offset(q, base, align);
483 RW_IVAL(io, q, r_r->undoc_buffer, 0); q += 4; /* undocumented buffer pointer. */
484 RW_IVAL(io, q, r_r->num_ref_doms_1, 0); q += 4; /* num referenced domains? */
485 RW_IVAL(io, q, r_r->buffer_dom_name, 0); q += 4; /* undocumented domain name buffer pointer. */
486 RW_IVAL(io, q, r_r->max_entries, 0); q += 4; /* 32 - max number of entries */
487 RW_IVAL(io, q, r_r->num_ref_doms_2, 0); q += 4; /* 4 - num referenced domains? */
489 q = smb_io_unihdr2(io, &(r_r->hdr_dom_name), q, base, align); /* domain name unicode string header */
491 for (i = 0; i < r_r->num_ref_doms_1-1; i++)
493 q = smb_io_unihdr2(io, &(r_r->hdr_ref_dom[i]), q, base, align);
496 q = smb_io_unistr(io, &(r_r->uni_dom_name), q, base, align); /* domain name unicode string */
498 for (i = 0; i < r_r->num_ref_doms_2; i++)
500 q = smb_io_dom_sid(io, &(r_r->ref_dom[i]), q, base, align); /* referenced domain SIDs */
505 /*******************************************************************
506 reads or writes a DOM_NAME structure.
507 ********************************************************************/
508 char* smb_io_dom_name(BOOL io, DOM_NAME *name, char *q, char *base, int align)
510 if (name == NULL) return NULL;
512 q = align_offset(q, base, align);
514 RW_IVAL(io, q, name->uni_str_len, 0); q += 4;
516 /* don't know if len is specified by uni_str_len member... */
517 /* assume unicode string is unicode-null-terminated, instead */
519 q = smb_io_unistr(io, &(name->str), q, base, align);
525 /*******************************************************************
526 reads or writes a structure.
527 ********************************************************************/
528 char* smb_io_neg_flags(BOOL io, NEG_FLAGS *neg, char *q, char *base, int align)
530 if (neg == NULL) return NULL;
532 q = align_offset(q, base, align);
534 RW_IVAL(io, q, neg->neg_flags, 0); q += 4;
541 /*******************************************************************
542 reads or writes a structure.
543 ********************************************************************/
544 char* smb_io_(BOOL io, *, char *q, char *base, int align)
546 if (== NULL) return NULL;
548 q = align_offset(q, base, align);
550 RW_IVAL(io, q, , 0); q += 4;