Ok - this is a *BIG* change - but it fixes the problems with static strings
[ira/wip.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 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, &(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 create_ntc_from_cli_state (CREDS_NT *to, const struct cli_state *cli_from)
429 {
430         /* 
431          * NULL credentials -- 
432          * if this gets executed, it is a programming error.
433          * fall through to copy_nt_creds() 
434          */
435         if (cli_from == NULL)
436         {
437                 copy_nt_creds (to, NULL);
438                 return;
439         }
440
441         safe_strcpy(to->domain   , cli_from->domain   , sizeof(cli_from->domain   )-1);
442         safe_strcpy(to->user_name, cli_from->user_name, sizeof(cli_from->user_name)-1);
443         memcpy(&to->pwd, &cli_from->pwd, sizeof(cli_from->pwd));
444         to->ntlmssp_flags = cli_from->ntlmssp_flags;
445         DEBUG(10,("create_ntc_fromcli_state: user %s domain %s flgs: %x\n",
446                to->user_name, to->domain,
447                to->ntlmssp_flags));
448
449 };
450
451
452 void copy_nt_creds(struct ntuser_creds *to,
453                                 const struct ntuser_creds *from)
454 {
455         if (from == NULL)
456         {
457                 DEBUG(10,("copy_nt_creds: null creds\n"));
458                 to->domain[0] = 0;
459                 to->user_name[0] = 0;
460                 pwd_set_nullpwd(&to->pwd);
461                 to->ntlmssp_flags = 0;
462
463                 return;
464         }
465         safe_strcpy(to->domain   , from->domain   , sizeof(from->domain   )-1);
466         safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1);
467         memcpy(&to->pwd, &from->pwd, sizeof(from->pwd));
468         to->ntlmssp_flags = from->ntlmssp_flags;
469         DEBUG(10,("copy_nt_creds: user %s domain %s flgs: %x\n",
470                to->user_name, to->domain, 
471                to->ntlmssp_flags));
472 };
473
474 void copy_user_creds(struct user_creds *to,
475                                 const struct user_creds *from)
476 {
477         ZERO_STRUCTP(to);
478         if (from == NULL)
479         {
480                 to->ptr_ntc = 0;
481                 to->ptr_uxc = 0;
482                 to->ptr_nts = 0;
483                 to->ptr_uxs = 0;
484                 to->ptr_ssk = 0;
485                 copy_nt_creds(&to->ntc, NULL);
486                 copy_unix_creds(&to->uxc, NULL);
487                 copy_nt_sec_creds(&to->nts, NULL);
488                 copy_unix_sec_creds(&to->uxs, NULL);
489                 to->reuse = False;
490                 return;
491         }
492
493         to->reuse = from->reuse;
494
495         to->ptr_nts = from->ptr_nts;
496         to->ptr_uxs = from->ptr_uxs;
497         to->ptr_ntc = from->ptr_ntc;
498         to->ptr_uxc = from->ptr_uxc;
499         to->ptr_ssk = from->ptr_ssk;
500
501         if (to->ptr_ntc != 0)
502         {
503                 copy_nt_creds(&to->ntc, &from->ntc);
504         }
505         if (to->ptr_uxc != 0)
506         {
507                 copy_unix_creds(&to->uxc, &from->uxc);
508         }
509         if (to->ptr_nts != 0)
510         {
511                 copy_nt_sec_creds(&to->nts, &from->nts);
512         }
513         if (to->ptr_uxs != 0)
514         {
515                 copy_unix_sec_creds(&to->uxs, &from->uxs);
516         }
517         if (to->ptr_ssk != 0)
518         {
519                 memcpy(to->usr_sess_key, from->usr_sess_key,
520                         sizeof(to->usr_sess_key));
521         }
522 };
523
524 void free_user_creds(struct user_creds *creds)
525 {
526         creds_free_unix(&creds->uxc);
527         creds_free_nt  (&creds->ntc);
528         creds_free_unix_sec(&creds->uxs);
529         creds_free_nt_sec  (&creds->nts);
530 }
531
532 /*******************************************************************
533 reads or writes a structure.
534 ********************************************************************/
535 BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth)
536 {
537         if (r_u == NULL) return False;
538
539         prs_debug(ps, depth, desc, "creds_io_cmd");
540         depth++;
541
542         prs_align(ps);
543
544         prs_uint16("version", ps, depth, &(r_u->version));
545         prs_uint16("command", ps, depth, &(r_u->command));
546         prs_uint32("pid    ", ps, depth, &(r_u->pid    ));
547
548         prs_string("name   ", ps, depth,   r_u->name, strlen(r_u->name), sizeof(r_u->name));
549         prs_align(ps);
550         
551         prs_uint32("ptr_creds", ps, depth, &(r_u->ptr_creds));
552         if (r_u->ptr_creds != 0)
553         {
554                 if (!creds_io_hybrid("creds", r_u->cred, ps, depth))
555                 {
556                         return False;
557                 }
558         }
559
560
561         return True;
562 }
563
564
565 BOOL create_ntuser_creds( prs_struct *ps,
566                                 const char* name, 
567                                 uint16 version, uint16 command,
568                                 uint32 pid,
569                                 const struct ntuser_creds *ntu,
570                                 BOOL reuse)
571 {
572         CREDS_CMD cmd;
573         struct user_creds usr;
574
575         ZERO_STRUCT(cmd);
576         ZERO_STRUCT(usr);
577
578         DEBUG(10,("create_user_creds: %s %d %d\n",
579                 name, version, command));
580
581         usr.reuse = reuse;
582
583         fstrcpy(cmd.name, name);
584         cmd.version = version;
585         cmd.command = command;
586         cmd.pid   = pid  ;
587         cmd.ptr_creds = ntu != NULL ? 1 : 0;
588         cmd.cred = &usr;
589
590         if (ntu != NULL)
591         {
592                 copy_nt_creds(&usr.ntc, ntu);
593                 usr.ptr_ntc = 1;
594         }
595         else
596         {
597                 usr.ptr_ntc = 0;
598         }
599                 
600         prs_init(ps, 1024, 4, NULL, False);
601
602         ps->data_offset = 4;
603         return creds_io_cmd("creds", &cmd, ps, 0);
604 }
605
606 BOOL create_user_creds( prs_struct *ps,
607                                 const char* name, 
608                                 uint16 version, uint16 command,
609                                 uint32 pid,
610                                 struct user_creds *usr)
611 {
612         CREDS_CMD cmd;
613
614         ZERO_STRUCT(cmd);
615
616         DEBUG(10,("create_user_creds: %s %d %d\n",
617                 name, version, command));
618
619         fstrcpy(cmd.name, name);
620         cmd.version = version;
621         cmd.command = command;
622         cmd.pid     = pid  ;
623         cmd.ptr_creds = usr != NULL ? 1 : 0;
624         cmd.cred = usr;
625
626         prs_init(ps, 1024, 4, NULL, False);
627
628         ps->data_offset = 4;
629         return creds_io_cmd("creds", &cmd, ps, 0);
630 }