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