1ad9143009fc5d89821aca5c3b58e0d399a71a3a
[samba.git] / source3 / 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 Tridgell              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, (uint32 *)&(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*)malloc(sizeof(r_u->grps[0]) * r_u->num_grps);
94         if (r_u->grps == NULL && num_grps != 0)
95         {
96                 return False;
97         }
98         for (i = 0; i < num_grps; i++)
99         {
100                 r_u->grps[i] = (gid_t)grps[i];
101         }
102
103         return True;
104 }
105
106 /*******************************************************************
107 reads or writes a structure.
108 ********************************************************************/
109 BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int depth)
110 {
111         uint32 i;
112
113         if (r_u == NULL) return False;
114
115         prs_debug(ps, depth, desc, "creds_io_unix_sec");
116         depth++;
117
118         prs_align(ps);
119
120         prs_uint32("uid", ps, depth, &(r_u->uid));
121         prs_uint32("gid", ps, depth, &(r_u->gid));
122         prs_uint32("num_grps", ps, depth, (uint32 *)&(r_u->num_grps));
123         if (r_u->num_grps != 0)
124         {
125                 uint32 *tgr;
126                 
127                 tgr = (uint32*)Realloc(r_u->grps,
128                                        sizeof(r_u->grps[0]) *
129                                        r_u->num_grps);
130                 if (tgr == NULL)
131                 {
132                         creds_free_unix_sec(r_u);
133                         return False;
134                 }
135                 else r_u->grps = tgr;
136         }
137         for (i = 0; i < r_u->num_grps; i++)
138         {
139                 prs_uint32("", ps, depth, &(r_u->grps[i]));
140         }
141         return True;
142 }
143
144
145 /*******************************************************************
146 frees a structure.
147 ********************************************************************/
148 void creds_free_unix_sec(CREDS_UNIX_SEC *r_u)
149 {
150         SAFE_FREE(r_u->grps);
151 }
152
153 /*******************************************************************
154 makes a CREDS_NT_SEC structure.
155 ********************************************************************/
156 BOOL make_creds_nt_sec(CREDS_NT_SEC *r_u,
157                 DOM_SID *sid, uint32 num_grps, uint32 *grps)
158 {
159         int i;
160         if (r_u == NULL) return False;
161
162         DEBUG(5,("make_creds_unix_sec\n"));
163
164         sid_copy(&r_u->sid, sid);
165         r_u->num_grps = num_grps;
166         r_u->grp_rids = (uint32*)malloc(sizeof(r_u->grp_rids[0]) * r_u->num_grps);
167
168         if (r_u->grp_rids == NULL && num_grps != 0)
169         {
170                 return False;
171         }
172         for (i = 0; i < num_grps; i++)
173         {
174                 r_u->grp_rids[i] = grps[i];
175         }
176
177         return True;
178 }
179
180 /*******************************************************************
181 reads or writes a structure.
182 ********************************************************************/
183 BOOL creds_io_nt_sec(char *desc, CREDS_NT_SEC *r_u, prs_struct *ps, int depth)
184 {
185         int i;
186         if (r_u == NULL) return False;
187
188         prs_debug(ps, depth, desc, "creds_io_nt");
189         depth++;
190
191         prs_align(ps);
192
193         smb_io_dom_sid ("sid", &r_u->sid, ps, depth);
194         prs_align(ps);
195
196         prs_uint32("num_grps", ps, depth, &(r_u->num_grps));
197         if (r_u->num_grps != 0)
198         {
199                 uint32 *tgrid;
200                 
201                 tgrid = (uint32*)Realloc(r_u->grp_rids,
202                                        sizeof(r_u->grp_rids[0]) *
203                                        r_u->num_grps);
204                 if (tgrid == NULL)
205                 {
206                         creds_free_nt_sec(r_u);
207                         return False;
208                 }
209                 else r_u->grp_rids = tgrid;
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         SAFE_FREE(r_u->grp_rids);
225 }
226
227 /*******************************************************************
228 reads or writes a structure.
229 ********************************************************************/
230 BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth)
231 {
232         if (pwd == NULL) return False;
233
234         prs_debug(ps, depth, desc, "creds_io_pwd_info");
235         depth++;
236
237         prs_align(ps);
238
239         prs_uint32("nullpwd", ps, depth, (uint32 *)&(pwd->null_pwd));
240         if (pwd->null_pwd)
241         {
242                 return True;
243         }
244         
245         prs_uint32("cleartext", ps, depth, (uint32 *)&(pwd->cleartext));
246         if (pwd->cleartext)
247         {
248                 prs_string("password", ps, depth,   pwd->password, strlen(pwd->password), sizeof(pwd->password));
249                 prs_align(ps);
250                 return True;
251         }
252         prs_uint32("crypted", ps, depth, (uint32 *)&(pwd->crypted));
253                 
254         prs_uint8s(False, "smb_lm_pwd", ps, depth, (unsigned char*)&pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
255         prs_align(ps);
256         prs_uint8s(False, "smb_nt_pwd", ps, depth, (unsigned char*)&pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
257         prs_align(ps);
258
259         prs_uint8s(False, "smb_lm_owf", ps, depth, (unsigned char*)&pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
260         prs_align(ps);
261         prs_uint32("nt_owf_len", ps, depth, &(pwd->nt_owf_len));
262         if (pwd->nt_owf_len > sizeof(pwd->smb_nt_owf))
263         {
264                 return False;
265         }
266         prs_uint8s(False, "smb_nt_owf", ps, depth, (unsigned char*)&pwd->smb_nt_owf, pwd->nt_owf_len);
267         prs_align(ps);
268
269         prs_uint8s(False, "lm_cli_chal", ps, depth, (unsigned char*)&pwd->lm_cli_chal, sizeof(pwd->lm_cli_chal));
270         prs_align(ps);
271         prs_uint32("nt_cli_chal_len", ps, depth, &(pwd->nt_cli_chal_len));
272
273         if (pwd->nt_cli_chal_len > sizeof(pwd->nt_cli_chal))
274         {
275                 return False;
276         }
277         prs_uint8s(False, "nt_cli_chal", ps, depth, (unsigned char*)&pwd->nt_cli_chal, pwd->nt_cli_chal_len);
278         prs_align(ps);
279
280         return True;
281 }
282
283 /*******************************************************************
284 reads or writes a structure.
285 ********************************************************************/
286 BOOL creds_io_nt(char *desc, CREDS_NT *r_u, prs_struct *ps, int depth)
287 {
288         if (r_u == NULL) return False;
289
290         prs_debug(ps, depth, desc, "creds_io_nt");
291         depth++;
292
293         prs_align(ps);
294
295         /* lkclXXXX CHEAT!!!!!!!! */
296         prs_string("user_name", ps, depth,   r_u->user_name, strlen(r_u->user_name), sizeof(r_u->user_name));
297         prs_align(ps);
298         prs_string("domain", ps, depth,   r_u->domain, strlen(r_u->domain), sizeof(r_u->domain));
299         prs_align(ps);
300
301         creds_io_pwd_info("pwd", &r_u->pwd, ps, depth);
302         prs_align(ps);
303
304         prs_uint32("ntlmssp", ps, depth, &(r_u->ntlmssp_flags));
305
306         return True;
307 }
308
309 /*******************************************************************
310 frees a structure.
311 ********************************************************************/
312 void creds_free_nt(CREDS_NT *r_u)
313 {
314 }
315
316 /*******************************************************************
317 reads or writes a structure.
318 ********************************************************************/
319 BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth)
320 {
321         if (r_u == NULL) return False;
322
323         prs_debug(ps, depth, desc, "creds_io_hybrid");
324         depth++;
325
326         prs_align(ps);
327
328         prs_uint32("reuse", ps, depth, (uint32 *)&(r_u->reuse));
329
330         prs_uint32("ptr_ntc", ps, depth, &(r_u->ptr_ntc));
331         prs_uint32("ptr_uxc", ps, depth, &(r_u->ptr_uxc));
332         prs_uint32("ptr_nts", ps, depth, &(r_u->ptr_nts));
333         prs_uint32("ptr_uxs", ps, depth, &(r_u->ptr_uxs));
334         prs_uint32("ptr_ssk", ps, depth, &(r_u->ptr_ssk));
335         if (r_u->ptr_ntc != 0)
336         {
337                 if (!creds_io_nt  ("ntc", &r_u->ntc, ps, depth)) return False;
338         }
339         if (r_u->ptr_uxc != 0)
340         {
341                 if (!creds_io_unix("uxc", &r_u->uxc, ps, depth)) return False;
342         }
343         if (r_u->ptr_nts != 0)
344         {
345                 if (!creds_io_nt_sec  ("nts", &r_u->nts, ps, depth)) return False;
346         }
347         if (r_u->ptr_uxs != 0)
348         {
349                 if (!creds_io_unix_sec("uxs", &r_u->uxs, ps, depth)) return False;
350         }
351         if (r_u->ptr_ssk != 0)
352         {
353                 prs_uint8s(False, "usr_sess_key", ps, depth, (unsigned char*)&r_u->usr_sess_key, sizeof(r_u->usr_sess_key));
354         }
355         else
356         {
357                 memset(r_u->usr_sess_key, 0, sizeof(r_u->usr_sess_key));
358         }
359         return True;
360 }
361
362 void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from)
363 {
364         if (from == NULL)
365         {
366                 to->user_name[0] = 0;
367                 return;
368         }
369         fstrcpy(to->user_name, from->user_name);
370 }
371
372 void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from)
373 {
374         if (from == NULL)
375         {
376                 ZERO_STRUCTP(to);
377                 return;
378         }
379         sid_copy(&to->sid, &from->sid);
380         to->num_grps = 0;
381         to->grp_rids = NULL;
382
383         if (from->num_grps != 0)
384         {
385                 size_t size = from->num_grps * sizeof(from->grp_rids[0]);
386                 to->grp_rids = (uint32*)malloc(size);
387                 if (to->grp_rids == NULL)
388                 {
389                         return;
390                 }
391                 to->num_grps = from->num_grps;
392                 memcpy(to->grp_rids, from->grp_rids, size);
393         }
394 }
395
396 void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from)
397 {
398         if (from == NULL)
399         {
400                 to->uid = -1;
401                 to->gid = -1;
402                 to->num_grps = 0;
403                 to->grps = NULL;
404                 return;
405         }
406         to->uid = from->uid;
407         to->gid = from->gid;
408         to->num_grps = 0;
409         to->grps = NULL;
410
411         if (from->num_grps != 0)
412         {
413                 size_t size = from->num_grps * sizeof(from->grps[0]);
414                 to->grps = (uint32*)malloc(size);
415                 if (to->grps == NULL)
416                 {
417                         return;
418                 }
419                 to->num_grps = from->num_grps;
420                 memcpy(to->grps, from->grps, size);
421         }
422 }
423
424 void create_ntc_from_cli_state (CREDS_NT *to, const struct cli_state *cli_from)
425 {
426         /* 
427          * NULL credentials -- 
428          * if this gets executed, it is a programming error.
429          * fall through to copy_nt_creds() 
430          */
431         if (cli_from == NULL)
432         {
433                 copy_nt_creds (to, NULL);
434                 return;
435         }
436
437         safe_strcpy(to->domain   , cli_from->domain   , sizeof(cli_from->domain   )-1);
438         safe_strcpy(to->user_name, cli_from->user_name, sizeof(cli_from->user_name)-1);
439         memcpy(&to->pwd, &cli_from->pwd, sizeof(cli_from->pwd));
440         to->ntlmssp_flags = cli_from->ntlmssp_flags;
441         DEBUG(10,("create_ntc_fromcli_state: user %s domain %s flgs: %x\n",
442                to->user_name, to->domain,
443                to->ntlmssp_flags));
444
445 }
446
447
448 void copy_nt_creds(struct ntuser_creds *to,
449                                 const struct ntuser_creds *from)
450 {
451         if (from == NULL)
452         {
453                 DEBUG(10,("copy_nt_creds: null creds\n"));
454                 to->domain[0] = 0;
455                 to->user_name[0] = 0;
456                 pwd_set_nullpwd(&to->pwd);
457                 to->ntlmssp_flags = 0;
458
459                 return;
460         }
461         safe_strcpy(to->domain   , from->domain   , sizeof(from->domain   )-1);
462         safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1);
463         memcpy(&to->pwd, &from->pwd, sizeof(from->pwd));
464         to->ntlmssp_flags = from->ntlmssp_flags;
465         DEBUG(10,("copy_nt_creds: user %s domain %s flgs: %x\n",
466                to->user_name, to->domain, 
467                to->ntlmssp_flags));
468 }
469
470 void copy_user_creds(struct user_creds *to,
471                                 const struct user_creds *from)
472 {
473         ZERO_STRUCTP(to);
474         if (from == NULL)
475         {
476                 to->ptr_ntc = 0;
477                 to->ptr_uxc = 0;
478                 to->ptr_nts = 0;
479                 to->ptr_uxs = 0;
480                 to->ptr_ssk = 0;
481                 copy_nt_creds(&to->ntc, NULL);
482                 copy_unix_creds(&to->uxc, NULL);
483                 copy_nt_sec_creds(&to->nts, NULL);
484                 copy_unix_sec_creds(&to->uxs, NULL);
485                 to->reuse = False;
486                 return;
487         }
488
489         to->reuse = from->reuse;
490
491         to->ptr_nts = from->ptr_nts;
492         to->ptr_uxs = from->ptr_uxs;
493         to->ptr_ntc = from->ptr_ntc;
494         to->ptr_uxc = from->ptr_uxc;
495         to->ptr_ssk = from->ptr_ssk;
496
497         if (to->ptr_ntc != 0)
498         {
499                 copy_nt_creds(&to->ntc, &from->ntc);
500         }
501         if (to->ptr_uxc != 0)
502         {
503                 copy_unix_creds(&to->uxc, &from->uxc);
504         }
505         if (to->ptr_nts != 0)
506         {
507                 copy_nt_sec_creds(&to->nts, &from->nts);
508         }
509         if (to->ptr_uxs != 0)
510         {
511                 copy_unix_sec_creds(&to->uxs, &from->uxs);
512         }
513         if (to->ptr_ssk != 0)
514         {
515                 memcpy(to->usr_sess_key, from->usr_sess_key,
516                         sizeof(to->usr_sess_key));
517         }
518 }
519
520 void free_user_creds(struct user_creds *creds)
521 {
522         creds_free_unix(&creds->uxc);
523         creds_free_nt  (&creds->ntc);
524         creds_free_unix_sec(&creds->uxs);
525         creds_free_nt_sec  (&creds->nts);
526 }
527
528 /*******************************************************************
529 reads or writes a structure.
530 ********************************************************************/
531 BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth)
532 {
533         if (r_u == NULL) return False;
534
535         prs_debug(ps, depth, desc, "creds_io_cmd");
536         depth++;
537
538         prs_align(ps);
539
540         prs_uint16("version", ps, depth, &(r_u->version));
541         prs_uint16("command", ps, depth, &(r_u->command));
542         prs_uint32("pid    ", ps, depth, &(r_u->pid    ));
543
544         prs_string("name   ", ps, depth,   r_u->name, strlen(r_u->name), sizeof(r_u->name));
545         prs_align(ps);
546         
547         prs_uint32("ptr_creds", ps, depth, &(r_u->ptr_creds));
548         if (r_u->ptr_creds != 0)
549         {
550                 if (!creds_io_hybrid("creds", r_u->cred, ps, depth))
551                 {
552                         return False;
553                 }
554         }
555
556
557         return True;
558 }
559
560
561 BOOL create_ntuser_creds( prs_struct *ps,
562                                 const char* name, 
563                                 uint16 version, uint16 command,
564                                 uint32 pid,
565                                 const struct ntuser_creds *ntu,
566                                 BOOL reuse)
567 {
568         CREDS_CMD cmd;
569         struct user_creds usr;
570
571         ZERO_STRUCT(cmd);
572         ZERO_STRUCT(usr);
573
574         DEBUG(10,("create_user_creds: %s %d %d\n",
575                 name, version, command));
576
577         usr.reuse = reuse;
578
579         fstrcpy(cmd.name, name);
580         cmd.version = version;
581         cmd.command = command;
582         cmd.pid   = pid  ;
583         cmd.ptr_creds = ntu != NULL ? 1 : 0;
584         cmd.cred = &usr;
585
586         if (ntu != NULL)
587         {
588                 copy_nt_creds(&usr.ntc, ntu);
589                 usr.ptr_ntc = 1;
590         }
591         else
592         {
593                 usr.ptr_ntc = 0;
594         }
595                 
596         prs_init(ps, 1024, NULL, MARSHALL);
597
598         ps->data_offset = 4;
599         return creds_io_cmd("creds", &cmd, ps, 0);
600 }
601
602 BOOL create_user_creds( prs_struct *ps,
603                                 const char* name, 
604                                 uint16 version, uint16 command,
605                                 uint32 pid,
606                                 struct user_creds *usr)
607 {
608         CREDS_CMD cmd;
609
610         ZERO_STRUCT(cmd);
611
612         DEBUG(10,("create_user_creds: %s %d %d\n",
613                 name, version, command));
614
615         fstrcpy(cmd.name, name);
616         cmd.version = version;
617         cmd.command = command;
618         cmd.pid     = pid  ;
619         cmd.ptr_creds = usr != NULL ? 1 : 0;
620         cmd.cred = usr;
621
622         prs_init(ps, 1024, NULL, MARSHALL);
623
624         ps->data_offset = 4;
625         return creds_io_cmd("creds", &cmd, ps, 0);
626 }