More printf fixes - size_t is long on some architectures.
[samba.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 %l 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 %lu for "
2765                          "user %s\n", (unsigned long)gid, 
2766                          pdb_get_username(sampass)));
2767                 return False;
2768         }
2769
2770         if (smb_set_primary_group(grp->gr_name,
2771                                   pdb_get_username(sampass)) != 0) {
2772                 DEBUG(2,("Could not set primary group for user %s to "
2773                          "%s\n",
2774                          pdb_get_username(sampass), grp->gr_name));
2775                 return False;
2776         }
2777
2778         return True;
2779 }
2780         
2781
2782 /*******************************************************************
2783  set_user_info_21
2784  ********************************************************************/
2785
2786 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2787 {
2788         SAM_ACCOUNT *pwd = NULL;
2789  
2790         if (id21 == NULL) {
2791                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2792                 return False;
2793         }
2794  
2795         pdb_init_sam(&pwd);
2796  
2797         if (!pdb_getsampwsid(pwd, sid)) {
2798                 pdb_free_sam(&pwd);
2799                 return False;
2800         }
2801  
2802         copy_id21_to_sam_passwd(pwd, id21);
2803  
2804         /*
2805          * The funny part about the previous two calls is
2806          * that pwd still has the password hashes from the
2807          * passdb entry.  These have not been updated from
2808          * id21.  I don't know if they need to be set.    --jerry
2809          */
2810  
2811         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2812                 set_unix_primary_group(pwd);
2813
2814         /* write the change out */
2815         if(!pdb_update_sam_account(pwd)) {
2816                 pdb_free_sam(&pwd);
2817                 return False;
2818         }
2819
2820         pdb_free_sam(&pwd);
2821
2822         return True;
2823 }
2824
2825 /*******************************************************************
2826  set_user_info_23
2827  ********************************************************************/
2828
2829 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2830 {
2831         SAM_ACCOUNT *pwd = NULL;
2832         pstring plaintext_buf;
2833         uint32 len;
2834         uint16 acct_ctrl;
2835  
2836         if (id23 == NULL) {
2837                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2838                 return False;
2839         }
2840  
2841         pdb_init_sam(&pwd);
2842  
2843         if (!pdb_getsampwsid(pwd, sid)) {
2844                 pdb_free_sam(&pwd);
2845                 return False;
2846         }
2847
2848         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2849                   pdb_get_username(pwd)));
2850
2851         acct_ctrl = pdb_get_acct_ctrl(pwd);
2852
2853         if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2854                 pdb_free_sam(&pwd);
2855                 return False;
2856         }
2857   
2858         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2859                 pdb_free_sam(&pwd);
2860                 return False;
2861         }
2862  
2863         copy_id23_to_sam_passwd(pwd, id23);
2864  
2865         /* if it's a trust account, don't update /etc/passwd */
2866         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2867                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2868                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2869                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2870         } else  {
2871                 /* update the UNIX password */
2872                 if (lp_unix_password_sync() )
2873                         if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2874                                 pdb_free_sam(&pwd);
2875                                 return False;
2876                         }
2877         }
2878  
2879         ZERO_STRUCT(plaintext_buf);
2880  
2881         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2882                 set_unix_primary_group(pwd);
2883
2884         if(!pdb_update_sam_account(pwd)) {
2885                 pdb_free_sam(&pwd);
2886                 return False;
2887         }
2888  
2889         pdb_free_sam(&pwd);
2890
2891         return True;
2892 }
2893
2894 /*******************************************************************
2895  set_user_info_pw
2896  ********************************************************************/
2897
2898 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2899 {
2900         SAM_ACCOUNT *pwd = NULL;
2901         uint32 len;
2902         pstring plaintext_buf;
2903         uint16 acct_ctrl;
2904  
2905         pdb_init_sam(&pwd);
2906  
2907         if (!pdb_getsampwsid(pwd, sid)) {
2908                 pdb_free_sam(&pwd);
2909                 return False;
2910         }
2911         
2912         DEBUG(5, ("Attempting administrator password change for user %s\n",
2913                   pdb_get_username(pwd)));
2914
2915         acct_ctrl = pdb_get_acct_ctrl(pwd);
2916
2917         ZERO_STRUCT(plaintext_buf);
2918  
2919         if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2920                 pdb_free_sam(&pwd);
2921                 return False;
2922         }
2923
2924         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2925                 pdb_free_sam(&pwd);
2926                 return False;
2927         }
2928  
2929         /* if it's a trust account, don't update /etc/passwd */
2930         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2931                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2932                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2933                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2934         } else {
2935                 /* update the UNIX password */
2936                 if (lp_unix_password_sync()) {
2937                         if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2938                                 pdb_free_sam(&pwd);
2939                                 return False;
2940                         }
2941                 }
2942         }
2943  
2944         ZERO_STRUCT(plaintext_buf);
2945  
2946         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2947  
2948         /* update the SAMBA password */
2949         if(!pdb_update_sam_account(pwd)) {
2950                 pdb_free_sam(&pwd);
2951                 return False;
2952         }
2953
2954         pdb_free_sam(&pwd);
2955
2956         return True;
2957 }
2958
2959 /*******************************************************************
2960  samr_reply_set_userinfo
2961  ********************************************************************/
2962
2963 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2964 {
2965         DOM_SID sid;
2966         POLICY_HND *pol = &q_u->pol;
2967         uint16 switch_value = q_u->switch_value;
2968         SAM_USERINFO_CTR *ctr = q_u->ctr;
2969         uint32 acc_granted;
2970         uint32 acc_required;
2971
2972         DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2973
2974         r_u->status = NT_STATUS_OK;
2975
2976         /* find the policy handle.  open a policy on it. */
2977         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2978                 return NT_STATUS_INVALID_HANDLE;
2979         
2980         acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */   
2981         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2982                 return r_u->status;
2983         }
2984                 
2985         DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2986
2987         if (ctr == NULL) {
2988                 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2989                 return NT_STATUS_INVALID_INFO_CLASS;
2990         }
2991
2992         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2993         switch (switch_value) {
2994                 case 0x12:
2995                         if (!set_user_info_12(ctr->info.id12, &sid))
2996                                 return NT_STATUS_ACCESS_DENIED;
2997                         break;
2998
2999                 case 24:
3000                         SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
3001
3002                         dump_data(100, (char *)ctr->info.id24->pass, 516);
3003
3004                         if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3005                                 return NT_STATUS_ACCESS_DENIED;
3006                         break;
3007
3008                 case 25:
3009 #if 0
3010                         /*
3011                          * Currently we don't really know how to unmarshall
3012                          * the level 25 struct, and the password encryption
3013                          * is different. This is a placeholder for when we
3014                          * do understand it. In the meantime just return INVALID
3015                          * info level and W2K SP2 drops down to level 23... JRA.
3016                          */
3017
3018                         SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3019
3020                         dump_data(100, (char *)ctr->info.id25->pass, 532);
3021
3022                         if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3023                                 return NT_STATUS_ACCESS_DENIED;
3024                         break;
3025 #endif
3026                         return NT_STATUS_INVALID_INFO_CLASS;
3027
3028                 case 23:
3029                         SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3030
3031                         dump_data(100, (char *)ctr->info.id23->pass, 516);
3032
3033                         if (!set_user_info_23(ctr->info.id23, &sid))
3034                                 return NT_STATUS_ACCESS_DENIED;
3035                         break;
3036
3037                 default:
3038                         return NT_STATUS_INVALID_INFO_CLASS;
3039         }
3040
3041         return r_u->status;
3042 }
3043
3044 /*******************************************************************
3045  samr_reply_set_userinfo2
3046  ********************************************************************/
3047
3048 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3049 {
3050         DOM_SID sid;
3051         SAM_USERINFO_CTR *ctr = q_u->ctr;
3052         POLICY_HND *pol = &q_u->pol;
3053         uint16 switch_value = q_u->switch_value;
3054         uint32 acc_granted;
3055         uint32 acc_required;
3056
3057         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3058
3059         r_u->status = NT_STATUS_OK;
3060
3061         /* find the policy handle.  open a policy on it. */
3062         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3063                 return NT_STATUS_INVALID_HANDLE;
3064         
3065         acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */   
3066         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3067                 return r_u->status;
3068         }
3069
3070         DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3071
3072         if (ctr == NULL) {
3073                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3074                 return NT_STATUS_INVALID_INFO_CLASS;
3075         }
3076
3077         switch_value=ctr->switch_value;
3078
3079         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3080         switch (switch_value) {
3081                 case 21:
3082                         if (!set_user_info_21(ctr->info.id21, &sid))
3083                                 return NT_STATUS_ACCESS_DENIED;
3084                         break;
3085                 case 16:
3086                         if (!set_user_info_10(ctr->info.id10, &sid))
3087                                 return NT_STATUS_ACCESS_DENIED;
3088                         break;
3089                 case 18:
3090                         /* Used by AS/U JRA. */
3091                         if (!set_user_info_12(ctr->info.id12, &sid))
3092                                 return NT_STATUS_ACCESS_DENIED;
3093                         break;
3094                 default:
3095                         return NT_STATUS_INVALID_INFO_CLASS;
3096         }
3097
3098         return r_u->status;
3099 }
3100
3101 /*********************************************************************
3102  _samr_query_aliasmem
3103 *********************************************************************/
3104
3105 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3106 {
3107         int num_groups = 0, tmp_num_groups=0;
3108         uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3109         struct samr_info *info = NULL;
3110         int i,j;
3111                 
3112         NTSTATUS ntstatus1;
3113         NTSTATUS ntstatus2;
3114
3115         /* until i see a real useraliases query, we fack one up */
3116
3117         /* I have seen one, JFM 2/12/2001 */
3118         /*
3119          * Explanation of what this call does:
3120          * for all the SID given in the request:
3121          * return a list of alias (local groups)
3122          * that have those SID as members.
3123          *
3124          * and that's the alias in the domain specified
3125          * in the policy_handle
3126          *
3127          * if the policy handle is on an incorrect sid
3128          * for example a user's sid
3129          * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3130          */
3131         
3132         r_u->status = NT_STATUS_OK;
3133
3134         DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3135
3136         /* find the policy handle.  open a policy on it. */
3137         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3138                 return NT_STATUS_INVALID_HANDLE;
3139                 
3140         ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3141         ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3142         
3143         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3144                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3145                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3146                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3147                 }
3148         }               
3149
3150         if (!sid_check_is_domain(&info->sid) &&
3151             !sid_check_is_builtin(&info->sid))
3152                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3153
3154
3155         for (i=0; i<q_u->num_sids1; i++) {
3156
3157                 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3158
3159                 /*
3160                  * if there is an error, we just continue as
3161                  * it can be an unfound user or group
3162                  */
3163                 if (!NT_STATUS_IS_OK(r_u->status)) {
3164                         DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3165                         continue;
3166                 }
3167
3168                 if (tmp_num_groups==0) {
3169                         DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3170                         continue;
3171                 }
3172
3173                 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3174                 if (new_rids==NULL) {
3175                         DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3176                         return NT_STATUS_NO_MEMORY;
3177                 }
3178                 rids=new_rids;
3179
3180                 for (j=0; j<tmp_num_groups; j++)
3181                         rids[j+num_groups]=tmp_rids[j];
3182                 
3183                 safe_free(tmp_rids);
3184                 
3185                 num_groups+=tmp_num_groups;
3186         }
3187         
3188         init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3189         return NT_STATUS_OK;
3190 }
3191
3192 /*********************************************************************
3193  _samr_query_aliasmem
3194 *********************************************************************/
3195
3196 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3197 {
3198         int i;
3199
3200         GROUP_MAP map;
3201         int num_uids = 0;
3202         DOM_SID2 *sid;
3203         uid_t *uid=NULL;
3204
3205         DOM_SID alias_sid;
3206         DOM_SID als_sid;
3207         uint32 alias_rid;
3208         fstring alias_sid_str;
3209         DOM_SID temp_sid;
3210
3211         SAM_ACCOUNT *sam_user = NULL;
3212         BOOL check;
3213         uint32 acc_granted;
3214
3215         /* find the policy handle.  open a policy on it. */
3216         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3217                 return NT_STATUS_INVALID_HANDLE;
3218         
3219         if (!NT_STATUS_IS_OK(r_u->status = 
3220                 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3221                 return r_u->status;
3222         }
3223                 
3224         sid_copy(&als_sid, &alias_sid);
3225         sid_to_string(alias_sid_str, &alias_sid);
3226         sid_split_rid(&alias_sid, &alias_rid);
3227
3228         DEBUG(10, ("sid is %s\n", alias_sid_str));
3229
3230         if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3231                 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3232                 if(!get_builtin_group_from_sid(als_sid, &map))
3233                         return NT_STATUS_NO_SUCH_ALIAS;
3234         } else {
3235                 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3236                         DEBUG(10, ("lookup on Server SID\n"));
3237                         if(!get_local_group_from_sid(als_sid, &map))
3238                                 return NT_STATUS_NO_SUCH_ALIAS;
3239                 }
3240         }
3241
3242         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3243                 return NT_STATUS_NO_SUCH_ALIAS;
3244
3245         DEBUG(10, ("sid is %s\n", alias_sid_str));
3246         sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids); 
3247         if (num_uids!=0 && sid == NULL) 
3248                 return NT_STATUS_NO_MEMORY;
3249
3250         for (i = 0; i < num_uids; i++) {
3251                 struct passwd *pass;
3252                 uint32 rid;
3253
3254                 sid_copy(&temp_sid, get_global_sam_sid());
3255
3256                 pass = getpwuid_alloc(uid[i]);
3257                 if (!pass) continue;
3258
3259                 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3260                         passwd_free(&pass);
3261                         continue;
3262                 }
3263
3264                 become_root();
3265                 check = pdb_getsampwnam(sam_user, pass->pw_name);
3266                 unbecome_root();
3267         
3268                 if (check != True) {
3269                         pdb_free_sam(&sam_user);
3270                         passwd_free(&pass);
3271                         continue;
3272                 }
3273         
3274                 rid = pdb_get_user_rid(sam_user);
3275                 if (rid == 0) {
3276                         pdb_free_sam(&sam_user);
3277                         passwd_free(&pass);
3278                         continue;
3279                 }
3280
3281                 pdb_free_sam(&sam_user);
3282                 passwd_free(&pass);
3283
3284                 sid_append_rid(&temp_sid, rid);
3285                 
3286                 init_dom_sid2(&sid[i], &temp_sid);
3287         }
3288
3289         DEBUG(10, ("sid is %s\n", alias_sid_str));
3290         init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3291
3292         return NT_STATUS_OK;
3293 }
3294
3295 /*********************************************************************
3296  _samr_query_groupmem
3297 *********************************************************************/
3298
3299 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3300 {
3301         int num_uids = 0;
3302         int i;
3303         DOM_SID group_sid;
3304         uint32 group_rid;
3305         fstring group_sid_str;
3306         uid_t *uid=NULL;
3307         
3308         GROUP_MAP map;
3309
3310         uint32 *rid=NULL;
3311         uint32 *attr=NULL;
3312
3313         SAM_ACCOUNT *sam_user = NULL;
3314         BOOL check;
3315         uint32 acc_granted;
3316
3317         /* find the policy handle.  open a policy on it. */
3318         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3319                 return NT_STATUS_INVALID_HANDLE;
3320                 
3321         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3322                 return r_u->status;
3323         }
3324                 
3325         /* todo: change to use sid_compare_front */
3326
3327         sid_split_rid(&group_sid, &group_rid);
3328         sid_to_string(group_sid_str, &group_sid);
3329         DEBUG(10, ("sid is %s\n", group_sid_str));
3330
3331         /* can we get a query for an SID outside our domain ? */
3332         if (!sid_equal(&group_sid, get_global_sam_sid()))
3333                 return NT_STATUS_NO_SUCH_GROUP;
3334
3335         sid_append_rid(&group_sid, group_rid);
3336         DEBUG(10, ("lookup on Domain SID\n"));
3337
3338         if(!get_domain_group_from_sid(group_sid, &map))
3339                 return NT_STATUS_NO_SUCH_GROUP;
3340
3341         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3342                 return NT_STATUS_NO_SUCH_GROUP;
3343
3344         rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3345         attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3346         
3347         if (num_uids!=0 && (rid==NULL || attr==NULL))
3348                 return NT_STATUS_NO_MEMORY;
3349         
3350         for (i=0; i<num_uids; i++) {
3351                 struct passwd *pass;
3352                 uint32 urid;
3353
3354                 pass = getpwuid_alloc(uid[i]);
3355                 if (!pass) continue;
3356
3357                 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3358                         passwd_free(&pass);
3359                         continue;
3360                 }
3361
3362                 become_root();
3363                 check = pdb_getsampwnam(sam_user, pass->pw_name);
3364                 unbecome_root();
3365         
3366                 if (check != True) {
3367                         pdb_free_sam(&sam_user);
3368                         passwd_free(&pass);
3369                         continue;
3370                 }
3371         
3372                 urid = pdb_get_user_rid(sam_user);
3373                 if (urid == 0) {
3374                         pdb_free_sam(&sam_user);
3375                         passwd_free(&pass);
3376                         continue;
3377                 }
3378
3379                 pdb_free_sam(&sam_user);
3380                 passwd_free(&pass);
3381
3382                 rid[i] = urid;
3383                 attr[i] = SID_NAME_USER;                
3384         }
3385
3386         init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3387
3388         return NT_STATUS_OK;
3389 }
3390
3391 /*********************************************************************
3392  _samr_add_aliasmem
3393 *********************************************************************/
3394
3395 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3396 {
3397         DOM_SID alias_sid;
3398         fstring alias_sid_str;
3399         uid_t uid;
3400         struct passwd *pwd;
3401         struct group *grp;
3402         fstring grp_name;
3403         GROUP_MAP map;
3404         NTSTATUS ret;
3405         SAM_ACCOUNT *sam_user = NULL;
3406         BOOL check;
3407         uint32 acc_granted;
3408
3409         /* Find the policy handle. Open a policy on it. */
3410         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3411                 return NT_STATUS_INVALID_HANDLE;
3412         
3413         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3414                 return r_u->status;
3415         }
3416                 
3417         sid_to_string(alias_sid_str, &alias_sid);
3418         DEBUG(10, ("sid is %s\n", alias_sid_str));
3419
3420         if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3421                 DEBUG(10, ("adding member on Server SID\n"));
3422                 if(!get_local_group_from_sid(alias_sid, &map))
3423                         return NT_STATUS_NO_SUCH_ALIAS;
3424         
3425         } else {
3426                 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3427                         DEBUG(10, ("adding member on BUILTIN SID\n"));
3428                         if( !get_local_group_from_sid(alias_sid, &map))
3429                                 return NT_STATUS_NO_SUCH_ALIAS;
3430
3431                 } else
3432                         return NT_STATUS_NO_SUCH_ALIAS;
3433         }
3434
3435         ret = pdb_init_sam(&sam_user);
3436         if (!NT_STATUS_IS_OK(ret))
3437                 return ret;
3438         
3439         check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3440         
3441         if (check != True) {
3442                 pdb_free_sam(&sam_user);
3443                 return NT_STATUS_NO_SUCH_USER;
3444         }
3445
3446         /* check a real user exist before we run the script to add a user to a group */
3447         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3448                 pdb_free_sam(&sam_user);
3449                 return NT_STATUS_NO_SUCH_USER;
3450         }
3451
3452         pdb_free_sam(&sam_user);
3453
3454         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3455                 return NT_STATUS_NO_SUCH_USER;
3456         }
3457         
3458         if ((grp=getgrgid(map.gid)) == NULL) {
3459                 passwd_free(&pwd);
3460                 return NT_STATUS_NO_SUCH_ALIAS;
3461         }
3462
3463         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3464         fstrcpy(grp_name, grp->gr_name);
3465
3466         /* if the user is already in the group */
3467         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3468                 passwd_free(&pwd);
3469                 return NT_STATUS_MEMBER_IN_ALIAS;
3470         }
3471
3472         /* 
3473          * ok, the group exist, the user exist, the user is not in the group,
3474          * we can (finally) add it to the group !
3475          */
3476         smb_add_user_group(grp_name, pwd->pw_name);
3477
3478         /* check if the user has been added then ... */
3479         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3480                 passwd_free(&pwd);
3481                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3482         }
3483
3484         passwd_free(&pwd);
3485         return NT_STATUS_OK;
3486 }
3487
3488 /*********************************************************************
3489  _samr_del_aliasmem
3490 *********************************************************************/
3491
3492 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3493 {
3494         DOM_SID alias_sid;
3495         fstring alias_sid_str;
3496         struct group *grp;
3497         fstring grp_name;
3498         GROUP_MAP map;
3499         SAM_ACCOUNT *sam_pass=NULL;
3500         uint32 acc_granted;
3501
3502         /* Find the policy handle. Open a policy on it. */
3503         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3504                 return NT_STATUS_INVALID_HANDLE;
3505         
3506         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3507                 return r_u->status;
3508         }
3509         
3510         sid_to_string(alias_sid_str, &alias_sid);
3511         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3512
3513         if (!sid_check_is_in_our_domain(&alias_sid) &&
3514             !sid_check_is_in_builtin(&alias_sid)) {
3515                 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3516                 return NT_STATUS_NO_SUCH_ALIAS;
3517         }
3518
3519         if( !get_local_group_from_sid(alias_sid, &map))
3520                 return NT_STATUS_NO_SUCH_ALIAS;
3521
3522         if ((grp=getgrgid(map.gid)) == NULL)
3523                 return NT_STATUS_NO_SUCH_ALIAS;
3524
3525         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3526         fstrcpy(grp_name, grp->gr_name);
3527
3528         /* check if the user exists before trying to remove it from the group */
3529         pdb_init_sam(&sam_pass);
3530         if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3531                 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3532                 pdb_free_sam(&sam_pass);
3533                 return NT_STATUS_NO_SUCH_USER;
3534         }
3535
3536         /* if the user is not in the group */
3537         if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3538                 pdb_free_sam(&sam_pass);
3539                 return NT_STATUS_MEMBER_IN_ALIAS;
3540         }
3541
3542         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3543
3544         /* check if the user has been removed then ... */
3545         if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3546                 pdb_free_sam(&sam_pass);
3547                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3548         }
3549
3550         pdb_free_sam(&sam_pass);
3551         return NT_STATUS_OK;
3552 }
3553
3554 /*********************************************************************
3555  _samr_add_groupmem
3556 *********************************************************************/
3557
3558 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3559 {
3560         DOM_SID group_sid;
3561         DOM_SID user_sid;
3562         fstring group_sid_str;
3563         uid_t uid;
3564         struct passwd *pwd;
3565         struct group *grp;
3566         fstring grp_name;
3567         GROUP_MAP map;
3568         NTSTATUS ret;
3569         SAM_ACCOUNT *sam_user=NULL;
3570         BOOL check;
3571         uint32 acc_granted;
3572
3573         /* Find the policy handle. Open a policy on it. */
3574         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3575                 return NT_STATUS_INVALID_HANDLE;
3576         
3577         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3578                 return r_u->status;
3579         }
3580
3581         sid_to_string(group_sid_str, &group_sid);
3582         DEBUG(10, ("sid is %s\n", group_sid_str));
3583
3584         if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3585                 return NT_STATUS_NO_SUCH_GROUP;
3586
3587         DEBUG(10, ("lookup on Domain SID\n"));
3588
3589         if(!get_domain_group_from_sid(group_sid, &map))
3590                 return NT_STATUS_NO_SUCH_GROUP;
3591
3592         sid_copy(&user_sid, get_global_sam_sid());
3593         sid_append_rid(&user_sid, q_u->rid);
3594
3595         ret = pdb_init_sam(&sam_user);
3596         if (!NT_STATUS_IS_OK(ret))
3597                 return ret;
3598         
3599         check = pdb_getsampwsid(sam_user, &user_sid);
3600         
3601         if (check != True) {
3602                 pdb_free_sam(&sam_user);
3603                 return NT_STATUS_NO_SUCH_USER;
3604         }
3605
3606         /* check a real user exist before we run the script to add a user to a group */
3607         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3608                 pdb_free_sam(&sam_user);
3609                 return NT_STATUS_NO_SUCH_USER;
3610         }
3611
3612         pdb_free_sam(&sam_user);
3613
3614         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3615                 return NT_STATUS_NO_SUCH_USER;
3616         }
3617
3618         if ((grp=getgrgid(map.gid)) == NULL) {
3619                 passwd_free(&pwd);
3620                 return NT_STATUS_NO_SUCH_GROUP;
3621         }
3622
3623         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3624         fstrcpy(grp_name, grp->gr_name);
3625
3626         /* if the user is already in the group */
3627         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3628                 passwd_free(&pwd);
3629                 return NT_STATUS_MEMBER_IN_GROUP;
3630         }
3631
3632         /* 
3633          * ok, the group exist, the user exist, the user is not in the group,
3634          *
3635          * we can (finally) add it to the group !
3636          */
3637
3638         smb_add_user_group(grp_name, pwd->pw_name);
3639
3640         /* check if the user has been added then ... */
3641         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3642                 passwd_free(&pwd);
3643                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
3644         }
3645
3646         passwd_free(&pwd);
3647         return NT_STATUS_OK;
3648 }
3649
3650 /*********************************************************************
3651  _samr_del_groupmem
3652 *********************************************************************/
3653
3654 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3655 {
3656         DOM_SID group_sid;
3657         DOM_SID user_sid;
3658         SAM_ACCOUNT *sam_pass=NULL;
3659         GROUP_MAP map;
3660         fstring grp_name;
3661         struct group *grp;
3662         uint32 acc_granted;
3663
3664         /*
3665          * delete the group member named q_u->rid
3666          * who is a member of the sid associated with the handle
3667          * the rid is a user's rid as the group is a domain group.
3668          */
3669
3670         /* Find the policy handle. Open a policy on it. */
3671         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3672                 return NT_STATUS_INVALID_HANDLE;
3673         
3674         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3675                 return r_u->status;
3676         }
3677                 
3678         if (!sid_check_is_in_our_domain(&group_sid))
3679                 return NT_STATUS_NO_SUCH_GROUP;
3680
3681         sid_copy(&user_sid, get_global_sam_sid());
3682         sid_append_rid(&user_sid, q_u->rid);
3683
3684         if (!get_domain_group_from_sid(group_sid, &map))
3685                 return NT_STATUS_NO_SUCH_GROUP;
3686
3687         if ((grp=getgrgid(map.gid)) == NULL)
3688                 return NT_STATUS_NO_SUCH_GROUP;
3689
3690         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3691         fstrcpy(grp_name, grp->gr_name);
3692
3693         /* check if the user exists before trying to remove it from the group */
3694         pdb_init_sam(&sam_pass);
3695         if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3696                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3697                 pdb_free_sam(&sam_pass);
3698                 return NT_STATUS_NO_SUCH_USER;
3699         }
3700
3701         /* if the user is not in the group */
3702         if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3703                 pdb_free_sam(&sam_pass);
3704                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3705         }
3706
3707         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3708
3709         /* check if the user has been removed then ... */
3710         if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3711                 pdb_free_sam(&sam_pass);
3712                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3713         }
3714         
3715         pdb_free_sam(&sam_pass);
3716         return NT_STATUS_OK;
3717
3718 }
3719
3720 /****************************************************************************
3721  Delete a UNIX user on demand.
3722 ****************************************************************************/
3723
3724 static int smb_delete_user(const char *unix_user)
3725 {
3726         pstring del_script;
3727         int ret;
3728
3729         /* try winbindd first since it is impossible to determine where 
3730            a user came from via NSS.  Try the delete user script if this fails
3731            meaning the user did not exist in winbindd's list of accounts */
3732
3733         if ( winbind_delete_user( unix_user ) ) {
3734                 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3735                 return 0;
3736         }
3737
3738
3739         /* fall back to 'delete user script' */
3740
3741         pstrcpy(del_script, lp_deluser_script());
3742         if (! *del_script)
3743                 return -1;
3744         all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3745         ret = smbrun(del_script,NULL);
3746         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3747
3748         return ret;
3749 }
3750
3751 /*********************************************************************
3752  _samr_delete_dom_user
3753 *********************************************************************/
3754
3755 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3756 {
3757         DOM_SID user_sid;
3758         SAM_ACCOUNT *sam_pass=NULL;
3759         uint32 acc_granted;
3760
3761         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3762
3763         /* Find the policy handle. Open a policy on it. */
3764         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
3765                 return NT_STATUS_INVALID_HANDLE;
3766                 
3767         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3768                 return r_u->status;
3769         }
3770                 
3771         if (!sid_check_is_in_our_domain(&user_sid))
3772                 return NT_STATUS_CANNOT_DELETE;
3773
3774         /* check if the user exists before trying to delete */
3775         pdb_init_sam(&sam_pass);
3776         if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3777                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3778                 pdb_free_sam(&sam_pass);
3779                 return NT_STATUS_NO_SUCH_USER;
3780         }
3781
3782         /* delete the unix side */
3783         /*
3784          * note: we don't check if the delete really happened
3785          * as the script is not necessary present
3786          * and maybe the sysadmin doesn't want to delete the unix side
3787          */
3788         smb_delete_user(pdb_get_username(sam_pass));
3789
3790         /* and delete the samba side */
3791         if (!pdb_delete_sam_account(sam_pass)) {
3792                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3793                 pdb_free_sam(&sam_pass);
3794                 return NT_STATUS_CANNOT_DELETE;
3795         }
3796         
3797         pdb_free_sam(&sam_pass);
3798
3799         if (!close_policy_hnd(p, &q_u->user_pol))
3800                 return NT_STATUS_OBJECT_NAME_INVALID;
3801
3802         return NT_STATUS_OK;
3803 }
3804
3805 /*********************************************************************
3806  _samr_delete_dom_group
3807 *********************************************************************/
3808
3809 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3810 {
3811         DOM_SID group_sid;
3812         DOM_SID dom_sid;
3813         uint32 group_rid;
3814         fstring group_sid_str;
3815         gid_t gid;
3816         struct group *grp;
3817         GROUP_MAP map;
3818         uint32 acc_granted;
3819
3820         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3821
3822         /* Find the policy handle. Open a policy on it. */
3823         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3824                 return NT_STATUS_INVALID_HANDLE;
3825                 
3826         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3827                 return r_u->status;
3828         }
3829                 
3830         sid_copy(&dom_sid, &group_sid);
3831         sid_to_string(group_sid_str, &dom_sid);
3832         sid_split_rid(&dom_sid, &group_rid);
3833
3834         DEBUG(10, ("sid is %s\n", group_sid_str));
3835
3836         /* we check if it's our SID before deleting */
3837         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3838                 return NT_STATUS_NO_SUCH_GROUP;
3839
3840         DEBUG(10, ("lookup on Domain SID\n"));
3841
3842         if(!get_domain_group_from_sid(group_sid, &map))
3843                 return NT_STATUS_NO_SUCH_GROUP;
3844
3845         gid=map.gid;
3846
3847         /* check if group really exists */
3848         if ( (grp=getgrgid(gid)) == NULL)
3849                 return NT_STATUS_NO_SUCH_GROUP;
3850
3851         /* we can delete the UNIX group */
3852         smb_delete_group(grp->gr_name);
3853
3854         /* check if the group has been successfully deleted */
3855         if ( (grp=getgrgid(gid)) != NULL)
3856                 return NT_STATUS_ACCESS_DENIED;
3857
3858         if(!pdb_delete_group_mapping_entry(group_sid))
3859                 return NT_STATUS_ACCESS_DENIED;
3860
3861         if (!close_policy_hnd(p, &q_u->group_pol))
3862                 return NT_STATUS_OBJECT_NAME_INVALID;
3863
3864         return NT_STATUS_OK;
3865 }
3866
3867 /*********************************************************************
3868  _samr_delete_dom_alias
3869 *********************************************************************/
3870
3871 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3872 {
3873         DOM_SID alias_sid;
3874         DOM_SID dom_sid;
3875         uint32 alias_rid;
3876         fstring alias_sid_str;
3877         gid_t gid;
3878         struct group *grp;
3879         GROUP_MAP map;
3880         uint32 acc_granted;
3881
3882         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3883
3884         /* Find the policy handle. Open a policy on it. */
3885         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3886                 return NT_STATUS_INVALID_HANDLE;
3887         
3888         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3889                 return r_u->status;
3890         }
3891                 
3892         sid_copy(&dom_sid, &alias_sid);
3893         sid_to_string(alias_sid_str, &dom_sid);
3894         sid_split_rid(&dom_sid, &alias_rid);
3895
3896         DEBUG(10, ("sid is %s\n", alias_sid_str));
3897
3898         /* we check if it's our SID before deleting */
3899         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3900                 return NT_STATUS_NO_SUCH_ALIAS;
3901
3902         DEBUG(10, ("lookup on Local SID\n"));
3903
3904         if(!get_local_group_from_sid(alias_sid, &map))
3905                 return NT_STATUS_NO_SUCH_ALIAS;
3906
3907         gid=map.gid;
3908
3909         /* check if group really exists */
3910         if ( (grp=getgrgid(gid)) == NULL)
3911                 return NT_STATUS_NO_SUCH_ALIAS;
3912
3913         /* we can delete the UNIX group */
3914         smb_delete_group(grp->gr_name);
3915
3916         /* check if the group has been successfully deleted */
3917         if ( (grp=getgrgid(gid)) != NULL)
3918                 return NT_STATUS_ACCESS_DENIED;
3919
3920         /* don't check if we removed it as it could be an un-mapped group */
3921         pdb_delete_group_mapping_entry(alias_sid);
3922
3923         if (!close_policy_hnd(p, &q_u->alias_pol))
3924                 return NT_STATUS_OBJECT_NAME_INVALID;
3925
3926         return NT_STATUS_OK;
3927 }
3928
3929 /*********************************************************************
3930  _samr_create_dom_group
3931 *********************************************************************/
3932
3933 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3934 {
3935         DOM_SID dom_sid;
3936         DOM_SID info_sid;
3937         fstring name;
3938         fstring sid_string;
3939         struct group *grp;
3940         struct samr_info *info;
3941         uint32 acc_granted;
3942         gid_t gid;
3943
3944         /* Find the policy handle. Open a policy on it. */
3945         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
3946                 return NT_STATUS_INVALID_HANDLE;
3947         
3948         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3949                 return r_u->status;
3950         }
3951                 
3952         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3953                 return NT_STATUS_ACCESS_DENIED;
3954
3955         /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3956
3957         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3958
3959         /* check if group already exist */
3960         if ((grp=getgrnam(name)) != NULL)
3961                 return NT_STATUS_GROUP_EXISTS;
3962
3963         /* we can create the UNIX group */
3964         if (smb_create_group(name, &gid) != 0)
3965                 return NT_STATUS_ACCESS_DENIED;
3966
3967         /* check if the group has been successfully created */
3968         if ((grp=getgrgid(gid)) == NULL)
3969                 return NT_STATUS_ACCESS_DENIED;
3970
3971         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3972
3973         /* add the group to the mapping table */
3974         sid_copy(&info_sid, get_global_sam_sid());
3975         sid_append_rid(&info_sid, r_u->rid);
3976         sid_to_string(sid_string, &info_sid);
3977
3978         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3979                 return NT_STATUS_ACCESS_DENIED;
3980
3981         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3982                 return NT_STATUS_NO_MEMORY;
3983
3984         /* get a (unique) handle.  open a policy on it. */
3985         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3986                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3987
3988         return NT_STATUS_OK;
3989 }
3990
3991 /*********************************************************************
3992  _samr_create_dom_alias
3993 *********************************************************************/
3994
3995 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3996 {
3997         DOM_SID dom_sid;
3998         DOM_SID info_sid;
3999         fstring name;
4000         fstring sid_string;
4001         struct group *grp;
4002         struct samr_info *info;
4003         uint32 acc_granted;
4004         gid_t gid;
4005
4006         /* Find the policy handle. Open a policy on it. */
4007         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
4008                 return NT_STATUS_INVALID_HANDLE;
4009                 
4010         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4011                 return r_u->status;
4012         }
4013                 
4014         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4015                 return NT_STATUS_ACCESS_DENIED;
4016
4017         /* TODO: check if allowed to create group  and add a become_root/unbecome_root pair.*/
4018
4019         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4020
4021         /* check if group already exists */
4022         if ( (grp=getgrnam(name)) != NULL)
4023                 return NT_STATUS_GROUP_EXISTS;
4024
4025         /* we can create the UNIX group */
4026         if (smb_create_group(name, &gid) != 0)
4027                 return NT_STATUS_ACCESS_DENIED;
4028
4029         /* check if the group has been successfully created */
4030         if ((grp=getgrgid(gid)) == NULL)
4031                 return NT_STATUS_ACCESS_DENIED;
4032
4033         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4034
4035         sid_copy(&info_sid, get_global_sam_sid());
4036         sid_append_rid(&info_sid, r_u->rid);
4037         sid_to_string(sid_string, &info_sid);
4038
4039         /* add the group to the mapping table */
4040         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
4041                 return NT_STATUS_ACCESS_DENIED;
4042
4043         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4044                 return NT_STATUS_NO_MEMORY;
4045
4046         /* get a (unique) handle.  open a policy on it. */
4047         if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4048                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4049
4050         return NT_STATUS_OK;
4051 }
4052
4053 /*********************************************************************
4054  _samr_query_groupinfo
4055
4056 sends the name/comment pair of a domain group
4057 level 1 send also the number of users of that group
4058 *********************************************************************/
4059
4060 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4061 {
4062         DOM_SID group_sid;
4063         GROUP_MAP map;
4064         uid_t *uid=NULL;
4065         int num_uids=0;
4066         GROUP_INFO_CTR *ctr;
4067         uint32 acc_granted;
4068
4069         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
4070                 return NT_STATUS_INVALID_HANDLE;
4071         
4072         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4073                 return r_u->status;
4074         }
4075                 
4076         if (!get_domain_group_from_sid(group_sid, &map))
4077                 return NT_STATUS_INVALID_HANDLE;
4078
4079         ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4080         if (ctr==NULL)
4081                 return NT_STATUS_NO_MEMORY;
4082
4083         switch (q_u->switch_level) {
4084                 case 1:
4085                         ctr->switch_value1 = 1;
4086                         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4087                                 return NT_STATUS_NO_SUCH_GROUP;
4088                         init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4089                         SAFE_FREE(uid);
4090                         break;
4091                 case 3:
4092                         ctr->switch_value1 = 3;
4093                         init_samr_group_info3(&ctr->group.info3);
4094                         break;
4095                 case 4:
4096                         ctr->switch_value1 = 4;
4097                         init_samr_group_info4(&ctr->group.info4, map.comment);
4098                         break;
4099                 default:
4100                         return NT_STATUS_INVALID_INFO_CLASS;
4101         }
4102
4103         init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4104
4105         return NT_STATUS_OK;
4106 }
4107
4108 /*********************************************************************
4109  _samr_set_groupinfo
4110  
4111  update a domain group's comment.
4112 *********************************************************************/
4113
4114 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4115 {
4116         DOM_SID group_sid;
4117         GROUP_MAP map;
4118         GROUP_INFO_CTR *ctr;
4119         uint32 acc_granted;
4120
4121         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4122                 return NT_STATUS_INVALID_HANDLE;
4123         
4124         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4125                 return r_u->status;
4126         }
4127                 
4128         if (!get_domain_group_from_sid(group_sid, &map))
4129                 return NT_STATUS_NO_SUCH_GROUP;
4130         
4131         ctr=q_u->ctr;
4132
4133         switch (ctr->switch_value1) {
4134                 case 1:
4135                         unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4136                         break;
4137                 case 4:
4138                         unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4139                         break;
4140                 default:
4141                         return NT_STATUS_INVALID_INFO_CLASS;
4142         }
4143
4144         if(!pdb_update_group_mapping_entry(&map)) {
4145                 return NT_STATUS_NO_SUCH_GROUP;
4146         }
4147
4148         return NT_STATUS_OK;
4149 }
4150
4151 /*********************************************************************
4152  _samr_set_aliasinfo
4153  
4154  update an alias's comment.
4155 *********************************************************************/
4156
4157 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4158 {
4159         DOM_SID group_sid;
4160         GROUP_MAP map;
4161         ALIAS_INFO_CTR *ctr;
4162         uint32 acc_granted;
4163
4164         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4165                 return NT_STATUS_INVALID_HANDLE;
4166         
4167         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4168                 return r_u->status;
4169         }
4170                 
4171         if (!get_local_group_from_sid(group_sid, &map))
4172                 return NT_STATUS_NO_SUCH_GROUP;
4173         
4174         ctr=&q_u->ctr;
4175
4176         switch (ctr->switch_value1) {
4177                 case 3:
4178                         unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4179                         break;
4180                 default:
4181                         return NT_STATUS_INVALID_INFO_CLASS;
4182         }
4183
4184         if(!pdb_update_group_mapping_entry(&map)) {
4185                 return NT_STATUS_NO_SUCH_GROUP;
4186         }
4187
4188         return NT_STATUS_OK;
4189 }
4190
4191 /*********************************************************************
4192  _samr_get_dom_pwinfo
4193 *********************************************************************/
4194
4195 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4196 {
4197         /* Perform access check.  Since this rpc does not require a
4198            policy handle it will not be caught by the access checks on
4199            SAMR_CONNECT or SAMR_CONNECT_ANON. */
4200
4201         if (!pipe_access_check(p)) {
4202                 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4203                 r_u->status = NT_STATUS_ACCESS_DENIED;
4204                 return r_u->status;
4205         }
4206
4207         /* Actually, returning zeros here works quite well :-). */
4208
4209         return NT_STATUS_OK;
4210 }
4211
4212 /*********************************************************************
4213  _samr_open_group
4214 *********************************************************************/
4215
4216 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4217 {
4218         DOM_SID sid;
4219         DOM_SID info_sid;
4220         GROUP_MAP map;
4221         struct samr_info *info;
4222         SEC_DESC         *psd = NULL;
4223         uint32            acc_granted;
4224         uint32            des_access;
4225         size_t            sd_size;
4226         NTSTATUS          status;
4227         fstring sid_string;
4228
4229         if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
4230                 return NT_STATUS_INVALID_HANDLE;
4231         
4232         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4233                 return status;
4234         }
4235                 
4236         /*check if access can be granted as requested by client. */
4237         samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4238         se_map_generic(&des_access,&grp_generic_mapping);
4239         if (!NT_STATUS_IS_OK(status = 
4240                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
4241                                                       des_access, &acc_granted, "_samr_open_group"))) {
4242                 return status;
4243         }
4244
4245
4246         /* this should not be hard-coded like this */
4247         if (!sid_equal(&sid, get_global_sam_sid()))
4248                 return NT_STATUS_ACCESS_DENIED;
4249
4250         sid_copy(&info_sid, get_global_sam_sid());
4251         sid_append_rid(&info_sid, q_u->rid_group);
4252         sid_to_string(sid_string, &info_sid);
4253
4254         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4255                 return NT_STATUS_NO_MEMORY;
4256                 
4257         info->acc_granted = acc_granted;
4258
4259         DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4260
4261         /* check if that group really exists */
4262         if (!get_domain_group_from_sid(info->sid, &map))
4263                 return NT_STATUS_NO_SUCH_GROUP;
4264
4265         /* get a (unique) handle.  open a policy on it. */
4266         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4267                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4268
4269         return NT_STATUS_OK;
4270 }
4271
4272 /*********************************************************************
4273  _samr_unknown_2d
4274 *********************************************************************/
4275
4276 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4277 {
4278         DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4279         return NT_STATUS_NOT_IMPLEMENTED;
4280 }
4281
4282 /*******************************************************************
4283  _samr_unknown_2e
4284  ********************************************************************/
4285
4286 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4287 {
4288         struct samr_info *info = NULL;
4289         SAM_UNK_CTR *ctr;
4290         uint32 min_pass_len,pass_hist,flag;
4291         time_t u_expire, u_min_age;
4292         NTTIME nt_expire, nt_min_age;
4293
4294         time_t u_lock_duration, u_reset_time;
4295         NTTIME nt_lock_duration, nt_reset_time;
4296         uint32 lockout;
4297         
4298         time_t u_logout;
4299         NTTIME nt_logout;
4300
4301         uint32 num_users=0, num_groups=0, num_aliases=0;
4302
4303         uint32 account_policy_temp;
4304
4305         if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4306                 return NT_STATUS_NO_MEMORY;
4307
4308         ZERO_STRUCTP(ctr);
4309
4310         r_u->status = NT_STATUS_OK;
4311
4312         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4313
4314         /* find the policy handle.  open a policy on it. */
4315         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4316                 return NT_STATUS_INVALID_HANDLE;
4317
4318         switch (q_u->switch_value) {
4319                 case 0x01:
4320                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4321                         min_pass_len = account_policy_temp;
4322
4323                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4324                         pass_hist = account_policy_temp;
4325
4326                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4327                         flag = account_policy_temp;
4328
4329                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4330                         u_expire = account_policy_temp;
4331
4332                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4333                         u_min_age = account_policy_temp;
4334
4335                         unix_to_nt_time_abs(&nt_expire, u_expire);
4336                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
4337
4338                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
4339                                        flag, nt_expire, nt_min_age);
4340                         break;
4341                 case 0x02:
4342                         become_root();          
4343                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4344                         unbecome_root();
4345                         if (!NT_STATUS_IS_OK(r_u->status)) {
4346                                 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4347                                 return r_u->status;
4348                         }
4349                         num_users=info->disp_info.num_user_account;
4350                         free_samr_db(info);
4351                         
4352                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4353                         if (NT_STATUS_IS_ERR(r_u->status)) {
4354                                 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4355                                 return r_u->status;
4356                         }
4357                         num_groups=info->disp_info.num_group_account;
4358                         free_samr_db(info);
4359
4360                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4361                         init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL), 
4362                                        num_users, num_groups, num_aliases);
4363                         break;
4364                 case 0x03:
4365                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4366                         u_logout = account_policy_temp;
4367
4368                         unix_to_nt_time_abs(&nt_logout, u_logout);
4369                         
4370                         init_unk_info3(&ctr->info.inf3, nt_logout);
4371                         break;
4372                 case 0x05:
4373                         init_unk_info5(&ctr->info.inf5, global_myname());
4374                         break;
4375                 case 0x06:
4376                         init_unk_info6(&ctr->info.inf6);
4377                         break;
4378                 case 0x07:
4379                         init_unk_info7(&ctr->info.inf7);
4380                         break;
4381                 case 0x0c:
4382                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4383                         u_lock_duration = account_policy_temp;
4384
4385                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4386                         u_reset_time = account_policy_temp;
4387
4388                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4389                         lockout = account_policy_temp;
4390         
4391                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4392                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4393         
4394                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4395                         break;
4396                 default:
4397                         return NT_STATUS_INVALID_INFO_CLASS;
4398         }
4399
4400         init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4401
4402         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4403
4404         return r_u->status;
4405 }
4406
4407 /*******************************************************************
4408  _samr_
4409  ********************************************************************/
4410
4411 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4412 {
4413         time_t u_expire, u_min_age;
4414         time_t u_logout;
4415         time_t u_lock_duration, u_reset_time;
4416
4417         r_u->status = NT_STATUS_OK;
4418
4419         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4420
4421         /* find the policy handle.  open a policy on it. */
4422         if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4423                 return NT_STATUS_INVALID_HANDLE;
4424
4425         DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4426
4427         switch (q_u->switch_value) {
4428                 case 0x01:
4429                         u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4430                         u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4431                         
4432                         account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4433                         account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4434                         account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4435                         account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4436                         account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4437                         break;
4438                 case 0x02:
4439                         break;
4440                 case 0x03:
4441                         u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4442                         account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4443                         break;
4444                 case 0x05:
4445                         break;
4446                 case 0x06:
4447                         break;
4448                 case 0x07:
4449                         break;
4450                 case 0x0c:
4451                         u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4452                         u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4453                         
4454                         account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4455                         account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4456                         account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4457                         break;
4458                 default:
4459                         return NT_STATUS_INVALID_INFO_CLASS;
4460         }
4461
4462         init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4463
4464         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4465
4466         return r_u->status;
4467 }
4468