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