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