proto.h:
[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
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 an NTTIME structure.
29 ********************************************************************/
30 char* smb_io_time(BOOL io, NTTIME *nttime, char *q, char *base, int align)
31 {
32         if (nttime == NULL) return NULL;
33
34         q = align_offset(q, base, align);
35         
36         RW_IVAL(io, q, nttime->low , 0); q += 4; /* low part */
37         RW_IVAL(io, q, nttime->high, 0); q += 4; /* high part */
38
39         return q;
40 }
41
42 /*******************************************************************
43 reads or writes a DOM_SID structure.
44 ********************************************************************/
45 char* smb_io_sid(BOOL io, DOM_SID *sid, char *q, char *base, int align)
46 {
47         int i;
48
49         if (sid == NULL) return NULL;
50
51         q = align_offset(q, base, align);
52         
53         RW_CVAL(io, q, sid->sid_no, 0); q++; 
54         RW_CVAL(io, q, sid->num_auths, 0); q++;
55
56         for (i = 0; i < 6; i++)
57         {
58                 RW_CVAL(io, q, sid->id_auth[i], 0); q++;
59         }
60
61         /* oops! XXXX should really issue a warning here... */
62         if (sid->num_auths > MAXSUBAUTHS) sid->num_auths = MAXSUBAUTHS;
63
64         RW_PSVAL(io, q, sid->sub_auths, sid->num_auths); q += sid->num_auths * 2;
65
66         return q;
67 }
68
69 /*******************************************************************
70 reads or writes a UNIHDR structure.
71 ********************************************************************/
72 char* smb_io_unihdr(BOOL io, UNIHDR *hdr, char *q, char *base, int align)
73 {
74         if (hdr == NULL) return NULL;
75
76         /* should be value 4, so enforce it. */
77         hdr->undoc = 4;
78
79         q = align_offset(q, base, align);
80         
81         RW_IVAL(io, q, hdr->uni_max_len, 0); q += 4;
82         RW_IVAL(io, q, hdr->uni_str_len, 0); q += 4;
83         RW_IVAL(io, q, hdr->undoc      , 0); q += 4;
84
85         return q;
86 }
87
88 /*******************************************************************
89 reads or writes a UNIHDR2 structure.
90 ********************************************************************/
91 char* smb_io_unihdr2(BOOL io, UNIHDR2 *hdr2, char *q, char *base, int align)
92 {
93         if (hdr2 == NULL) return NULL;
94
95         q = align_offset(q, base, align);
96
97         q = smb_io_unihdr(io, &(hdr2->unihdr), q, base, align);
98         RW_IVAL(io, q, hdr2->undoc_buffer, 0); q += 4;
99
100         return q;
101 }
102
103 /*******************************************************************
104 reads or writes a UNISTR structure.
105 XXXX NOTE: UNISTR structures NEED to be null-terminated.
106 ********************************************************************/
107 char* smb_io_unistr(BOOL io, UNISTR *uni, char *q, char *base, int align)
108 {
109         if (uni == NULL) return NULL;
110
111         q = align_offset(q, base, align);
112         
113         if (io)
114         {
115                 /* io True indicates read _from_ the SMB buffer into the string */
116                 q += 2 * unistrcpy((char*)uni->buffer, q);
117         }
118         else
119         {
120                 /* io True indicates copy _from_ the string into SMB buffer */
121                 q += 2 * unistrcpy(q, (char*)uni->buffer);
122         }
123         return q;
124 }
125
126 /*******************************************************************
127 reads or writes a UNISTR2 structure.
128 XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
129      the uni_str_len member tells you how long the string is;
130      the uni_max_len member tells you how large the buffer is.
131 ********************************************************************/
132 char* smb_io_unistr2(BOOL io, UNISTR2 *uni2, char *q, char *base, int align)
133 {
134         if (uni2 == NULL) return NULL;
135
136         q = align_offset(q, base, align);
137         
138         /* should be value 0, so enforce it. */
139         uni2->undoc = 0;
140
141         RW_IVAL(io, q, uni2->uni_max_len, 0); q += 4;
142         RW_IVAL(io, q, uni2->undoc      , 0); q += 4;
143         RW_IVAL(io, q, uni2->uni_str_len, 0); q += 4;
144
145         /* oops! XXXX maybe issue a warning that this is happening... */
146         if (uni2->uni_max_len > MAX_UNISTRLEN) uni2->uni_max_len = MAX_UNISTRLEN;
147         if (uni2->uni_str_len > MAX_UNISTRLEN) uni2->uni_str_len = MAX_UNISTRLEN;
148
149         /* buffer advanced by indicated length of string
150        NOT by searching for null-termination */
151         RW_PSVAL(io, q, uni2->buffer, uni2->uni_max_len); q += uni2->uni_max_len * 2;
152
153         return q;
154 }
155
156 /*******************************************************************
157 reads or writes a DOM_SID2 structure.
158 ********************************************************************/
159 char* smb_io_dom_sid2(BOOL io, DOM_SID2 *sid2, char *q, char *base, int align)
160 {
161         if (sid2 == NULL) return NULL;
162
163         q = align_offset(q, base, align);
164         
165         /* should be value 5, so enforce it */
166         sid2->type = 5;
167
168         /* should be value 0, so enforce it */
169         sid2->undoc = 0;
170
171         RW_IVAL(io, q, sid2->type , 0); q += 4;
172         RW_IVAL(io, q, sid2->undoc, 0); q += 4;
173
174         q = smb_io_unihdr2(io, &(sid2->hdr), q, base, align);
175         q = smb_io_unistr (io, &(sid2->str), q, base, align);
176
177         return q;
178 }
179
180 /*******************************************************************
181 reads or writes a DOM_RID2 structure.
182 ********************************************************************/
183 char* smb_io_dom_rid2(BOOL io, DOM_RID2 *rid2, char *q, char *base, int align)
184 {
185         if (rid2 == NULL) return NULL;
186
187         q = align_offset(q, base, align);
188         
189         /* should be value 5, so enforce it */
190         rid2->type = 5;
191
192         /* should be value 5, so enforce it */
193         rid2->undoc = 5;
194
195         RW_IVAL(io, q, rid2->type, 0); q += 4;
196         RW_IVAL(io, q, rid2->undoc   , 0); q += 4;
197         RW_IVAL(io, q, rid2->rid     , 0); q += 4;
198         RW_IVAL(io, q, rid2->rid_idx , 0); q += 4;
199
200         return q;
201 }
202
203 /*******************************************************************
204 reads or writes a DOM_LOG_INFO structure.
205 ********************************************************************/
206 char* smb_io_log_info(BOOL io, DOM_LOG_INFO *log, char *q, char *base, int align)
207 {
208         if (log == NULL) return NULL;
209
210         q = align_offset(q, base, align);
211         
212         RW_IVAL(io, q, log->undoc_buffer, 0); q += 4;
213
214         q = smb_io_unistr2(io, &(log->uni_logon_srv), q, base, align);
215         q = smb_io_unistr2(io, &(log->uni_acct_name), q, base, align);
216
217         RW_SVAL(io, q, log->sec_chan, 0); q += 2;
218
219         /* XXXX no alignment required between sec_chan and uni_comp_name */
220         q = smb_io_unistr2(io, &(log->uni_comp_name), q, base, 0);
221
222         return q;
223 }
224
225 /*******************************************************************
226 reads or writes a DOM_CRED structure.
227 ********************************************************************/
228 char* smb_io_cred(BOOL io, DOM_CRED *cred, char *q, char *base, int align)
229 {
230         if (cred == NULL) return NULL;
231
232         q = align_offset(q, base, align);
233         
234         RW_PCVAL(io, q, cred->data, 8); q += 8;
235         RW_IVAL (io, q, cred->timestamp, 0); q += 4;
236
237         return q;
238 }
239
240 /*******************************************************************
241 reads or writes a DOM_CLNT_INFO structure.
242 ********************************************************************/
243 char* smb_io_clnt_info(BOOL io, DOM_CLNT_INFO *clnt, char *q, char *base, int align)
244 {
245         if (clnt == NULL) return NULL;
246
247         q = align_offset(q, base, align);
248         
249         q = smb_io_log_info(io, &(clnt->login), q, base, align);
250         q = smb_io_cred    (io, &(clnt->cred ), q, base, align);
251
252         return q;
253 }
254
255 /*******************************************************************
256 reads or writes a DOM_LOGON_ID structure.
257 ********************************************************************/
258 char* smb_io_logon_id(BOOL io, DOM_LOGON_ID *log, char *q, char *base, int align)
259 {
260         if (log == NULL) return NULL;
261
262         q = align_offset(q, base, align);
263         
264         RW_IVAL(io, q, log->low , 0); q += 4;
265         RW_IVAL(io, q, log->high, 0); q += 4;
266
267         return q;
268 }
269
270 /*******************************************************************
271 reads or writes an RC4_OWF structure.
272 ********************************************************************/
273 char* smb_io_rc4_owf(BOOL io, RC4_OWF *hash, char *q, char *base, int align)
274 {
275         if (hash == NULL) return NULL;
276
277         q = align_offset(q, base, align);
278         
279         RW_PCVAL(io, q, hash->data, 16); q += 16;
280
281         return q;
282 }
283
284 /*******************************************************************
285 reads or writes an DOM_ID_INFO_1 structure.
286 ********************************************************************/
287 char* smb_io_id_info1(BOOL io, DOM_ID_INFO_1 *id, char *q, char *base, int align)
288 {
289         if (id == NULL) return NULL;
290
291         q = align_offset(q, base, align);
292         
293         q = smb_io_unihdr(io, &(id->hdr_domain_name   ), q, base, align);
294
295         RW_IVAL(io, q, id->param, 0); q += 4;
296         q = smb_io_logon_id(io, &(id->logon_id), q, base, align);
297
298         q = smb_io_unihdr(io, &(id->hdr_user_name     ), q, base, align);
299         q = smb_io_unihdr(io, &(id->hdr_workgroup_name), q, base, align);
300
301         q = smb_io_rc4_owf(io, &(id->rc4_lm_owf), q, base, align);
302         q = smb_io_rc4_owf(io, &(id->rc4_nt_owf), q, base, align);
303
304         q = smb_io_unistr2(io, &(id->uni_domain_name   ), q, base, align);
305         q = smb_io_unistr2(io, &(id->uni_user_name     ), q, base, align);
306         q = smb_io_unistr2(io, &(id->uni_workgroup_name), q, base, align);
307
308         return q;
309 }
310
311 /*******************************************************************
312 reads or writes a DOM_SAM_INFO structure.
313 ********************************************************************/
314 char* smb_io_sam_info(BOOL io, DOM_SAM_INFO *sam, char *q, char *base, int align)
315 {
316         if (sam == NULL) return NULL;
317
318         q = align_offset(q, base, align);
319         
320         q = smb_io_clnt_info(io, &(sam->client  ), q, base, align);
321         q = smb_io_cred     (io, &(sam->rtn_cred), q, base, align);
322
323         RW_IVAL(io, q, sam->logon_level, 0); q += 4;
324         RW_SVAL(io, q, sam->auth_level , 0); q += 4;
325
326         switch (sam->auth_level)
327         {
328                 case 1:
329                 {
330                         q = smb_io_id_info1(io, &(sam->auth.id1), q, base, align);
331                         break;
332                 }
333                 default:
334                 {
335                         /* PANIC! */
336                         break;
337                 }
338         }
339         return q;
340 }
341
342 /*******************************************************************
343 reads or writes a DOM_GID structure.
344 ********************************************************************/
345 char* smb_io_gid(BOOL io, DOM_GID *gid, char *q, char *base, int align)
346 {
347         if (gid == NULL) return NULL;
348
349         q = align_offset(q, base, align);
350         
351         RW_IVAL(io, q, gid->gid , 0); q += 4;
352         RW_IVAL(io, q, gid->attr, 0); q += 4;
353
354         return q;
355 }
356
357 /*******************************************************************
358 reads or writes an RPC_HDR structure.
359 ********************************************************************/
360 char* smb_io_rpc_hdr(BOOL io, RPC_HDR *rpc, char *q, char *base, int align)
361 {
362         if (rpc == NULL) return NULL;
363
364         /* reserved should be zero: enforce it */
365         rpc->reserved = 0;
366
367         RW_CVAL(io, q, rpc->major, 0); q++;
368         RW_CVAL(io, q, rpc->minor, 0); q++;
369         RW_CVAL(io, q, rpc->pkt_type, 0); q++;
370         RW_CVAL(io, q, rpc->frag, 0); q++;
371         RW_IVAL(io, q, rpc->pack_type, 0); q += 4;
372         RW_SVAL(io, q, rpc->frag_len, 0); q += 2;
373         RW_SVAL(io, q, rpc->auth_len, 0); q += 2;
374         RW_IVAL(io, q, rpc->call_id, 0); q += 4;
375         RW_SVAL(io, q, rpc->alloc_hint, 0); q += 2;
376         RW_CVAL(io, q, rpc->context_id, 0); q++;
377         RW_CVAL(io, q, rpc->reserved, 0); q++;
378
379         return q;
380 }
381
382 #if 0
383 /*******************************************************************
384 reads or writes a structure.
385 ********************************************************************/
386  char* smb_io_(BOOL io, *, char *q, char *base, int align)
387 {
388         if (== NULL) return NULL;
389
390         q = align_offset(q, base, align);
391         
392         RW_IVAL(io, q, , 0); q += 4;
393
394         return q;
395 }
396 #endif