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