This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to...
[ira/wip.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison               2001-2002,
9  *  Copyright (C) Jean François Micouleau      1998-2001,
10  *  Copyright (C) Anthony Liguori                   2002,
11  *  Copyright (C) Jim McDonough                     2002.
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this program; if not, write to the Free Software
25  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26  */
27
28 /*
29  * This is the implementation of the SAMR code.
30  */
31
32 #include "includes.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
36
37 extern DOM_SID global_sid_Builtin;
38
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
42
43
44 typedef struct _disp_info {
45         BOOL user_dbloaded;
46         uint32 num_user_account;
47         DISP_USER_INFO *disp_user_info;
48         BOOL group_dbloaded;
49         uint32 num_group_account;
50         DISP_GROUP_INFO *disp_group_info;
51 } DISP_INFO;
52
53 struct samr_info {
54         /* for use by the \PIPE\samr policy */
55         DOM_SID sid;
56         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
57         uint32 acc_granted;
58         uint16 acb_mask;
59         BOOL all_machines;
60         DISP_INFO disp_info;
61
62         TALLOC_CTX *mem_ctx;
63 };
64
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
70
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
72
73 /*******************************************************************
74  Checks if access to an object should be granted, and returns that
75  level of access for further checks.
76 ********************************************************************/
77
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access, 
79                                   uint32 *acc_granted, const char *debug) 
80 {
81         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
82
83         if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84                 if (geteuid() == sec_initial_uid()) {
85                         DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n",
86                                 debug, des_access));
87                         DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
88                         status = NT_STATUS_OK;
89                 }
90                 else {
91                         DEBUG(2,("%s: ACCESS DENIED  (requested: %#010x)\n",
92                                 debug, des_access));
93                 }
94         }
95         return status;
96 }
97
98 /*******************************************************************
99  Checks if access to a function can be granted
100 ********************************************************************/
101
102 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
103 {
104         DEBUG(5,("%s: access check ((granted: %#010x;  required: %#010x)\n",
105                         debug, acc_granted, acc_required));
106         if ((acc_granted & acc_required) != acc_required) {
107                 if (geteuid() == sec_initial_uid()) {
108                         DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
109                                 debug, acc_granted, acc_required));
110                         DEBUGADD(4,("but overwritten by euid == 0\n"));
111                         return NT_STATUS_OK;
112                 }
113                 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n",
114                         debug, acc_granted, acc_required));
115                 return NT_STATUS_ACCESS_DENIED;
116         }
117         return NT_STATUS_OK;
118 }
119
120
121 /*******************************************************************
122  Create a samr_info struct.
123 ********************************************************************/
124
125 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
126 {
127         struct samr_info *info;
128         fstring sid_str;
129         TALLOC_CTX *mem_ctx;
130         
131         if (psid) {
132                 sid_to_string(sid_str, psid);
133         } else {
134                 fstrcpy(sid_str,"(NULL)");
135         }
136
137         mem_ctx = talloc_init_named("samr_info for domain sid %s", sid_str);
138
139         if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
140                 return NULL;
141
142         ZERO_STRUCTP(info);
143         DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
144         if (psid) {
145                 sid_copy( &info->sid, psid);
146         } else {
147                 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
148         }
149         info->mem_ctx = mem_ctx;
150         return info;
151 }
152
153
154 /*******************************************************************
155  Function to free the per handle data.
156  ********************************************************************/
157 static void free_samr_users(struct samr_info *info) 
158 {
159         int i;
160
161         if (info->disp_info.user_dbloaded){
162                 for (i=0; i<info->disp_info.num_user_account; i++) {
163                         /* Not really a free, actually a 'clear' */
164                         pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
165                 }
166         }
167         info->disp_info.user_dbloaded=False;
168         info->disp_info.num_user_account=0;
169 }
170
171
172 /*******************************************************************
173  Function to free the per handle data.
174  ********************************************************************/
175 static void free_samr_db(struct samr_info *info)
176 {
177         /* Groups are talloced */
178
179         free_samr_users(info);
180
181         info->disp_info.group_dbloaded=False;
182         info->disp_info.num_group_account=0;
183 }
184
185
186 static void free_samr_info(void *ptr)
187 {
188         struct samr_info *info=(struct samr_info *) ptr;
189
190         free_samr_db(info);
191         talloc_destroy(info->mem_ctx);
192 }
193
194 /*******************************************************************
195  Ensure password info is never given out. Paranioa... JRA.
196  ********************************************************************/
197
198 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
199 {
200         
201         if (!sam_pass)
202                 return;
203
204         /* These now zero out the old password */
205
206         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
207         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
208 }
209
210
211 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
212 {
213         SAM_ACCOUNT *pwd = NULL;
214         DISP_USER_INFO *pwd_array = NULL;
215         NTSTATUS nt_status = NT_STATUS_OK;
216         TALLOC_CTX *mem_ctx = info->mem_ctx;
217
218         DEBUG(10,("load_sampwd_entries\n"));
219
220         /* if the snapshoot is already loaded, return */
221         if ((info->disp_info.user_dbloaded==True) 
222             && (info->acb_mask == acb_mask) 
223             && (info->all_machines == all_machines)) {
224                 DEBUG(10,("load_sampwd_entries: already in memory\n"));
225                 return NT_STATUS_OK;
226         }
227
228         free_samr_users(info);
229
230         if (!pdb_setsampwent(False)) {
231                 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
232                 return NT_STATUS_ACCESS_DENIED;
233         }
234
235         for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd))) 
236                      && pdb_getsampwent(pwd) == True; pwd=NULL) {
237                 
238                 if (all_machines) {
239                         if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST) 
240                               || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
241                                 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
242                                 pdb_free_sam(&pwd);
243                                 continue;
244                         }
245                 } else {
246                         if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
247                                 pdb_free_sam(&pwd);
248                                 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
249                                 continue;
250                         }
251                 }
252
253                 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
254                 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
255                 
256                         DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
257                         pwd_array=(DISP_USER_INFO *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info, 
258                                           (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
259
260                         if (pwd_array==NULL)
261                                 return NT_STATUS_NO_MEMORY;
262
263                         info->disp_info.disp_user_info=pwd_array;
264                 }
265         
266                 /* link the SAM_ACCOUNT to the array */
267                 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
268
269                 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
270
271                 info->disp_info.num_user_account++;     
272         }
273
274         pdb_endsampwent();
275
276         /* the snapshoot is in memory, we're ready to enumerate fast */
277
278         info->acb_mask = acb_mask;
279         info->all_machines = all_machines;
280         info->disp_info.user_dbloaded=True;
281
282         DEBUG(10,("load_sampwd_entries: done\n"));
283
284         return nt_status;
285 }
286
287 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
288 {
289         GROUP_MAP *map=NULL;
290         DISP_GROUP_INFO *grp_array = NULL;
291         uint32 group_entries = 0;
292         uint32 i;
293         TALLOC_CTX *mem_ctx = info->mem_ctx;
294
295         DEBUG(10,("load_group_domain_entries\n"));
296
297         /* if the snapshoot is already loaded, return */
298         if (info->disp_info.group_dbloaded==True) {
299                 DEBUG(10,("load_group_domain_entries: already in memory\n"));
300                 return NT_STATUS_OK;
301         }
302
303         if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) {
304                 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
305                 return NT_STATUS_NO_MEMORY;
306         }
307
308         info->disp_info.num_group_account=group_entries;
309
310         grp_array=(DISP_GROUP_INFO *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
311
312         if (group_entries!=0 && grp_array==NULL) {
313                 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
314                 SAFE_FREE(map);
315                 return NT_STATUS_NO_MEMORY;
316         }
317
318         info->disp_info.disp_group_info=grp_array;
319
320         for (i=0; i<group_entries; i++) {
321         
322                 grp_array[i].grp=(DOMAIN_GRP *)talloc(mem_ctx, sizeof(DOMAIN_GRP));
323         
324                 fstrcpy(grp_array[i].grp->name, map[i].nt_name);
325                 fstrcpy(grp_array[i].grp->comment, map[i].comment);
326                 sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
327                 grp_array[i].grp->attr=SID_NAME_DOM_GRP;
328         }
329
330         SAFE_FREE(map);
331
332         /* the snapshoot is in memory, we're ready to enumerate fast */
333
334         info->disp_info.group_dbloaded=True;
335
336         DEBUG(10,("load_group_domain_entries: done\n"));
337
338         return NT_STATUS_OK;
339 }
340
341
342 /*******************************************************************
343  _samr_close_hnd
344  ********************************************************************/
345
346 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
347 {
348         r_u->status = NT_STATUS_OK;
349
350         /* close the policy handle */
351         if (!close_policy_hnd(p, &q_u->pol))
352                 return NT_STATUS_OBJECT_NAME_INVALID;
353
354         DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
355
356         return r_u->status;
357 }
358
359 /*******************************************************************
360  samr_reply_open_domain
361  ********************************************************************/
362
363 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
364 {
365         struct    samr_info *info;
366         SEC_DESC *psd = NULL;
367         uint32    acc_granted;
368         uint32    des_access = q_u->flags;
369         size_t    sd_size;
370         NTSTATUS  status;
371
372         r_u->status = NT_STATUS_OK;
373
374         /* find the connection policy handle. */
375         if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
376                 return NT_STATUS_INVALID_HANDLE;
377
378         if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
379                 return status;
380         }
381
382         /*check if access can be granted as requested by client. */
383         samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
384         se_map_generic(&des_access,&dom_generic_mapping);
385
386         if (!NT_STATUS_IS_OK(status = 
387                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
388                                                       des_access, &acc_granted, "_samr_open_domain"))) {
389                 return status;
390         }
391
392         /* associate the domain SID with the (unique) handle. */
393         if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
394                 return NT_STATUS_NO_MEMORY;
395         info->acc_granted = acc_granted;
396
397         /* get a (unique) handle.  open a policy on it. */
398         if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
399                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
400
401         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
402
403         return r_u->status;
404 }
405
406 /*******************************************************************
407  _samr_get_usrdom_pwinfo
408  ********************************************************************/
409
410 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
411 {
412         struct samr_info *info = NULL;
413
414         r_u->status = NT_STATUS_OK;
415
416         /* find the policy handle.  open a policy on it. */
417         if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
418                 return NT_STATUS_INVALID_HANDLE;
419
420         if (!sid_check_is_in_our_domain(&info->sid))
421                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
422
423         init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
424
425         DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
426
427         /* 
428          * NT sometimes return NT_STATUS_ACCESS_DENIED
429          * I don't know yet why.
430          */
431
432         return r_u->status;
433 }
434
435 /*******************************************************************
436  samr_make_dom_obj_sd
437  ********************************************************************/
438
439 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
440 {
441         extern DOM_SID global_sid_World;
442         DOM_SID adm_sid;
443         DOM_SID act_sid;
444
445         SEC_ACE ace[3];
446         SEC_ACCESS mask;
447
448         SEC_ACL *psa = NULL;
449
450         sid_copy(&adm_sid, &global_sid_Builtin);
451         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
452
453         sid_copy(&act_sid, &global_sid_Builtin);
454         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
455
456         /*basic access for every one*/
457         init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
458         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
459
460         /*full access for builtin aliases Administrators and Account Operators*/
461         init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
462         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
463         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
464
465         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
466                 return NT_STATUS_NO_MEMORY;
467
468         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
469                 return NT_STATUS_NO_MEMORY;
470
471         return NT_STATUS_OK;
472 }
473
474 /*******************************************************************
475  samr_make_usr_obj_sd
476  ********************************************************************/
477
478 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
479 {
480         extern DOM_SID global_sid_World;
481         DOM_SID adm_sid;
482         DOM_SID act_sid;
483
484         SEC_ACE ace[4];
485         SEC_ACCESS mask;
486
487         SEC_ACL *psa = NULL;
488
489         sid_copy(&adm_sid, &global_sid_Builtin);
490         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
491
492         sid_copy(&act_sid, &global_sid_Builtin);
493         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
494
495         /*basic access for every one*/
496         init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
497         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
498
499         /*full access for builtin aliases Administrators and Account Operators*/
500         init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
501         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
502         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
503
504         /*extended access for the user*/
505         init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
506         init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
507
508         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
509                 return NT_STATUS_NO_MEMORY;
510
511         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
512                 return NT_STATUS_NO_MEMORY;
513
514         return NT_STATUS_OK;
515 }
516
517 /*******************************************************************
518  samr_make_grp_obj_sd
519  ********************************************************************/
520
521 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
522 {
523         extern DOM_SID global_sid_World;
524         DOM_SID adm_sid;
525         DOM_SID act_sid;
526
527         SEC_ACE ace[3];
528         SEC_ACCESS mask;
529
530         SEC_ACL *psa = NULL;
531
532         sid_copy(&adm_sid, &global_sid_Builtin);
533         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
534
535         sid_copy(&act_sid, &global_sid_Builtin);
536         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
537
538         /*basic access for every one*/
539         init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
540         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
541
542         /*full access for builtin aliases Administrators and Account Operators*/
543         init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
544         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
545         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
546
547         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
548                 return NT_STATUS_NO_MEMORY;
549
550         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
551                 return NT_STATUS_NO_MEMORY;
552
553         return NT_STATUS_OK;
554 }
555
556 /*******************************************************************
557  samr_make_ali_obj_sd
558  ********************************************************************/
559
560 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
561 {
562         extern DOM_SID global_sid_World;
563         DOM_SID adm_sid;
564         DOM_SID act_sid;
565
566         SEC_ACE ace[3];
567         SEC_ACCESS mask;
568
569         SEC_ACL *psa = NULL;
570
571         sid_copy(&adm_sid, &global_sid_Builtin);
572         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
573
574         sid_copy(&act_sid, &global_sid_Builtin);
575         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
576
577         /*basic access for every one*/
578         init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
579         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
580
581         /*full access for builtin aliases Administrators and Account Operators*/
582         init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
583         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
584         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
585
586         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
587                 return NT_STATUS_NO_MEMORY;
588
589         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
590                 return NT_STATUS_NO_MEMORY;
591
592         return NT_STATUS_OK;
593 }
594
595 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
596 {
597         struct samr_info *info = NULL;
598
599         /* find the policy handle.  open a policy on it. */
600         if (!find_policy_by_hnd(p, pol, (void **)&info))
601                 return False;
602
603         if (!info)
604                 return False;
605
606         *sid = info->sid;
607         *acc_granted = info->acc_granted;
608         return True;
609 }
610
611 /*******************************************************************
612  _samr_set_sec_obj
613  ********************************************************************/
614
615 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
616 {
617         DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
618         return NT_STATUS_NOT_IMPLEMENTED;
619 }
620
621
622 /*******************************************************************
623  _samr_query_sec_obj
624  ********************************************************************/
625
626 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
627 {
628         DOM_SID pol_sid;
629         fstring str_sid;
630         SEC_DESC * psd = NULL;
631         size_t sd_size;
632         uint32 acc_granted;
633
634         r_u->status = NT_STATUS_OK;
635
636         /* Get the SID. */
637         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
638                 return NT_STATUS_INVALID_HANDLE;
639
640
641
642         DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
643
644         /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
645
646         /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
647         if (pol_sid.sid_rev_num == 0)
648         {
649                 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
650                 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
651         }
652         else if (sid_equal(&pol_sid,get_global_sam_sid()))  /* check if it is our domain SID */
653
654         {
655                 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
656                 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
657         }
658         else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin  Domain */
659         {
660                 /* TODO: Builtin probably needs a different SD with restricted write access*/
661                 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
662                 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
663         }
664         else if (sid_check_is_in_our_domain(&pol_sid) ||
665                  sid_check_is_in_builtin(&pol_sid))
666         {
667                 /* TODO: different SDs have to be generated for aliases groups and users.
668                          Currently all three get a default user SD  */
669                 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
670                 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
671         }
672         else return NT_STATUS_OBJECT_TYPE_MISMATCH;
673
674         if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
675                 return NT_STATUS_NO_MEMORY;
676
677         if (NT_STATUS_IS_OK(r_u->status))
678                 r_u->ptr = 1;
679
680         return r_u->status;
681 }
682
683 /*******************************************************************
684 makes a SAM_ENTRY / UNISTR2* structure from a user list.
685 ********************************************************************/
686
687 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
688                                          uint32 num_entries, uint32 start_idx, DISP_USER_INFO *disp_user_info,
689                                          DOM_SID *domain_sid)
690 {
691         uint32 i;
692         SAM_ENTRY *sam;
693         UNISTR2 *uni_name;
694         SAM_ACCOUNT *pwd = NULL;
695         UNISTR2 uni_temp_name;
696         const char *temp_name;
697         const DOM_SID *user_sid;
698         uint32 user_rid;
699         fstring user_sid_string;
700         fstring domain_sid_string;
701         
702         *sam_pp = NULL;
703         *uni_name_pp = NULL;
704
705         if (num_entries == 0)
706                 return NT_STATUS_OK;
707
708         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
709
710         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
711
712         if (sam == NULL || uni_name == NULL) {
713                 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
714                 return NT_STATUS_NO_MEMORY;
715         }
716
717         for (i = 0; i < num_entries; i++) {
718                 pwd = disp_user_info[i+start_idx].sam;
719                 temp_name = pdb_get_username(pwd);
720                 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
721                 user_sid = pdb_get_user_sid(pwd);
722
723                 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
724                         DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
725                                   "the domain sid %s.  Failing operation.\n", 
726                                   temp_name, 
727                                   sid_to_string(user_sid_string, user_sid),
728                                   sid_to_string(domain_sid_string, domain_sid)));
729                         return NT_STATUS_UNSUCCESSFUL;
730                 }
731
732                 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
733                 copy_unistr2(&uni_name[i], &uni_temp_name);
734         }
735
736         *sam_pp = sam;
737         *uni_name_pp = uni_name;
738         return NT_STATUS_OK;
739 }
740
741 /*******************************************************************
742  samr_reply_enum_dom_users
743  ********************************************************************/
744
745 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, 
746                               SAMR_R_ENUM_DOM_USERS *r_u)
747 {
748         struct samr_info *info = NULL;
749         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
750         int num_account;
751         uint32 enum_context=q_u->start_idx;
752         uint32 max_size=q_u->max_size;
753         uint32 temp_size;
754         enum remote_arch_types ra_type = get_remote_arch();
755         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
756         uint32 max_entries = max_sam_entries;
757         DOM_SID domain_sid;
758         
759         r_u->status = NT_STATUS_OK;
760
761         /* find the policy handle.  open a policy on it. */
762         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
763                 return NT_STATUS_INVALID_HANDLE;
764
765         domain_sid = info->sid;
766
767         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, 
768                                         SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, 
769                                         "_samr_enum_dom_users"))) {
770                 return r_u->status;
771         }
772         
773         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
774
775         become_root();
776         r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
777         unbecome_root();
778         
779         if (!NT_STATUS_IS_OK(r_u->status))
780                 return r_u->status;
781
782         num_account = info->disp_info.num_user_account;
783
784         if (enum_context > num_account) {
785                 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
786                 return NT_STATUS_OK;
787         }
788
789         /* verify we won't overflow */
790         if (max_entries > num_account-enum_context) {
791                 max_entries = num_account-enum_context;
792                 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
793         }
794
795         /* calculate the size and limit on the number of entries we will return */
796         temp_size=max_entries*struct_size;
797         
798         if (temp_size>max_size) {
799                 max_entries=MIN((max_size/struct_size),max_entries);;
800                 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
801         }
802
803         /* 
804          * Note from JRA. total_entries is not being used here. Currently if there is a
805          * large user base then it looks like NT will enumerate until get_sampwd_entries
806          * returns False due to num_entries being zero. This will cause an access denied
807          * return. I don't think this is right and needs further investigation. Note that
808          * this is also the same in the TNG code (I don't think that has been tested with
809          * a very large user list as MAX_SAM_ENTRIES is set to 600).
810          * 
811          * I also think that one of the 'num_entries' return parameters is probably
812          * the "max entries" parameter - but in the TNG code they're all currently set to the same
813          * value (again I think this is wrong).
814          */
815
816         r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, 
817                                                max_entries, enum_context, 
818                                                info->disp_info.disp_user_info,
819                                                &domain_sid);
820
821         if (!NT_STATUS_IS_OK(r_u->status))
822                 return r_u->status;
823
824         if (enum_context+max_entries < num_account)
825                 r_u->status = STATUS_MORE_ENTRIES;
826
827         DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
828
829         init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
830
831         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
832
833         return r_u->status;
834 }
835
836 /*******************************************************************
837 makes a SAM_ENTRY / UNISTR2* structure from a group list.
838 ********************************************************************/
839
840 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
841                 uint32 num_sam_entries, DOMAIN_GRP *grp)
842 {
843         uint32 i;
844         SAM_ENTRY *sam;
845         UNISTR2 *uni_name;
846
847         *sam_pp = NULL;
848         *uni_name_pp = NULL;
849
850         if (num_sam_entries == 0)
851                 return;
852
853         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
854
855         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
856
857         if (sam == NULL || uni_name == NULL) {
858                 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
859                 return;
860         }
861
862         for (i = 0; i < num_sam_entries; i++) {
863                 /*
864                  * JRA. I think this should include the null. TNG does not.
865                  */
866                 int len = strlen(grp[i].name)+1;
867
868                 init_sam_entry(&sam[i], len, grp[i].rid);
869                 init_unistr2(&uni_name[i], grp[i].name, len);
870         }
871
872         *sam_pp = sam;
873         *uni_name_pp = uni_name;
874 }
875
876 /*******************************************************************
877  Get the group entries - similar to get_sampwd_entries().
878  ********************************************************************/
879
880 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
881                                     uint32 *p_num_entries, uint32 max_entries)
882 {
883         fstring sid_str;
884         uint32 num_entries = 0;
885         int i;
886         GROUP_MAP smap;
887         GROUP_MAP *map = NULL;
888
889         sid_to_string(sid_str, sid);
890         DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
891
892         *p_num_entries = 0;
893
894         /* well-known aliases */
895         if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
896                 
897                 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
898                 
899                 if (num_entries != 0) {         
900                         *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
901                         if (*d_grp==NULL)
902                                 return NT_STATUS_NO_MEMORY;
903                         
904                         for(i=0; i<num_entries && i<max_entries; i++) {
905                                 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
906                                 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
907                                 
908                         }
909                 }
910                 SAFE_FREE(map);
911                 
912         } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
913                 struct sys_grent *glist;
914                 struct sys_grent *grp;
915                 struct passwd *pw;
916                 gid_t winbind_gid_low, winbind_gid_high;
917                 BOOL winbind_groups_exist = lp_winbind_gid(&winbind_gid_low, &winbind_gid_high);
918
919                 /* local aliases */
920                 /* we return the UNIX groups here.  This seems to be the right */
921                 /* thing to do, since NT member servers return their local     */
922                 /* groups in the same situation.                               */
923
924                 /* use getgrent_list() to retrieve the list of groups to avoid
925                  * problems with getgrent possible infinite loop by internal
926                  * libc grent structures overwrites by called functions */
927                 grp = glist = getgrent_list();
928                 if (grp == NULL)
929                         return NT_STATUS_NO_MEMORY;
930                 
931                 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
932                         uint32 trid;
933                         
934                         if(!pdb_getgrgid(&smap, grp->gr_gid, MAPPING_WITHOUT_PRIV))
935                                 continue;
936                         
937                         if (smap.sid_name_use!=SID_NAME_ALIAS) {
938                                 continue;
939                         }
940
941                         sid_split_rid(&smap.sid, &trid);
942                         
943                         if (!sid_equal(sid, &smap.sid))
944                                 continue;
945
946                         /* Don't return winbind groups as they are not local! */
947                         if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
948                                 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
949                                 continue;
950                         }
951
952                         /* Don't return user private groups... */
953
954                         if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
955                                 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
956                                 continue;                       
957                         }
958
959                         for( i = 0; i < num_entries; i++)
960                                 if ( (*d_grp)[i].rid == trid )
961                                         break;
962
963                         if ( i < num_entries ) {
964                                 continue; /* rid was there, dup! */
965                         }
966
967                         /* JRA - added this for large group db enumeration... */
968
969                         if (start_idx > 0) {
970                                 /* skip the requested number of entries.
971                                         not very efficient, but hey...
972                                 */
973                                 start_idx--;
974                                 continue;
975                         }
976
977                         *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
978                         if (*d_grp==NULL) {
979                                 grent_free(glist);
980                                 return NT_STATUS_NO_MEMORY;
981                         }
982
983                         fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
984                         (*d_grp)[num_entries].rid = trid;
985                         num_entries++;
986                         DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
987                 }
988
989                 grent_free(glist);
990         }
991
992         *p_num_entries = num_entries;
993
994         DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
995
996         if (num_entries >= max_entries)
997                 return STATUS_MORE_ENTRIES;
998         return NT_STATUS_OK;
999 }
1000
1001 /*******************************************************************
1002  Get the group entries - similar to get_sampwd_entries().
1003  ********************************************************************/
1004
1005 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1006                                      uint32 *p_num_entries, uint32 max_entries)
1007 {
1008         GROUP_MAP *map=NULL;
1009         int i;
1010         uint32 group_entries = 0;
1011         uint32 num_entries = 0;
1012
1013         *p_num_entries = 0;
1014
1015         pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
1016
1017         num_entries=group_entries-start_idx;
1018
1019         /* limit the number of entries */
1020         if (num_entries>max_entries) {
1021                 DEBUG(5,("Limiting to %d entries\n", max_entries));
1022                 num_entries=max_entries;
1023         }
1024
1025         *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1026         if (num_entries!=0 && *d_grp==NULL){
1027                 SAFE_FREE(map);
1028                 return NT_STATUS_NO_MEMORY;
1029         }
1030         
1031         for (i=0; i<num_entries; i++) {
1032                 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1033                 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1034                 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1035                 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1036         }
1037
1038         SAFE_FREE(map);
1039
1040         *p_num_entries = num_entries;
1041
1042         return NT_STATUS_OK;
1043 }
1044
1045 /*******************************************************************
1046  samr_reply_enum_dom_groups
1047  ********************************************************************/
1048
1049 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1050 {
1051         DOMAIN_GRP *grp=NULL;
1052         uint32 num_entries;
1053         DOM_SID sid;
1054         uint32 acc_granted;
1055
1056         r_u->status = NT_STATUS_OK;
1057
1058         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1059                 return NT_STATUS_INVALID_HANDLE;
1060                 
1061         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1062                 return r_u->status;
1063         }
1064
1065         DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1066
1067         /* the domain group array is being allocated in the function below */
1068         if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
1069                 return r_u->status;
1070         }
1071
1072         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1073
1074         init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1075
1076         DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1077
1078         return r_u->status;
1079 }
1080
1081
1082 /*******************************************************************
1083  samr_reply_enum_dom_aliases
1084  ********************************************************************/
1085
1086 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1087 {
1088         DOMAIN_GRP *grp=NULL;
1089         uint32 num_entries = 0;
1090         fstring sid_str;
1091         DOM_SID sid;
1092         NTSTATUS status;
1093         uint32  acc_granted;
1094         
1095         r_u->status = NT_STATUS_OK;
1096
1097         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1098                 return NT_STATUS_INVALID_HANDLE;
1099
1100         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1101                 return r_u->status;
1102         }
1103         
1104         sid_to_string(sid_str, &sid);
1105         DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1106
1107         status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, 
1108                                          &num_entries, MAX_SAM_ENTRIES);
1109         if (NT_STATUS_IS_ERR(status)) return status;
1110
1111         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1112
1113         /*safe_free(grp);*/
1114
1115         init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1116
1117         DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1118
1119         return r_u->status;
1120 }
1121
1122 /*******************************************************************
1123  samr_reply_query_dispinfo
1124  ********************************************************************/
1125 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, 
1126                               SAMR_R_QUERY_DISPINFO *r_u)
1127 {
1128         struct samr_info *info = NULL;
1129         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1130         
1131         uint32 max_entries=q_u->max_entries;
1132         uint32 enum_context=q_u->start_idx;
1133         uint32 max_size=q_u->max_size;
1134
1135         SAM_DISPINFO_CTR *ctr;
1136         uint32 temp_size=0, total_data_size=0;
1137         NTSTATUS disp_ret;
1138         uint32 num_account = 0;
1139         enum remote_arch_types ra_type = get_remote_arch();
1140         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1141         DOM_SID domain_sid;
1142
1143         DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1144         r_u->status = NT_STATUS_OK;
1145
1146         /* find the policy handle.  open a policy on it. */
1147         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1148                 return NT_STATUS_INVALID_HANDLE;
1149
1150         domain_sid = info->sid;
1151
1152         /*
1153          * calculate how many entries we will return.
1154          * based on 
1155          * - the number of entries the client asked
1156          * - our limit on that
1157          * - the starting point (enumeration context)
1158          * - the buffer size the client will accept
1159          */
1160
1161         /*
1162          * We are a lot more like W2K. Instead of reading the SAM
1163          * each time to find the records we need to send back,
1164          * we read it once and link that copy to the sam handle.
1165          * For large user list (over the MAX_SAM_ENTRIES)
1166          * it's a definitive win.
1167          * second point to notice: between enumerations
1168          * our sam is now the same as it's a snapshoot.
1169          * third point: got rid of the static SAM_USER_21 struct
1170          * no more intermediate.
1171          * con: it uses much more memory, as a full copy is stored
1172          * in memory.
1173          *
1174          * If you want to change it, think twice and think
1175          * of the second point , that's really important.
1176          *
1177          * JFM, 12/20/2001
1178          */
1179
1180         /* Get what we need from the password database */
1181         switch (q_u->switch_level) {
1182                 case 0x1:
1183                 case 0x2:
1184                 case 0x4:
1185                         become_root();          
1186                         /* Level 2 is for all machines, otherwise only 'normal' users */
1187                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1188                         unbecome_root();
1189                         if (!NT_STATUS_IS_OK(r_u->status)) {
1190                                 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1191                                 return r_u->status;
1192                         }
1193                         num_account = info->disp_info.num_user_account;
1194                         break;
1195                 case 0x3:
1196                 case 0x5:
1197                         r_u->status = load_group_domain_entries(info, &info->sid);
1198                         if (!NT_STATUS_IS_OK(r_u->status))
1199                                 return r_u->status;
1200                         num_account = info->disp_info.num_group_account;
1201                         break;
1202                 default:
1203                         DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1204                         return NT_STATUS_INVALID_INFO_CLASS;
1205         }
1206
1207         /* first limit the number of entries we will return */
1208         if(max_entries > max_sam_entries) {
1209                 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1210                 max_entries = max_sam_entries;
1211         }
1212
1213         if (enum_context > num_account) {
1214                 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1215                 return NT_STATUS_NO_MORE_ENTRIES;
1216         }
1217
1218         /* verify we won't overflow */
1219         if (max_entries > num_account-enum_context) {
1220                 max_entries = num_account-enum_context;
1221                 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1222         }
1223
1224         /* calculate the size and limit on the number of entries we will return */
1225         temp_size=max_entries*struct_size;
1226         
1227         if (temp_size>max_size) {
1228                 max_entries=MIN((max_size/struct_size),max_entries);;
1229                 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1230         }
1231
1232         if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1233                 return NT_STATUS_NO_MEMORY;
1234
1235         ZERO_STRUCTP(ctr);
1236
1237         /* Now create reply structure */
1238         switch (q_u->switch_level) {
1239         case 0x1:
1240                 if (max_entries) {
1241                         if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1242                                 return NT_STATUS_NO_MEMORY;
1243                 }
1244                 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, 
1245                                                info->disp_info.disp_user_info, &domain_sid);
1246                 if (!NT_STATUS_IS_OK(disp_ret))
1247                         return disp_ret;
1248                 break;
1249         case 0x2:
1250                 if (max_entries) {
1251                         if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1252                                 return NT_STATUS_NO_MEMORY;
1253                 }
1254                 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, 
1255                                                info->disp_info.disp_user_info, &domain_sid);
1256                 if (!NT_STATUS_IS_OK(disp_ret))
1257                         return disp_ret;
1258                 break;
1259         case 0x3:
1260                 if (max_entries) {
1261                         if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1262                                 return NT_STATUS_NO_MEMORY;
1263                 }
1264                 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1265                 if (!NT_STATUS_IS_OK(disp_ret))
1266                         return disp_ret;
1267                 break;
1268         case 0x4:
1269                 if (max_entries) {
1270                         if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1271                                 return NT_STATUS_NO_MEMORY;
1272                 }
1273                 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1274                 if (!NT_STATUS_IS_OK(disp_ret))
1275                         return disp_ret;
1276                 break;
1277         case 0x5:
1278                 if (max_entries) {
1279                         if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1280                                 return NT_STATUS_NO_MEMORY;
1281                 }
1282                 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1283                 if (!NT_STATUS_IS_OK(disp_ret))
1284                         return disp_ret;
1285                 break;
1286
1287         default:
1288                 ctr->sam.info = NULL;
1289                 return NT_STATUS_INVALID_INFO_CLASS;
1290         }
1291
1292         /* calculate the total size */
1293         total_data_size=num_account*struct_size;
1294
1295         if (enum_context+max_entries < num_account)
1296                 r_u->status = STATUS_MORE_ENTRIES;
1297
1298         DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1299
1300         init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1301
1302         return r_u->status;
1303
1304 }
1305
1306 /*******************************************************************
1307  samr_reply_query_aliasinfo
1308  ********************************************************************/
1309
1310 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1311 {
1312         DOM_SID   sid;
1313         GROUP_MAP map;
1314         uint32    acc_granted;
1315
1316         r_u->status = NT_STATUS_OK;
1317
1318         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1319
1320         /* find the policy handle.  open a policy on it. */
1321         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1322                 return NT_STATUS_INVALID_HANDLE;
1323         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1324                 return r_u->status;
1325         }
1326
1327         if (!sid_check_is_in_our_domain(&sid) &&
1328             !sid_check_is_in_builtin(&sid))
1329                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1330
1331         if (!pdb_getgrsid(&map, sid, MAPPING_WITHOUT_PRIV))
1332                 return NT_STATUS_NO_SUCH_ALIAS;
1333
1334         switch (q_u->switch_level) {
1335         case 1:
1336                 r_u->ptr = 1;
1337                 r_u->ctr.switch_value1 = 1;
1338                 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1339                 break;
1340         case 3:
1341                 r_u->ptr = 1;
1342                 r_u->ctr.switch_value1 = 3;
1343                 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1344                 break;
1345         default:
1346                 return NT_STATUS_INVALID_INFO_CLASS;
1347         }
1348
1349         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1350
1351         return r_u->status;
1352 }
1353
1354 #if 0
1355 /*******************************************************************
1356  samr_reply_lookup_ids
1357  ********************************************************************/
1358
1359  uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1360 {
1361     uint32 rid[MAX_SAM_ENTRIES];
1362     int num_rids = q_u->num_sids1;
1363
1364     r_u->status = NT_STATUS_OK;
1365
1366     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1367
1368     if (num_rids > MAX_SAM_ENTRIES) {
1369         num_rids = MAX_SAM_ENTRIES;
1370         DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1371     }
1372
1373 #if 0
1374     int i;
1375     SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1376
1377     for (i = 0; i < num_rids && status == 0; i++)
1378     {
1379         struct sam_passwd *sam_pass;
1380         fstring user_name;
1381
1382
1383         fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1384                                     q_u->uni_user_name[i].uni_str_len));
1385
1386         /* find the user account */
1387         become_root();
1388         sam_pass = get_smb21pwd_entry(user_name, 0);
1389         unbecome_root();
1390
1391         if (sam_pass == NULL)
1392         {
1393             status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1394             rid[i] = 0;
1395         }
1396         else
1397         {
1398             rid[i] = sam_pass->user_rid;
1399         }
1400     }
1401 #endif
1402
1403     num_rids = 1;
1404     rid[0] = BUILTIN_ALIAS_RID_USERS;
1405
1406     init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1407
1408     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1409
1410     return r_u->status;
1411 }
1412 #endif
1413
1414 /*******************************************************************
1415  _samr_lookup_names
1416  ********************************************************************/
1417
1418 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1419 {
1420         uint32 rid[MAX_SAM_ENTRIES];
1421         uint32 local_rid;
1422         enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1423         enum SID_NAME_USE local_type;
1424         int i;
1425         int num_rids = q_u->num_names2;
1426         DOM_SID pol_sid;
1427         fstring sid_str;
1428         uint32  acc_granted;
1429
1430         r_u->status = NT_STATUS_OK;
1431
1432         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1433
1434         ZERO_ARRAY(rid);
1435         ZERO_ARRAY(type);
1436
1437         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1438                 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1439                 return r_u->status;
1440         }
1441         
1442         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1443                 return r_u->status;
1444         }
1445
1446         if (num_rids > MAX_SAM_ENTRIES) {
1447                 num_rids = MAX_SAM_ENTRIES;
1448                 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1449         }
1450
1451         DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1452         
1453         become_root(); /* local_lookup_name can require root privs */
1454
1455         for (i = 0; i < num_rids; i++) {
1456                 fstring name;
1457                 DOM_SID sid;
1458
1459                 r_u->status = NT_STATUS_NONE_MAPPED;
1460
1461                 rid [i] = 0xffffffff;
1462                 type[i] = SID_NAME_UNKNOWN;
1463
1464                 rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1465
1466                 /*
1467                  * we are only looking for a name
1468                  * the SID we get back can be outside
1469                  * the scope of the pol_sid
1470                  * 
1471                  * in clear: it prevents to reply to domain\group: yes
1472                  * when only builtin\group exists.
1473                  *
1474                  * a cleaner code is to add the sid of the domain we're looking in
1475                  * to the local_lookup_name function.
1476                  */
1477                 if(local_lookup_name(name, &sid, &local_type)) {
1478                         sid_split_rid(&sid, &local_rid);
1479                                 
1480                         if (sid_equal(&sid, &pol_sid)) {
1481                                 rid[i]=local_rid;
1482                                 type[i]=local_type;
1483                                 r_u->status = NT_STATUS_OK;
1484                         }
1485                 }
1486         }
1487
1488         unbecome_root();
1489
1490         init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1491
1492         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1493
1494         return r_u->status;
1495 }
1496
1497 /*******************************************************************
1498  _samr_chgpasswd_user
1499  ********************************************************************/
1500
1501 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1502 {
1503     fstring user_name;
1504     fstring wks;
1505
1506     DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1507
1508     r_u->status = NT_STATUS_OK;
1509
1510     rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1511     rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1512
1513     DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1514
1515         /*
1516          * Pass the user through the NT -> unix user mapping
1517          * function.
1518          */
1519  
1520         (void)map_username(user_name);
1521  
1522         /*
1523          * UNIX username case mangling not required, pass_oem_change 
1524          * is case insensitive.
1525          */
1526
1527     if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1528                          q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1529         r_u->status = NT_STATUS_WRONG_PASSWORD;
1530
1531     init_samr_r_chgpasswd_user(r_u, r_u->status);
1532
1533     DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1534
1535     return r_u->status;
1536 }
1537
1538 /*******************************************************************
1539 makes a SAMR_R_LOOKUP_RIDS structure.
1540 ********************************************************************/
1541
1542 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1543             UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1544 {
1545         uint32 i;
1546         UNIHDR *hdr_name=NULL;
1547         UNISTR2 *uni_name=NULL;
1548
1549         *pp_uni_name = NULL;
1550         *pp_hdr_name = NULL;
1551
1552         if (num_names != 0) {
1553                 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1554                 if (hdr_name == NULL)
1555                         return False;
1556
1557                 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1558                 if (uni_name == NULL)
1559                         return False;
1560         }
1561
1562         for (i = 0; i < num_names; i++) {
1563                 int len = names[i] != NULL ? strlen(names[i]) : 0;
1564                 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1565                 init_uni_hdr(&hdr_name[i], len);
1566                 init_unistr2(&uni_name[i], names[i], len);
1567         }
1568
1569         *pp_uni_name = uni_name;
1570         *pp_hdr_name = hdr_name;
1571
1572         return True;
1573 }
1574
1575 /*******************************************************************
1576  _samr_lookup_rids
1577  ********************************************************************/
1578
1579 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1580 {
1581         fstring group_names[MAX_SAM_ENTRIES];
1582         uint32 *group_attrs = NULL;
1583         UNIHDR *hdr_name = NULL;
1584         UNISTR2 *uni_name = NULL;
1585         DOM_SID pol_sid;
1586         int num_rids = q_u->num_rids1;
1587         int i;
1588         uint32 acc_granted;
1589
1590         r_u->status = NT_STATUS_OK;
1591
1592         DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1593
1594         /* find the policy handle.  open a policy on it. */
1595         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1596                 return NT_STATUS_INVALID_HANDLE;
1597
1598         if (num_rids > MAX_SAM_ENTRIES) {
1599                 num_rids = MAX_SAM_ENTRIES;
1600                 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1601         }
1602
1603         if (num_rids) {
1604                 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1605                         return NT_STATUS_NO_MEMORY;
1606         }
1607  
1608         r_u->status = NT_STATUS_NONE_MAPPED;
1609
1610         become_root();  /* lookup_sid can require root privs */
1611
1612         for (i = 0; i < num_rids; i++) {
1613                 fstring tmpname;
1614                 fstring domname;
1615                 DOM_SID sid;
1616                 enum SID_NAME_USE type;
1617
1618                 group_attrs[i] = SID_NAME_UNKNOWN;
1619                 *group_names[i] = '\0';
1620
1621                 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1622                         sid_copy(&sid, &pol_sid);
1623                         sid_append_rid(&sid, q_u->rid[i]);
1624
1625                         if (lookup_sid(&sid, domname, tmpname, &type)) {
1626                                 r_u->status = NT_STATUS_OK;
1627                                 group_attrs[i] = (uint32)type;
1628                                 fstrcpy(group_names[i],tmpname);
1629                                 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1630                         }
1631                 }
1632         }
1633
1634         unbecome_root();
1635
1636         if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1637                 return NT_STATUS_NO_MEMORY;
1638
1639         init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1640
1641         DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1642
1643         return r_u->status;
1644 }
1645
1646 /*******************************************************************
1647  _api_samr_open_user. Safe - gives out no passwd info.
1648  ********************************************************************/
1649
1650 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1651 {
1652         SAM_ACCOUNT *sampass=NULL;
1653         DOM_SID sid;
1654         POLICY_HND domain_pol = q_u->domain_pol;
1655         POLICY_HND *user_pol = &r_u->user_pol;
1656         struct samr_info *info = NULL;
1657         SEC_DESC *psd = NULL;
1658         uint32    acc_granted;
1659         uint32    des_access = q_u->access_mask;
1660         size_t    sd_size;
1661         BOOL ret;
1662         NTSTATUS nt_status;
1663
1664         r_u->status = NT_STATUS_OK;
1665
1666         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1667         if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1668                 return NT_STATUS_INVALID_HANDLE;
1669         
1670         if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1671                 return nt_status;
1672         }
1673
1674         nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1675         if (!NT_STATUS_IS_OK(nt_status)) {
1676                 return nt_status;
1677         }
1678
1679         /* append the user's RID to it */
1680         if (!sid_append_rid(&sid, q_u->user_rid))
1681                 return NT_STATUS_NO_SUCH_USER;
1682         
1683         /* check if access can be granted as requested by client. */
1684         samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1685         se_map_generic(&des_access, &usr_generic_mapping);
1686         if (!NT_STATUS_IS_OK(nt_status = 
1687                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
1688                                                       des_access, &acc_granted, "_samr_open_user"))) {
1689                 return nt_status;
1690         }
1691
1692         become_root();
1693         ret=pdb_getsampwsid(sampass, &sid);
1694         unbecome_root();
1695
1696         /* check that the SID exists in our domain. */
1697         if (ret == False) {
1698                 return NT_STATUS_NO_SUCH_USER;
1699         }
1700
1701         pdb_free_sam(&sampass);
1702
1703         /* associate the user's SID and access bits with the new handle. */
1704         if ((info = get_samr_info_by_sid(&sid)) == NULL)
1705                 return NT_STATUS_NO_MEMORY;
1706         info->acc_granted = acc_granted;
1707
1708         /* get a (unique) handle.  open a policy on it. */
1709         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1710                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1711
1712         return r_u->status;
1713 }
1714
1715 /*************************************************************************
1716  get_user_info_10. Safe. Only gives out acb bits.
1717  *************************************************************************/
1718
1719 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1720 {
1721         SAM_ACCOUNT *smbpass=NULL;
1722         BOOL ret;
1723         NTSTATUS nt_status;
1724
1725         nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1726         
1727         if (!NT_STATUS_IS_OK(nt_status)) {
1728                 return nt_status;
1729         }
1730
1731         become_root();
1732         ret = pdb_getsampwsid(smbpass, user_sid);
1733         unbecome_root();
1734
1735         if (ret==False) {
1736                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1737                 return NT_STATUS_NO_SUCH_USER;
1738         }
1739
1740         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1741
1742         ZERO_STRUCTP(id10);
1743         init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1744
1745         pdb_free_sam(&smbpass);
1746
1747         return NT_STATUS_OK;
1748 }
1749
1750 /*************************************************************************
1751  get_user_info_12. OK - this is the killer as it gives out password info.
1752  Ensure that this is only allowed on an encrypted connection with a root
1753  user. JRA. 
1754  *************************************************************************/
1755
1756 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1757 {
1758         SAM_ACCOUNT *smbpass=NULL;
1759         BOOL ret;
1760         NTSTATUS nt_status;
1761
1762         if (!p->ntlmssp_auth_validated)
1763                 return NT_STATUS_ACCESS_DENIED;
1764
1765         if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1766                 return NT_STATUS_ACCESS_DENIED;
1767
1768         /*
1769          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1770          */
1771
1772         nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1773         
1774         if (!NT_STATUS_IS_OK(nt_status)) {
1775                 return nt_status;
1776         }
1777
1778         ret = pdb_getsampwsid(smbpass, user_sid);
1779
1780         if (ret == False) {
1781                 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1782                 pdb_free_sam(&smbpass);
1783                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1784         }
1785
1786         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1787
1788         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1789                 pdb_free_sam(&smbpass);
1790                 return NT_STATUS_ACCOUNT_DISABLED;
1791         }
1792
1793         ZERO_STRUCTP(id12);
1794         init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1795         
1796         pdb_free_sam(&smbpass);
1797
1798         return NT_STATUS_OK;
1799 }
1800
1801 /*************************************************************************
1802  get_user_info_20
1803  *************************************************************************/
1804
1805 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1806 {
1807         SAM_ACCOUNT *sampass=NULL;
1808         BOOL ret;
1809
1810         pdb_init_sam_talloc(mem_ctx, &sampass);
1811
1812         become_root();
1813         ret = pdb_getsampwsid(sampass, user_sid);
1814         unbecome_root();
1815
1816         if (ret == False) {
1817                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1818                 return NT_STATUS_NO_SUCH_USER;
1819         }
1820
1821         samr_clear_sam_passwd(sampass);
1822
1823         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1824
1825         ZERO_STRUCTP(id20);
1826         init_sam_user_info20A(id20, sampass);
1827         
1828         pdb_free_sam(&sampass);
1829
1830         return NT_STATUS_OK;
1831 }
1832
1833 /*************************************************************************
1834  get_user_info_21
1835  *************************************************************************/
1836
1837 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21, 
1838                                  DOM_SID *user_sid, DOM_SID *domain_sid)
1839 {
1840         SAM_ACCOUNT *sampass=NULL;
1841         BOOL ret;
1842         NTSTATUS nt_status;
1843
1844         nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1845         if (!NT_STATUS_IS_OK(nt_status)) {
1846                 return nt_status;
1847         }
1848
1849         become_root();
1850         ret = pdb_getsampwsid(sampass, user_sid);
1851         unbecome_root();
1852
1853         if (ret == False) {
1854                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1855                 return NT_STATUS_NO_SUCH_USER;
1856         }
1857
1858         samr_clear_sam_passwd(sampass);
1859
1860         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1861
1862         ZERO_STRUCTP(id21);
1863         nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1864         
1865         pdb_free_sam(&sampass);
1866
1867         return NT_STATUS_OK;
1868 }
1869
1870 /*******************************************************************
1871  _samr_query_userinfo
1872  ********************************************************************/
1873
1874 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1875 {
1876         SAM_USERINFO_CTR *ctr;
1877         struct samr_info *info = NULL;
1878         DOM_SID domain_sid;
1879         uint32 rid;
1880         
1881         r_u->status=NT_STATUS_OK;
1882
1883         /* search for the handle */
1884         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1885                 return NT_STATUS_INVALID_HANDLE;
1886
1887         domain_sid = info->sid;
1888
1889         sid_split_rid(&domain_sid, &rid);
1890
1891         if (!sid_check_is_in_our_domain(&info->sid))
1892                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1893
1894         DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1895
1896         ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1897         if (!ctr)
1898                 return NT_STATUS_NO_MEMORY;
1899
1900         ZERO_STRUCTP(ctr);
1901
1902         /* ok!  user info levels (lots: see MSDEV help), off we go... */
1903         ctr->switch_value = q_u->switch_value;
1904
1905         switch (q_u->switch_value) {
1906         case 0x10:
1907                 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1908                 if (ctr->info.id10 == NULL)
1909                         return NT_STATUS_NO_MEMORY;
1910
1911                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1912                         return r_u->status;
1913                 break;
1914
1915 #if 0
1916 /* whoops - got this wrong.  i think.  or don't understand what's happening. */
1917         case 0x11:
1918         {
1919             NTTIME expire;
1920             info = (void *)&id11;
1921
1922             expire.low = 0xffffffff;
1923             expire.high = 0x7fffffff;
1924
1925             ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1926                                     sizeof
1927                                     (*ctr->
1928                                      info.
1929                                      id11));
1930             ZERO_STRUCTP(ctr->info.id11);
1931             init_sam_user_info11(ctr->info.id11, &expire,
1932                          "BROOKFIELDS$",    /* name */
1933                          0x03ef,    /* user rid */
1934                          0x201, /* group rid */
1935                          0x0080);   /* acb info */
1936
1937             break;
1938         }
1939 #endif
1940
1941         case 0x12:
1942                 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1943                 if (ctr->info.id12 == NULL)
1944                         return NT_STATUS_NO_MEMORY;
1945
1946                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1947                         return r_u->status;
1948                 break;
1949                 
1950         case 20:
1951                 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1952                 if (ctr->info.id20 == NULL)
1953                         return NT_STATUS_NO_MEMORY;
1954                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1955                         return r_u->status;
1956                 break;
1957
1958         case 21:
1959                 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1960                 if (ctr->info.id21 == NULL)
1961                         return NT_STATUS_NO_MEMORY;
1962                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21, 
1963                                                                     &info->sid, &domain_sid)))
1964                         return r_u->status;
1965                 break;
1966
1967         default:
1968                 return NT_STATUS_INVALID_INFO_CLASS;
1969         }
1970
1971         init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1972
1973         DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1974         
1975         return r_u->status;
1976 }
1977
1978 /*******************************************************************
1979  samr_reply_query_usergroups
1980  ********************************************************************/
1981
1982 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1983 {
1984         SAM_ACCOUNT *sam_pass=NULL;
1985         DOM_SID  sid;
1986         DOM_GID *gids = NULL;
1987         int num_groups = 0;
1988         uint32 acc_granted;
1989         BOOL ret;
1990
1991         /*
1992          * from the SID in the request:
1993          * we should send back the list of DOMAIN GROUPS
1994          * the user is a member of
1995          *
1996          * and only the DOMAIN GROUPS
1997          * no ALIASES !!! neither aliases of the domain
1998          * nor aliases of the builtin SID
1999          *
2000          * JFM, 12/2/2001
2001          */
2002
2003         r_u->status = NT_STATUS_OK;
2004
2005         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2006
2007         /* find the policy handle.  open a policy on it. */
2008         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2009                 return NT_STATUS_INVALID_HANDLE;
2010         
2011         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2012                 return r_u->status;
2013         }
2014
2015         if (!sid_check_is_in_our_domain(&sid))
2016                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2017
2018         pdb_init_sam(&sam_pass);
2019         
2020         become_root();
2021         ret = pdb_getsampwsid(sam_pass, &sid);
2022         unbecome_root();
2023
2024         if (ret == False) {
2025                 pdb_free_sam(&sam_pass);
2026                 return NT_STATUS_NO_SUCH_USER;
2027         }
2028         
2029         if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2030                 pdb_free_sam(&sam_pass);
2031                 return NT_STATUS_NO_SUCH_GROUP;
2032         }
2033         
2034         /* construct the response.  lkclXXXX: gids are not copied! */
2035         init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2036         
2037         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2038         
2039         pdb_free_sam(&sam_pass);
2040         
2041         return r_u->status;
2042 }
2043
2044 /*******************************************************************
2045  _samr_query_dom_info
2046  ********************************************************************/
2047
2048 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2049 {
2050         struct samr_info *info = NULL;
2051         SAM_UNK_CTR *ctr;
2052         uint32 min_pass_len,pass_hist,flag;
2053         time_t u_expire, u_min_age;
2054         NTTIME nt_expire, nt_min_age;
2055
2056         time_t u_lock_duration, u_reset_time;
2057         NTTIME nt_lock_duration, nt_reset_time;
2058         uint32 lockout;
2059         
2060         time_t u_logout;
2061         NTTIME nt_logout;
2062
2063         uint32 account_policy_temp;
2064
2065         uint32 num_users=0, num_groups=0, num_aliases=0;
2066
2067         if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2068                 return NT_STATUS_NO_MEMORY;
2069
2070         ZERO_STRUCTP(ctr);
2071
2072         r_u->status = NT_STATUS_OK;
2073         
2074         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2075         
2076         /* find the policy handle.  open a policy on it. */
2077         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2078                 return NT_STATUS_INVALID_HANDLE;
2079         
2080         switch (q_u->switch_value) {
2081                 case 0x01:
2082                         
2083                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2084                         min_pass_len = account_policy_temp;
2085
2086                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2087                         pass_hist = account_policy_temp;
2088
2089                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2090                         flag = account_policy_temp;
2091
2092                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2093                         u_expire = account_policy_temp;
2094
2095                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2096                         u_min_age = account_policy_temp;
2097                         
2098                         unix_to_nt_time_abs(&nt_expire, u_expire);
2099                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2100
2101                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
2102                                        flag, nt_expire, nt_min_age);
2103                         break;
2104                 case 0x02:
2105                         become_root();          
2106                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2107                         unbecome_root();
2108                         if (!NT_STATUS_IS_OK(r_u->status)) {
2109                                 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2110                                 return r_u->status;
2111                         }
2112                         num_users=info->disp_info.num_user_account;
2113                         free_samr_db(info);
2114                         
2115                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2116                         if (!NT_STATUS_IS_OK(r_u->status)) {
2117                                 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2118                                 return r_u->status;
2119                         }
2120                         num_groups=info->disp_info.num_group_account;
2121                         free_samr_db(info);
2122                         
2123                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2124                         init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL), 
2125                                        num_users, num_groups, num_aliases);
2126                         break;
2127                 case 0x03:
2128                         account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
2129                         unix_to_nt_time_abs(&nt_logout, u_logout);
2130                         
2131                         init_unk_info3(&ctr->info.inf3, nt_logout);
2132                         break;
2133                 case 0x05:
2134                         init_unk_info5(&ctr->info.inf5, global_myname());
2135                         break;
2136                 case 0x06:
2137                         init_unk_info6(&ctr->info.inf6);
2138                         break;
2139                 case 0x07:
2140                         init_unk_info7(&ctr->info.inf7);
2141                         break;
2142                 case 0x0c:
2143                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2144                         u_lock_duration = account_policy_temp;
2145
2146                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2147                         u_reset_time = account_policy_temp;
2148
2149                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2150                         lockout = account_policy_temp;
2151
2152                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2153                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2154         
2155                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2156                         break;
2157                 default:
2158                         return NT_STATUS_INVALID_INFO_CLASS;
2159                 }
2160         
2161         init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2162         
2163         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2164         
2165         return r_u->status;
2166 }
2167
2168 /*******************************************************************
2169  _api_samr_create_user
2170  Create an account, can be either a normal user or a machine.
2171  This funcion will need to be updated for bdc/domain trusts.
2172  ********************************************************************/
2173
2174 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2175 {
2176         SAM_ACCOUNT *sam_pass=NULL;
2177         fstring account;
2178         DOM_SID sid;
2179         pstring add_script;
2180         POLICY_HND dom_pol = q_u->domain_pol;
2181         UNISTR2 user_account = q_u->uni_name;
2182         uint16 acb_info = q_u->acb_info;
2183         POLICY_HND *user_pol = &r_u->user_pol;
2184         struct samr_info *info = NULL;
2185         BOOL ret;
2186         NTSTATUS nt_status;
2187         struct passwd *pw;
2188         uint32 acc_granted;
2189         SEC_DESC *psd;
2190         size_t    sd_size;
2191         uint32    des_access;
2192
2193         /* Get the domain SID stored in the domain policy */
2194         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2195                 return NT_STATUS_INVALID_HANDLE;
2196
2197         if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2198                 return nt_status;
2199         }
2200
2201         /* find the account: tell the caller if it exists.
2202           lkclXXXX i have *no* idea if this is a problem or not
2203           or even if you are supposed to construct a different
2204           reply if the account already exists...
2205          */
2206
2207         rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2208         strlower(account);
2209
2210         pdb_init_sam(&sam_pass);
2211
2212         become_root();
2213         ret = pdb_getsampwnam(sam_pass, account);
2214         unbecome_root();
2215         if (ret == True) {
2216                 /* this account exists: say so */
2217                 pdb_free_sam(&sam_pass);
2218                 return NT_STATUS_USER_EXISTS;
2219         }
2220
2221         pdb_free_sam(&sam_pass);
2222
2223         /*
2224          * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2225          * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2226          * that only people with write access to the smbpasswd file will be able
2227          * to create a user. JRA.
2228          */
2229
2230         /*
2231          * add the user in the /etc/passwd file or the unix authority system.
2232          * We don't check if the smb_create_user() function succed or not for 2 reasons:
2233          * a) local_password_change() checks for us if the /etc/passwd account really exists
2234          * b) smb_create_user() would return an error if the account already exists
2235          * and as it could return an error also if it can't create the account, it would be tricky.
2236          *
2237          * So we go the easy way, only check after if the account exists.
2238          * JFM (2/3/2001), to clear any possible bad understanding (-:
2239          *
2240          * We now have seperate script paramaters for adding users/machines so we
2241          * now have some sainity-checking to match. 
2242          */
2243
2244         DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2245 #if 0
2246         if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2247                 pstrcpy(add_script, lp_addmachine_script());            
2248         } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2249                 pstrcpy(add_script, lp_adduser_script());
2250         } else {
2251                 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2252                 pdb_free_sam(&sam_pass);
2253                 return NT_STATUS_UNSUCCESSFUL;
2254         }
2255 #endif
2256
2257         /* 
2258          * we can't check both the ending $ and the acb_info.
2259          * 
2260          * UserManager creates trust accounts (ending in $,
2261          * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2262          * JFM, 11/29/2001
2263          */
2264         if (account[strlen(account)-1] == '$')
2265                 pstrcpy(add_script, lp_addmachine_script());            
2266         else 
2267                 pstrcpy(add_script, lp_adduser_script());
2268
2269         if (*add_script) {
2270                 int add_ret;
2271                 all_string_sub(add_script, "%u", account, sizeof(account));
2272                 add_ret = smbrun(add_script,NULL);
2273                 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2274         }
2275         
2276         pw = getpwnam_alloc(account);
2277
2278         if (pw) {
2279                 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sam_pass, pw))) {
2280                         passwd_free(&pw);
2281                         return nt_status;
2282                 }
2283                 passwd_free(&pw); /* done with this now */
2284         } else {
2285                 DEBUG(3,("attempting to create non-unix account %s\n", account));
2286                 
2287                 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sam_pass))) {
2288                         return nt_status;
2289                 }
2290                 
2291                 if (!pdb_set_username(sam_pass, account, PDB_CHANGED)) {
2292                         pdb_free_sam(&sam_pass);
2293                         return NT_STATUS_NO_MEMORY;
2294                 }
2295         }
2296
2297         pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2298  
2299         if (!pdb_add_sam_account(sam_pass)) {
2300                 pdb_free_sam(&sam_pass);
2301                 DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n", 
2302                           account));
2303                 return NT_STATUS_ACCESS_DENIED;         
2304         }
2305
2306         pdb_reset_sam(sam_pass);
2307         
2308         if (!pdb_getsampwnam(sam_pass, account)) {
2309                 pdb_free_sam(&sam_pass);
2310                 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n", 
2311                           account));
2312                 return NT_STATUS_ACCESS_DENIED;         
2313         }
2314         
2315         /* Get the user's SID */
2316         sid_copy(&sid, pdb_get_user_sid(sam_pass));
2317         
2318         samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2319         se_map_generic(&des_access, &usr_generic_mapping);
2320         if (!NT_STATUS_IS_OK(nt_status = 
2321                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2322                                                       des_access, &acc_granted, "_samr_create_user"))) {
2323                 return nt_status;
2324         }
2325
2326         /* associate the user's SID with the new handle. */
2327         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2328                 pdb_free_sam(&sam_pass);
2329                 return NT_STATUS_NO_MEMORY;
2330         }
2331
2332         ZERO_STRUCTP(info);
2333         info->sid = sid;
2334         info->acc_granted = acc_granted;
2335
2336         /* get a (unique) handle.  open a policy on it. */
2337         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2338                 pdb_free_sam(&sam_pass);
2339                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2340         }
2341
2342         r_u->user_rid=pdb_get_user_rid(sam_pass);
2343
2344         r_u->access_granted = acc_granted;
2345
2346         pdb_free_sam(&sam_pass);
2347
2348         return NT_STATUS_OK;
2349 }
2350
2351 /*******************************************************************
2352  samr_reply_connect_anon
2353  ********************************************************************/
2354
2355 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2356 {
2357         struct samr_info *info = NULL;
2358
2359         /* Access check */
2360
2361         if (!pipe_access_check(p)) {
2362                 DEBUG(3, ("access denied to samr_connect_anon\n"));
2363                 r_u->status = NT_STATUS_ACCESS_DENIED;
2364                 return r_u->status;
2365         }
2366
2367         /* set up the SAMR connect_anon response */
2368
2369         r_u->status = NT_STATUS_OK;
2370
2371         /* associate the user's SID with the new handle. */
2372         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2373                 return NT_STATUS_NO_MEMORY;
2374
2375         info->status = q_u->unknown_0;
2376
2377         /* get a (unique) handle.  open a policy on it. */
2378         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2379                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2380
2381         return r_u->status;
2382 }
2383
2384 /*******************************************************************
2385  samr_reply_connect
2386  ********************************************************************/
2387
2388 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2389 {
2390         struct samr_info *info = NULL;
2391         SEC_DESC *psd = NULL;
2392         uint32    acc_granted;
2393         uint32    des_access = q_u->access_mask;
2394         size_t    sd_size;
2395         NTSTATUS  nt_status;
2396
2397
2398         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2399
2400         /* Access check */
2401
2402         if (!pipe_access_check(p)) {
2403                 DEBUG(3, ("access denied to samr_connect\n"));
2404                 r_u->status = NT_STATUS_ACCESS_DENIED;
2405                 return r_u->status;
2406         }
2407
2408         samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2409         se_map_generic(&des_access, &sam_generic_mapping);
2410         if (!NT_STATUS_IS_OK(nt_status = 
2411                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2412                                                       des_access, &acc_granted, "_samr_connect"))) {
2413                 return nt_status;
2414         }
2415
2416         r_u->status = NT_STATUS_OK;
2417
2418         /* associate the user's SID and access granted with the new handle. */
2419         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2420                 return NT_STATUS_NO_MEMORY;
2421
2422         info->acc_granted = acc_granted;
2423         info->status = q_u->access_mask;
2424
2425         /* get a (unique) handle.  open a policy on it. */
2426         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2427                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2428
2429         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2430
2431         return r_u->status;
2432 }
2433
2434 /*******************************************************************
2435  samr_connect4
2436  ********************************************************************/
2437
2438 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2439 {
2440         struct samr_info *info = NULL;
2441         SEC_DESC *psd = NULL;
2442         uint32    acc_granted;
2443         uint32    des_access = q_u->access_mask;
2444         size_t    sd_size;
2445         NTSTATUS  nt_status;
2446
2447
2448         DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2449
2450         /* Access check */
2451
2452         if (!pipe_access_check(p)) {
2453                 DEBUG(3, ("access denied to samr_connect4\n"));
2454                 r_u->status = NT_STATUS_ACCESS_DENIED;
2455                 return r_u->status;
2456         }
2457
2458         samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2459         se_map_generic(&des_access, &sam_generic_mapping);
2460         if (!NT_STATUS_IS_OK(nt_status = 
2461                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2462                                                       des_access, &acc_granted, "_samr_connect"))) {
2463                 return nt_status;
2464         }
2465
2466         r_u->status = NT_STATUS_OK;
2467
2468         /* associate the user's SID and access granted with the new handle. */
2469         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2470                 return NT_STATUS_NO_MEMORY;
2471
2472         info->acc_granted = acc_granted;
2473         info->status = q_u->access_mask;
2474
2475         /* get a (unique) handle.  open a policy on it. */
2476         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2477                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2478
2479         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2480
2481         return r_u->status;
2482 }
2483
2484 /**********************************************************************
2485  api_samr_lookup_domain
2486  **********************************************************************/
2487
2488 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2489 {
2490         struct samr_info *info;
2491         fstring domain_name;
2492         DOM_SID sid;
2493
2494         r_u->status = NT_STATUS_OK;
2495
2496         if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2497                 return NT_STATUS_INVALID_HANDLE;
2498
2499         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2500                 return r_u->status;
2501         }
2502
2503         rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2504
2505         ZERO_STRUCT(sid);
2506
2507         if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2508                 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2509         }
2510
2511         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2512
2513         init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2514
2515         return r_u->status;
2516 }
2517
2518 /******************************************************************
2519 makes a SAMR_R_ENUM_DOMAINS structure.
2520 ********************************************************************/
2521
2522 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2523                         UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2524 {
2525         uint32 i;
2526         SAM_ENTRY *sam;
2527         UNISTR2 *uni_name;
2528
2529         DEBUG(5, ("make_enum_domains\n"));
2530
2531         *pp_sam = NULL;
2532         *pp_uni_name = NULL;
2533
2534         if (num_sam_entries == 0)
2535                 return True;
2536
2537         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2538         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2539
2540         if (sam == NULL || uni_name == NULL)
2541                 return False;
2542
2543         for (i = 0; i < num_sam_entries; i++) {
2544                 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2545
2546                 init_sam_entry(&sam[i], len, 0);
2547                 init_unistr2(&uni_name[i], doms[i], len);
2548         }
2549
2550         *pp_sam = sam;
2551         *pp_uni_name = uni_name;
2552
2553         return True;
2554 }
2555
2556 /**********************************************************************
2557  api_samr_enum_domains
2558  **********************************************************************/
2559
2560 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2561 {
2562         struct samr_info *info;
2563         uint32 num_entries = 2;
2564         fstring dom[2];
2565         const char *name;
2566
2567         r_u->status = NT_STATUS_OK;
2568         
2569         if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2570                 return NT_STATUS_INVALID_HANDLE;
2571         
2572         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2573                 return r_u->status;
2574         }
2575
2576         switch (lp_server_role()) {
2577         case ROLE_DOMAIN_PDC:
2578         case ROLE_DOMAIN_BDC:
2579                 name = lp_workgroup();
2580                 break;
2581         default:
2582                 name = global_myname();
2583         }
2584
2585         fstrcpy(dom[0],name);
2586         strupper(dom[0]);
2587         fstrcpy(dom[1],"Builtin");
2588
2589         if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2590                 return NT_STATUS_NO_MEMORY;
2591
2592         init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2593
2594         return r_u->status;
2595 }
2596
2597 /*******************************************************************
2598  api_samr_open_alias
2599  ********************************************************************/
2600
2601 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2602 {
2603         DOM_SID sid;
2604         POLICY_HND domain_pol = q_u->dom_pol;
2605         uint32 alias_rid = q_u->rid_alias;
2606         POLICY_HND *alias_pol = &r_u->pol;
2607         struct    samr_info *info = NULL;
2608         SEC_DESC *psd = NULL;
2609         uint32    acc_granted;
2610         uint32    des_access = q_u->access_mask;
2611         size_t    sd_size;
2612         NTSTATUS  status;
2613
2614         r_u->status = NT_STATUS_OK;
2615
2616         /* find the domain policy and get the SID / access bits stored in the domain policy */
2617         if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2618                 return NT_STATUS_INVALID_HANDLE;
2619                 
2620         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2621                 return status;
2622         }
2623
2624         /* append the alias' RID to it */
2625         if (!sid_append_rid(&sid, alias_rid))
2626                 return NT_STATUS_NO_SUCH_USER;
2627                 
2628         /*check if access can be granted as requested by client. */
2629         samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2630         se_map_generic(&des_access,&ali_generic_mapping);
2631         if (!NT_STATUS_IS_OK(status = 
2632                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2633                                                       des_access, &acc_granted, "_samr_open_alias"))) {
2634                 return status;
2635         }
2636
2637         /*
2638          * we should check if the rid really exist !!!
2639          * JFM.
2640          */
2641
2642         /* associate the user's SID with the new handle. */
2643         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2644                 return NT_STATUS_NO_MEMORY;
2645                 
2646         info->acc_granted = acc_granted;
2647
2648         /* get a (unique) handle.  open a policy on it. */
2649         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2650                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2651
2652         return r_u->status;
2653 }
2654
2655 /*******************************************************************
2656  set_user_info_10
2657  ********************************************************************/
2658
2659 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2660 {
2661         SAM_ACCOUNT *pwd =NULL;
2662         BOOL ret;
2663         
2664         pdb_init_sam(&pwd);
2665         
2666         ret = pdb_getsampwsid(pwd, sid);
2667         
2668         if(ret==False) {
2669                 pdb_free_sam(&pwd);
2670                 return False;
2671         }
2672
2673         if (id10 == NULL) {
2674                 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2675                 pdb_free_sam(&pwd);
2676                 return False;
2677         }
2678         
2679         /* FIX ME: check if the value is really changed --metze */
2680         if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2681                 pdb_free_sam(&pwd);
2682                 return False;
2683         }
2684
2685         if(!pdb_update_sam_account(pwd)) {
2686                 pdb_free_sam(&pwd);
2687                 return False;
2688         }
2689
2690         pdb_free_sam(&pwd);
2691
2692         return True;
2693 }
2694
2695 /*******************************************************************
2696  set_user_info_12
2697  ********************************************************************/
2698
2699 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2700 {
2701         SAM_ACCOUNT *pwd = NULL;
2702
2703         pdb_init_sam(&pwd);
2704
2705         if(!pdb_getsampwsid(pwd, sid)) {
2706                 pdb_free_sam(&pwd);
2707                 return False;
2708         }
2709
2710         if (id12 == NULL) {
2711                 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2712                 pdb_free_sam(&pwd);
2713                 return False;
2714         }
2715  
2716         if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2717                 pdb_free_sam(&pwd);
2718                 return False;
2719         }
2720         if (!pdb_set_nt_passwd     (pwd, id12->nt_pwd, PDB_CHANGED)) {
2721                 pdb_free_sam(&pwd);
2722                 return False;
2723         }
2724         if (!pdb_set_pass_changed_now (pwd)) {
2725                 pdb_free_sam(&pwd);
2726                 return False; 
2727         }
2728  
2729         if(!pdb_update_sam_account(pwd)) {
2730                 pdb_free_sam(&pwd);
2731                 return False;
2732         }
2733
2734         pdb_free_sam(&pwd);
2735         return True;
2736 }
2737
2738 /*******************************************************************
2739  set_user_info_21
2740  ********************************************************************/
2741
2742 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2743 {
2744         SAM_ACCOUNT *pwd = NULL;
2745  
2746         if (id21 == NULL) {
2747                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2748                 return False;
2749         }
2750  
2751         pdb_init_sam(&pwd);
2752  
2753         if (!pdb_getsampwsid(pwd, sid)) {
2754                 pdb_free_sam(&pwd);
2755                 return False;
2756         }
2757  
2758         copy_id21_to_sam_passwd(pwd, id21);
2759  
2760         /*
2761          * The funny part about the previous two calls is
2762          * that pwd still has the password hashes from the
2763          * passdb entry.  These have not been updated from
2764          * id21.  I don't know if they need to be set.    --jerry
2765          */
2766  
2767         /* write the change out */
2768         if(!pdb_update_sam_account(pwd)) {
2769                 pdb_free_sam(&pwd);
2770                 return False;
2771         }
2772
2773         pdb_free_sam(&pwd);
2774
2775         return True;
2776 }
2777
2778 /*******************************************************************
2779  set_user_info_23
2780  ********************************************************************/
2781
2782 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2783 {
2784         SAM_ACCOUNT *pwd = NULL;
2785         pstring plaintext_buf;
2786         uint32 len;
2787         uint16 acct_ctrl;
2788  
2789         if (id23 == NULL) {
2790                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2791                 return False;
2792         }
2793  
2794         pdb_init_sam(&pwd);
2795  
2796         if (!pdb_getsampwsid(pwd, sid)) {
2797                 pdb_free_sam(&pwd);
2798                 return False;
2799         }
2800
2801         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2802                   pdb_get_username(pwd)));
2803
2804         acct_ctrl = pdb_get_acct_ctrl(pwd);
2805
2806         if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2807                 pdb_free_sam(&pwd);
2808                 return False;
2809         }
2810   
2811         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2812                 pdb_free_sam(&pwd);
2813                 return False;
2814         }
2815  
2816         copy_id23_to_sam_passwd(pwd, id23);
2817  
2818         /* if it's a trust account, don't update /etc/passwd */
2819         if ( (!IS_SAM_UNIX_USER(pwd)) ||
2820                 ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2821                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2822                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2823                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2824         } else  {
2825                 /* update the UNIX password */
2826                 if (lp_unix_password_sync() )
2827                         if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2828                                 pdb_free_sam(&pwd);
2829                                 return False;
2830                         }
2831         }
2832  
2833         ZERO_STRUCT(plaintext_buf);
2834  
2835         if(!pdb_update_sam_account(pwd)) {
2836                 pdb_free_sam(&pwd);
2837                 return False;
2838         }
2839  
2840         pdb_free_sam(&pwd);
2841
2842         return True;
2843 }
2844
2845 /*******************************************************************
2846  set_user_info_pw
2847  ********************************************************************/
2848
2849 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2850 {
2851         SAM_ACCOUNT *pwd = NULL;
2852         uint32 len;
2853         pstring plaintext_buf;
2854         uint16 acct_ctrl;
2855  
2856         pdb_init_sam(&pwd);
2857  
2858         if (!pdb_getsampwsid(pwd, sid)) {
2859                 pdb_free_sam(&pwd);
2860                 return False;
2861         }
2862         
2863         DEBUG(5, ("Attempting administrator password change for user %s\n",
2864                   pdb_get_username(pwd)));
2865
2866         acct_ctrl = pdb_get_acct_ctrl(pwd);
2867
2868         ZERO_STRUCT(plaintext_buf);
2869  
2870         if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2871                 pdb_free_sam(&pwd);
2872                 return False;
2873         }
2874
2875         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2876                 pdb_free_sam(&pwd);
2877                 return False;
2878         }
2879  
2880         /* if it's a trust account, don't update /etc/passwd */
2881         if ( (!IS_SAM_UNIX_USER(pwd)) ||
2882                 ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2883                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2884                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2885                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2886         } else {
2887                 /* update the UNIX password */
2888                 if (lp_unix_password_sync()) {
2889                         if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2890                                 pdb_free_sam(&pwd);
2891                                 return False;
2892                         }
2893                 }
2894         }
2895  
2896         ZERO_STRUCT(plaintext_buf);
2897  
2898         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2899  
2900         /* update the SAMBA password */
2901         if(!pdb_update_sam_account(pwd)) {
2902                 pdb_free_sam(&pwd);
2903                 return False;
2904         }
2905
2906         pdb_free_sam(&pwd);
2907
2908         return True;
2909 }
2910
2911 /*******************************************************************
2912  samr_reply_set_userinfo
2913  ********************************************************************/
2914
2915 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2916 {
2917         DOM_SID sid;
2918         POLICY_HND *pol = &q_u->pol;
2919         uint16 switch_value = q_u->switch_value;
2920         SAM_USERINFO_CTR *ctr = q_u->ctr;
2921         uint32 acc_granted;
2922         uint32 acc_required;
2923
2924         DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2925
2926         r_u->status = NT_STATUS_OK;
2927
2928         /* find the policy handle.  open a policy on it. */
2929         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2930                 return NT_STATUS_INVALID_HANDLE;
2931         
2932         acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */   
2933         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2934                 return r_u->status;
2935         }
2936                 
2937         DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2938
2939         if (ctr == NULL) {
2940                 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2941                 return NT_STATUS_INVALID_INFO_CLASS;
2942         }
2943
2944         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2945         switch (switch_value) {
2946                 case 0x12:
2947                         if (!set_user_info_12(ctr->info.id12, &sid))
2948                                 return NT_STATUS_ACCESS_DENIED;
2949                         break;
2950
2951                 case 24:
2952                         SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2953
2954                         dump_data(100, (char *)ctr->info.id24->pass, 516);
2955
2956                         if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2957                                 return NT_STATUS_ACCESS_DENIED;
2958                         break;
2959
2960                 case 25:
2961 #if 0
2962                         /*
2963                          * Currently we don't really know how to unmarshall
2964                          * the level 25 struct, and the password encryption
2965                          * is different. This is a placeholder for when we
2966                          * do understand it. In the meantime just return INVALID
2967                          * info level and W2K SP2 drops down to level 23... JRA.
2968                          */
2969
2970                         SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
2971
2972                         dump_data(100, (char *)ctr->info.id25->pass, 532);
2973
2974                         if (!set_user_info_pw(ctr->info.id25->pass, &sid))
2975                                 return NT_STATUS_ACCESS_DENIED;
2976                         break;
2977 #endif
2978                         return NT_STATUS_INVALID_INFO_CLASS;
2979
2980                 case 23:
2981                         SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
2982
2983                         dump_data(100, (char *)ctr->info.id23->pass, 516);
2984
2985                         if (!set_user_info_23(ctr->info.id23, &sid))
2986                                 return NT_STATUS_ACCESS_DENIED;
2987                         break;
2988
2989                 default:
2990                         return NT_STATUS_INVALID_INFO_CLASS;
2991         }
2992
2993         return r_u->status;
2994 }
2995
2996 /*******************************************************************
2997  samr_reply_set_userinfo2
2998  ********************************************************************/
2999
3000 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3001 {
3002         DOM_SID sid;
3003         SAM_USERINFO_CTR *ctr = q_u->ctr;
3004         POLICY_HND *pol = &q_u->pol;
3005         uint16 switch_value = q_u->switch_value;
3006         uint32 acc_granted;
3007         uint32 acc_required;
3008
3009         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3010
3011         r_u->status = NT_STATUS_OK;
3012
3013         /* find the policy handle.  open a policy on it. */
3014         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3015                 return NT_STATUS_INVALID_HANDLE;
3016         
3017         acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */   
3018         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3019                 return r_u->status;
3020         }
3021
3022         DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3023
3024         if (ctr == NULL) {
3025                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3026                 return NT_STATUS_INVALID_INFO_CLASS;
3027         }
3028
3029         switch_value=ctr->switch_value;
3030
3031         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3032         switch (switch_value) {
3033                 case 21:
3034                         if (!set_user_info_21(ctr->info.id21, &sid))
3035                                 return NT_STATUS_ACCESS_DENIED;
3036                         break;
3037                 case 16:
3038                         if (!set_user_info_10(ctr->info.id10, &sid))
3039                                 return NT_STATUS_ACCESS_DENIED;
3040                         break;
3041                 case 18:
3042                         /* Used by AS/U JRA. */
3043                         if (!set_user_info_12(ctr->info.id12, &sid))
3044                                 return NT_STATUS_ACCESS_DENIED;
3045                         break;
3046                 default:
3047                         return NT_STATUS_INVALID_INFO_CLASS;
3048         }
3049
3050         return r_u->status;
3051 }
3052
3053 /*********************************************************************
3054  _samr_query_aliasmem
3055 *********************************************************************/
3056
3057 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3058 {
3059         int num_groups = 0, tmp_num_groups=0;
3060         uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3061         struct samr_info *info = NULL;
3062         int i,j;
3063                 
3064         NTSTATUS ntstatus1;
3065         NTSTATUS ntstatus2;
3066
3067         /* until i see a real useraliases query, we fack one up */
3068
3069         /* I have seen one, JFM 2/12/2001 */
3070         /*
3071          * Explanation of what this call does:
3072          * for all the SID given in the request:
3073          * return a list of alias (local groups)
3074          * that have those SID as members.
3075          *
3076          * and that's the alias in the domain specified
3077          * in the policy_handle
3078          *
3079          * if the policy handle is on an incorrect sid
3080          * for example a user's sid
3081          * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3082          */
3083         
3084         r_u->status = NT_STATUS_OK;
3085
3086         DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3087
3088         /* find the policy handle.  open a policy on it. */
3089         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3090                 return NT_STATUS_INVALID_HANDLE;
3091                 
3092         ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3093         ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3094         
3095         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3096                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3097                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3098                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3099                 }
3100         }               
3101
3102         if (!sid_check_is_domain(&info->sid) &&
3103             !sid_check_is_builtin(&info->sid))
3104                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3105
3106
3107         for (i=0; i<q_u->num_sids1; i++) {
3108
3109                 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3110
3111                 /*
3112                  * if there is an error, we just continue as
3113                  * it can be an unfound user or group
3114                  */
3115                 if (!NT_STATUS_IS_OK(r_u->status)) {
3116                         DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3117                         continue;
3118                 }
3119
3120                 if (tmp_num_groups==0) {
3121                         DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3122                         continue;
3123                 }
3124
3125                 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3126                 if (new_rids==NULL) {
3127                         DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3128                         return NT_STATUS_NO_MEMORY;
3129                 }
3130                 rids=new_rids;
3131
3132                 for (j=0; j<tmp_num_groups; j++)
3133                         rids[j+num_groups]=tmp_rids[j];
3134                 
3135                 safe_free(tmp_rids);
3136                 
3137                 num_groups+=tmp_num_groups;
3138         }
3139         
3140         init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3141         return NT_STATUS_OK;
3142 }
3143
3144 /*********************************************************************
3145  _samr_query_aliasmem
3146 *********************************************************************/
3147
3148 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3149 {
3150         int i;
3151
3152         GROUP_MAP map;
3153         int num_uids = 0;
3154         DOM_SID2 *sid;
3155         uid_t *uid=NULL;
3156
3157         DOM_SID alias_sid;
3158         DOM_SID als_sid;
3159         uint32 alias_rid;
3160         fstring alias_sid_str;
3161         DOM_SID temp_sid;
3162
3163         SAM_ACCOUNT *sam_user = NULL;
3164         BOOL check;
3165         uint32 acc_granted;
3166
3167         /* find the policy handle.  open a policy on it. */
3168         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3169                 return NT_STATUS_INVALID_HANDLE;
3170         
3171         if (!NT_STATUS_IS_OK(r_u->status = 
3172                 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3173                 return r_u->status;
3174         }
3175                 
3176         sid_copy(&als_sid, &alias_sid);
3177         sid_to_string(alias_sid_str, &alias_sid);
3178         sid_split_rid(&alias_sid, &alias_rid);
3179
3180         DEBUG(10, ("sid is %s\n", alias_sid_str));
3181
3182         if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3183                 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3184                 if(!get_builtin_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3185                         return NT_STATUS_NO_SUCH_ALIAS;
3186         } else {
3187                 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3188                         DEBUG(10, ("lookup on Server SID\n"));
3189                         if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3190                                 return NT_STATUS_NO_SUCH_ALIAS;
3191                 }
3192         }
3193
3194         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3195                 return NT_STATUS_NO_SUCH_ALIAS;
3196
3197         DEBUG(10, ("sid is %s\n", alias_sid_str));
3198         sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids); 
3199         if (num_uids!=0 && sid == NULL) 
3200                 return NT_STATUS_NO_MEMORY;
3201
3202         for (i = 0; i < num_uids; i++) {
3203                 struct passwd *pass;
3204                 uint32 rid;
3205
3206                 sid_copy(&temp_sid, get_global_sam_sid());
3207
3208                 pass = getpwuid_alloc(uid[i]);
3209                 if (!pass) continue;
3210
3211                 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3212                         passwd_free(&pass);
3213                         continue;
3214                 }
3215
3216                 become_root();
3217                 check = pdb_getsampwnam(sam_user, pass->pw_name);
3218                 unbecome_root();
3219         
3220                 if (check != True) {
3221                         pdb_free_sam(&sam_user);
3222                         passwd_free(&pass);
3223                         continue;
3224                 }
3225         
3226                 rid = pdb_get_user_rid(sam_user);
3227                 if (rid == 0) {
3228                         pdb_free_sam(&sam_user);
3229                         passwd_free(&pass);
3230                         continue;
3231                 }
3232
3233                 pdb_free_sam(&sam_user);
3234                 passwd_free(&pass);
3235
3236                 sid_append_rid(&temp_sid, rid);
3237                 
3238                 init_dom_sid2(&sid[i], &temp_sid);
3239         }
3240
3241         DEBUG(10, ("sid is %s\n", alias_sid_str));
3242         init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3243
3244         return NT_STATUS_OK;
3245 }
3246
3247 /*********************************************************************
3248  _samr_query_groupmem
3249 *********************************************************************/
3250
3251 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3252 {
3253         int num_uids = 0;
3254         int i;
3255         DOM_SID group_sid;
3256         uint32 group_rid;
3257         fstring group_sid_str;
3258         uid_t *uid=NULL;
3259         
3260         GROUP_MAP map;
3261
3262         uint32 *rid=NULL;
3263         uint32 *attr=NULL;
3264
3265         SAM_ACCOUNT *sam_user = NULL;
3266         BOOL check;
3267         uint32 acc_granted;
3268
3269         /* find the policy handle.  open a policy on it. */
3270         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3271                 return NT_STATUS_INVALID_HANDLE;
3272                 
3273         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3274                 return r_u->status;
3275         }
3276                 
3277         /* todo: change to use sid_compare_front */
3278
3279         sid_split_rid(&group_sid, &group_rid);
3280         sid_to_string(group_sid_str, &group_sid);
3281         DEBUG(10, ("sid is %s\n", group_sid_str));
3282
3283         /* can we get a query for an SID outside our domain ? */
3284         if (!sid_equal(&group_sid, get_global_sam_sid()))
3285                 return NT_STATUS_NO_SUCH_GROUP;
3286
3287         sid_append_rid(&group_sid, group_rid);
3288         DEBUG(10, ("lookup on Domain SID\n"));
3289
3290         if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3291                 return NT_STATUS_NO_SUCH_GROUP;
3292
3293         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3294                 return NT_STATUS_NO_SUCH_GROUP;
3295
3296         rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3297         attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3298         
3299         if (num_uids!=0 && (rid==NULL || attr==NULL))
3300                 return NT_STATUS_NO_MEMORY;
3301         
3302         for (i=0; i<num_uids; i++) {
3303                 struct passwd *pass;
3304                 uint32 urid;
3305
3306                 pass = getpwuid_alloc(uid[i]);
3307                 if (!pass) continue;
3308
3309                 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3310                         passwd_free(&pass);
3311                         continue;
3312                 }
3313
3314                 become_root();
3315                 check = pdb_getsampwnam(sam_user, pass->pw_name);
3316                 unbecome_root();
3317         
3318                 if (check != True) {
3319                         pdb_free_sam(&sam_user);
3320                         passwd_free(&pass);
3321                         continue;
3322                 }
3323         
3324                 urid = pdb_get_user_rid(sam_user);
3325                 if (urid == 0) {
3326                         pdb_free_sam(&sam_user);
3327                         passwd_free(&pass);
3328                         continue;
3329                 }
3330
3331                 pdb_free_sam(&sam_user);
3332                 passwd_free(&pass);
3333
3334                 rid[i] = urid;
3335                 attr[i] = SID_NAME_USER;                
3336         }
3337
3338         init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3339
3340         return NT_STATUS_OK;
3341 }
3342
3343 /*********************************************************************
3344  _samr_add_aliasmem
3345 *********************************************************************/
3346
3347 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3348 {
3349         DOM_SID alias_sid;
3350         fstring alias_sid_str;
3351         uid_t uid;
3352         struct passwd *pwd;
3353         struct group *grp;
3354         fstring grp_name;
3355         GROUP_MAP map;
3356         NTSTATUS ret;
3357         SAM_ACCOUNT *sam_user = NULL;
3358         BOOL check;
3359         uint32 acc_granted;
3360
3361         /* Find the policy handle. Open a policy on it. */
3362         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3363                 return NT_STATUS_INVALID_HANDLE;
3364         
3365         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3366                 return r_u->status;
3367         }
3368                 
3369         sid_to_string(alias_sid_str, &alias_sid);
3370         DEBUG(10, ("sid is %s\n", alias_sid_str));
3371
3372         if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3373                 DEBUG(10, ("adding member on Server SID\n"));
3374                 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3375                         return NT_STATUS_NO_SUCH_ALIAS;
3376         
3377         } else {
3378                 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3379                         DEBUG(10, ("adding member on BUILTIN SID\n"));
3380                         if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3381                                 return NT_STATUS_NO_SUCH_ALIAS;
3382
3383                 } else
3384                         return NT_STATUS_NO_SUCH_ALIAS;
3385         }
3386
3387         ret = pdb_init_sam(&sam_user);
3388         if (!NT_STATUS_IS_OK(ret))
3389                 return ret;
3390         
3391         check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3392         
3393         if (check != True) {
3394                 pdb_free_sam(&sam_user);
3395                 return NT_STATUS_NO_SUCH_USER;
3396         }
3397         
3398         uid = pdb_get_uid(sam_user);
3399         if (uid == -1) {
3400                 pdb_free_sam(&sam_user);
3401                 return NT_STATUS_NO_SUCH_USER;
3402         }
3403
3404         pdb_free_sam(&sam_user);
3405
3406         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3407                 return NT_STATUS_NO_SUCH_USER;
3408         }
3409
3410         if ((grp=getgrgid(map.gid)) == NULL) {
3411                 passwd_free(&pwd);
3412                 return NT_STATUS_NO_SUCH_ALIAS;
3413         }
3414
3415         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3416         fstrcpy(grp_name, grp->gr_name);
3417
3418         /* if the user is already in the group */
3419         if(user_in_group_list(pwd->pw_name, grp_name)) {
3420                 passwd_free(&pwd);
3421                 return NT_STATUS_MEMBER_IN_ALIAS;
3422         }
3423
3424         /* 
3425          * ok, the group exist, the user exist, the user is not in the group,
3426          * we can (finally) add it to the group !
3427          */
3428         smb_add_user_group(grp_name, pwd->pw_name);
3429
3430         /* check if the user has been added then ... */
3431         if(!user_in_group_list(pwd->pw_name, grp_name)) {
3432                 passwd_free(&pwd);
3433                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3434         }
3435
3436         passwd_free(&pwd);
3437         return NT_STATUS_OK;
3438 }
3439
3440 /*********************************************************************
3441  _samr_del_aliasmem
3442 *********************************************************************/
3443
3444 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3445 {
3446         DOM_SID alias_sid;
3447         fstring alias_sid_str;
3448         struct group *grp;
3449         fstring grp_name;
3450         GROUP_MAP map;
3451         SAM_ACCOUNT *sam_pass=NULL;
3452         uint32 acc_granted;
3453
3454         /* Find the policy handle. Open a policy on it. */
3455         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3456                 return NT_STATUS_INVALID_HANDLE;
3457         
3458         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3459                 return r_u->status;
3460         }
3461         
3462         sid_to_string(alias_sid_str, &alias_sid);
3463         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3464
3465         if (!sid_check_is_in_our_domain(&alias_sid) &&
3466             !sid_check_is_in_builtin(&alias_sid)) {
3467                 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3468                 return NT_STATUS_NO_SUCH_ALIAS;
3469         }
3470
3471         if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3472                 return NT_STATUS_NO_SUCH_ALIAS;
3473
3474         if ((grp=getgrgid(map.gid)) == NULL)
3475                 return NT_STATUS_NO_SUCH_ALIAS;
3476
3477         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3478         fstrcpy(grp_name, grp->gr_name);
3479
3480         /* check if the user exists before trying to remove it from the group */
3481         pdb_init_sam(&sam_pass);
3482         if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3483                 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3484                 pdb_free_sam(&sam_pass);
3485                 return NT_STATUS_NO_SUCH_USER;
3486         }
3487
3488         /* if the user is not in the group */
3489         if(!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3490                 pdb_free_sam(&sam_pass);
3491                 return NT_STATUS_MEMBER_IN_ALIAS;
3492         }
3493
3494         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3495
3496         /* check if the user has been removed then ... */
3497         if(user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3498                 pdb_free_sam(&sam_pass);
3499                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3500         }
3501
3502         pdb_free_sam(&sam_pass);
3503         return NT_STATUS_OK;
3504 }
3505
3506 /*********************************************************************
3507  _samr_add_groupmem
3508 *********************************************************************/
3509
3510 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3511 {
3512         DOM_SID group_sid;
3513         DOM_SID user_sid;
3514         fstring group_sid_str;
3515         struct passwd *pwd;
3516         struct group *grp;
3517         fstring grp_name;
3518         GROUP_MAP map;
3519         uid_t uid;
3520         NTSTATUS ret;
3521         SAM_ACCOUNT *sam_user=NULL;
3522         BOOL check;
3523         uint32 acc_granted;
3524
3525         /* Find the policy handle. Open a policy on it. */
3526         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3527                 return NT_STATUS_INVALID_HANDLE;
3528         
3529         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3530                 return r_u->status;
3531         }
3532
3533         sid_to_string(group_sid_str, &group_sid);
3534         DEBUG(10, ("sid is %s\n", group_sid_str));
3535
3536         if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3537                 return NT_STATUS_NO_SUCH_GROUP;
3538
3539         DEBUG(10, ("lookup on Domain SID\n"));
3540
3541         if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3542                 return NT_STATUS_NO_SUCH_GROUP;
3543
3544         sid_copy(&user_sid, get_global_sam_sid());
3545         sid_append_rid(&user_sid, q_u->rid);
3546
3547         ret = pdb_init_sam(&sam_user);
3548         if (!NT_STATUS_IS_OK(ret))
3549                 return ret;
3550         
3551         check = pdb_getsampwsid(sam_user, &user_sid);
3552         
3553         if (check != True) {
3554                 pdb_free_sam(&sam_user);
3555                 return NT_STATUS_NO_SUCH_USER;
3556         }
3557         
3558         uid = pdb_get_uid(sam_user);
3559         if (uid == -1) {
3560                 pdb_free_sam(&sam_user);
3561                 return NT_STATUS_NO_SUCH_USER;
3562         }
3563
3564         pdb_free_sam(&sam_user);
3565
3566         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3567                 return NT_STATUS_NO_SUCH_USER;
3568         }
3569
3570         if ((grp=getgrgid(map.gid)) == NULL) {
3571                 passwd_free(&pwd);
3572                 return NT_STATUS_NO_SUCH_GROUP;
3573         }
3574
3575         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3576         fstrcpy(grp_name, grp->gr_name);
3577
3578         /* if the user is already in the group */
3579         if(user_in_group_list(pwd->pw_name, grp_name)) {
3580                 passwd_free(&pwd);
3581                 return NT_STATUS_MEMBER_IN_GROUP;
3582         }
3583
3584         /* 
3585          * ok, the group exist, the user exist, the user is not in the group,
3586          *
3587          * we can (finally) add it to the group !
3588          */
3589
3590         smb_add_user_group(grp_name, pwd->pw_name);
3591
3592         /* check if the user has been added then ... */
3593         if(!user_in_group_list(pwd->pw_name, grp_name)) {
3594                 passwd_free(&pwd);
3595                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
3596         }
3597
3598         passwd_free(&pwd);
3599         return NT_STATUS_OK;
3600 }
3601
3602 /*********************************************************************
3603  _samr_del_groupmem
3604 *********************************************************************/
3605
3606 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3607 {
3608         DOM_SID group_sid;
3609         DOM_SID user_sid;
3610         SAM_ACCOUNT *sam_pass=NULL;
3611         GROUP_MAP map;
3612         fstring grp_name;
3613         struct group *grp;
3614         uint32 acc_granted;
3615
3616         /*
3617          * delete the group member named q_u->rid
3618          * who is a member of the sid associated with the handle
3619          * the rid is a user's rid as the group is a domain group.
3620          */
3621
3622         /* Find the policy handle. Open a policy on it. */
3623         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3624                 return NT_STATUS_INVALID_HANDLE;
3625         
3626         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3627                 return r_u->status;
3628         }
3629                 
3630         if (!sid_check_is_in_our_domain(&group_sid))
3631                 return NT_STATUS_NO_SUCH_GROUP;
3632
3633         sid_copy(&user_sid, get_global_sam_sid());
3634         sid_append_rid(&user_sid, q_u->rid);
3635
3636         if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3637                 return NT_STATUS_NO_SUCH_GROUP;
3638
3639         if ((grp=getgrgid(map.gid)) == NULL)
3640                 return NT_STATUS_NO_SUCH_GROUP;
3641
3642         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3643         fstrcpy(grp_name, grp->gr_name);
3644
3645         /* check if the user exists before trying to remove it from the group */
3646         pdb_init_sam(&sam_pass);
3647         if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3648                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3649                 pdb_free_sam(&sam_pass);
3650                 return NT_STATUS_NO_SUCH_USER;
3651         }
3652
3653         /* if the user is not in the group */
3654         if (!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3655                 pdb_free_sam(&sam_pass);
3656                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3657         }
3658
3659         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3660
3661         /* check if the user has been removed then ... */
3662         if (user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3663                 pdb_free_sam(&sam_pass);
3664                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3665         }
3666         
3667         pdb_free_sam(&sam_pass);
3668         return NT_STATUS_OK;
3669
3670 }
3671
3672 /****************************************************************************
3673  Delete a UNIX user on demand.
3674 ****************************************************************************/
3675
3676 static int smb_delete_user(const char *unix_user)
3677 {
3678         pstring del_script;
3679         int ret;
3680
3681         pstrcpy(del_script, lp_deluser_script());
3682         if (! *del_script)
3683                 return -1;
3684         all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3685         ret = smbrun(del_script,NULL);
3686         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3687         return ret;
3688 }
3689
3690 /*********************************************************************
3691  _samr_delete_dom_user
3692 *********************************************************************/
3693
3694 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3695 {
3696         DOM_SID user_sid;
3697         SAM_ACCOUNT *sam_pass=NULL;
3698         uint32 acc_granted;
3699
3700         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3701
3702         /* Find the policy handle. Open a policy on it. */
3703         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
3704                 return NT_STATUS_INVALID_HANDLE;
3705                 
3706         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3707                 return r_u->status;
3708         }
3709                 
3710         if (!sid_check_is_in_our_domain(&user_sid))
3711                 return NT_STATUS_CANNOT_DELETE;
3712
3713         /* check if the user exists before trying to delete */
3714         pdb_init_sam(&sam_pass);
3715         if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3716                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3717                 pdb_free_sam(&sam_pass);
3718                 return NT_STATUS_NO_SUCH_USER;
3719         }
3720
3721         /* delete the unix side */
3722         /*
3723          * note: we don't check if the delete really happened
3724          * as the script is not necessary present
3725          * and maybe the sysadmin doesn't want to delete the unix side
3726          */
3727         smb_delete_user(pdb_get_username(sam_pass));
3728
3729         /* and delete the samba side */
3730         if (!pdb_delete_sam_account(sam_pass)) {
3731                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3732                 pdb_free_sam(&sam_pass);
3733                 return NT_STATUS_CANNOT_DELETE;
3734         }
3735         
3736         pdb_free_sam(&sam_pass);
3737
3738         if (!close_policy_hnd(p, &q_u->user_pol))
3739                 return NT_STATUS_OBJECT_NAME_INVALID;
3740
3741         return NT_STATUS_OK;
3742 }
3743
3744 /*********************************************************************
3745  _samr_delete_dom_group
3746 *********************************************************************/
3747
3748 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3749 {
3750         DOM_SID group_sid;
3751         DOM_SID dom_sid;
3752         uint32 group_rid;
3753         fstring group_sid_str;
3754         gid_t gid;
3755         struct group *grp;
3756         GROUP_MAP map;
3757         uint32 acc_granted;
3758
3759         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3760
3761         /* Find the policy handle. Open a policy on it. */
3762         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3763                 return NT_STATUS_INVALID_HANDLE;
3764                 
3765         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3766                 return r_u->status;
3767         }
3768                 
3769         sid_copy(&dom_sid, &group_sid);
3770         sid_to_string(group_sid_str, &dom_sid);
3771         sid_split_rid(&dom_sid, &group_rid);
3772
3773         DEBUG(10, ("sid is %s\n", group_sid_str));
3774
3775         /* we check if it's our SID before deleting */
3776         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3777                 return NT_STATUS_NO_SUCH_GROUP;
3778
3779         DEBUG(10, ("lookup on Domain SID\n"));
3780
3781         if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3782                 return NT_STATUS_NO_SUCH_GROUP;
3783
3784         gid=map.gid;
3785
3786         /* check if group really exists */
3787         if ( (grp=getgrgid(gid)) == NULL)
3788                 return NT_STATUS_NO_SUCH_GROUP;
3789
3790         /* we can delete the UNIX group */
3791         smb_delete_group(grp->gr_name);
3792
3793         /* check if the group has been successfully deleted */
3794         if ( (grp=getgrgid(gid)) != NULL)
3795                 return NT_STATUS_ACCESS_DENIED;
3796
3797         if(!pdb_delete_group_mapping_entry(group_sid))
3798                 return NT_STATUS_ACCESS_DENIED;
3799
3800         if (!close_policy_hnd(p, &q_u->group_pol))
3801                 return NT_STATUS_OBJECT_NAME_INVALID;
3802
3803         return NT_STATUS_OK;
3804 }
3805
3806 /*********************************************************************
3807  _samr_delete_dom_alias
3808 *********************************************************************/
3809
3810 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3811 {
3812         DOM_SID alias_sid;
3813         DOM_SID dom_sid;
3814         uint32 alias_rid;
3815         fstring alias_sid_str;
3816         gid_t gid;
3817         struct group *grp;
3818         GROUP_MAP map;
3819         uint32 acc_granted;
3820
3821         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3822
3823         /* Find the policy handle. Open a policy on it. */
3824         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3825                 return NT_STATUS_INVALID_HANDLE;
3826         
3827         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3828                 return r_u->status;
3829         }
3830                 
3831         sid_copy(&dom_sid, &alias_sid);
3832         sid_to_string(alias_sid_str, &dom_sid);
3833         sid_split_rid(&dom_sid, &alias_rid);
3834
3835         DEBUG(10, ("sid is %s\n", alias_sid_str));
3836
3837         /* we check if it's our SID before deleting */
3838         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3839                 return NT_STATUS_NO_SUCH_ALIAS;
3840
3841         DEBUG(10, ("lookup on Local SID\n"));
3842
3843         if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3844                 return NT_STATUS_NO_SUCH_ALIAS;
3845
3846         gid=map.gid;
3847
3848         /* check if group really exists */
3849         if ( (grp=getgrgid(gid)) == NULL)
3850                 return NT_STATUS_NO_SUCH_ALIAS;
3851
3852         /* we can delete the UNIX group */
3853         smb_delete_group(grp->gr_name);
3854
3855         /* check if the group has been successfully deleted */
3856         if ( (grp=getgrgid(gid)) != NULL)
3857                 return NT_STATUS_ACCESS_DENIED;
3858
3859         /* don't check if we removed it as it could be an un-mapped group */
3860         pdb_delete_group_mapping_entry(alias_sid);
3861
3862         if (!close_policy_hnd(p, &q_u->alias_pol))
3863                 return NT_STATUS_OBJECT_NAME_INVALID;
3864
3865         return NT_STATUS_OK;
3866 }
3867
3868 /*********************************************************************
3869  _samr_create_dom_group
3870 *********************************************************************/
3871
3872 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3873 {
3874         DOM_SID dom_sid;
3875         DOM_SID info_sid;
3876         fstring name;
3877         fstring sid_string;
3878         struct group *grp;
3879         struct samr_info *info;
3880         PRIVILEGE_SET priv_set;
3881         uint32 acc_granted;
3882         gid_t gid;
3883
3884         init_privilege(&priv_set);
3885
3886         /* Find the policy handle. Open a policy on it. */
3887         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
3888                 return NT_STATUS_INVALID_HANDLE;
3889         
3890         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3891                 return r_u->status;
3892         }
3893                 
3894         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3895                 return NT_STATUS_ACCESS_DENIED;
3896
3897         /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3898
3899         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3900
3901         /* check if group already exist */
3902         if ((grp=getgrnam(name)) != NULL)
3903                 return NT_STATUS_GROUP_EXISTS;
3904
3905         /* we can create the UNIX group */
3906         if (smb_create_group(name, &gid) != 0)
3907                 return NT_STATUS_ACCESS_DENIED;
3908
3909         /* check if the group has been successfully created */
3910         if ((grp=getgrgid(gid)) == NULL)
3911                 return NT_STATUS_ACCESS_DENIED;
3912
3913         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3914
3915         /* add the group to the mapping table */
3916         sid_copy(&info_sid, get_global_sam_sid());
3917         sid_append_rid(&info_sid, r_u->rid);
3918         sid_to_string(sid_string, &info_sid);
3919
3920         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3921                 return NT_STATUS_ACCESS_DENIED;
3922
3923         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3924                 return NT_STATUS_NO_MEMORY;
3925
3926         /* get a (unique) handle.  open a policy on it. */
3927         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3928                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3929
3930         return NT_STATUS_OK;
3931 }
3932
3933 /*********************************************************************
3934  _samr_create_dom_alias
3935 *********************************************************************/
3936
3937 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3938 {
3939         DOM_SID dom_sid;
3940         DOM_SID info_sid;
3941         fstring name;
3942         fstring sid_string;
3943         struct group *grp;
3944         struct samr_info *info;
3945         PRIVILEGE_SET priv_set;
3946         uint32 acc_granted;
3947         gid_t gid;
3948
3949         init_privilege(&priv_set);
3950
3951         /* Find the policy handle. Open a policy on it. */
3952         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
3953                 return NT_STATUS_INVALID_HANDLE;
3954                 
3955         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3956                 return r_u->status;
3957         }
3958                 
3959         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3960                 return NT_STATUS_ACCESS_DENIED;
3961
3962         /* TODO: check if allowed to create group  and add a become_root/unbecome_root pair.*/
3963
3964         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3965
3966         /* check if group already exists */
3967         if ( (grp=getgrnam(name)) != NULL)
3968                 return NT_STATUS_GROUP_EXISTS;
3969
3970         /* we can create the UNIX group */
3971         if (smb_create_group(name, &gid) != 0)
3972                 return NT_STATUS_ACCESS_DENIED;
3973
3974         /* check if the group has been successfully created */
3975         if ((grp=getgrgid(gid)) == NULL)
3976                 return NT_STATUS_ACCESS_DENIED;
3977
3978         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3979
3980         sid_copy(&info_sid, get_global_sam_sid());
3981         sid_append_rid(&info_sid, r_u->rid);
3982         sid_to_string(sid_string, &info_sid);
3983
3984         /* add the group to the mapping table */
3985         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3986                 return NT_STATUS_ACCESS_DENIED;
3987
3988         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3989                 return NT_STATUS_NO_MEMORY;
3990
3991         /* get a (unique) handle.  open a policy on it. */
3992         if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3993                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3994
3995         return NT_STATUS_OK;
3996 }
3997
3998 /*********************************************************************
3999  _samr_query_groupinfo
4000
4001 sends the name/comment pair of a domain group
4002 level 1 send also the number of users of that group
4003 *********************************************************************/
4004
4005 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4006 {
4007         DOM_SID group_sid;
4008         GROUP_MAP map;
4009         uid_t *uid=NULL;
4010         int num_uids=0;
4011         GROUP_INFO_CTR *ctr;
4012         uint32 acc_granted;
4013
4014         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
4015                 return NT_STATUS_INVALID_HANDLE;
4016         
4017         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4018                 return r_u->status;
4019         }
4020                 
4021         if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
4022                 return NT_STATUS_INVALID_HANDLE;
4023
4024         ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4025         if (ctr==NULL)
4026                 return NT_STATUS_NO_MEMORY;
4027
4028         switch (q_u->switch_level) {
4029                 case 1:
4030                         ctr->switch_value1 = 1;
4031                         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4032                                 return NT_STATUS_NO_SUCH_GROUP;
4033                         init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4034                         SAFE_FREE(uid);
4035                         break;
4036                 case 3:
4037                         ctr->switch_value1 = 3;
4038                         init_samr_group_info3(&ctr->group.info3);
4039                         break;
4040                 case 4:
4041                         ctr->switch_value1 = 4;
4042                         init_samr_group_info4(&ctr->group.info4, map.comment);
4043                         break;
4044                 default:
4045                         return NT_STATUS_INVALID_INFO_CLASS;
4046         }
4047
4048         init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4049
4050         return NT_STATUS_OK;
4051 }
4052
4053 /*********************************************************************
4054  _samr_set_groupinfo
4055  
4056  update a domain group's comment.
4057 *********************************************************************/
4058
4059 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4060 {
4061         DOM_SID group_sid;
4062         GROUP_MAP map;
4063         GROUP_INFO_CTR *ctr;
4064         uint32 acc_granted;
4065
4066         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4067                 return NT_STATUS_INVALID_HANDLE;
4068         
4069         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4070                 return r_u->status;
4071         }
4072                 
4073         if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4074                 return NT_STATUS_NO_SUCH_GROUP;
4075         
4076         ctr=q_u->ctr;
4077
4078         switch (ctr->switch_value1) {
4079                 case 1:
4080                         unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4081                         break;
4082                 case 4:
4083                         unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4084                         break;
4085                 default:
4086                         free_privilege(&map.priv_set);
4087                         return NT_STATUS_INVALID_INFO_CLASS;
4088         }
4089
4090         if(!pdb_update_group_mapping_entry(&map)) {
4091                 free_privilege(&map.priv_set);
4092                 return NT_STATUS_NO_SUCH_GROUP;
4093         }
4094
4095         free_privilege(&map.priv_set);
4096
4097         return NT_STATUS_OK;
4098 }
4099
4100 /*********************************************************************
4101  _samr_set_aliasinfo
4102  
4103  update an alias's comment.
4104 *********************************************************************/
4105
4106 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4107 {
4108         DOM_SID group_sid;
4109         GROUP_MAP map;
4110         ALIAS_INFO_CTR *ctr;
4111         uint32 acc_granted;
4112
4113         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4114                 return NT_STATUS_INVALID_HANDLE;
4115         
4116         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4117                 return r_u->status;
4118         }
4119                 
4120         if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4121                 return NT_STATUS_NO_SUCH_GROUP;
4122         
4123         ctr=&q_u->ctr;
4124
4125         switch (ctr->switch_value1) {
4126                 case 3:
4127                         unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4128                         break;
4129                 default:
4130                         free_privilege(&map.priv_set);
4131                         return NT_STATUS_INVALID_INFO_CLASS;
4132         }
4133
4134         if(!pdb_update_group_mapping_entry(&map)) {
4135                 free_privilege(&map.priv_set);
4136                 return NT_STATUS_NO_SUCH_GROUP;
4137         }
4138
4139         free_privilege(&map.priv_set);
4140
4141         return NT_STATUS_OK;
4142 }
4143
4144 /*********************************************************************
4145  _samr_get_dom_pwinfo
4146 *********************************************************************/
4147
4148 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4149 {
4150         /* Perform access check.  Since this rpc does not require a
4151            policy handle it will not be caught by the access checks on
4152            SAMR_CONNECT or SAMR_CONNECT_ANON. */
4153
4154         if (!pipe_access_check(p)) {
4155                 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4156                 r_u->status = NT_STATUS_ACCESS_DENIED;
4157                 return r_u->status;
4158         }
4159
4160         /* Actually, returning zeros here works quite well :-). */
4161
4162         return NT_STATUS_OK;
4163 }
4164
4165 /*********************************************************************
4166  _samr_open_group
4167 *********************************************************************/
4168
4169 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4170 {
4171         DOM_SID sid;
4172         DOM_SID info_sid;
4173         GROUP_MAP map;
4174         struct samr_info *info;
4175         SEC_DESC         *psd = NULL;
4176         uint32            acc_granted;
4177         uint32            des_access;
4178         size_t            sd_size;
4179         NTSTATUS          status;
4180         fstring sid_string;
4181
4182         if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
4183                 return NT_STATUS_INVALID_HANDLE;
4184         
4185         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4186                 return status;
4187         }
4188                 
4189         /*check if access can be granted as requested by client. */
4190         samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4191         se_map_generic(&des_access,&grp_generic_mapping);
4192         if (!NT_STATUS_IS_OK(status = 
4193                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
4194                                                       des_access, &acc_granted, "_samr_open_group"))) {
4195                 return status;
4196         }
4197
4198
4199         /* this should not be hard-coded like this */
4200         if (!sid_equal(&sid, get_global_sam_sid()))
4201                 return NT_STATUS_ACCESS_DENIED;
4202
4203         sid_copy(&info_sid, get_global_sam_sid());
4204         sid_append_rid(&info_sid, q_u->rid_group);
4205         sid_to_string(sid_string, &info_sid);
4206
4207         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4208                 return NT_STATUS_NO_MEMORY;
4209                 
4210         info->acc_granted = acc_granted;
4211
4212         DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4213
4214         /* check if that group really exists */
4215         if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
4216                 return NT_STATUS_NO_SUCH_GROUP;
4217
4218         /* get a (unique) handle.  open a policy on it. */
4219         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4220                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4221
4222         return NT_STATUS_OK;
4223 }
4224
4225 /*********************************************************************
4226  _samr_unknown_2d
4227 *********************************************************************/
4228
4229 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4230 {
4231         DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4232         return NT_STATUS_NOT_IMPLEMENTED;
4233 }
4234
4235 /*******************************************************************
4236  _samr_unknown_2e
4237  ********************************************************************/
4238
4239 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4240 {
4241         struct samr_info *info = NULL;
4242         SAM_UNK_CTR *ctr;
4243         uint32 min_pass_len,pass_hist,flag;
4244         time_t u_expire, u_min_age;
4245         NTTIME nt_expire, nt_min_age;
4246
4247         time_t u_lock_duration, u_reset_time;
4248         NTTIME nt_lock_duration, nt_reset_time;
4249         uint32 lockout;
4250         
4251         time_t u_logout;
4252         NTTIME nt_logout;
4253
4254         uint32 num_users=0, num_groups=0, num_aliases=0;
4255
4256         uint32 account_policy_temp;
4257
4258         if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4259                 return NT_STATUS_NO_MEMORY;
4260
4261         ZERO_STRUCTP(ctr);
4262
4263         r_u->status = NT_STATUS_OK;
4264
4265         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4266
4267         /* find the policy handle.  open a policy on it. */
4268         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4269                 return NT_STATUS_INVALID_HANDLE;
4270
4271         switch (q_u->switch_value) {
4272                 case 0x01:
4273                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4274                         min_pass_len = account_policy_temp;
4275
4276                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4277                         pass_hist = account_policy_temp;
4278
4279                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4280                         flag = account_policy_temp;
4281
4282                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4283                         u_expire = account_policy_temp;
4284
4285                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4286                         u_min_age = account_policy_temp;
4287
4288                         unix_to_nt_time_abs(&nt_expire, u_expire);
4289                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
4290
4291                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
4292                                        flag, nt_expire, nt_min_age);
4293                         break;
4294                 case 0x02:
4295                         become_root();          
4296                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4297                         unbecome_root();
4298                         if (!NT_STATUS_IS_OK(r_u->status)) {
4299                                 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4300                                 return r_u->status;
4301                         }
4302                         num_users=info->disp_info.num_user_account;
4303                         free_samr_db(info);
4304                         
4305                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4306                         if (NT_STATUS_IS_ERR(r_u->status)) {
4307                                 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4308                                 return r_u->status;
4309                         }
4310                         num_groups=info->disp_info.num_group_account;
4311                         free_samr_db(info);
4312
4313                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4314                         init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL), 
4315                                        num_users, num_groups, num_aliases);
4316                         break;
4317                 case 0x03:
4318                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4319                         u_logout = account_policy_temp;
4320
4321                         unix_to_nt_time_abs(&nt_logout, u_logout);
4322                         
4323                         init_unk_info3(&ctr->info.inf3, nt_logout);
4324                         break;
4325                 case 0x05:
4326                         init_unk_info5(&ctr->info.inf5, global_myname());
4327                         break;
4328                 case 0x06:
4329                         init_unk_info6(&ctr->info.inf6);
4330                         break;
4331                 case 0x07:
4332                         init_unk_info7(&ctr->info.inf7);
4333                         break;
4334                 case 0x0c:
4335                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4336                         u_lock_duration = account_policy_temp;
4337
4338                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4339                         u_reset_time = account_policy_temp;
4340
4341                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4342                         lockout = account_policy_temp;
4343         
4344                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4345                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4346         
4347                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4348                         break;
4349                 default:
4350                         return NT_STATUS_INVALID_INFO_CLASS;
4351         }
4352
4353         init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4354
4355         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4356
4357         return r_u->status;
4358 }
4359
4360 /*******************************************************************
4361  _samr_
4362  ********************************************************************/
4363
4364 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4365 {
4366         time_t u_expire, u_min_age;
4367         time_t u_logout;
4368         time_t u_lock_duration, u_reset_time;
4369
4370         r_u->status = NT_STATUS_OK;
4371
4372         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4373
4374         /* find the policy handle.  open a policy on it. */
4375         if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4376                 return NT_STATUS_INVALID_HANDLE;
4377
4378         DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4379
4380         switch (q_u->switch_value) {
4381                 case 0x01:
4382                         u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4383                         u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4384                         
4385                         account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4386                         account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4387                         account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4388                         account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4389                         account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4390                         break;
4391                 case 0x02:
4392                         break;
4393                 case 0x03:
4394                         u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4395                         account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4396                         break;
4397                 case 0x05:
4398                         break;
4399                 case 0x06:
4400                         break;
4401                 case 0x07:
4402                         break;
4403                 case 0x0c:
4404                         u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4405                         u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4406                         
4407                         account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4408                         account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4409                         account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4410                         break;
4411                 default:
4412                         return NT_STATUS_INVALID_INFO_CLASS;
4413         }
4414
4415         init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4416
4417         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4418
4419         return r_u->status;
4420 }
4421