ba45fa163afe72c8735b5fe4fef27071b91b7a26
[tprouty/samba.git] / source / rpc_parse / parse_creds.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tgrpsgell              1992-1999,
6  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
7  *  Copyright (C) Paul Ashton                  1997-1999.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambgrpsge, MA 02139, USA.
22  */
23
24
25 #include "includes.h"
26
27 extern int DEBUGLEVEL;
28
29
30 /*******************************************************************
31 makes a CREDS_UNIX structure.
32 ********************************************************************/
33 BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name,
34                                 const char* requested_name,
35                                 const char* real_name,
36                                 BOOL guest)
37 {
38         if (r_u == NULL) return False;
39
40         DEBUG(5,("make_creds_unix\n"));
41
42         fstrcpy(r_u->user_name     , user_name);
43         fstrcpy(r_u->requested_name, requested_name);
44         fstrcpy(r_u->real_name     , real_name);
45         r_u->guest = guest;
46
47         return True;
48 }
49
50 /*******************************************************************
51 reads or writes a structure.
52 ********************************************************************/
53 BOOL creds_io_unix(char *desc, CREDS_UNIX *r_u, prs_struct *ps, int depth)
54 {
55         if (r_u == NULL) return False;
56
57         prs_debug(ps, depth, desc, "creds_io_unix");
58         depth++;
59
60         prs_align(ps);
61         prs_string("user_name", ps, depth,   r_u->user_name, strlen(r_u->user_name), sizeof(r_u->user_name));
62         prs_align(ps);
63         prs_string("requested_name", ps, depth,   r_u->requested_name, strlen(r_u->requested_name), sizeof(r_u->requested_name));
64         prs_align(ps);
65         prs_string("real_name", ps, depth,   r_u->real_name, strlen(r_u->real_name), sizeof(r_u->real_name));
66         prs_align(ps);
67         prs_uint32("guest", ps, depth, &(r_u->guest));
68         return True;
69 }
70
71
72 /*******************************************************************
73 frees a structure.
74 ********************************************************************/
75 void creds_free_unix(CREDS_UNIX *r_u)
76 {
77 }
78
79 /*******************************************************************
80 makes a CREDS_UNIX_SEC structure.
81 ********************************************************************/
82 BOOL make_creds_unix_sec(CREDS_UNIX_SEC *r_u,
83                 uint32 uid, uint32 gid, uint32 num_grps, gid_t *grps)
84 {
85         int i;
86         if (r_u == NULL) return False;
87
88         DEBUG(5,("make_creds_unix_sec\n"));
89
90         r_u->uid      = uid;
91         r_u->gid      = gid;
92         r_u->num_grps = num_grps;
93         r_u->grps = (uint32*)Realloc(NULL, sizeof(r_u->grps[0]) *
94                                        r_u->num_grps);
95         if (r_u->grps == NULL && num_grps != 0)
96         {
97                 return False;
98         }
99         for (i = 0; i < num_grps; i++)
100         {
101                 r_u->grps[i] = (gid_t)grps[i];
102         }
103
104         return True;
105 }
106
107 /*******************************************************************
108 reads or writes a structure.
109 ********************************************************************/
110 BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int depth)
111 {
112         uint32 i;
113
114         if (r_u == NULL) return False;
115
116         prs_debug(ps, depth, desc, "creds_io_unix_sec");
117         depth++;
118
119         prs_align(ps);
120
121         prs_uint32("uid", ps, depth, &(r_u->uid));
122         prs_uint32("gid", ps, depth, &(r_u->gid));
123         prs_uint32("num_grps", ps, depth, &(r_u->num_grps));
124         if (r_u->num_grps != 0)
125         {
126                 r_u->grps = (uint32*)Realloc(r_u->grps,
127                                        sizeof(r_u->grps[0]) *
128                                        r_u->num_grps);
129                 if (r_u->grps == NULL)
130                 {
131                         creds_free_unix_sec(r_u);
132                         return False;
133                 }
134         }
135         for (i = 0; i < r_u->num_grps; i++)
136         {
137                 prs_uint32("", ps, depth, &(r_u->grps[i]));
138         }
139         return True;
140 }
141
142
143 /*******************************************************************
144 frees a structure.
145 ********************************************************************/
146 void creds_free_unix_sec(CREDS_UNIX_SEC *r_u)
147 {
148         if (r_u->grps != NULL)
149         {
150                 free(r_u->grps);
151                 r_u->grps = NULL;
152         }
153 }
154
155 /*******************************************************************
156 makes a CREDS_NT_SEC structure.
157 ********************************************************************/
158 BOOL make_creds_nt_sec(CREDS_NT_SEC *r_u,
159                 DOM_SID *sid, uint32 num_grps, uint32 *grps)
160 {
161         int i;
162         if (r_u == NULL) return False;
163
164         DEBUG(5,("make_creds_unix_sec\n"));
165
166         sid_copy(&r_u->sid, sid);
167         r_u->num_grps = num_grps;
168         r_u->grp_rids = (uint32*)Realloc(NULL, sizeof(r_u->grp_rids[0]) *
169                                        r_u->num_grps);
170
171         if (r_u->grp_rids == NULL && num_grps != 0)
172         {
173                 return False;
174         }
175         for (i = 0; i < num_grps; i++)
176         {
177                 r_u->grp_rids[i] = grps[i];
178         }
179
180         return True;
181 }
182
183 /*******************************************************************
184 reads or writes a structure.
185 ********************************************************************/
186 BOOL creds_io_nt_sec(char *desc, CREDS_NT_SEC *r_u, prs_struct *ps, int depth)
187 {
188         int i;
189         if (r_u == NULL) return False;
190
191         prs_debug(ps, depth, desc, "creds_io_nt");
192         depth++;
193
194         prs_align(ps);
195
196         smb_io_dom_sid ("sid", &r_u->sid, ps, depth);
197         prs_align(ps);
198
199         prs_uint32("num_grps", ps, depth, &(r_u->num_grps));
200         if (r_u->num_grps != 0)
201         {
202                 r_u->grp_rids = (uint32*)Realloc(r_u->grp_rids,
203                                        sizeof(r_u->grp_rids[0]) *
204                                        r_u->num_grps);
205                 if (r_u->grp_rids == NULL)
206                 {
207                         creds_free_nt_sec(r_u);
208                         return False;
209                 }
210         }
211         for (i = 0; i < r_u->num_grps; i++)
212         {
213                 prs_uint32("", ps, depth, &(r_u->grp_rids[i]));
214         }
215
216         return True;
217 }
218
219 /*******************************************************************
220 frees a structure.
221 ********************************************************************/
222 void creds_free_nt_sec(CREDS_NT_SEC *r_u)
223 {
224         if (r_u->grp_rids != NULL)
225         {
226                 free(r_u->grp_rids);
227                 r_u->grp_rids = NULL;
228         }
229 }
230
231 /*******************************************************************
232 reads or writes a structure.
233 ********************************************************************/
234 BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth)
235 {
236         if (pwd == NULL) return False;
237
238         prs_debug(ps, depth, desc, "creds_io_pwd_info");
239         depth++;
240
241         prs_align(ps);
242
243         prs_uint32("nullpwd", ps, depth, &(pwd->null_pwd));
244         if (pwd->null_pwd)
245         {
246                 return True;
247         }
248         
249         prs_uint32("cleartext", ps, depth, &(pwd->cleartext));
250         if (pwd->cleartext)
251         {
252                 prs_string("password", ps, depth,   pwd->password, strlen(pwd->password), sizeof(pwd->password));
253                 prs_align(ps);
254                 return True;
255         }
256         prs_uint32("crypted", ps, depth, &(pwd->crypted));
257                 
258         prs_uint8s(False, "smb_lm_pwd", ps, depth, (char*)&pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
259         prs_align(ps);
260         prs_uint8s(False, "smb_nt_pwd", ps, depth, (char*)&pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
261         prs_align(ps);
262
263         prs_uint8s(False, "smb_lm_owf", ps, depth, (char*)&pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
264         prs_align(ps);
265         prs_uint32("nt_owf_len", ps, depth, &(pwd->nt_owf_len));
266         if (pwd->nt_owf_len > sizeof(pwd->smb_nt_owf))
267         {
268                 return False;
269         }
270         prs_uint8s(False, "smb_nt_owf", ps, depth, (char*)&pwd->smb_nt_owf, pwd->nt_owf_len);
271         prs_align(ps);
272
273         prs_uint8s(False, "lm_cli_chal", ps, depth, (char*)&pwd->lm_cli_chal, sizeof(pwd->lm_cli_chal));
274         prs_align(ps);
275         prs_uint32("nt_cli_chal_len", ps, depth, &(pwd->nt_cli_chal_len));
276
277         if (pwd->nt_cli_chal_len > sizeof(pwd->nt_cli_chal))
278         {
279                 return False;
280         }
281         prs_uint8s(False, "nt_cli_chal", ps, depth, (char*)&pwd->nt_cli_chal, pwd->nt_cli_chal_len);
282         prs_align(ps);
283
284         return True;
285 }
286
287 /*******************************************************************
288 reads or writes a structure.
289 ********************************************************************/
290 BOOL creds_io_nt(char *desc, CREDS_NT *r_u, prs_struct *ps, int depth)
291 {
292         if (r_u == NULL) return False;
293
294         prs_debug(ps, depth, desc, "creds_io_nt");
295         depth++;
296
297         prs_align(ps);
298
299         /* lkclXXXX CHEAT!!!!!!!! */
300         prs_string("user_name", ps, depth,   r_u->user_name, strlen(r_u->user_name), sizeof(r_u->user_name));
301         prs_align(ps);
302         prs_string("domain", ps, depth,   r_u->domain, strlen(r_u->domain), sizeof(r_u->domain));
303         prs_align(ps);
304
305         creds_io_pwd_info("pwd", &r_u->pwd, ps, depth);
306         prs_align(ps);
307
308         prs_uint32("ntlmssp", ps, depth, &(r_u->ntlmssp_flags));
309
310         return True;
311 }
312
313 /*******************************************************************
314 frees a structure.
315 ********************************************************************/
316 void creds_free_nt(CREDS_NT *r_u)
317 {
318 }
319
320 /*******************************************************************
321 reads or writes a structure.
322 ********************************************************************/
323 BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth)
324 {
325         if (r_u == NULL) return False;
326
327         prs_debug(ps, depth, desc, "creds_io_hybrid");
328         depth++;
329
330         prs_align(ps);
331
332         prs_uint32("reuse", ps, depth, &(r_u->reuse));
333
334         prs_uint32("ptr_ntc", ps, depth, &(r_u->ptr_ntc));
335         prs_uint32("ptr_uxc", ps, depth, &(r_u->ptr_uxc));
336         prs_uint32("ptr_nts", ps, depth, &(r_u->ptr_nts));
337         prs_uint32("ptr_uxs", ps, depth, &(r_u->ptr_uxs));
338         prs_uint32("ptr_ssk", ps, depth, &(r_u->ptr_ssk));
339         if (r_u->ptr_ntc != 0)
340         {
341                 if (!creds_io_nt  ("ntc", &r_u->ntc, ps, depth)) return False;
342         }
343         if (r_u->ptr_uxc != 0)
344         {
345                 if (!creds_io_unix("uxc", &r_u->uxc, ps, depth)) return False;
346         }
347         if (r_u->ptr_nts != 0)
348         {
349                 if (!creds_io_nt_sec  ("nts", &r_u->nts, ps, depth)) return False;
350         }
351         if (r_u->ptr_uxs != 0)
352         {
353                 if (!creds_io_unix_sec("uxs", &r_u->uxs, ps, depth)) return False;
354         }
355         if (r_u->ptr_ssk != 0)
356         {
357                 prs_uint8s(False, "usr_sess_key", ps, depth, (char*)&r_u->usr_sess_key, sizeof(r_u->usr_sess_key));
358         }
359         else
360         {
361                 memset(r_u->usr_sess_key, 0, sizeof(r_u->usr_sess_key));
362         }
363         return True;
364 }
365
366 void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from)
367 {
368         if (from == NULL)
369         {
370                 to->user_name[0] = 0;
371                 return;
372         }
373         fstrcpy(to->user_name, from->user_name);
374 };
375
376 void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from)
377 {
378         if (from == NULL)
379         {
380                 ZERO_STRUCTP(to);
381                 return;
382         }
383         sid_copy(&to->sid, &from->sid);
384         to->num_grps = 0;
385         to->grp_rids = NULL;
386
387         if (from->num_grps != 0)
388         {
389                 size_t size = from->num_grps * sizeof(from->grp_rids[0]);
390                 to->grp_rids = (uint32*)malloc(size);
391                 if (to->grp_rids == NULL)
392                 {
393                         return;
394                 }
395                 to->num_grps = from->num_grps;
396                 memcpy(to->grp_rids, from->grp_rids, size);
397         }
398 };
399
400 void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from)
401 {
402         if (from == NULL)
403         {
404                 to->uid = -1;
405                 to->gid = -1;
406                 to->num_grps = 0;
407                 to->grps = NULL;
408                 return;
409         }
410         to->uid = from->uid;
411         to->gid = from->gid;
412         to->num_grps = 0;
413         to->grps = NULL;
414
415         if (from->num_grps != 0)
416         {
417                 size_t size = from->num_grps * sizeof(from->grps[0]);
418                 to->grps = (uint32*)malloc(size);
419                 if (to->grps == NULL)
420                 {
421                         return;
422                 }
423                 to->num_grps = from->num_grps;
424                 memcpy(to->grps, from->grps, size);
425         }
426 };
427
428 void copy_nt_creds(struct ntuser_creds *to,
429                                 const struct ntuser_creds *from)
430 {
431         if (from == NULL)
432         {
433                 DEBUG(10,("copy_nt_creds: null creds\n"));
434                 to->domain[0] = 0;
435                 to->user_name[0] = 0;
436                 pwd_set_nullpwd(&to->pwd);
437                 to->ntlmssp_flags = 0;
438
439                 return;
440         }
441         safe_strcpy(to->domain   , from->domain   , sizeof(from->domain   )-1);
442         safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1);
443         memcpy(&to->pwd, &from->pwd, sizeof(from->pwd));
444         to->ntlmssp_flags = from->ntlmssp_flags;
445         DEBUG(10,("copy_nt_creds: user %s domain %s flgs: %x\n",
446                to->user_name, to->domain, 
447                to->ntlmssp_flags));
448 };
449
450 void copy_user_creds(struct user_creds *to,
451                                 const struct user_creds *from)
452 {
453         ZERO_STRUCTP(to);
454         if (from == NULL)
455         {
456                 to->ptr_ntc = 0;
457                 to->ptr_uxc = 0;
458                 to->ptr_nts = 0;
459                 to->ptr_uxs = 0;
460                 to->ptr_ssk = 0;
461                 copy_nt_creds(&to->ntc, NULL);
462                 copy_unix_creds(&to->uxc, NULL);
463                 copy_nt_sec_creds(&to->nts, NULL);
464                 copy_unix_sec_creds(&to->uxs, NULL);
465                 to->reuse = False;
466                 return;
467         }
468
469         to->reuse = from->reuse;
470
471         to->ptr_nts = from->ptr_nts;
472         to->ptr_uxs = from->ptr_uxs;
473         to->ptr_ntc = from->ptr_ntc;
474         to->ptr_uxc = from->ptr_uxc;
475         to->ptr_ssk = from->ptr_ssk;
476
477         if (to->ptr_ntc != 0)
478         {
479                 copy_nt_creds(&to->ntc, &from->ntc);
480         }
481         if (to->ptr_uxc != 0)
482         {
483                 copy_unix_creds(&to->uxc, &from->uxc);
484         }
485         if (to->ptr_nts != 0)
486         {
487                 copy_nt_sec_creds(&to->nts, &from->nts);
488         }
489         if (to->ptr_uxs != 0)
490         {
491                 copy_unix_sec_creds(&to->uxs, &from->uxs);
492         }
493         if (to->ptr_ssk != 0)
494         {
495                 memcpy(to->usr_sess_key, from->usr_sess_key,
496                         sizeof(to->usr_sess_key));
497         }
498 };
499
500 void free_user_creds(struct user_creds *creds)
501 {
502         creds_free_unix(&creds->uxc);
503         creds_free_nt  (&creds->ntc);
504         creds_free_unix_sec(&creds->uxs);
505         creds_free_nt_sec  (&creds->nts);
506 }
507
508 /*******************************************************************
509 reads or writes a structure.
510 ********************************************************************/
511 BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth)
512 {
513         if (r_u == NULL) return False;
514
515         prs_debug(ps, depth, desc, "creds_io_cmd");
516         depth++;
517
518         prs_align(ps);
519
520         prs_uint16("version", ps, depth, &(r_u->version));
521         prs_uint16("command", ps, depth, &(r_u->command));
522         prs_uint32("pid    ", ps, depth, &(r_u->pid    ));
523
524         prs_string("name   ", ps, depth,   r_u->name, strlen(r_u->name), sizeof(r_u->name));
525         prs_align(ps);
526         
527         prs_uint32("ptr_creds", ps, depth, &(r_u->ptr_creds));
528         if (r_u->ptr_creds != 0)
529         {
530                 if (!creds_io_hybrid("creds", r_u->cred, ps, depth))
531                 {
532                         return False;
533                 }
534         }
535
536
537         return True;
538 }
539
540
541 BOOL create_ntuser_creds( prs_struct *ps,
542                                 const char* name, 
543                                 uint16 version, uint16 command,
544                                 uint32 pid,
545                                 const struct ntuser_creds *ntu,
546                                 BOOL reuse)
547 {
548         CREDS_CMD cmd;
549         struct user_creds usr;
550
551         ZERO_STRUCT(cmd);
552         ZERO_STRUCT(usr);
553
554         DEBUG(10,("create_user_creds: %s %d %d\n",
555                 name, version, command));
556
557         usr.reuse = reuse;
558
559         fstrcpy(cmd.name, name);
560         cmd.version = version;
561         cmd.command = command;
562         cmd.pid   = pid  ;
563         cmd.ptr_creds = ntu != NULL ? 1 : 0;
564         cmd.cred = &usr;
565
566         if (ntu != NULL)
567         {
568                 copy_nt_creds(&usr.ntc, ntu);
569                 usr.ptr_ntc = 1;
570         }
571         else
572         {
573                 usr.ptr_ntc = 0;
574         }
575                 
576         prs_init(ps, 1024, 4, False);
577
578         ps->data_offset = 4;
579         return creds_io_cmd("creds", &cmd, ps, 0);
580 }
581
582 BOOL create_user_creds( prs_struct *ps,
583                                 const char* name, 
584                                 uint16 version, uint16 command,
585                                 uint32 pid,
586                                 const struct user_creds *usr)
587 {
588         CREDS_CMD cmd;
589
590         ZERO_STRUCT(cmd);
591
592         DEBUG(10,("create_user_creds: %s %d %d\n",
593                 name, version, command));
594
595         fstrcpy(cmd.name, name);
596         cmd.version = version;
597         cmd.command = command;
598         cmd.pid     = pid  ;
599         cmd.ptr_creds = usr != NULL ? 1 : 0;
600         cmd.cred = usr;
601
602         prs_init(ps, 1024, 4, False);
603
604         ps->data_offset = 4;
605         return creds_io_cmd("creds", &cmd, ps, 0);
606 }