get rid of more compiler warnings
[gd/samba/.git] / source / libads / authdata.c
1 /* 
2    Unix SMB/CIFS implementation.
3    kerberos authorization data (PAC) utility library
4    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003   
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 #ifdef HAVE_KRB5
24
25 static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data)
26 {
27         DATA_BLOB pac_contents;
28         ASN1_DATA data;
29         int data_type;
30
31         asn1_load(&data, *auth_data);
32         asn1_start_tag(&data, ASN1_SEQUENCE(0));
33         asn1_start_tag(&data, ASN1_SEQUENCE(0));
34         asn1_start_tag(&data, ASN1_CONTEXT(0));
35         asn1_read_Integer(&data, &data_type);
36         asn1_end_tag(&data);
37         asn1_start_tag(&data, ASN1_CONTEXT(1));
38         asn1_read_OctetString(&data, &pac_contents);
39         asn1_end_tag(&data);
40         asn1_end_tag(&data);
41         asn1_end_tag(&data);
42         asn1_free(&data);
43         return pac_contents;
44 }
45
46 static BOOL pac_io_unknown_type_10(const char *desc, UNKNOWN_TYPE_10 *type_10,
47                                    prs_struct *ps, int depth)
48 {
49         if (NULL == type_10)
50                 return False;
51
52         prs_debug(ps, depth, desc, "pac_io_unknown_type_10");
53         depth++;
54
55         if (!smb_io_time("unknown_time", &type_10->unknown_time, ps, depth))
56                 return False;
57
58         if (!prs_uint16("len", ps, depth, &type_10->len))
59                 return False;
60
61         if (UNMARSHALLING(ps) && type_10->len) {
62                 type_10->username = (uint16 *) prs_alloc_mem(ps, type_10->len);
63                 if (!type_10->username) {
64                         DEBUG(3, ("No memory available\n"));
65                         return False;
66                 }
67         }
68
69         if (!prs_uint16s(True, "name", ps, depth, type_10->username, 
70                          (type_10->len / sizeof(uint16))))
71                 return False;
72
73         return True;
74
75 }
76
77
78 static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr,
79                             prs_struct *ps, int depth)
80 {
81         if (NULL == sid_and_attr)
82                 return False;
83
84         prs_debug(ps, depth, desc, "pac_io_krb_sids");
85         depth++;
86
87         if (UNMARSHALLING(ps)) {
88                 sid_and_attr->sid = 
89                         (DOM_SID2 * ) prs_alloc_mem(ps, sizeof(DOM_SID2));
90                 if (!sid_and_attr->sid) {
91                         DEBUG(3, ("No memory available\n"));
92                         return False;
93                 }
94         }
95
96         if(!smb_io_dom_sid2("sid", sid_and_attr->sid, ps, depth))
97                 return False;
98
99         return True;
100 }
101
102
103 static BOOL pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr,
104                              prs_struct *ps, int depth)
105 {
106         if (NULL == sid_and_attr)
107                 return False;
108
109         prs_debug(ps, depth, desc, "pac_io_krb_attrs");
110         depth++;
111
112         if (!prs_uint32("sid_ptr", ps, depth, &sid_and_attr->sid_ptr))
113                 return False;
114         if (!prs_uint32("attrs", ps, depth, &sid_and_attr->attrs))
115                 return False;
116
117         return True;
118 }
119
120 static BOOL pac_io_krb_sid_and_attr_array(const char *desc, 
121                                           KRB_SID_AND_ATTR_ARRAY *array,
122                                           uint32 num,
123                                           prs_struct *ps, int depth)
124 {
125         int i;
126
127         if (NULL == array)
128                 return False;
129
130         prs_debug(ps, depth, desc, "pac_io_krb_sid_and_attr_array");
131         depth++;
132
133
134         if (!prs_uint32("count", ps, depth, &array->count))
135                 return False;
136
137         if (UNMARSHALLING(ps)) {
138                 array->krb_sid_and_attrs = (KRB_SID_AND_ATTRS *)
139                         prs_alloc_mem(ps, sizeof(KRB_SID_AND_ATTRS) * num);
140                 if (!array->krb_sid_and_attrs) {
141                         DEBUG(3, ("No memory available\n"));
142                         return False;
143                 }
144         }
145
146         for (i=0; i<num; i++) {
147                 if (!pac_io_krb_attrs(desc, 
148                                       &array->krb_sid_and_attrs[i],
149                                       ps, depth))
150                         return False;
151
152         }
153         for (i=0; i<num; i++) {
154                 if (!pac_io_krb_sids(desc, 
155                                      &array->krb_sid_and_attrs[i],
156                                      ps, depth))
157                         return False;
158
159         }
160
161         return True;
162
163 }
164
165 static BOOL pac_io_group_membership(const char *desc, 
166                                     GROUP_MEMBERSHIP *membership,
167                                     prs_struct *ps, int depth)
168 {
169         if (NULL == membership)
170                 return False;
171
172         prs_debug(ps, depth, desc, "pac_io_group_membership");
173         depth++;
174
175         if (!prs_uint32("rid", ps, depth, &membership->rid))
176                 return False;
177         if (!prs_uint32("attrs", ps, depth, &membership->attrs))
178                 return False;
179
180         return True;
181 }
182
183
184 static BOOL pac_io_group_membership_array(const char *desc, 
185                                           GROUP_MEMBERSHIP_ARRAY *array,
186                                           uint32 num,
187                                           prs_struct *ps, int depth)
188 {
189         int i;
190
191         if (NULL == array)
192                 return False;
193
194         prs_debug(ps, depth, desc, "pac_io_group_membership_array");
195         depth++;
196
197
198         if (!prs_uint32("count", ps, depth, &array->count))
199                 return False;
200
201         if (UNMARSHALLING(ps)) {
202                 array->group_membership = (GROUP_MEMBERSHIP *)
203                         prs_alloc_mem(ps, sizeof(GROUP_MEMBERSHIP) * num);
204                 if (!array->group_membership) {
205                         DEBUG(3, ("No memory available\n"));
206                         return False;
207                 }
208         }
209
210         for (i=0; i<num; i++) {
211                 if (!pac_io_group_membership(desc, 
212                                              &array->group_membership[i],
213                                              ps, depth))
214                         return False;
215
216         }
217
218         return True;
219
220 }
221
222 static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, 
223                                   prs_struct *ps, int depth)
224 {
225         uint32 garbage;
226         if (NULL == info)
227                 return False;
228
229         prs_debug(ps, depth, desc, "pac_io_pac_logon_info");
230         depth++;
231
232         if (!prs_uint32("unknown", ps, depth, &garbage))
233                 return False;
234         if (!prs_uint32("unknown", ps, depth, &garbage))
235                 return False;
236         if (!prs_uint32("bufferlen", ps, depth, &garbage))
237                 return False;
238         if (!prs_uint32("bufferlenhi", ps, depth, &garbage))
239                 return False;
240         if (!prs_uint32("pointer", ps, depth, &garbage))
241                 return False;
242
243         if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
244                 return False;
245         if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
246                 return False;
247         if (!smb_io_time("kickoff_time", &info->kickoff_time, ps, depth))
248                 return False;
249         if (!smb_io_time("pass_last_set_time", &info->pass_last_set_time, 
250                          ps, depth))
251                 return False;
252         if (!smb_io_time("pass_can_change_time", &info->pass_can_change_time, 
253                          ps, depth))
254                 return False;
255         if (!smb_io_time("pass_must_change_time", &info->pass_must_change_time,
256                          ps, depth))
257                 return False;
258
259         if (!smb_io_unihdr("hdr_user_name", &info->hdr_user_name, ps, depth))
260                 return False;
261         if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
262                 return False;
263         if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, 
264                            ps, depth))
265                 return False;
266         if (!smb_io_unihdr("hdr_profile_path", &info->hdr_profile_path, 
267                            ps, depth))
268                 return False;
269         if (!smb_io_unihdr("hdr_home_dir", &info->hdr_home_dir, ps, depth))
270                 return False;
271         if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
272                 return False;
273
274         if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
275                 return False;
276         if (!prs_uint16("reserved12", ps, depth, &info->reserved12))
277                 return False;
278         if (!prs_uint32("user_rid", ps, depth, &info->user_rid))
279                 return False;
280         if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
281                 return False;
282         if (!prs_uint32("group_count", ps, depth, &info->group_count))
283                 return False;
284         /* I haven't seen this contain anything yet, but when it does
285            we will have to make sure we decode the contents in the middle
286            all the unistr2s ... */
287         if (!prs_uint32("group_mem_ptr", ps, depth, 
288                         &info->group_membership_ptr))
289                 return False;
290         if (!prs_uint32("user_flags", ps, depth, &info->user_flags))
291                 return False;
292
293         if (!prs_uint32("reserved13.0", ps, depth, &info->reserved13[0]))
294                 return False;
295         if (!prs_uint32("reserved13.1", ps, depth, &info->reserved13[1]))
296                 return False;
297         if (!prs_uint32("reserved13.2", ps, depth, &info->reserved13[2]))
298                 return False;
299         if (!prs_uint32("reserved13.3", ps, depth, &info->reserved13[3]))
300                 return False;
301         
302         if (!smb_io_unihdr("hdr_dom_controller", 
303                            &info->hdr_dom_controller, ps, depth))
304                 return False;
305         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
306                 return False;
307
308         /* this should be followed, but just get ptr for now */
309         if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid))
310                 return False;
311
312         if (!prs_uint32("reserved16.0", ps, depth, &info->reserved16[0]))
313                 return False;
314         if (!prs_uint32("reserved16.1", ps, depth, &info->reserved16[1]))
315                 return False;
316
317         /* might be acb_info */
318         if (!prs_uint32("reserved17", ps, depth, &info->reserved17))
319                 return False;
320
321
322         if (!prs_uint32("reserved18.0", ps, depth, &info->reserved18[0]))
323                 return False;
324         if (!prs_uint32("reserved18.1", ps, depth, &info->reserved18[1]))
325                 return False;
326         if (!prs_uint32("reserved18.2", ps, depth, &info->reserved18[2]))
327                 return False;
328         if (!prs_uint32("reserved18.3", ps, depth, &info->reserved18[3]))
329                 return False;
330         if (!prs_uint32("reserved18.4", ps, depth, &info->reserved18[4]))
331                 return False;
332         if (!prs_uint32("reserved18.5", ps, depth, &info->reserved18[5]))
333                 return False;
334         if (!prs_uint32("reserved18.6", ps, depth, &info->reserved18[6]))
335                 return False;
336
337         if (!prs_uint32("sid_count", ps, depth, &info->sid_count))
338                 return False;
339         if (!prs_uint32("ptr_extra_sids", ps, depth, &info->ptr_extra_sids))
340                 return False;
341         if (!prs_uint32("ptr_res_group_dom_sid", ps, depth, 
342                         &info->ptr_res_group_dom_sid))
343                 return False;
344         if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count))
345                 return False;
346         if (!prs_uint32("ptr_res_groups", ps, depth, &info->ptr_res_groups))
347                 return False;
348
349         if(!smb_io_unistr2("uni_user_name", &info->uni_user_name, 
350                            info->hdr_user_name.buffer, ps, depth))
351                 return False;
352         if(!smb_io_unistr2("uni_full_name", &info->uni_full_name, 
353                            info->hdr_full_name.buffer, ps, depth))
354                 return False;
355         if(!smb_io_unistr2("uni_logon_script", &info->uni_logon_script, 
356                            info->hdr_logon_script.buffer, ps, depth))
357                 return False;
358         if(!smb_io_unistr2("uni_profile_path", &info->uni_profile_path,
359                            info->hdr_profile_path.buffer, ps, depth))
360                 return False;
361         if(!smb_io_unistr2("uni_home_dir", &info->uni_home_dir,
362                            info->hdr_home_dir.buffer, ps, depth))
363                 return False;
364         if(!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
365                            info->hdr_dir_drive.buffer, ps, depth))
366                 return False;
367
368         if (info->group_membership_ptr) {
369                 if (!pac_io_group_membership_array("group membership",
370                                                    &info->groups,
371                                                    info->group_count,
372                                                    ps, depth))
373                         return False;
374         }
375
376
377         if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller,
378                            info->hdr_dom_controller.buffer, ps, depth))
379                 return False;
380         if(!smb_io_unistr2("uni_dom_name", &info->uni_dom_name, 
381                            info->hdr_dom_name.buffer, ps, depth))
382                 return False;
383
384         if(info->ptr_dom_sid)
385                 if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth))
386                         return False;
387
388         
389         if (info->sid_count && info->ptr_extra_sids)
390                 if (!pac_io_krb_sid_and_attr_array("extra_sids", 
391                                                    &info->extra_sids,
392                                                    info->sid_count,
393                                                    ps, depth))
394                         return False;
395
396         if (info->ptr_res_group_dom_sid)
397                 if (!smb_io_dom_sid2("res_group_dom_sid", 
398                                      &info->res_group_dom_sid, ps, depth))
399                         return False;
400
401         if (info->ptr_res_groups)
402                 if (!pac_io_group_membership_array("res group membership",
403                                                    &info->res_groups,
404                                                    info->res_group_count,
405                                                    ps, depth))
406                         return False;
407
408         return True;
409 }
410
411
412 static BOOL pac_io_pac_signature_data(const char *desc, 
413                                       PAC_SIGNATURE_DATA *data, uint32 length,
414                                       prs_struct *ps, int depth)
415 {
416         uint32 siglen = length - sizeof(uint32);
417         if (NULL == data)
418                 return False;
419
420         prs_debug(ps, depth, desc, "pac_io_pac_signature_data");
421         depth++;
422
423         if (!prs_uint32("type", ps, depth, &data->type))
424                 return False;
425         if (UNMARSHALLING(ps)) {
426                 data->signature = (unsigned char *)prs_alloc_mem(ps, siglen);
427                 if (!data->signature) {
428                         DEBUG(3, ("No memory available\n"));
429                         return False;
430                 }
431         }
432         if (!prs_uint8s(False, "signature", ps, depth, data->signature,siglen))
433                 return False;
434
435         return True;
436 }
437
438 static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr,
439                                     prs_struct *ps, int depth)
440 {
441         if (NULL == hdr)
442                 return False;
443
444         prs_debug(ps, depth, desc, "pac_io_pac_info_hdr_ctr");
445         depth++;
446
447         if (!prs_align(ps))
448                 return False;
449
450         if (hdr->offset != prs_offset(ps)) {
451                 DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n",
452                           hdr->offset, prs_offset(ps)));
453                 prs_set_offset(ps, hdr->offset);
454         }
455
456         if (UNMARSHALLING(ps) && hdr->size > 0) {
457                 hdr->ctr = (PAC_INFO_CTR *) 
458                         prs_alloc_mem(ps, sizeof(PAC_INFO_CTR));
459                 if (!hdr->ctr) {
460                         DEBUG(3, ("No memory available\n"));
461                         return False;
462                 }
463         }
464
465         switch(hdr->type) {
466         case PAC_TYPE_LOGON_INFO:
467                 DEBUG(5, ("PAC_TYPE_LOGON_INFO\n"));
468                 if (UNMARSHALLING(ps))
469                         hdr->ctr->pac.logon_info = (PAC_LOGON_INFO *)
470                                 prs_alloc_mem(ps, sizeof(PAC_LOGON_INFO));
471                 if (!hdr->ctr->pac.logon_info) {
472                         DEBUG(3, ("No memory available\n"));
473                         return False;
474                 }
475                 if (!pac_io_pac_logon_info(desc, hdr->ctr->pac.logon_info,
476                                            ps, depth))
477                         return False;
478                 break;
479
480         case PAC_TYPE_SERVER_CHECKSUM:
481                 DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n"));
482                 if (UNMARSHALLING(ps))
483                         hdr->ctr->pac.srv_cksum = (PAC_SIGNATURE_DATA *)
484                                 prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA));
485                 if (!hdr->ctr->pac.srv_cksum) {
486                         DEBUG(3, ("No memory available\n"));
487                         return False;
488                 }
489                 if (!pac_io_pac_signature_data(desc, hdr->ctr->pac.srv_cksum,
490                                                hdr->size, ps, depth))
491                         return False;
492                 break;
493
494         case PAC_TYPE_PRIVSVR_CHECKSUM:
495                 DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n"));
496                 if (UNMARSHALLING(ps))
497                         hdr->ctr->pac.privsrv_cksum = (PAC_SIGNATURE_DATA *)
498                                 prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA));
499                 if (!hdr->ctr->pac.privsrv_cksum) {
500                         DEBUG(3, ("No memory available\n"));
501                         return False;
502                 }
503                 if (!pac_io_pac_signature_data(desc, 
504                                                hdr->ctr->pac.privsrv_cksum,
505                                                hdr->size, ps, depth))
506                         return False;
507                 break;
508
509         case PAC_TYPE_UNKNOWN_10:
510                 DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n"));
511                 if (UNMARSHALLING(ps))
512                         hdr->ctr->pac.type_10 = (UNKNOWN_TYPE_10 *)
513                                 prs_alloc_mem(ps, sizeof(UNKNOWN_TYPE_10));
514                 if (!hdr->ctr->pac.type_10) {
515                         DEBUG(3, ("No memory available\n"));
516                         return False;
517                 }
518                 if (!pac_io_unknown_type_10(desc, hdr->ctr->pac.type_10,
519                                             ps, depth))
520                         return False;
521                 break;
522
523         default:
524                 /* dont' know, so we need to skip it */
525                 DEBUG(3, ("unknown PAC type %d\n", hdr->type));
526                 prs_set_offset(ps, prs_offset(ps) + hdr->size);
527         }
528
529         return True;
530 }
531
532 static BOOL pac_io_pac_info_hdr(const char *desc, PAC_INFO_HDR *hdr, 
533                                 prs_struct *ps, int depth)
534 {
535         if (NULL == hdr)
536                 return False;
537
538         prs_debug(ps, depth, desc, "pac_io_pac_info_hdr");
539         depth++;
540
541         if (!prs_align(ps))
542                 return False;
543         if (!prs_uint32("type", ps, depth, &hdr->type))
544                 return False;
545         if (!prs_uint32("size", ps, depth, &hdr->size))
546                 return False;
547         if (!prs_uint32("offset", ps, depth, &hdr->offset))
548                 return False;
549         if (!prs_uint32("offsethi", ps, depth, &hdr->offsethi))
550                 return False;
551
552         return True;
553 }
554
555 static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data, 
556                             prs_struct *ps, int depth)
557 {
558         int i;
559
560         if (NULL == data)
561                 return False;
562
563         prs_debug(ps, depth, desc, "pac_io_pac_data");
564         depth++;
565
566         if (!prs_align(ps))
567                 return False;
568         if (!prs_uint32("num_buffers", ps, depth, &data->num_buffers))
569                 return False;
570         if (!prs_uint32("version", ps, depth, &data->version))
571                 return False;
572
573         if (UNMARSHALLING(ps) && data->num_buffers > 0) {
574                 if ((data->pac_info_hdr_ptr = (PAC_INFO_HDR *) 
575                      prs_alloc_mem(ps, sizeof(PAC_INFO_HDR) * 
576                                    data->num_buffers)) == NULL) {
577                         return False;
578                 }
579         }
580
581         for (i=0; i<data->num_buffers; i++) {
582                 if (!pac_io_pac_info_hdr(desc, &data->pac_info_hdr_ptr[i], ps, 
583                                          depth))
584                         return False;
585         }
586
587         for (i=0; i<data->num_buffers; i++) {
588                 if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_info_hdr_ptr[i],
589                                              ps, depth))
590                         return False;
591         }
592
593         return True;
594 }
595
596 PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx)
597 {
598         DATA_BLOB pac_data_blob = unwrap_pac(auth_data);
599         prs_struct ps;
600         PAC_DATA *pac_data;
601
602         DEBUG(5,("dump_pac_data\n"));
603         prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL);
604         prs_copy_data_in(&ps, (char *)pac_data_blob.data, pac_data_blob.length);
605         prs_set_offset(&ps, 0);
606
607         data_blob_free(&pac_data_blob);
608
609         pac_data = (PAC_DATA *) talloc_zero(ctx, sizeof(PAC_DATA));
610         pac_io_pac_data("pac data", pac_data, &ps, 0);
611
612         prs_mem_free(&ps);
613
614         return pac_data;
615 }
616
617 #endif