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