7ea140f7cb737f2ac68ecea5e9d0c37c9e277869
[kai/samba.git] / source3 / smbparse.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba utility functions
5    Copyright (C) Luke Leighton 1996 - 1997  Paul Ashton 1997
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26
27 /*******************************************************************
28 reads or writes a UTIME type.
29 ********************************************************************/
30 char* smb_io_utime(BOOL io, UTIME *t, char *q, char *base, int align)
31 {
32         if (t == NULL) return NULL;
33
34         q = align_offset(q, base, align);
35         
36         RW_IVAL (io, q, t->time, 0); q += 4;
37
38         return q;
39 }
40
41 /*******************************************************************
42 reads or writes an NTTIME structure.
43 ********************************************************************/
44 char* smb_io_time(BOOL io, NTTIME *nttime, char *q, char *base, int align)
45 {
46         if (nttime == NULL) return NULL;
47
48         q = align_offset(q, base, align);
49         
50         RW_IVAL(io, q, nttime->low , 0); q += 4; /* low part */
51         RW_IVAL(io, q, nttime->high, 0); q += 4; /* high part */
52
53         return q;
54 }
55
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)
60 {
61         int i;
62
63         if (sid == NULL) return NULL;
64
65         q = align_offset(q, base, align);
66         
67         RW_CVAL(io, q, sid->sid_no, 0); q++; 
68         RW_CVAL(io, q, sid->num_auths, 0); q++;
69
70         for (i = 0; i < 6; i++)
71         {
72                 RW_CVAL(io, q, sid->id_auth[i], 0); q++;
73         }
74
75         /* oops! XXXX should really issue a warning here... */
76         if (sid->num_auths > MAXSUBAUTHS) sid->num_auths = MAXSUBAUTHS;
77
78         RW_PSVAL(io, q, sid->sub_auths, sid->num_auths); q += sid->num_auths * 2;
79
80         return q;
81 }
82
83 /*******************************************************************
84 reads or writes a UNIHDR structure.
85 ********************************************************************/
86 char* smb_io_unihdr(BOOL io, UNIHDR *hdr, char *q, char *base, int align)
87 {
88         if (hdr == NULL) return NULL;
89
90         /* should be value 4, so enforce it. */
91         hdr->undoc = 4;
92
93         q = align_offset(q, base, align);
94         
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;
98
99         return q;
100 }
101
102 /*******************************************************************
103 reads or writes a UNIHDR2 structure.
104 ********************************************************************/
105 char* smb_io_unihdr2(BOOL io, UNIHDR2 *hdr2, char *q, char *base, int align)
106 {
107         if (hdr2 == NULL) return NULL;
108
109         q = align_offset(q, base, align);
110
111         q = smb_io_unihdr(io, &(hdr2->unihdr), q, base, align);
112         RW_IVAL(io, q, hdr2->undoc_buffer, 0); q += 4;
113
114         return q;
115 }
116
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)
122 {
123         if (uni == NULL) return NULL;
124
125         q = align_offset(q, base, align);
126         
127         if (io)
128         {
129                 /* io True indicates read _from_ the SMB buffer into the string */
130                 q += 2 * unistrcpy((char*)uni->buffer, q);
131         }
132         else
133         {
134                 /* io True indicates copy _from_ the string into SMB buffer */
135                 q += 2 * unistrcpy(q, (char*)uni->buffer);
136         }
137         return q;
138 }
139
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)
147 {
148         if (uni2 == NULL) return NULL;
149
150         q = align_offset(q, base, align);
151         
152         /* should be value 0, so enforce it. */
153         uni2->undoc = 0;
154
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;
158
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;
162
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;
166
167         return q;
168 }
169
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)
174 {
175         if (sid2 == NULL) return NULL;
176
177         q = align_offset(q, base, align);
178         
179         /* should be value 5, so enforce it */
180         sid2->type = 5;
181
182         /* should be value 0, so enforce it */
183         sid2->undoc = 0;
184
185         RW_IVAL(io, q, sid2->type , 0); q += 4;
186         RW_IVAL(io, q, sid2->undoc, 0); q += 4;
187
188         q = smb_io_unihdr2(io, &(sid2->hdr), q, base, align);
189         q = smb_io_unistr (io, &(sid2->str), q, base, align);
190
191         return q;
192 }
193
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)
198 {
199         if (rid2 == NULL) return NULL;
200
201         q = align_offset(q, base, align);
202         
203         /* should be value 5, so enforce it */
204         rid2->type = 5;
205
206         /* should be value 5, so enforce it */
207         rid2->undoc = 5;
208
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;
213
214         return q;
215 }
216
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)
221 {
222         if (log == NULL) return NULL;
223
224         q = align_offset(q, base, align);
225         
226         RW_IVAL(io, q, log->undoc_buffer, 0); q += 4;
227
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);
230
231         RW_SVAL(io, q, log->sec_chan, 0); q += 2;
232
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);
235
236         return q;
237 }
238
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)
243 {
244         if (chal == NULL) return NULL;
245
246         q = align_offset(q, base, align);
247         
248         RW_PCVAL(io, q, chal->data, 8); q += 8;
249
250         return q;
251 }
252
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)
257 {
258         if (cred == NULL) return NULL;
259
260         q = align_offset(q, base, align);
261         
262         q = smb_io_chal (io, &(cred->challenge), q, base, align);
263         q = smb_io_utime(io, &(cred->timestamp), q, base, align);
264
265         return q;
266 }
267
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)
272 {
273         if (clnt == NULL) return NULL;
274
275         q = align_offset(q, base, align);
276         
277         q = smb_io_log_info(io, &(clnt->login), q, base, align);
278         q = smb_io_cred    (io, &(clnt->cred ), q, base, align);
279
280         return q;
281 }
282
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)
287 {
288         if (log == NULL) return NULL;
289
290         q = align_offset(q, base, align);
291         
292         RW_IVAL(io, q, log->low , 0); q += 4;
293         RW_IVAL(io, q, log->high, 0); q += 4;
294
295         return q;
296 }
297
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)
302 {
303         if (hash == NULL) return NULL;
304
305         q = align_offset(q, base, align);
306         
307         RW_PCVAL(io, q, hash->data, 16); q += 16;
308
309         return q;
310 }
311
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)
316 {
317         if (id == NULL) return NULL;
318
319         q = align_offset(q, base, align);
320         
321         q = smb_io_unihdr(io, &(id->hdr_domain_name   ), q, base, align);
322
323         RW_IVAL(io, q, id->param, 0); q += 4;
324         q = smb_io_logon_id(io, &(id->logon_id), q, base, align);
325
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);
328
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);
331
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);
335
336         return q;
337 }
338
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)
343 {
344         if (sam == NULL) return NULL;
345
346         q = align_offset(q, base, align);
347         
348         q = smb_io_clnt_info(io, &(sam->client  ), q, base, align);
349         q = smb_io_cred     (io, &(sam->rtn_cred), q, base, align);
350
351         RW_IVAL(io, q, sam->logon_level, 0); q += 4;
352         RW_SVAL(io, q, sam->auth_level , 0); q += 4;
353
354         switch (sam->auth_level)
355         {
356                 case 1:
357                 {
358                         q = smb_io_id_info1(io, &(sam->auth.id1), q, base, align);
359                         break;
360                 }
361                 default:
362                 {
363                         /* PANIC! */
364                         break;
365                 }
366         }
367         return q;
368 }
369
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)
374 {
375         if (gid == NULL) return NULL;
376
377         q = align_offset(q, base, align);
378         
379         RW_IVAL(io, q, gid->gid , 0); q += 4;
380         RW_IVAL(io, q, gid->attr, 0); q += 4;
381
382         return q;
383 }
384
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)
389 {
390         if (rpc == NULL) return NULL;
391
392         /* reserved should be zero: enforce it */
393         rpc->reserved = 0;
394
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++;
406
407         return q;
408 }
409
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)
414 {
415         if (pol == NULL) return NULL;
416
417         q = align_offset(q, base, align);
418         
419         RW_PCVAL(io, q, pol->data, POL_HND_SIZE); q += POL_HND_SIZE;
420
421         return q;
422 }
423
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)
428 {
429         return smb_io_dom_query(io, d_q, q, base, align);
430 }
431
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)
436 {
437         return smb_io_dom_query(io, d_q, q, base, align);
438 }
439
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)
444 {
445         if (d_q == NULL) return NULL;
446
447         q = align_offset(q, base, align);
448         
449
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 */
453
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 */
456
457         if (d_q->buffer_dom_name != 0)
458         {
459                 q = smb_io_unistr(io, &(d_q->uni_domain_name), q, base, align); /* domain name (unicode string) */
460         }
461         if (d_q->buffer_dom_sid != 0)
462         {
463                 q = smb_io_dom_sid(io, &(d_q->dom_sid), q, base, align); /* domain SID */
464         }
465
466         return q;
467 }
468
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)
473 {
474         int i;
475
476         if (r_r == NULL) return NULL;
477
478         q = align_offset(q, base, align);
479         
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? */
485
486         q = smb_io_unihdr2(io, &(r_r->hdr_dom_name), q, base, align); /* domain name unicode string header */
487
488         for (i = 0; i < r_r->num_ref_doms_1-1; i++)
489         {
490                 q = smb_io_unihdr2(io, &(r_r->hdr_ref_dom[i]), q, base, align);
491         }
492
493         q = smb_io_unistr(io, &(r_r->uni_dom_name), q, base, align); /* domain name unicode string */
494
495         for (i = 0; i < r_r->num_ref_doms_2; i++)
496         {
497                 q = smb_io_dom_sid(io, &(r_r->ref_dom[i]), q, base, align); /* referenced domain SIDs */
498         }
499         return q;
500 }
501
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)
506 {
507         if (name == NULL) return NULL;
508
509         q = align_offset(q, base, align);
510         
511         RW_IVAL(io, q, name->uni_str_len, 0); q += 4;
512
513         /* don't know if len is specified by uni_str_len member... */
514         /* assume unicode string is unicode-null-terminated, instead */
515
516         q = smb_io_unistr(io, &(name->buffer), q, base, align);
517
518         return q;
519 }
520
521
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)
526 {
527         if (neg == NULL) return NULL;
528
529         q = align_offset(q, base, align);
530         
531         RW_IVAL(io, q, neg->neg_flags, 0); q += 4;
532
533         return q;
534 }
535
536
537 #if 0
538 /*******************************************************************
539 reads or writes a structure.
540 ********************************************************************/
541  char* smb_io_(BOOL io, *, char *q, char *base, int align)
542 {
543         if (== NULL) return NULL;
544
545         q = align_offset(q, base, align);
546         
547         RW_IVAL(io, q, , 0); q += 4;
548
549         return q;
550 }
551 #endif