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