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