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