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
)
415 if (pol
== NULL
) return NULL
;
417 q
= align_offset(q
, base
, align
);
419 RW_PCVAL(io
, q
, pol
->data
, POL_HND_SIZE
); q
+= POL_HND_SIZE
;
424 /*******************************************************************
425 reads or writes a dom query structure.
426 ********************************************************************/
427 char* smb_io_dom_query_3(BOOL io
, DOM_QUERY_3
*d_q
, char *q
, char *base
, int align
)
429 return smb_io_dom_query(io
, d_q
, q
, base
, align
);
432 /*******************************************************************
433 reads or writes a dom query structure.
434 ********************************************************************/
435 char* smb_io_dom_query_5(BOOL io
, DOM_QUERY_3
*d_q
, char *q
, char *base
, int align
)
437 return smb_io_dom_query(io
, d_q
, q
, base
, align
);
440 /*******************************************************************
441 reads or writes a dom query structure.
442 ********************************************************************/
443 char* smb_io_dom_query(BOOL io
, DOM_QUERY
*d_q
, char *q
, char *base
, int align
)
445 if (d_q
== NULL
) return NULL
;
447 q
= align_offset(q
, base
, align
);
450 RW_SVAL(io
, q
, d_q
->uni_dom_max_len
, 0); q
+= 2; /* domain name string length * 2 */
451 RW_SVAL(io
, q
, d_q
->padding
, 0); q
+= 2; /* 2 padding bytes */
452 RW_SVAL(io
, q
, d_q
->uni_dom_str_len
, 0); q
+= 2; /* domain name string length * 2 */
454 RW_IVAL(io
, q
, d_q
->buffer_dom_name
, 0); q
+= 4; /* undocumented domain name string buffer pointer */
455 RW_IVAL(io
, q
, d_q
->buffer_dom_sid
, 0); q
+= 4; /* undocumented domain SID string buffer pointer */
457 if (d_q
->buffer_dom_name
!= 0)
459 q
= smb_io_unistr2(io
, &(d_q
->uni_domain_name
), q
, base
, align
); /* domain name (unicode string) */
461 if (d_q
->buffer_dom_sid
!= 0)
463 q
= smb_io_dom_sid(io
, &(d_q
->dom_sid
), q
, base
, align
); /* domain SID */
469 /*******************************************************************
470 reads or writes a DOM_R_REF structure.
471 ********************************************************************/
472 char* smb_io_dom_r_ref(BOOL io
, DOM_R_REF
*r_r
, char *q
, char *base
, int align
)
476 if (r_r
== NULL
) return NULL
;
478 q
= align_offset(q
, base
, align
);
480 RW_IVAL(io
, q
, r_r
->undoc_buffer
, 0); q
+= 4; /* undocumented buffer pointer. */
481 RW_IVAL(io
, q
, r_r
->num_ref_doms_1
, 0); q
+= 4; /* num referenced domains? */
482 RW_IVAL(io
, q
, r_r
->buffer_dom_name
, 0); q
+= 4; /* undocumented domain name buffer pointer. */
483 RW_IVAL(io
, q
, r_r
->max_entries
, 0); q
+= 4; /* 32 - max number of entries */
484 RW_IVAL(io
, q
, r_r
->num_ref_doms_2
, 0); q
+= 4; /* 4 - num referenced domains? */
486 q
= smb_io_unihdr2(io
, &(r_r
->hdr_dom_name
), q
, base
, align
); /* domain name unicode string header */
488 for (i
= 0; i
< r_r
->num_ref_doms_1
-1; i
++)
490 q
= smb_io_unihdr2(io
, &(r_r
->hdr_ref_dom
[i
]), q
, base
, align
);
493 q
= smb_io_unistr(io
, &(r_r
->uni_dom_name
), q
, base
, align
); /* domain name unicode string */
495 for (i
= 0; i
< r_r
->num_ref_doms_2
; i
++)
497 q
= smb_io_dom_sid(io
, &(r_r
->ref_dom
[i
]), q
, base
, align
); /* referenced domain SIDs */
502 /*******************************************************************
503 reads or writes a DOM_NAME structure.
504 ********************************************************************/
505 char* smb_io_dom_name(BOOL io
, DOM_NAME
*name
, char *q
, char *base
, int align
)
507 if (name
== NULL
) return NULL
;
509 q
= align_offset(q
, base
, align
);
511 RW_IVAL(io
, q
, name
->uni_str_len
, 0); q
+= 4;
513 /* don't know if len is specified by uni_str_len member... */
514 /* assume unicode string is unicode-null-terminated, instead */
516 q
= smb_io_unistr(io
, &(name
->str
), q
, base
, align
);
522 /*******************************************************************
523 reads or writes a structure.
524 ********************************************************************/
525 char* smb_io_neg_flags(BOOL io
, NEG_FLAGS
*neg
, char *q
, char *base
, int align
)
527 if (neg
== NULL
) return NULL
;
529 q
= align_offset(q
, base
, align
);
531 RW_IVAL(io
, q
, neg
->neg_flags
, 0); q
+= 4;
538 /*******************************************************************
539 reads or writes a structure.
540 ********************************************************************/
541 char* smb_io_(BOOL io
, *, char *q
, char *base
, int align
)
543 if (== NULL
) return NULL
;
545 q
= align_offset(q
, base
, align
);
547 RW_IVAL(io
, q
, , 0); q
+= 4;