127557d1b8becee18ab64cc47f49a5b43e8543da
[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 {
35         if (r_u == NULL) return False;
36
37         DEBUG(5,("make_creds_unix\n"));
38
39         fstrcpy(r_u->user_name, user_name);
40
41         return True;
42 }
43
44 /*******************************************************************
45 reads or writes a structure.
46 ********************************************************************/
47 BOOL creds_io_unix(char *desc, CREDS_UNIX *r_u, prs_struct *ps, int depth)
48 {
49         if (r_u == NULL) return False;
50
51         prs_debug(ps, depth, desc, "creds_io_unix");
52         depth++;
53
54         prs_align(ps);
55         prs_string("user_name", ps, depth,   r_u->user_name, strlen(r_u->user_name), sizeof(r_u->user_name));
56         prs_align(ps);
57
58         return True;
59 }
60
61
62 /*******************************************************************
63 frees a structure.
64 ********************************************************************/
65 void creds_free_unix(CREDS_UNIX *r_u)
66 {
67 }
68
69 /*******************************************************************
70 makes a CREDS_UNIX_SEC structure.
71 ********************************************************************/
72 BOOL make_creds_unix_sec(CREDS_UNIX_SEC *r_u,
73                 uint32 uid, uint32 gid, uint32 num_grps, uint32 *grps)
74 {
75         if (r_u == NULL) return False;
76
77         DEBUG(5,("make_creds_unix_sec\n"));
78
79         r_u->uid      = uid;
80         r_u->gid      = gid;
81         r_u->num_grps = num_grps;
82         r_u->grps     = grps;
83
84         return True;
85 }
86
87 /*******************************************************************
88 reads or writes a structure.
89 ********************************************************************/
90 BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int depth)
91 {
92         uint32 i;
93
94         if (r_u == NULL) return False;
95
96         prs_debug(ps, depth, desc, "creds_io_unix_sec");
97         depth++;
98
99         prs_align(ps);
100
101         prs_uint32("uid", ps, depth, &(r_u->uid));
102         prs_uint32("gid", ps, depth, &(r_u->gid));
103         prs_uint32("num_grps", ps, depth, &(r_u->num_grps));
104         if (r_u->num_grps != 0)
105         {
106                 r_u->grps = (uint32*)Realloc(r_u->grps,
107                                        sizeof(r_u->grps[0]) *
108                                        r_u->num_grps);
109                 if (r_u->grps == NULL)
110                 {
111                         creds_free_unix_sec(r_u);
112                         return False;
113                 }
114         }
115         for (i = 0; i < r_u->num_grps; i++)
116         {
117                 prs_grow(ps);
118                 prs_uint32("", ps, depth, &(r_u->grps[i]));
119         }
120         return True;
121 }
122
123
124 /*******************************************************************
125 frees a structure.
126 ********************************************************************/
127 void creds_free_unix_sec(CREDS_UNIX_SEC *r_u)
128 {
129         if (r_u->grps != NULL)
130         {
131                 free(r_u->grps);
132                 r_u->grps = NULL;
133         }
134 }
135
136 /*******************************************************************
137 reads or writes a structure.
138 ********************************************************************/
139 BOOL creds_io_nt_sec(char *desc, CREDS_NT_SEC *r_u, prs_struct *ps, int depth)
140 {
141         if (r_u == NULL) return False;
142
143         prs_debug(ps, depth, desc, "creds_io_nt");
144         depth++;
145
146         prs_align(ps);
147
148         smb_io_dom_sid ("sid", &r_u->sid, ps, depth);
149         prs_align(ps);
150
151         sec_io_desc_buf("sd ", &r_u->sd , ps, depth);
152         prs_align(ps);
153
154         return True;
155 }
156
157 /*******************************************************************
158 frees a structure.
159 ********************************************************************/
160 void creds_free_nt_sec(CREDS_NT_SEC *r_u)
161 {
162 }
163
164 /*******************************************************************
165 reads or writes a structure.
166 ********************************************************************/
167 BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth)
168 {
169         if (pwd == NULL) return False;
170
171         prs_debug(ps, depth, desc, "creds_io_pwd_info");
172         depth++;
173
174         prs_align(ps);
175
176         prs_uint32("nullpwd", ps, depth, &(pwd->null_pwd));
177         if (pwd->null_pwd)
178         {
179                 return True;
180         }
181         
182         prs_uint32("cleartext", ps, depth, &(pwd->cleartext));
183         if (pwd->cleartext)
184         {
185                 prs_string("password", ps, depth,   pwd->password, strlen(pwd->password), sizeof(pwd->password));
186                 prs_align(ps);
187                 return True;
188         }
189         prs_uint32("crypted", ps, depth, &(pwd->crypted));
190                 
191         prs_uint8s(False, "smb_lm_pwd", ps, depth, (char*)&pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
192         prs_align(ps);
193         prs_uint8s(False, "smb_nt_pwd", ps, depth, (char*)&pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
194         prs_align(ps);
195
196         prs_uint8s(False, "smb_lm_owf", ps, depth, (char*)&pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
197         prs_align(ps);
198         prs_uint32("nt_owf_len", ps, depth, &(pwd->nt_owf_len));
199         if (pwd->nt_owf_len > sizeof(pwd->smb_nt_owf))
200         {
201                 return False;
202         }
203         prs_uint8s(False, "smb_nt_owf", ps, depth, (char*)&pwd->smb_nt_owf, pwd->nt_owf_len);
204         prs_align(ps);
205
206         prs_uint8s(False, "lm_cli_chal", ps, depth, (char*)&pwd->lm_cli_chal, sizeof(pwd->lm_cli_chal));
207         prs_align(ps);
208         prs_uint32("nt_cli_chal_len", ps, depth, &(pwd->nt_cli_chal_len));
209
210         if (pwd->nt_cli_chal_len > sizeof(pwd->nt_cli_chal))
211         {
212                 return False;
213         }
214         prs_uint8s(False, "nt_cli_chal", ps, depth, (char*)&pwd->nt_cli_chal, pwd->nt_cli_chal_len);
215         prs_align(ps);
216
217         return True;
218 }
219
220 /*******************************************************************
221 reads or writes a structure.
222 ********************************************************************/
223 BOOL creds_io_nt(char *desc, CREDS_NT *r_u, prs_struct *ps, int depth)
224 {
225         if (r_u == NULL) return False;
226
227         prs_debug(ps, depth, desc, "creds_io_nt");
228         depth++;
229
230         prs_align(ps);
231
232         /* lkclXXXX CHEAT!!!!!!!! */
233         prs_string("user_name", ps, depth,   r_u->user_name, strlen(r_u->user_name), sizeof(r_u->user_name));
234         prs_align(ps);
235         prs_string("domain", ps, depth,   r_u->domain, strlen(r_u->domain), sizeof(r_u->domain));
236         prs_align(ps);
237
238         creds_io_pwd_info("pwd", &r_u->pwd, ps, depth);
239         prs_align(ps);
240
241         prs_uint32("ntlmssp", ps, depth, &(r_u->ntlmssp_flags));
242
243         return True;
244 }
245
246 /*******************************************************************
247 frees a structure.
248 ********************************************************************/
249 void creds_free_nt(CREDS_NT *r_u)
250 {
251 }
252
253 /*******************************************************************
254 reads or writes a structure.
255 ********************************************************************/
256 BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth)
257 {
258         if (r_u == NULL) return False;
259
260         prs_debug(ps, depth, desc, "creds_io_hybrid");
261         depth++;
262
263         prs_align(ps);
264
265         prs_uint32("reuse", ps, depth, &(r_u->reuse));
266         prs_uint32("ptr_ntc", ps, depth, &(r_u->ptr_ntc));
267         prs_uint32("ptr_uxc", ps, depth, &(r_u->ptr_uxc));
268         if (r_u->ptr_ntc != 0)
269         {
270                 if (!creds_io_nt  ("ntc", &r_u->ntc, ps, depth)) return False;
271         }
272         if (r_u->ptr_uxc != 0)
273         {
274                 if (!creds_io_unix("uxc", &r_u->uxc, ps, depth)) return False;
275         }
276         if (r_u->ptr_nts != 0)
277         {
278                 if (!creds_io_nt_sec  ("nts", &r_u->nts, ps, depth)) return False;
279         }
280         if (r_u->ptr_uxs != 0)
281         {
282                 if (!creds_io_unix_sec("uxs", &r_u->uxs, ps, depth)) return False;
283         }
284         return True;
285 }
286
287 void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from)
288 {
289         if (from == NULL)
290         {
291                 to->user_name[0] = 0;
292                 return;
293         }
294         fstrcpy(to->user_name, from->user_name);
295 };
296
297 void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from)
298 {
299         if (from == NULL)
300         {
301                 ZERO_STRUCTP(to);
302                 return;
303         }
304         memcpy(&to, &from, sizeof(*from));
305 };
306
307 void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from)
308 {
309         if (from == NULL)
310         {
311                 to->uid = -1;
312                 to->gid = -1;
313                 to->num_grps = 0;
314                 to->grps = NULL;
315                 return;
316         }
317         to->uid = from->uid;
318         to->gid = from->gid;
319         to->num_grps = 0;
320         to->grps = NULL;
321
322         if (from->num_grps != 0)
323         {
324                 size_t size = to->num_grps * sizeof(to->grps[0]);
325                 to->grps = (uint32*)malloc(size);
326                 if (to->grps == NULL)
327                 {
328                         return;
329                 }
330                 to->num_grps = from->num_grps;
331                 memcpy(to->grps, from->grps, size);
332         }
333 };
334
335 void copy_nt_creds(struct ntuser_creds *to,
336                                 const struct ntuser_creds *from)
337 {
338         if (from == NULL)
339         {
340                 to->domain[0] = 0;
341                 to->user_name[0] = 0;
342                 pwd_set_nullpwd(&to->pwd);
343                 to->ntlmssp_flags = 0;
344
345                 return;
346         }
347         safe_strcpy(to->domain   , from->domain   , sizeof(from->domain   )-1);
348         safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1);
349         memcpy(&to->pwd, &from->pwd, sizeof(from->pwd));
350         to->ntlmssp_flags = from->ntlmssp_flags;
351 };
352
353 void copy_user_creds(struct user_creds *to,
354                                 const struct user_creds *from)
355 {
356         ZERO_STRUCTP(to);
357         if (from == NULL)
358         {
359                 to->ptr_ntc = 0;
360                 to->ptr_uxc = 0;
361                 to->ptr_nts = 0;
362                 to->ptr_uxs = 0;
363                 copy_nt_creds(&to->ntc, NULL);
364                 copy_unix_creds(&to->uxc, NULL);
365                 copy_nt_sec_creds(&to->nts, NULL);
366                 copy_unix_sec_creds(&to->uxs, NULL);
367                 to->reuse = False;
368                 return;
369         }
370         to->ptr_nts = from->ptr_nts;
371         to->ptr_uxs = from->ptr_uxs;
372         to->ptr_ntc = from->ptr_ntc;
373         to->ptr_uxc = from->ptr_uxc;
374         if (to->ptr_ntc != 0)
375         {
376                 copy_nt_creds(&to->ntc, &from->ntc);
377         }
378         if (to->ptr_uxc != 0)
379         {
380                 copy_unix_creds(&to->uxc, &from->uxc);
381         }
382         if (to->ptr_ntc != 0)
383         {
384                 copy_nt_sec_creds(&to->nts, &from->nts);
385         }
386         if (to->ptr_uxc != 0)
387         {
388                 copy_unix_sec_creds(&to->uxs, &from->uxs);
389         }
390         to->reuse = from->reuse;
391 };
392
393 void free_user_creds(struct user_creds *creds)
394 {
395         creds_free_unix(&creds->uxc);
396         creds_free_nt  (&creds->ntc);
397         creds_free_unix_sec(&creds->uxs);
398         creds_free_nt_sec  (&creds->nts);
399 }
400
401 /*******************************************************************
402 reads or writes a structure.
403 ********************************************************************/
404 BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth)
405 {
406         if (r_u == NULL) return False;
407
408         prs_debug(ps, depth, desc, "creds_io_cmd");
409         depth++;
410
411         prs_align(ps);
412
413         prs_uint16("version", ps, depth, &(r_u->version));
414         prs_uint16("command", ps, depth, &(r_u->command));
415
416         prs_string("name   ", ps, depth,   r_u->name, strlen(r_u->name), sizeof(r_u->name));
417         prs_align(ps);
418         
419         prs_uint32("ptr_creds", ps, depth, &(r_u->ptr_creds));
420         if (r_u->ptr_creds != 0)
421         {
422                 if (!creds_io_hybrid("creds", r_u->cred, ps, depth))
423                 {
424                         return False;
425                 }
426         }
427
428
429         return True;
430 }
431
432
433 BOOL create_ntuser_creds( prs_struct *ps,
434                                 const char* name, 
435                                 uint16 version, uint16 command,
436                                 const struct ntuser_creds *ntu,
437                                 BOOL reuse)
438 {
439         CREDS_CMD cmd;
440         struct user_creds usr;
441
442         ZERO_STRUCT(cmd);
443         ZERO_STRUCT(usr);
444
445         DEBUG(10,("create_user_creds: %s %d %d\n",
446                 name, version, command));
447
448         usr.reuse = reuse;
449
450         fstrcpy(cmd.name, name);
451         cmd.version = version;
452         cmd.command = command;
453         cmd.ptr_creds = ntu != NULL ? 1 : 0;
454         cmd.cred = &usr;
455
456         if (ntu != NULL)
457         {
458                 copy_nt_creds(&usr.ntc, ntu);
459                 usr.ptr_ntc = 1;
460         }
461         else
462         {
463                 usr.ptr_ntc = 0;
464         }
465                 
466         prs_init(ps, 1024, 4, 0, False);
467
468         ps->offset = 4;
469         return creds_io_cmd("creds", &cmd, ps, 0);
470 }
471
472 BOOL create_user_creds( prs_struct *ps,
473                                 const char* name, 
474                                 uint16 version, uint16 command,
475                                 const struct user_creds *usr)
476 {
477         CREDS_CMD cmd;
478
479         ZERO_STRUCT(cmd);
480
481         DEBUG(10,("create_user_creds: %s %d %d\n",
482                 name, version, command));
483
484         fstrcpy(cmd.name, name);
485         cmd.version = version;
486         cmd.command = command;
487         cmd.ptr_creds = usr != NULL ? 1 : 0;
488         cmd.cred = usr;
489
490         prs_init(ps, 1024, 4, 0, False);
491
492         ps->offset = 4;
493         return creds_io_cmd("creds", &cmd, ps, 0);
494 }