simple mods to add msrpc pipe redirection. default behaviour: fall back
[kai/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 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         prs_uint32("ptr_ntc", ps, depth, &(r_u->ptr_ntc));
334         prs_uint32("ptr_uxc", ps, depth, &(r_u->ptr_uxc));
335         prs_uint32("ptr_nts", ps, depth, &(r_u->ptr_nts));
336         prs_uint32("ptr_uxs", ps, depth, &(r_u->ptr_uxs));
337         if (r_u->ptr_ntc != 0)
338         {
339                 if (!creds_io_nt  ("ntc", &r_u->ntc, ps, depth)) return False;
340         }
341         if (r_u->ptr_uxc != 0)
342         {
343                 if (!creds_io_unix("uxc", &r_u->uxc, ps, depth)) return False;
344         }
345         if (r_u->ptr_nts != 0)
346         {
347                 if (!creds_io_nt_sec  ("nts", &r_u->nts, ps, depth)) return False;
348         }
349         if (r_u->ptr_uxs != 0)
350         {
351                 if (!creds_io_unix_sec("uxs", &r_u->uxs, ps, depth)) return False;
352         }
353         return True;
354 }
355
356 void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from)
357 {
358         if (from == NULL)
359         {
360                 to->user_name[0] = 0;
361                 return;
362         }
363         fstrcpy(to->user_name, from->user_name);
364 };
365
366 void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from)
367 {
368         if (from == NULL)
369         {
370                 ZERO_STRUCTP(to);
371                 return;
372         }
373         sid_copy(&to->sid, &from->sid);
374         to->num_grps = 0;
375         to->grp_rids = NULL;
376
377         if (from->num_grps != 0)
378         {
379                 size_t size = from->num_grps * sizeof(from->grp_rids[0]);
380                 to->grp_rids = (uint32*)malloc(size);
381                 if (to->grp_rids == NULL)
382                 {
383                         return;
384                 }
385                 to->num_grps = from->num_grps;
386                 memcpy(to->grp_rids, from->grp_rids, size);
387         }
388 };
389
390 void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from)
391 {
392         if (from == NULL)
393         {
394                 to->uid = -1;
395                 to->gid = -1;
396                 to->num_grps = 0;
397                 to->grps = NULL;
398                 return;
399         }
400         to->uid = from->uid;
401         to->gid = from->gid;
402         to->num_grps = 0;
403         to->grps = NULL;
404
405         if (from->num_grps != 0)
406         {
407                 size_t size = from->num_grps * sizeof(from->grps[0]);
408                 to->grps = (uint32*)malloc(size);
409                 if (to->grps == NULL)
410                 {
411                         return;
412                 }
413                 to->num_grps = from->num_grps;
414                 memcpy(to->grps, from->grps, size);
415         }
416 };
417
418 void copy_nt_creds(struct ntuser_creds *to,
419                                 const struct ntuser_creds *from)
420 {
421         if (from == NULL)
422         {
423                 DEBUG(10,("copy_nt_creds: null creds\n"));
424                 to->domain[0] = 0;
425                 to->user_name[0] = 0;
426                 pwd_set_nullpwd(&to->pwd);
427                 to->ntlmssp_flags = 0;
428
429                 return;
430         }
431         safe_strcpy(to->domain   , from->domain   , sizeof(from->domain   )-1);
432         safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1);
433         memcpy(&to->pwd, &from->pwd, sizeof(from->pwd));
434         to->ntlmssp_flags = from->ntlmssp_flags;
435 };
436
437 void copy_user_creds(struct user_creds *to,
438                                 const struct user_creds *from)
439 {
440         ZERO_STRUCTP(to);
441         if (from == NULL)
442         {
443                 to->ptr_ntc = 0;
444                 to->ptr_uxc = 0;
445                 to->ptr_nts = 0;
446                 to->ptr_uxs = 0;
447                 copy_nt_creds(&to->ntc, NULL);
448                 copy_unix_creds(&to->uxc, NULL);
449                 copy_nt_sec_creds(&to->nts, NULL);
450                 copy_unix_sec_creds(&to->uxs, NULL);
451                 to->reuse = False;
452                 return;
453         }
454         to->ptr_nts = from->ptr_nts;
455         to->ptr_uxs = from->ptr_uxs;
456         to->ptr_ntc = from->ptr_ntc;
457         to->ptr_uxc = from->ptr_uxc;
458         if (to->ptr_ntc != 0)
459         {
460                 copy_nt_creds(&to->ntc, &from->ntc);
461         }
462         if (to->ptr_uxc != 0)
463         {
464                 copy_unix_creds(&to->uxc, &from->uxc);
465         }
466         if (to->ptr_nts != 0)
467         {
468                 copy_nt_sec_creds(&to->nts, &from->nts);
469         }
470         if (to->ptr_uxs != 0)
471         {
472                 copy_unix_sec_creds(&to->uxs, &from->uxs);
473         }
474         to->reuse = from->reuse;
475 };
476
477 void free_user_creds(struct user_creds *creds)
478 {
479         creds_free_unix(&creds->uxc);
480         creds_free_nt  (&creds->ntc);
481         creds_free_unix_sec(&creds->uxs);
482         creds_free_nt_sec  (&creds->nts);
483 }
484
485 /*******************************************************************
486 reads or writes a structure.
487 ********************************************************************/
488 BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth)
489 {
490         if (r_u == NULL) return False;
491
492         prs_debug(ps, depth, desc, "creds_io_cmd");
493         depth++;
494
495         prs_align(ps);
496
497         prs_uint16("version", ps, depth, &(r_u->version));
498         prs_uint16("command", ps, depth, &(r_u->command));
499
500         prs_string("name   ", ps, depth,   r_u->name, strlen(r_u->name), sizeof(r_u->name));
501         prs_align(ps);
502         
503         prs_uint32("ptr_creds", ps, depth, &(r_u->ptr_creds));
504         if (r_u->ptr_creds != 0)
505         {
506                 if (!creds_io_hybrid("creds", r_u->cred, ps, depth))
507                 {
508                         return False;
509                 }
510         }
511
512
513         return True;
514 }
515
516
517 BOOL create_ntuser_creds( prs_struct *ps,
518                                 const char* name, 
519                                 uint16 version, uint16 command,
520                                 const struct ntuser_creds *ntu,
521                                 BOOL reuse)
522 {
523         CREDS_CMD cmd;
524         struct user_creds usr;
525
526         ZERO_STRUCT(cmd);
527         ZERO_STRUCT(usr);
528
529         DEBUG(10,("create_user_creds: %s %d %d\n",
530                 name, version, command));
531
532         usr.reuse = reuse;
533
534         fstrcpy(cmd.name, name);
535         cmd.version = version;
536         cmd.command = command;
537         cmd.ptr_creds = ntu != NULL ? 1 : 0;
538         cmd.cred = &usr;
539
540         if (ntu != NULL)
541         {
542                 copy_nt_creds(&usr.ntc, ntu);
543                 usr.ptr_ntc = 1;
544         }
545         else
546         {
547                 usr.ptr_ntc = 0;
548         }
549                 
550         prs_init(ps, 1024, 4, False);
551
552         ps->data_offset = 4;
553         return creds_io_cmd("creds", &cmd, ps, 0);
554 }
555
556 BOOL create_user_creds( prs_struct *ps,
557                                 const char* name, 
558                                 uint16 version, uint16 command,
559                                 const struct user_creds *usr)
560 {
561         CREDS_CMD cmd;
562
563         ZERO_STRUCT(cmd);
564
565         DEBUG(10,("create_user_creds: %s %d %d\n",
566                 name, version, command));
567
568         fstrcpy(cmd.name, name);
569         cmd.version = version;
570         cmd.command = command;
571         cmd.ptr_creds = usr != NULL ? 1 : 0;
572         cmd.cred = usr;
573
574         prs_init(ps, 1024, 4, False);
575
576         ps->data_offset = 4;
577         return creds_io_cmd("creds", &cmd, ps, 0);
578 }