794fea56df612f87600cd050503c587b146e0f2e
[ira/wip.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison               2001-2002,
9  *  Copyright (C) Jean Fran├žois Micouleau      1998-2001,
10  *  Copyright (C) Anthony Liguori                   2002,
11  *  Copyright (C) Jim McDonough                     2002.
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this program; if not, write to the Free Software
25  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26  */
27
28 /*
29  * This is the implementation of the SAMR code.
30  */
31
32 #include "includes.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
36
37 extern DOM_SID global_sid_Builtin;
38
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
42
43
44 typedef struct _disp_info {
45         BOOL user_dbloaded;
46         uint32 num_user_account;
47         DISP_USER_INFO *disp_user_info;
48         BOOL group_dbloaded;
49         uint32 num_group_account;
50         DISP_GROUP_INFO *disp_group_info;
51 } DISP_INFO;
52
53 struct samr_info {
54         /* for use by the \PIPE\samr policy */
55         DOM_SID sid;
56         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
57         uint32 acc_granted;
58         uint16 acb_mask;
59         BOOL all_machines;
60         DISP_INFO disp_info;
61
62         TALLOC_CTX *mem_ctx;
63 };
64
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
70
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
72
73 /*******************************************************************
74  Checks if access to an object should be granted, and returns that
75  level of access for further checks.
76 ********************************************************************/
77
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access, 
79                                   uint32 *acc_granted, const char *debug) 
80 {
81         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
82
83         if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84                 *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 /*******************************************************************
156  Function to free the per handle data.
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                         /* Not really a free, actually a 'clear' */
165                         pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
166                 }
167         }
168         info->disp_info.user_dbloaded=False;
169         info->disp_info.num_user_account=0;
170 }
171
172
173 /*******************************************************************
174  Function to free the per handle data.
175  ********************************************************************/
176 static void free_samr_db(struct samr_info *info)
177 {
178         /* Groups are talloced */
179
180         free_samr_users(info);
181
182         info->disp_info.group_dbloaded=False;
183         info->disp_info.num_group_account=0;
184 }
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         DISP_USER_INFO *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=(DISP_USER_INFO *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info, 
259                                           (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
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                 /* link the SAM_ACCOUNT to the array */
268                 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=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         DISP_GROUP_INFO *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, MAPPING_WITHOUT_PRIV)) {
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=(DISP_GROUP_INFO *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
317
318         if (group_entries!=0 && grp_array==NULL) {
319                 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
320                 SAFE_FREE(map);
321                 return NT_STATUS_NO_MEMORY;
322         }
323
324         info->disp_info.disp_group_info=grp_array;
325
326         for (i=0; i<group_entries; i++) {
327         
328                 grp_array[i].grp=(DOMAIN_GRP *)talloc(mem_ctx, sizeof(DOMAIN_GRP));
329         
330                 fstrcpy(grp_array[i].grp->name, map[i].nt_name);
331                 fstrcpy(grp_array[i].grp->comment, map[i].comment);
332                 sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
333                 grp_array[i].grp->attr=SID_NAME_DOM_GRP;
334         }
335
336         SAFE_FREE(map);
337
338         /* the snapshoot is in memory, we're ready to enumerate fast */
339
340         info->disp_info.group_dbloaded=True;
341
342         DEBUG(10,("load_group_domain_entries: done\n"));
343
344         return NT_STATUS_OK;
345 }
346
347
348 /*******************************************************************
349  _samr_close_hnd
350  ********************************************************************/
351
352 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
353 {
354         r_u->status = NT_STATUS_OK;
355
356         /* close the policy handle */
357         if (!close_policy_hnd(p, &q_u->pol))
358                 return NT_STATUS_OBJECT_NAME_INVALID;
359
360         DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
361
362         return r_u->status;
363 }
364
365 /*******************************************************************
366  samr_reply_open_domain
367  ********************************************************************/
368
369 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
370 {
371         struct    samr_info *info;
372         SEC_DESC *psd = NULL;
373         uint32    acc_granted;
374         uint32    des_access = q_u->flags;
375         size_t    sd_size;
376         NTSTATUS  status;
377
378         r_u->status = NT_STATUS_OK;
379
380         /* find the connection policy handle. */
381         if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
382                 return NT_STATUS_INVALID_HANDLE;
383
384         if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
385                 return status;
386         }
387
388         /*check if access can be granted as requested by client. */
389         samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
390         se_map_generic(&des_access,&dom_generic_mapping);
391
392         if (!NT_STATUS_IS_OK(status = 
393                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
394                                                       des_access, &acc_granted, "_samr_open_domain"))) {
395                 return status;
396         }
397
398         /* associate the domain SID with the (unique) handle. */
399         if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
400                 return NT_STATUS_NO_MEMORY;
401         info->acc_granted = acc_granted;
402
403         /* get a (unique) handle.  open a policy on it. */
404         if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
405                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
406
407         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
408
409         return r_u->status;
410 }
411
412 /*******************************************************************
413  _samr_get_usrdom_pwinfo
414  ********************************************************************/
415
416 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
417 {
418         struct samr_info *info = NULL;
419
420         r_u->status = NT_STATUS_OK;
421
422         /* find the policy handle.  open a policy on it. */
423         if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
424                 return NT_STATUS_INVALID_HANDLE;
425
426         if (!sid_check_is_in_our_domain(&info->sid))
427                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
428
429         init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
430
431         DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
432
433         /* 
434          * NT sometimes return NT_STATUS_ACCESS_DENIED
435          * I don't know yet why.
436          */
437
438         return r_u->status;
439 }
440
441 /*******************************************************************
442  samr_make_dom_obj_sd
443  ********************************************************************/
444
445 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
446 {
447         extern DOM_SID global_sid_World;
448         DOM_SID adm_sid;
449         DOM_SID act_sid;
450
451         SEC_ACE ace[3];
452         SEC_ACCESS mask;
453
454         SEC_ACL *psa = NULL;
455
456         sid_copy(&adm_sid, &global_sid_Builtin);
457         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
458
459         sid_copy(&act_sid, &global_sid_Builtin);
460         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
461
462         /*basic access for every one*/
463         init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
464         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
465
466         /*full access for builtin aliases Administrators and Account Operators*/
467         init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
468         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
469         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
470
471         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
472                 return NT_STATUS_NO_MEMORY;
473
474         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
475                 return NT_STATUS_NO_MEMORY;
476
477         return NT_STATUS_OK;
478 }
479
480 /*******************************************************************
481  samr_make_usr_obj_sd
482  ********************************************************************/
483
484 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
485 {
486         extern DOM_SID global_sid_World;
487         DOM_SID adm_sid;
488         DOM_SID act_sid;
489
490         SEC_ACE ace[4];
491         SEC_ACCESS mask;
492
493         SEC_ACL *psa = NULL;
494
495         sid_copy(&adm_sid, &global_sid_Builtin);
496         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
497
498         sid_copy(&act_sid, &global_sid_Builtin);
499         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
500
501         /*basic access for every one*/
502         init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
503         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
504
505         /*full access for builtin aliases Administrators and Account Operators*/
506         init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
507         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
508         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
509
510         /*extended access for the user*/
511         init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
512         init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
513
514         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
515                 return NT_STATUS_NO_MEMORY;
516
517         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
518                 return NT_STATUS_NO_MEMORY;
519
520         return NT_STATUS_OK;
521 }
522
523 /*******************************************************************
524  samr_make_grp_obj_sd
525  ********************************************************************/
526
527 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
528 {
529         extern DOM_SID global_sid_World;
530         DOM_SID adm_sid;
531         DOM_SID act_sid;
532
533         SEC_ACE ace[3];
534         SEC_ACCESS mask;
535
536         SEC_ACL *psa = NULL;
537
538         sid_copy(&adm_sid, &global_sid_Builtin);
539         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
540
541         sid_copy(&act_sid, &global_sid_Builtin);
542         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
543
544         /*basic access for every one*/
545         init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
546         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
547
548         /*full access for builtin aliases Administrators and Account Operators*/
549         init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
550         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
551         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
552
553         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
554                 return NT_STATUS_NO_MEMORY;
555
556         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
557                 return NT_STATUS_NO_MEMORY;
558
559         return NT_STATUS_OK;
560 }
561
562 /*******************************************************************
563  samr_make_ali_obj_sd
564  ********************************************************************/
565
566 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
567 {
568         extern DOM_SID global_sid_World;
569         DOM_SID adm_sid;
570         DOM_SID act_sid;
571
572         SEC_ACE ace[3];
573         SEC_ACCESS mask;
574
575         SEC_ACL *psa = NULL;
576
577         sid_copy(&adm_sid, &global_sid_Builtin);
578         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
579
580         sid_copy(&act_sid, &global_sid_Builtin);
581         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
582
583         /*basic access for every one*/
584         init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
585         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586
587         /*full access for builtin aliases Administrators and Account Operators*/
588         init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
589         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
590         init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
591
592         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
593                 return NT_STATUS_NO_MEMORY;
594
595         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
596                 return NT_STATUS_NO_MEMORY;
597
598         return NT_STATUS_OK;
599 }
600
601 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
602 {
603         struct samr_info *info = NULL;
604
605         /* find the policy handle.  open a policy on it. */
606         if (!find_policy_by_hnd(p, pol, (void **)&info))
607                 return False;
608
609         if (!info)
610                 return False;
611
612         *sid = info->sid;
613         *acc_granted = info->acc_granted;
614         return True;
615 }
616
617 /*******************************************************************
618  _samr_set_sec_obj
619  ********************************************************************/
620
621 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
622 {
623         DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
624         return NT_STATUS_NOT_IMPLEMENTED;
625 }
626
627
628 /*******************************************************************
629  _samr_query_sec_obj
630  ********************************************************************/
631
632 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
633 {
634         DOM_SID pol_sid;
635         fstring str_sid;
636         SEC_DESC * psd = NULL;
637         size_t sd_size;
638         uint32 acc_granted;
639
640         r_u->status = NT_STATUS_OK;
641
642         /* Get the SID. */
643         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
644                 return NT_STATUS_INVALID_HANDLE;
645
646
647
648         DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
649
650         /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
651
652         /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
653         if (pol_sid.sid_rev_num == 0)
654         {
655                 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
656                 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
657         }
658         else if (sid_equal(&pol_sid,get_global_sam_sid()))  /* check if it is our domain SID */
659
660         {
661                 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
662                 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
663         }
664         else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin  Domain */
665         {
666                 /* TODO: Builtin probably needs a different SD with restricted write access*/
667                 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
668                 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
669         }
670         else if (sid_check_is_in_our_domain(&pol_sid) ||
671                  sid_check_is_in_builtin(&pol_sid))
672         {
673                 /* TODO: different SDs have to be generated for aliases groups and users.
674                          Currently all three get a default user SD  */
675                 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
676                 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
677         }
678         else return NT_STATUS_OBJECT_TYPE_MISMATCH;
679
680         if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
681                 return NT_STATUS_NO_MEMORY;
682
683         if (NT_STATUS_IS_OK(r_u->status))
684                 r_u->ptr = 1;
685
686         return r_u->status;
687 }
688
689 /*******************************************************************
690 makes a SAM_ENTRY / UNISTR2* structure from a user list.
691 ********************************************************************/
692
693 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
694                                          uint32 num_entries, uint32 start_idx, DISP_USER_INFO *disp_user_info,
695                                          DOM_SID *domain_sid)
696 {
697         uint32 i;
698         SAM_ENTRY *sam;
699         UNISTR2 *uni_name;
700         SAM_ACCOUNT *pwd = NULL;
701         UNISTR2 uni_temp_name;
702         const char *temp_name;
703         const DOM_SID *user_sid;
704         uint32 user_rid;
705         fstring user_sid_string;
706         fstring domain_sid_string;
707         
708         *sam_pp = NULL;
709         *uni_name_pp = NULL;
710
711         if (num_entries == 0)
712                 return NT_STATUS_OK;
713
714         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
715
716         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
717
718         if (sam == NULL || uni_name == NULL) {
719                 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
720                 return NT_STATUS_NO_MEMORY;
721         }
722
723         for (i = 0; i < num_entries; i++) {
724                 pwd = disp_user_info[i+start_idx].sam;
725                 temp_name = pdb_get_username(pwd);
726                 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
727                 user_sid = pdb_get_user_sid(pwd);
728
729                 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
730                         DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
731                                   "the domain sid %s.  Failing operation.\n", 
732                                   temp_name, 
733                                   sid_to_string(user_sid_string, user_sid),
734                                   sid_to_string(domain_sid_string, domain_sid)));
735                         return NT_STATUS_UNSUCCESSFUL;
736                 }
737
738                 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
739                 copy_unistr2(&uni_name[i], &uni_temp_name);
740         }
741
742         *sam_pp = sam;
743         *uni_name_pp = uni_name;
744         return NT_STATUS_OK;
745 }
746
747 /*******************************************************************
748  samr_reply_enum_dom_users
749  ********************************************************************/
750
751 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, 
752                               SAMR_R_ENUM_DOM_USERS *r_u)
753 {
754         struct samr_info *info = NULL;
755         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
756         int num_account;
757         uint32 enum_context=q_u->start_idx;
758         uint32 max_size=q_u->max_size;
759         uint32 temp_size;
760         enum remote_arch_types ra_type = get_remote_arch();
761         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
762         uint32 max_entries = max_sam_entries;
763         DOM_SID domain_sid;
764         
765         r_u->status = NT_STATUS_OK;
766
767         /* find the policy handle.  open a policy on it. */
768         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
769                 return NT_STATUS_INVALID_HANDLE;
770
771         domain_sid = info->sid;
772
773         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, 
774                                         SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, 
775                                         "_samr_enum_dom_users"))) {
776                 return r_u->status;
777         }
778         
779         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
780
781         become_root();
782         r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
783         unbecome_root();
784         
785         if (!NT_STATUS_IS_OK(r_u->status))
786                 return r_u->status;
787
788         num_account = info->disp_info.num_user_account;
789
790         if (enum_context > num_account) {
791                 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
792                 return NT_STATUS_OK;
793         }
794
795         /* verify we won't overflow */
796         if (max_entries > num_account-enum_context) {
797                 max_entries = num_account-enum_context;
798                 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
799         }
800
801         /* calculate the size and limit on the number of entries we will return */
802         temp_size=max_entries*struct_size;
803         
804         if (temp_size>max_size) {
805                 max_entries=MIN((max_size/struct_size),max_entries);;
806                 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
807         }
808
809         /* 
810          * Note from JRA. total_entries is not being used here. Currently if there is a
811          * large user base then it looks like NT will enumerate until get_sampwd_entries
812          * returns False due to num_entries being zero. This will cause an access denied
813          * return. I don't think this is right and needs further investigation. Note that
814          * this is also the same in the TNG code (I don't think that has been tested with
815          * a very large user list as MAX_SAM_ENTRIES is set to 600).
816          * 
817          * I also think that one of the 'num_entries' return parameters is probably
818          * the "max entries" parameter - but in the TNG code they're all currently set to the same
819          * value (again I think this is wrong).
820          */
821
822         r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, 
823                                                max_entries, enum_context, 
824                                                info->disp_info.disp_user_info,
825                                                &domain_sid);
826
827         if (!NT_STATUS_IS_OK(r_u->status))
828                 return r_u->status;
829
830         if (enum_context+max_entries < num_account)
831                 r_u->status = STATUS_MORE_ENTRIES;
832
833         DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
834
835         init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
836
837         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
838
839         return r_u->status;
840 }
841
842 /*******************************************************************
843 makes a SAM_ENTRY / UNISTR2* structure from a group list.
844 ********************************************************************/
845
846 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
847                 uint32 num_sam_entries, DOMAIN_GRP *grp)
848 {
849         uint32 i;
850         SAM_ENTRY *sam;
851         UNISTR2 *uni_name;
852
853         *sam_pp = NULL;
854         *uni_name_pp = NULL;
855
856         if (num_sam_entries == 0)
857                 return;
858
859         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
860
861         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
862
863         if (sam == NULL || uni_name == NULL) {
864                 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
865                 return;
866         }
867
868         for (i = 0; i < num_sam_entries; i++) {
869                 /*
870                  * JRA. I think this should include the null. TNG does not.
871                  */
872                 int len = strlen(grp[i].name)+1;
873
874                 init_sam_entry(&sam[i], len, grp[i].rid);
875                 init_unistr2(&uni_name[i], grp[i].name, len);
876         }
877
878         *sam_pp = sam;
879         *uni_name_pp = uni_name;
880 }
881
882 /*******************************************************************
883  Get the group entries - similar to get_sampwd_entries().
884  ********************************************************************/
885
886 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
887                                     uint32 *p_num_entries, uint32 max_entries)
888 {
889         fstring sid_str;
890         uint32 num_entries = 0;
891         int i;
892         GROUP_MAP smap;
893         GROUP_MAP *map = NULL;
894
895         sid_to_string(sid_str, sid);
896         DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
897
898         *p_num_entries = 0;
899
900         /* well-known aliases */
901         if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
902                 
903                 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
904                 
905                 if (num_entries != 0) {         
906                         *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
907                         if (*d_grp==NULL)
908                                 return NT_STATUS_NO_MEMORY;
909                         
910                         for(i=0; i<num_entries && i<max_entries; i++) {
911                                 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
912                                 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
913                                 
914                         }
915                 }
916                 SAFE_FREE(map);
917                 
918         } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
919                 struct sys_grent *glist;
920                 struct sys_grent *grp;
921                 struct passwd *pw;
922                 gid_t winbind_gid_low, winbind_gid_high;
923                 BOOL winbind_groups_exist = lp_winbind_gid(&winbind_gid_low, &winbind_gid_high);
924
925                 /* local aliases */
926                 /* we return the UNIX groups here.  This seems to be the right */
927                 /* thing to do, since NT member servers return their local     */
928                 /* groups in the same situation.                               */
929
930                 /* use getgrent_list() to retrieve the list of groups to avoid
931                  * problems with getgrent possible infinite loop by internal
932                  * libc grent structures overwrites by called functions */
933                 grp = glist = getgrent_list();
934                 if (grp == NULL)
935                         return NT_STATUS_NO_MEMORY;
936                 
937                 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
938                         uint32 trid;
939                         
940                         if(!pdb_getgrgid(&smap, grp->gr_gid, MAPPING_WITHOUT_PRIV))
941                                 continue;
942                         
943                         if (smap.sid_name_use!=SID_NAME_ALIAS) {
944                                 continue;
945                         }
946
947                         sid_split_rid(&smap.sid, &trid);
948                         
949                         if (!sid_equal(sid, &smap.sid))
950                                 continue;
951
952                         /* Don't return winbind groups as they are not local! */
953                         if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
954                                 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
955                                 continue;
956                         }
957
958                         /* Don't return user private groups... */
959
960                         if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
961                                 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
962                                 continue;                       
963                         }
964
965                         for( i = 0; i < num_entries; i++)
966                                 if ( (*d_grp)[i].rid == trid )
967                                         break;
968
969                         if ( i < num_entries ) {
970                                 continue; /* rid was there, dup! */
971                         }
972
973                         /* JRA - added this for large group db enumeration... */
974
975                         if (start_idx > 0) {
976                                 /* skip the requested number of entries.
977                                         not very efficient, but hey...
978                                 */
979                                 start_idx--;
980                                 continue;
981                         }
982
983                         *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
984                         if (*d_grp==NULL) {
985                                 grent_free(glist);
986                                 return NT_STATUS_NO_MEMORY;
987                         }
988
989                         fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
990                         (*d_grp)[num_entries].rid = trid;
991                         num_entries++;
992                         DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
993                 }
994
995                 grent_free(glist);
996         }
997
998         *p_num_entries = num_entries;
999
1000         DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
1001
1002         if (num_entries >= max_entries)
1003                 return STATUS_MORE_ENTRIES;
1004         return NT_STATUS_OK;
1005 }
1006
1007 /*******************************************************************
1008  Get the group entries - similar to get_sampwd_entries().
1009  ********************************************************************/
1010
1011 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1012                                      uint32 *p_num_entries, uint32 max_entries)
1013 {
1014         GROUP_MAP *map=NULL;
1015         int i;
1016         uint32 group_entries = 0;
1017         uint32 num_entries = 0;
1018
1019         *p_num_entries = 0;
1020
1021         pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
1022
1023         num_entries=group_entries-start_idx;
1024
1025         /* limit the number of entries */
1026         if (num_entries>max_entries) {
1027                 DEBUG(5,("Limiting to %d entries\n", max_entries));
1028                 num_entries=max_entries;
1029         }
1030
1031         *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1032         if (num_entries!=0 && *d_grp==NULL){
1033                 SAFE_FREE(map);
1034                 return NT_STATUS_NO_MEMORY;
1035         }
1036         
1037         for (i=0; i<num_entries; i++) {
1038                 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1039                 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1040                 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1041                 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1042         }
1043
1044         SAFE_FREE(map);
1045
1046         *p_num_entries = num_entries;
1047
1048         return NT_STATUS_OK;
1049 }
1050
1051 /*******************************************************************
1052  samr_reply_enum_dom_groups
1053  ********************************************************************/
1054
1055 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1056 {
1057         DOMAIN_GRP *grp=NULL;
1058         uint32 num_entries;
1059         DOM_SID sid;
1060         uint32 acc_granted;
1061
1062         r_u->status = NT_STATUS_OK;
1063
1064         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1065                 return NT_STATUS_INVALID_HANDLE;
1066                 
1067         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1068                 return r_u->status;
1069         }
1070
1071         DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1072
1073         /* the domain group array is being allocated in the function below */
1074         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))) {
1075                 return r_u->status;
1076         }
1077
1078         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1079
1080         init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1081
1082         DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1083
1084         return r_u->status;
1085 }
1086
1087
1088 /*******************************************************************
1089  samr_reply_enum_dom_aliases
1090  ********************************************************************/
1091
1092 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1093 {
1094         DOMAIN_GRP *grp=NULL;
1095         uint32 num_entries = 0;
1096         fstring sid_str;
1097         DOM_SID sid;
1098         NTSTATUS status;
1099         uint32  acc_granted;
1100         
1101         r_u->status = NT_STATUS_OK;
1102
1103         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1104                 return NT_STATUS_INVALID_HANDLE;
1105
1106         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1107                 return r_u->status;
1108         }
1109         
1110         sid_to_string(sid_str, &sid);
1111         DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1112
1113         status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, 
1114                                          &num_entries, MAX_SAM_ENTRIES);
1115         if (NT_STATUS_IS_ERR(status)) return status;
1116
1117         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1118
1119         /*safe_free(grp);*/
1120
1121         init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1122
1123         DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1124
1125         return r_u->status;
1126 }
1127
1128 /*******************************************************************
1129  samr_reply_query_dispinfo
1130  ********************************************************************/
1131 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, 
1132                               SAMR_R_QUERY_DISPINFO *r_u)
1133 {
1134         struct samr_info *info = NULL;
1135         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1136         
1137         uint32 max_entries=q_u->max_entries;
1138         uint32 enum_context=q_u->start_idx;
1139         uint32 max_size=q_u->max_size;
1140
1141         SAM_DISPINFO_CTR *ctr;
1142         uint32 temp_size=0, total_data_size=0;
1143         NTSTATUS disp_ret;
1144         uint32 num_account = 0;
1145         enum remote_arch_types ra_type = get_remote_arch();
1146         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1147         DOM_SID domain_sid;
1148
1149         DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1150         r_u->status = NT_STATUS_OK;
1151
1152         /* find the policy handle.  open a policy on it. */
1153         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1154                 return NT_STATUS_INVALID_HANDLE;
1155
1156         domain_sid = info->sid;
1157
1158         /*
1159          * calculate how many entries we will return.
1160          * based on 
1161          * - the number of entries the client asked
1162          * - our limit on that
1163          * - the starting point (enumeration context)
1164          * - the buffer size the client will accept
1165          */
1166
1167         /*
1168          * We are a lot more like W2K. Instead of reading the SAM
1169          * each time to find the records we need to send back,
1170          * we read it once and link that copy to the sam handle.
1171          * For large user list (over the MAX_SAM_ENTRIES)
1172          * it's a definitive win.
1173          * second point to notice: between enumerations
1174          * our sam is now the same as it's a snapshoot.
1175          * third point: got rid of the static SAM_USER_21 struct
1176          * no more intermediate.
1177          * con: it uses much more memory, as a full copy is stored
1178          * in memory.
1179          *
1180          * If you want to change it, think twice and think
1181          * of the second point , that's really important.
1182          *
1183          * JFM, 12/20/2001
1184          */
1185
1186         /* Get what we need from the password database */
1187         switch (q_u->switch_level) {
1188                 case 0x1:
1189                         /* When playing with usrmgr, this is necessary
1190                            if you want immediate refresh after editing
1191                            a user. I would like to do this after the
1192                            setuserinfo2, but we do not have access to
1193                            the domain handle in that call, only to the
1194                            user handle. Where else does this hurt?
1195                            -- Volker
1196                         */
1197 #if 0
1198                         /* We cannot do this here - it kills performace. JRA. */
1199                         free_samr_users(info);
1200 #endif
1201                 case 0x2:
1202                 case 0x4:
1203                         become_root();          
1204                         /* Level 2 is for all machines, otherwise only 'normal' users */
1205                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1206                         unbecome_root();
1207                         if (!NT_STATUS_IS_OK(r_u->status)) {
1208                                 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1209                                 return r_u->status;
1210                         }
1211                         num_account = info->disp_info.num_user_account;
1212                         break;
1213                 case 0x3:
1214                 case 0x5:
1215                         r_u->status = load_group_domain_entries(info, &info->sid);
1216                         if (!NT_STATUS_IS_OK(r_u->status))
1217                                 return r_u->status;
1218                         num_account = info->disp_info.num_group_account;
1219                         break;
1220                 default:
1221                         DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1222                         return NT_STATUS_INVALID_INFO_CLASS;
1223         }
1224
1225         /* first limit the number of entries we will return */
1226         if(max_entries > max_sam_entries) {
1227                 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1228                 max_entries = max_sam_entries;
1229         }
1230
1231         if (enum_context > num_account) {
1232                 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1233                 return NT_STATUS_NO_MORE_ENTRIES;
1234         }
1235
1236         /* verify we won't overflow */
1237         if (max_entries > num_account-enum_context) {
1238                 max_entries = num_account-enum_context;
1239                 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1240         }
1241
1242         /* calculate the size and limit on the number of entries we will return */
1243         temp_size=max_entries*struct_size;
1244         
1245         if (temp_size>max_size) {
1246                 max_entries=MIN((max_size/struct_size),max_entries);;
1247                 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1248         }
1249
1250         if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1251                 return NT_STATUS_NO_MEMORY;
1252
1253         ZERO_STRUCTP(ctr);
1254
1255         /* Now create reply structure */
1256         switch (q_u->switch_level) {
1257         case 0x1:
1258                 if (max_entries) {
1259                         if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1260                                 return NT_STATUS_NO_MEMORY;
1261                 }
1262                 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, 
1263                                                info->disp_info.disp_user_info, &domain_sid);
1264                 if (!NT_STATUS_IS_OK(disp_ret))
1265                         return disp_ret;
1266                 break;
1267         case 0x2:
1268                 if (max_entries) {
1269                         if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1270                                 return NT_STATUS_NO_MEMORY;
1271                 }
1272                 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, 
1273                                                info->disp_info.disp_user_info, &domain_sid);
1274                 if (!NT_STATUS_IS_OK(disp_ret))
1275                         return disp_ret;
1276                 break;
1277         case 0x3:
1278                 if (max_entries) {
1279                         if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1280                                 return NT_STATUS_NO_MEMORY;
1281                 }
1282                 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1283                 if (!NT_STATUS_IS_OK(disp_ret))
1284                         return disp_ret;
1285                 break;
1286         case 0x4:
1287                 if (max_entries) {
1288                         if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1289                                 return NT_STATUS_NO_MEMORY;
1290                 }
1291                 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1292                 if (!NT_STATUS_IS_OK(disp_ret))
1293                         return disp_ret;
1294                 break;
1295         case 0x5:
1296                 if (max_entries) {
1297                         if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1298                                 return NT_STATUS_NO_MEMORY;
1299                 }
1300                 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1301                 if (!NT_STATUS_IS_OK(disp_ret))
1302                         return disp_ret;
1303                 break;
1304
1305         default:
1306                 ctr->sam.info = NULL;
1307                 return NT_STATUS_INVALID_INFO_CLASS;
1308         }
1309
1310         /* calculate the total size */
1311         total_data_size=num_account*struct_size;
1312
1313         if (enum_context+max_entries < num_account)
1314                 r_u->status = STATUS_MORE_ENTRIES;
1315
1316         DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1317
1318         init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1319
1320         return r_u->status;
1321
1322 }
1323
1324 /*******************************************************************
1325  samr_reply_query_aliasinfo
1326  ********************************************************************/
1327
1328 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1329 {
1330         DOM_SID   sid;
1331         GROUP_MAP map;
1332         uint32    acc_granted;
1333
1334         r_u->status = NT_STATUS_OK;
1335
1336         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1337
1338         /* find the policy handle.  open a policy on it. */
1339         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1340                 return NT_STATUS_INVALID_HANDLE;
1341         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1342                 return r_u->status;
1343         }
1344
1345         if (!sid_check_is_in_our_domain(&sid) &&
1346             !sid_check_is_in_builtin(&sid))
1347                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1348
1349         if (!pdb_getgrsid(&map, sid, MAPPING_WITHOUT_PRIV))
1350                 return NT_STATUS_NO_SUCH_ALIAS;
1351
1352         switch (q_u->switch_level) {
1353         case 1:
1354                 r_u->ptr = 1;
1355                 r_u->ctr.switch_value1 = 1;
1356                 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1357                 break;
1358         case 3:
1359                 r_u->ptr = 1;
1360                 r_u->ctr.switch_value1 = 3;
1361                 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1362                 break;
1363         default:
1364                 return NT_STATUS_INVALID_INFO_CLASS;
1365         }
1366
1367         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1368
1369         return r_u->status;
1370 }
1371
1372 #if 0
1373 /*******************************************************************
1374  samr_reply_lookup_ids
1375  ********************************************************************/
1376
1377  uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1378 {
1379     uint32 rid[MAX_SAM_ENTRIES];
1380     int num_rids = q_u->num_sids1;
1381
1382     r_u->status = NT_STATUS_OK;
1383
1384     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1385
1386     if (num_rids > MAX_SAM_ENTRIES) {
1387         num_rids = MAX_SAM_ENTRIES;
1388         DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1389     }
1390
1391 #if 0
1392     int i;
1393     SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1394
1395     for (i = 0; i < num_rids && status == 0; i++)
1396     {
1397         struct sam_passwd *sam_pass;
1398         fstring user_name;
1399
1400
1401         fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1402                                     q_u->uni_user_name[i].uni_str_len));
1403
1404         /* find the user account */
1405         become_root();
1406         sam_pass = get_smb21pwd_entry(user_name, 0);
1407         unbecome_root();
1408
1409         if (sam_pass == NULL)
1410         {
1411             status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1412             rid[i] = 0;
1413         }
1414         else
1415         {
1416             rid[i] = sam_pass->user_rid;
1417         }
1418     }
1419 #endif
1420
1421     num_rids = 1;
1422     rid[0] = BUILTIN_ALIAS_RID_USERS;
1423
1424     init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1425
1426     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1427
1428     return r_u->status;
1429 }
1430 #endif
1431
1432 /*******************************************************************
1433  _samr_lookup_names
1434  ********************************************************************/
1435
1436 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1437 {
1438         uint32 rid[MAX_SAM_ENTRIES];
1439         uint32 local_rid;
1440         enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1441         enum SID_NAME_USE local_type;
1442         int i;
1443         int num_rids = q_u->num_names2;
1444         DOM_SID pol_sid;
1445         fstring sid_str;
1446         uint32  acc_granted;
1447
1448         r_u->status = NT_STATUS_OK;
1449
1450         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1451
1452         ZERO_ARRAY(rid);
1453         ZERO_ARRAY(type);
1454
1455         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1456                 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1457                 return r_u->status;
1458         }
1459         
1460         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 */
1461                 return r_u->status;
1462         }
1463
1464         if (num_rids > MAX_SAM_ENTRIES) {
1465                 num_rids = MAX_SAM_ENTRIES;
1466                 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1467         }
1468
1469         DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1470         
1471         become_root(); /* local_lookup_name can require root privs */
1472
1473         for (i = 0; i < num_rids; i++) {
1474                 fstring name;
1475                 DOM_SID sid;
1476
1477                 r_u->status = NT_STATUS_NONE_MAPPED;
1478
1479                 rid [i] = 0xffffffff;
1480                 type[i] = SID_NAME_UNKNOWN;
1481
1482                 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                 if(local_lookup_name(name, &sid, &local_type)) {
1496                         sid_split_rid(&sid, &local_rid);
1497                                 
1498                         if (sid_equal(&sid, &pol_sid)) {
1499                                 rid[i]=local_rid;
1500                                 type[i]=local_type;
1501                                 r_u->status = NT_STATUS_OK;
1502                         }
1503                 }
1504         }
1505
1506         unbecome_root();
1507
1508         init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1509
1510         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1511
1512         return r_u->status;
1513 }
1514
1515 /*******************************************************************
1516  _samr_chgpasswd_user
1517  ********************************************************************/
1518
1519 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1520 {
1521     fstring user_name;
1522     fstring wks;
1523
1524     DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1525
1526     r_u->status = NT_STATUS_OK;
1527
1528     rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1529     rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1530
1531     DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1532
1533         /*
1534          * Pass the user through the NT -> unix user mapping
1535          * function.
1536          */
1537  
1538         (void)map_username(user_name);
1539  
1540         /*
1541          * UNIX username case mangling not required, pass_oem_change 
1542          * is case insensitive.
1543          */
1544
1545     r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1546                                   q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1547
1548     init_samr_r_chgpasswd_user(r_u, r_u->status);
1549
1550     DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1551
1552     return r_u->status;
1553 }
1554
1555 /*******************************************************************
1556 makes a SAMR_R_LOOKUP_RIDS structure.
1557 ********************************************************************/
1558
1559 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1560             UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1561 {
1562         uint32 i;
1563         UNIHDR *hdr_name=NULL;
1564         UNISTR2 *uni_name=NULL;
1565
1566         *pp_uni_name = NULL;
1567         *pp_hdr_name = NULL;
1568
1569         if (num_names != 0) {
1570                 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1571                 if (hdr_name == NULL)
1572                         return False;
1573
1574                 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1575                 if (uni_name == NULL)
1576                         return False;
1577         }
1578
1579         for (i = 0; i < num_names; i++) {
1580                 int len = names[i] != NULL ? strlen(names[i]) : 0;
1581                 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1582                 init_uni_hdr(&hdr_name[i], len);
1583                 init_unistr2(&uni_name[i], names[i], len);
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  _api_samr_open_user. Safe - gives out no passwd info.
1665  ********************************************************************/
1666
1667 NTSTATUS _api_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, (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  _api_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 _api_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    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2209
2210         /* Get the domain SID stored in the domain policy */
2211         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2212                 return NT_STATUS_INVALID_HANDLE;
2213
2214         if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2215                 return nt_status;
2216         }
2217
2218         /* find the account: tell the caller if it exists.
2219           lkclXXXX i have *no* idea if this is a problem or not
2220           or even if you are supposed to construct a different
2221           reply if the account already exists...
2222          */
2223
2224         rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2225         strlower(account);
2226
2227         pdb_init_sam(&sam_pass);
2228
2229         become_root();
2230         ret = pdb_getsampwnam(sam_pass, account);
2231         unbecome_root();
2232         if (ret == True) {
2233                 /* this account exists: say so */
2234                 pdb_free_sam(&sam_pass);
2235                 return NT_STATUS_USER_EXISTS;
2236         }
2237
2238         pdb_free_sam(&sam_pass);
2239
2240         /*
2241          * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2242          * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2243          * that only people with write access to the smbpasswd file will be able
2244          * to create a user. JRA.
2245          */
2246
2247         /*
2248          * add the user in the /etc/passwd file or the unix authority system.
2249          * We don't check if the smb_create_user() function succed or not for 2 reasons:
2250          * a) local_password_change() checks for us if the /etc/passwd account really exists
2251          * b) smb_create_user() would return an error if the account already exists
2252          * and as it could return an error also if it can't create the account, it would be tricky.
2253          *
2254          * So we go the easy way, only check after if the account exists.
2255          * JFM (2/3/2001), to clear any possible bad understanding (-:
2256          *
2257          * We now have seperate script paramaters for adding users/machines so we
2258          * now have some sainity-checking to match. 
2259          */
2260
2261         DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2262 #if 0
2263         if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2264                 pstrcpy(add_script, lp_addmachine_script());            
2265         } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2266                 pstrcpy(add_script, lp_adduser_script());
2267         } else {
2268                 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2269                 pdb_free_sam(&sam_pass);
2270                 return NT_STATUS_UNSUCCESSFUL;
2271         }
2272 #endif
2273
2274         /* 
2275          * we can't check both the ending $ and the acb_info.
2276          * 
2277          * UserManager creates trust accounts (ending in $,
2278          * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2279          * JFM, 11/29/2001
2280          */
2281         if (account[strlen(account)-1] == '$')
2282                 pstrcpy(add_script, lp_addmachine_script());            
2283         else 
2284                 pstrcpy(add_script, lp_adduser_script());
2285
2286         if (*add_script) {
2287                 int add_ret;
2288                 all_string_sub(add_script, "%u", account, sizeof(account));
2289                 add_ret = smbrun(add_script,NULL);
2290                 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2291         }
2292         
2293         if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sam_pass))) {
2294                 return nt_status;
2295         }
2296                 
2297         pw = getpwnam_alloc(account);
2298
2299         if (pw) {
2300                 DOM_SID user_sid;
2301                 DOM_SID group_sid;
2302                 if (!uid_to_sid(&user_sid, pw->pw_uid)) {
2303                         passwd_free(&pw); /* done with this now */
2304                         pdb_free_sam(&sam_pass);
2305                         DEBUG(1, ("_api_samr_create_user: uid_to_sid failed, cannot add user.\n"));
2306                         return NT_STATUS_ACCESS_DENIED;
2307                 }
2308
2309                 if (!pdb_set_user_sid(sam_pass, &user_sid, PDB_CHANGED)) {
2310                         passwd_free(&pw); /* done with this now */
2311                         pdb_free_sam(&sam_pass);
2312                         return NT_STATUS_NO_MEMORY;
2313                 }
2314
2315                 if (!gid_to_sid(&group_sid, pw->pw_gid)) {
2316                         passwd_free(&pw); /* done with this now */
2317                         pdb_free_sam(&sam_pass);
2318                         DEBUG(1, ("_api_samr_create_user: gid_to_sid failed, cannot add user.\n"));
2319                         return NT_STATUS_ACCESS_DENIED;
2320                 }
2321
2322                 if (!pdb_set_group_sid(sam_pass, &group_sid, PDB_CHANGED)) {
2323                         passwd_free(&pw); /* done with this now */
2324                         pdb_free_sam(&sam_pass);
2325                         return NT_STATUS_NO_MEMORY;
2326                 }
2327
2328                 passwd_free(&pw); /* done with this now */
2329         } else {
2330                 DEBUG(3,("attempting to create non-unix account %s\n", account));
2331                 
2332                 }
2333                 
2334                 if (!pdb_set_username(sam_pass, account, PDB_CHANGED)) {
2335                         pdb_free_sam(&sam_pass);
2336                         return NT_STATUS_NO_MEMORY;
2337         }
2338
2339         pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2340  
2341         if (!pdb_add_sam_account(sam_pass)) {
2342                 pdb_free_sam(&sam_pass);
2343                 DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n", 
2344                           account));
2345                 return NT_STATUS_ACCESS_DENIED;         
2346         }
2347
2348         pdb_reset_sam(sam_pass);
2349         
2350         if (!pdb_getsampwnam(sam_pass, account)) {
2351                 pdb_free_sam(&sam_pass);
2352                 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n", 
2353                           account));
2354                 return NT_STATUS_ACCESS_DENIED;         
2355         }
2356         
2357         /* Get the user's SID */
2358         sid_copy(&sid, pdb_get_user_sid(sam_pass));
2359         
2360         samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2361         se_map_generic(&des_access, &usr_generic_mapping);
2362         if (!NT_STATUS_IS_OK(nt_status = 
2363                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2364                                                       des_access, &acc_granted, "_samr_create_user"))) {
2365                 return nt_status;
2366         }
2367
2368         /* associate the user's SID with the new handle. */
2369         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2370                 pdb_free_sam(&sam_pass);
2371                 return NT_STATUS_NO_MEMORY;
2372         }
2373
2374         ZERO_STRUCTP(info);
2375         info->sid = sid;
2376         info->acc_granted = acc_granted;
2377
2378         /* get a (unique) handle.  open a policy on it. */
2379         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2380                 pdb_free_sam(&sam_pass);
2381                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2382         }
2383
2384         r_u->user_rid=pdb_get_user_rid(sam_pass);
2385
2386         r_u->access_granted = acc_granted;
2387
2388         pdb_free_sam(&sam_pass);
2389
2390         return NT_STATUS_OK;
2391 }
2392
2393 /*******************************************************************
2394  samr_reply_connect_anon
2395  ********************************************************************/
2396
2397 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2398 {
2399         struct samr_info *info = NULL;
2400
2401         /* Access check */
2402
2403         if (!pipe_access_check(p)) {
2404                 DEBUG(3, ("access denied to samr_connect_anon\n"));
2405                 r_u->status = NT_STATUS_ACCESS_DENIED;
2406                 return r_u->status;
2407         }
2408
2409         /* set up the SAMR connect_anon response */
2410
2411         r_u->status = NT_STATUS_OK;
2412
2413         /* associate the user's SID with the new handle. */
2414         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2415                 return NT_STATUS_NO_MEMORY;
2416
2417         info->status = q_u->unknown_0;
2418
2419         /* get a (unique) handle.  open a policy on it. */
2420         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2421                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2422
2423         return r_u->status;
2424 }
2425
2426 /*******************************************************************
2427  samr_reply_connect
2428  ********************************************************************/
2429
2430 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2431 {
2432         struct samr_info *info = NULL;
2433         SEC_DESC *psd = NULL;
2434         uint32    acc_granted;
2435         uint32    des_access = q_u->access_mask;
2436         size_t    sd_size;
2437         NTSTATUS  nt_status;
2438
2439
2440         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2441
2442         /* Access check */
2443
2444         if (!pipe_access_check(p)) {
2445                 DEBUG(3, ("access denied to samr_connect\n"));
2446                 r_u->status = NT_STATUS_ACCESS_DENIED;
2447                 return r_u->status;
2448         }
2449
2450         samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2451         se_map_generic(&des_access, &sam_generic_mapping);
2452         if (!NT_STATUS_IS_OK(nt_status = 
2453                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2454                                                       des_access, &acc_granted, "_samr_connect"))) {
2455                 return nt_status;
2456         }
2457
2458         r_u->status = NT_STATUS_OK;
2459
2460         /* associate the user's SID and access granted with the new handle. */
2461         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2462                 return NT_STATUS_NO_MEMORY;
2463
2464         info->acc_granted = acc_granted;
2465         info->status = q_u->access_mask;
2466
2467         /* get a (unique) handle.  open a policy on it. */
2468         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2469                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2470
2471         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2472
2473         return r_u->status;
2474 }
2475
2476 /*******************************************************************
2477  samr_connect4
2478  ********************************************************************/
2479
2480 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2481 {
2482         struct samr_info *info = NULL;
2483         SEC_DESC *psd = NULL;
2484         uint32    acc_granted;
2485         uint32    des_access = q_u->access_mask;
2486         size_t    sd_size;
2487         NTSTATUS  nt_status;
2488
2489
2490         DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2491
2492         /* Access check */
2493
2494         if (!pipe_access_check(p)) {
2495                 DEBUG(3, ("access denied to samr_connect4\n"));
2496                 r_u->status = NT_STATUS_ACCESS_DENIED;
2497                 return r_u->status;
2498         }
2499
2500         samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2501         se_map_generic(&des_access, &sam_generic_mapping);
2502         if (!NT_STATUS_IS_OK(nt_status = 
2503                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2504                                                       des_access, &acc_granted, "_samr_connect"))) {
2505                 return nt_status;
2506         }
2507
2508         r_u->status = NT_STATUS_OK;
2509
2510         /* associate the user's SID and access granted with the new handle. */
2511         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2512                 return NT_STATUS_NO_MEMORY;
2513
2514         info->acc_granted = acc_granted;
2515         info->status = q_u->access_mask;
2516
2517         /* get a (unique) handle.  open a policy on it. */
2518         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2519                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2520
2521         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2522
2523         return r_u->status;
2524 }
2525
2526 /**********************************************************************
2527  api_samr_lookup_domain
2528  **********************************************************************/
2529
2530 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2531 {
2532         struct samr_info *info;
2533         fstring domain_name;
2534         DOM_SID sid;
2535
2536         r_u->status = NT_STATUS_OK;
2537
2538         if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2539                 return NT_STATUS_INVALID_HANDLE;
2540
2541         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2542                 return r_u->status;
2543         }
2544
2545         rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2546
2547         ZERO_STRUCT(sid);
2548
2549         if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2550                 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2551         }
2552
2553         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2554
2555         init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2556
2557         return r_u->status;
2558 }
2559
2560 /******************************************************************
2561 makes a SAMR_R_ENUM_DOMAINS structure.
2562 ********************************************************************/
2563
2564 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2565                         UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2566 {
2567         uint32 i;
2568         SAM_ENTRY *sam;
2569         UNISTR2 *uni_name;
2570
2571         DEBUG(5, ("make_enum_domains\n"));
2572
2573         *pp_sam = NULL;
2574         *pp_uni_name = NULL;
2575
2576         if (num_sam_entries == 0)
2577                 return True;
2578
2579         sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2580         uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2581
2582         if (sam == NULL || uni_name == NULL)
2583                 return False;
2584
2585         for (i = 0; i < num_sam_entries; i++) {
2586                 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2587
2588                 init_sam_entry(&sam[i], len, 0);
2589                 init_unistr2(&uni_name[i], doms[i], len);
2590         }
2591
2592         *pp_sam = sam;
2593         *pp_uni_name = uni_name;
2594
2595         return True;
2596 }
2597
2598 /**********************************************************************
2599  api_samr_enum_domains
2600  **********************************************************************/
2601
2602 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2603 {
2604         struct samr_info *info;
2605         uint32 num_entries = 2;
2606         fstring dom[2];
2607         const char *name;
2608
2609         r_u->status = NT_STATUS_OK;
2610         
2611         if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2612                 return NT_STATUS_INVALID_HANDLE;
2613         
2614         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2615                 return r_u->status;
2616         }
2617
2618         switch (lp_server_role()) {
2619         case ROLE_DOMAIN_PDC:
2620         case ROLE_DOMAIN_BDC:
2621                 name = lp_workgroup();
2622                 break;
2623         default:
2624                 name = global_myname();
2625         }
2626
2627         fstrcpy(dom[0],name);
2628         strupper(dom[0]);
2629         fstrcpy(dom[1],"Builtin");
2630
2631         if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2632                 return NT_STATUS_NO_MEMORY;
2633
2634         init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2635
2636         return r_u->status;
2637 }
2638
2639 /*******************************************************************
2640  api_samr_open_alias
2641  ********************************************************************/
2642
2643 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2644 {
2645         DOM_SID sid;
2646         POLICY_HND domain_pol = q_u->dom_pol;
2647         uint32 alias_rid = q_u->rid_alias;
2648         POLICY_HND *alias_pol = &r_u->pol;
2649         struct    samr_info *info = NULL;
2650         SEC_DESC *psd = NULL;
2651         uint32    acc_granted;
2652         uint32    des_access = q_u->access_mask;
2653         size_t    sd_size;
2654         NTSTATUS  status;
2655
2656         r_u->status = NT_STATUS_OK;
2657
2658         /* find the domain policy and get the SID / access bits stored in the domain policy */
2659         if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2660                 return NT_STATUS_INVALID_HANDLE;
2661                 
2662         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2663                 return status;
2664         }
2665
2666         /* append the alias' RID to it */
2667         if (!sid_append_rid(&sid, alias_rid))
2668                 return NT_STATUS_NO_SUCH_USER;
2669                 
2670         /*check if access can be granted as requested by client. */
2671         samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2672         se_map_generic(&des_access,&ali_generic_mapping);
2673         if (!NT_STATUS_IS_OK(status = 
2674                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2675                                                       des_access, &acc_granted, "_samr_open_alias"))) {
2676                 return status;
2677         }
2678
2679         /*
2680          * we should check if the rid really exist !!!
2681          * JFM.
2682          */
2683
2684         /* associate the user's SID with the new handle. */
2685         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2686                 return NT_STATUS_NO_MEMORY;
2687                 
2688         info->acc_granted = acc_granted;
2689
2690         /* get a (unique) handle.  open a policy on it. */
2691         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2692                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2693
2694         return r_u->status;
2695 }
2696
2697 /*******************************************************************
2698  set_user_info_10
2699  ********************************************************************/
2700
2701 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2702 {
2703         SAM_ACCOUNT *pwd =NULL;
2704         BOOL ret;
2705         
2706         pdb_init_sam(&pwd);
2707         
2708         ret = pdb_getsampwsid(pwd, sid);
2709         
2710         if(ret==False) {
2711                 pdb_free_sam(&pwd);
2712                 return False;
2713         }
2714
2715         if (id10 == NULL) {
2716                 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2717                 pdb_free_sam(&pwd);
2718                 return False;
2719         }
2720         
2721         /* FIX ME: check if the value is really changed --metze */
2722         if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2723                 pdb_free_sam(&pwd);
2724                 return False;
2725         }
2726
2727         if(!pdb_update_sam_account(pwd)) {
2728                 pdb_free_sam(&pwd);
2729                 return False;
2730         }
2731
2732         pdb_free_sam(&pwd);
2733
2734         return True;
2735 }
2736
2737 /*******************************************************************
2738  set_user_info_12
2739  ********************************************************************/
2740
2741 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2742 {
2743         SAM_ACCOUNT *pwd = NULL;
2744
2745         pdb_init_sam(&pwd);
2746
2747         if(!pdb_getsampwsid(pwd, sid)) {
2748                 pdb_free_sam(&pwd);
2749                 return False;
2750         }
2751
2752         if (id12 == NULL) {
2753                 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2754                 pdb_free_sam(&pwd);
2755                 return False;
2756         }
2757  
2758         if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2759                 pdb_free_sam(&pwd);
2760                 return False;
2761         }
2762         if (!pdb_set_nt_passwd     (pwd, id12->nt_pwd, PDB_CHANGED)) {
2763                 pdb_free_sam(&pwd);
2764                 return False;
2765         }
2766         if (!pdb_set_pass_changed_now (pwd)) {
2767                 pdb_free_sam(&pwd);
2768                 return False; 
2769         }
2770  
2771         if(!pdb_update_sam_account(pwd)) {
2772                 pdb_free_sam(&pwd);
2773                 return False;
2774         }
2775
2776         pdb_free_sam(&pwd);
2777         return True;
2778 }
2779
2780 /*******************************************************************
2781  set_user_info_21
2782  ********************************************************************/
2783
2784 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2785 {
2786         SAM_ACCOUNT *pwd = NULL;
2787  
2788         if (id21 == NULL) {
2789                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2790                 return False;
2791         }
2792  
2793         pdb_init_sam(&pwd);
2794  
2795         if (!pdb_getsampwsid(pwd, sid)) {
2796                 pdb_free_sam(&pwd);
2797                 return False;
2798         }
2799  
2800         copy_id21_to_sam_passwd(pwd, id21);
2801  
2802         /*
2803          * The funny part about the previous two calls is
2804          * that pwd still has the password hashes from the
2805          * passdb entry.  These have not been updated from
2806          * id21.  I don't know if they need to be set.    --jerry
2807          */
2808  
2809         /* write the change out */
2810         if(!pdb_update_sam_account(pwd)) {
2811                 pdb_free_sam(&pwd);
2812                 return False;
2813         }
2814
2815         pdb_free_sam(&pwd);
2816
2817         return True;
2818 }
2819
2820 /*******************************************************************
2821  set_user_info_23
2822  ********************************************************************/
2823
2824 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2825 {
2826         SAM_ACCOUNT *pwd = NULL;
2827         pstring plaintext_buf;
2828         uint32 len;
2829         uint16 acct_ctrl;
2830  
2831         if (id23 == NULL) {
2832                 DEBUG(5, ("set_user_info_23: NULL id23\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         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2844                   pdb_get_username(pwd)));
2845
2846         acct_ctrl = pdb_get_acct_ctrl(pwd);
2847
2848         if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2849                 pdb_free_sam(&pwd);
2850                 return False;
2851         }
2852   
2853         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2854                 pdb_free_sam(&pwd);
2855                 return False;
2856         }
2857  
2858         copy_id23_to_sam_passwd(pwd, id23);
2859  
2860         /* if it's a trust account, don't update /etc/passwd */
2861         if ( (!IS_SAM_UNIX_USER(pwd)) ||
2862                 ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2863                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2864                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2865                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2866         } else  {
2867                 /* update the UNIX password */
2868                 if (lp_unix_password_sync() )
2869                         if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2870                                 pdb_free_sam(&pwd);
2871                                 return False;
2872                         }
2873         }
2874  
2875         ZERO_STRUCT(plaintext_buf);
2876  
2877         if(!pdb_update_sam_account(pwd)) {
2878                 pdb_free_sam(&pwd);
2879                 return False;
2880         }
2881  
2882         pdb_free_sam(&pwd);
2883
2884         return True;
2885 }
2886
2887 /*******************************************************************
2888  set_user_info_pw
2889  ********************************************************************/
2890
2891 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2892 {
2893         SAM_ACCOUNT *pwd = NULL;
2894         uint32 len;
2895         pstring plaintext_buf;
2896         uint16 acct_ctrl;
2897  
2898         pdb_init_sam(&pwd);
2899  
2900         if (!pdb_getsampwsid(pwd, sid)) {
2901                 pdb_free_sam(&pwd);
2902                 return False;
2903         }
2904         
2905         DEBUG(5, ("Attempting administrator password change for user %s\n",
2906                   pdb_get_username(pwd)));
2907
2908         acct_ctrl = pdb_get_acct_ctrl(pwd);
2909
2910         ZERO_STRUCT(plaintext_buf);
2911  
2912         if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2913                 pdb_free_sam(&pwd);
2914                 return False;
2915         }
2916
2917         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2918                 pdb_free_sam(&pwd);
2919                 return False;
2920         }
2921  
2922         /* if it's a trust account, don't update /etc/passwd */
2923         if ( (!IS_SAM_UNIX_USER(pwd)) ||
2924                 ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2925                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2926                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2927                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2928         } else {
2929                 /* update the UNIX password */
2930                 if (lp_unix_password_sync()) {
2931                         if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2932                                 pdb_free_sam(&pwd);
2933                                 return False;
2934                         }
2935                 }
2936         }
2937  
2938         ZERO_STRUCT(plaintext_buf);
2939  
2940         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2941  
2942         /* update the SAMBA password */
2943         if(!pdb_update_sam_account(pwd)) {
2944                 pdb_free_sam(&pwd);
2945                 return False;
2946         }
2947
2948         pdb_free_sam(&pwd);
2949
2950         return True;
2951 }
2952
2953 /*******************************************************************
2954  samr_reply_set_userinfo
2955  ********************************************************************/
2956
2957 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2958 {
2959         DOM_SID sid;
2960         POLICY_HND *pol = &q_u->pol;
2961         uint16 switch_value = q_u->switch_value;
2962         SAM_USERINFO_CTR *ctr = q_u->ctr;
2963         uint32 acc_granted;
2964         uint32 acc_required;
2965
2966         DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2967
2968         r_u->status = NT_STATUS_OK;
2969
2970         /* find the policy handle.  open a policy on it. */
2971         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2972                 return NT_STATUS_INVALID_HANDLE;
2973         
2974         acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */   
2975         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2976                 return r_u->status;
2977         }
2978                 
2979         DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2980
2981         if (ctr == NULL) {
2982                 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2983                 return NT_STATUS_INVALID_INFO_CLASS;
2984         }
2985
2986         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2987         switch (switch_value) {
2988                 case 0x12:
2989                         if (!set_user_info_12(ctr->info.id12, &sid))
2990                                 return NT_STATUS_ACCESS_DENIED;
2991                         break;
2992
2993                 case 24:
2994                         SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2995
2996                         dump_data(100, (char *)ctr->info.id24->pass, 516);
2997
2998                         if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2999                                 return NT_STATUS_ACCESS_DENIED;
3000                         break;
3001
3002                 case 25:
3003 #if 0
3004                         /*
3005                          * Currently we don't really know how to unmarshall
3006                          * the level 25 struct, and the password encryption
3007                          * is different. This is a placeholder for when we
3008                          * do understand it. In the meantime just return INVALID
3009                          * info level and W2K SP2 drops down to level 23... JRA.
3010                          */
3011
3012                         SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3013
3014                         dump_data(100, (char *)ctr->info.id25->pass, 532);
3015
3016                         if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3017                                 return NT_STATUS_ACCESS_DENIED;
3018                         break;
3019 #endif
3020                         return NT_STATUS_INVALID_INFO_CLASS;
3021
3022                 case 23:
3023                         SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3024
3025                         dump_data(100, (char *)ctr->info.id23->pass, 516);
3026
3027                         if (!set_user_info_23(ctr->info.id23, &sid))
3028                                 return NT_STATUS_ACCESS_DENIED;
3029                         break;
3030
3031                 default:
3032                         return NT_STATUS_INVALID_INFO_CLASS;
3033         }
3034
3035         return r_u->status;
3036 }
3037
3038 /*******************************************************************
3039  samr_reply_set_userinfo2
3040  ********************************************************************/
3041
3042 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3043 {
3044         DOM_SID sid;
3045         SAM_USERINFO_CTR *ctr = q_u->ctr;
3046         POLICY_HND *pol = &q_u->pol;
3047         uint16 switch_value = q_u->switch_value;
3048         uint32 acc_granted;
3049         uint32 acc_required;
3050
3051         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3052
3053         r_u->status = NT_STATUS_OK;
3054
3055         /* find the policy handle.  open a policy on it. */
3056         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3057                 return NT_STATUS_INVALID_HANDLE;
3058         
3059         acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */   
3060         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3061                 return r_u->status;
3062         }
3063
3064         DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3065
3066         if (ctr == NULL) {
3067                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3068                 return NT_STATUS_INVALID_INFO_CLASS;
3069         }
3070
3071         switch_value=ctr->switch_value;
3072
3073         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3074         switch (switch_value) {
3075                 case 21:
3076                         if (!set_user_info_21(ctr->info.id21, &sid))
3077                                 return NT_STATUS_ACCESS_DENIED;
3078                         break;
3079                 case 16:
3080                         if (!set_user_info_10(ctr->info.id10, &sid))
3081                                 return NT_STATUS_ACCESS_DENIED;
3082                         break;
3083                 case 18:
3084                         /* Used by AS/U JRA. */
3085                         if (!set_user_info_12(ctr->info.id12, &sid))
3086                                 return NT_STATUS_ACCESS_DENIED;
3087                         break;
3088                 default:
3089                         return NT_STATUS_INVALID_INFO_CLASS;
3090         }
3091
3092         return r_u->status;
3093 }
3094
3095 /*********************************************************************
3096  _samr_query_aliasmem
3097 *********************************************************************/
3098
3099 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3100 {
3101         int num_groups = 0, tmp_num_groups=0;
3102         uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3103         struct samr_info *info = NULL;
3104         int i,j;
3105                 
3106         NTSTATUS ntstatus1;
3107         NTSTATUS ntstatus2;
3108
3109         /* until i see a real useraliases query, we fack one up */
3110
3111         /* I have seen one, JFM 2/12/2001 */
3112         /*
3113          * Explanation of what this call does:
3114          * for all the SID given in the request:
3115          * return a list of alias (local groups)
3116          * that have those SID as members.
3117          *
3118          * and that's the alias in the domain specified
3119          * in the policy_handle
3120          *
3121          * if the policy handle is on an incorrect sid
3122          * for example a user's sid
3123          * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3124          */
3125         
3126         r_u->status = NT_STATUS_OK;
3127
3128         DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3129
3130         /* find the policy handle.  open a policy on it. */
3131         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3132                 return NT_STATUS_INVALID_HANDLE;
3133                 
3134         ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3135         ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3136         
3137         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3138                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3139                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3140                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3141                 }
3142         }               
3143
3144         if (!sid_check_is_domain(&info->sid) &&
3145             !sid_check_is_builtin(&info->sid))
3146                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3147
3148
3149         for (i=0; i<q_u->num_sids1; i++) {
3150
3151                 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3152
3153                 /*
3154                  * if there is an error, we just continue as
3155                  * it can be an unfound user or group
3156                  */
3157                 if (!NT_STATUS_IS_OK(r_u->status)) {
3158                         DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3159                         continue;
3160                 }
3161
3162                 if (tmp_num_groups==0) {
3163                         DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3164                         continue;
3165                 }
3166
3167                 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3168                 if (new_rids==NULL) {
3169                         DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3170                         return NT_STATUS_NO_MEMORY;
3171                 }
3172                 rids=new_rids;
3173
3174                 for (j=0; j<tmp_num_groups; j++)
3175                         rids[j+num_groups]=tmp_rids[j];
3176                 
3177                 safe_free(tmp_rids);
3178                 
3179                 num_groups+=tmp_num_groups;
3180         }
3181         
3182         init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3183         return NT_STATUS_OK;
3184 }
3185
3186 /*********************************************************************
3187  _samr_query_aliasmem
3188 *********************************************************************/
3189
3190 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3191 {
3192         int i;
3193
3194         GROUP_MAP map;
3195         int num_uids = 0;
3196         DOM_SID2 *sid;
3197         uid_t *uid=NULL;
3198
3199         DOM_SID alias_sid;
3200         DOM_SID als_sid;
3201         uint32 alias_rid;
3202         fstring alias_sid_str;
3203         DOM_SID temp_sid;
3204
3205         SAM_ACCOUNT *sam_user = NULL;
3206         BOOL check;
3207         uint32 acc_granted;
3208
3209         /* find the policy handle.  open a policy on it. */
3210         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3211                 return NT_STATUS_INVALID_HANDLE;
3212         
3213         if (!NT_STATUS_IS_OK(r_u->status = 
3214                 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3215                 return r_u->status;
3216         }
3217                 
3218         sid_copy(&als_sid, &alias_sid);
3219         sid_to_string(alias_sid_str, &alias_sid);
3220         sid_split_rid(&alias_sid, &alias_rid);
3221
3222         DEBUG(10, ("sid is %s\n", alias_sid_str));
3223
3224         if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3225                 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3226                 if(!get_builtin_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3227                         return NT_STATUS_NO_SUCH_ALIAS;
3228         } else {
3229                 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3230                         DEBUG(10, ("lookup on Server SID\n"));
3231                         if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3232                                 return NT_STATUS_NO_SUCH_ALIAS;
3233                 }
3234         }
3235
3236         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3237                 return NT_STATUS_NO_SUCH_ALIAS;
3238
3239         DEBUG(10, ("sid is %s\n", alias_sid_str));
3240         sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids); 
3241         if (num_uids!=0 && sid == NULL) 
3242                 return NT_STATUS_NO_MEMORY;
3243
3244         for (i = 0; i < num_uids; i++) {
3245                 struct passwd *pass;
3246                 uint32 rid;
3247
3248                 sid_copy(&temp_sid, get_global_sam_sid());
3249
3250                 pass = getpwuid_alloc(uid[i]);
3251                 if (!pass) continue;
3252
3253                 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3254                         passwd_free(&pass);
3255                         continue;
3256                 }
3257
3258                 become_root();
3259                 check = pdb_getsampwnam(sam_user, pass->pw_name);
3260                 unbecome_root();
3261         
3262                 if (check != True) {
3263                         pdb_free_sam(&sam_user);
3264                         passwd_free(&pass);
3265                         continue;
3266                 }
3267         
3268                 rid = pdb_get_user_rid(sam_user);
3269                 if (rid == 0) {
3270                         pdb_free_sam(&sam_user);
3271                         passwd_free(&pass);
3272                         continue;
3273                 }
3274
3275                 pdb_free_sam(&sam_user);
3276                 passwd_free(&pass);
3277
3278                 sid_append_rid(&temp_sid, rid);
3279                 
3280                 init_dom_sid2(&sid[i], &temp_sid);
3281         }
3282
3283         DEBUG(10, ("sid is %s\n", alias_sid_str));
3284         init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3285
3286         return NT_STATUS_OK;
3287 }
3288
3289 /*********************************************************************
3290  _samr_query_groupmem
3291 *********************************************************************/
3292
3293 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3294 {
3295         int num_uids = 0;
3296         int i;
3297         DOM_SID group_sid;
3298         uint32 group_rid;
3299         fstring group_sid_str;
3300         uid_t *uid=NULL;
3301         
3302         GROUP_MAP map;
3303
3304         uint32 *rid=NULL;
3305         uint32 *attr=NULL;
3306
3307         SAM_ACCOUNT *sam_user = NULL;
3308         BOOL check;
3309         uint32 acc_granted;
3310
3311         /* find the policy handle.  open a policy on it. */
3312         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3313                 return NT_STATUS_INVALID_HANDLE;
3314                 
3315         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3316                 return r_u->status;
3317         }
3318                 
3319         /* todo: change to use sid_compare_front */
3320
3321         sid_split_rid(&group_sid, &group_rid);
3322         sid_to_string(group_sid_str, &group_sid);
3323         DEBUG(10, ("sid is %s\n", group_sid_str));
3324
3325         /* can we get a query for an SID outside our domain ? */
3326         if (!sid_equal(&group_sid, get_global_sam_sid()))
3327                 return NT_STATUS_NO_SUCH_GROUP;
3328
3329         sid_append_rid(&group_sid, group_rid);
3330         DEBUG(10, ("lookup on Domain SID\n"));
3331
3332         if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3333                 return NT_STATUS_NO_SUCH_GROUP;
3334
3335         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3336                 return NT_STATUS_NO_SUCH_GROUP;
3337
3338         rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3339         attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3340         
3341         if (num_uids!=0 && (rid==NULL || attr==NULL))
3342                 return NT_STATUS_NO_MEMORY;
3343         
3344         for (i=0; i<num_uids; i++) {
3345                 struct passwd *pass;
3346                 uint32 urid;
3347
3348                 pass = getpwuid_alloc(uid[i]);
3349                 if (!pass) continue;
3350
3351                 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3352                         passwd_free(&pass);
3353                         continue;
3354                 }
3355
3356                 become_root();
3357                 check = pdb_getsampwnam(sam_user, pass->pw_name);
3358                 unbecome_root();
3359         
3360                 if (check != True) {
3361                         pdb_free_sam(&sam_user);
3362                         passwd_free(&pass);
3363                         continue;
3364                 }
3365         
3366                 urid = pdb_get_user_rid(sam_user);
3367                 if (urid == 0) {
3368                         pdb_free_sam(&sam_user);
3369                         passwd_free(&pass);
3370                         continue;
3371                 }
3372
3373                 pdb_free_sam(&sam_user);
3374                 passwd_free(&pass);
3375
3376                 rid[i] = urid;
3377                 attr[i] = SID_NAME_USER;                
3378         }
3379
3380         init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3381
3382         return NT_STATUS_OK;
3383 }
3384
3385 /*********************************************************************
3386  _samr_add_aliasmem
3387 *********************************************************************/
3388
3389 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3390 {
3391         DOM_SID alias_sid;
3392         fstring alias_sid_str;
3393         uid_t uid;
3394         struct passwd *pwd;
3395         struct group *grp;
3396         fstring grp_name;
3397         GROUP_MAP map;
3398         NTSTATUS ret;
3399         SAM_ACCOUNT *sam_user = NULL;
3400         BOOL check;
3401         uint32 acc_granted;
3402
3403         /* Find the policy handle. Open a policy on it. */
3404         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3405                 return NT_STATUS_INVALID_HANDLE;
3406         
3407         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3408                 return r_u->status;
3409         }
3410                 
3411         sid_to_string(alias_sid_str, &alias_sid);
3412         DEBUG(10, ("sid is %s\n", alias_sid_str));
3413
3414         if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3415                 DEBUG(10, ("adding member on Server SID\n"));
3416                 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3417                         return NT_STATUS_NO_SUCH_ALIAS;
3418         
3419         } else {
3420                 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3421                         DEBUG(10, ("adding member on BUILTIN SID\n"));
3422                         if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3423                                 return NT_STATUS_NO_SUCH_ALIAS;
3424
3425                 } else
3426                         return NT_STATUS_NO_SUCH_ALIAS;
3427         }
3428
3429         ret = pdb_init_sam(&sam_user);
3430         if (!NT_STATUS_IS_OK(ret))
3431                 return ret;
3432         
3433         check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3434         
3435         if (check != True) {
3436                 pdb_free_sam(&sam_user);
3437                 return NT_STATUS_NO_SUCH_USER;
3438         }
3439         
3440         uid = pdb_get_uid(sam_user);
3441         if (uid == -1) {
3442                 pdb_free_sam(&sam_user);
3443                 return NT_STATUS_NO_SUCH_USER;
3444         }
3445
3446         pdb_free_sam(&sam_user);
3447
3448         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3449                 return NT_STATUS_NO_SUCH_USER;
3450         }
3451
3452         if ((grp=getgrgid(map.gid)) == NULL) {
3453                 passwd_free(&pwd);
3454                 return NT_STATUS_NO_SUCH_ALIAS;
3455         }
3456
3457         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3458         fstrcpy(grp_name, grp->gr_name);
3459
3460         /* if the user is already in the group */
3461         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3462                 passwd_free(&pwd);
3463                 return NT_STATUS_MEMBER_IN_ALIAS;
3464         }
3465
3466         /* 
3467          * ok, the group exist, the user exist, the user is not in the group,
3468          * we can (finally) add it to the group !
3469          */
3470         smb_add_user_group(grp_name, pwd->pw_name);
3471
3472         /* check if the user has been added then ... */
3473         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3474                 passwd_free(&pwd);
3475                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3476         }
3477
3478         passwd_free(&pwd);
3479         return NT_STATUS_OK;
3480 }
3481
3482 /*********************************************************************
3483  _samr_del_aliasmem
3484 *********************************************************************/
3485
3486 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3487 {
3488         DOM_SID alias_sid;
3489         fstring alias_sid_str;
3490         struct group *grp;
3491         fstring grp_name;
3492         GROUP_MAP map;
3493         SAM_ACCOUNT *sam_pass=NULL;
3494         uint32 acc_granted;
3495
3496         /* Find the policy handle. Open a policy on it. */
3497         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3498                 return NT_STATUS_INVALID_HANDLE;
3499         
3500         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3501                 return r_u->status;
3502         }
3503         
3504         sid_to_string(alias_sid_str, &alias_sid);
3505         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3506
3507         if (!sid_check_is_in_our_domain(&alias_sid) &&
3508             !sid_check_is_in_builtin(&alias_sid)) {
3509                 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3510                 return NT_STATUS_NO_SUCH_ALIAS;
3511         }
3512
3513         if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3514                 return NT_STATUS_NO_SUCH_ALIAS;
3515
3516         if ((grp=getgrgid(map.gid)) == NULL)
3517                 return NT_STATUS_NO_SUCH_ALIAS;
3518
3519         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3520         fstrcpy(grp_name, grp->gr_name);
3521
3522         /* check if the user exists before trying to remove it from the group */
3523         pdb_init_sam(&sam_pass);
3524         if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3525                 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3526                 pdb_free_sam(&sam_pass);
3527                 return NT_STATUS_NO_SUCH_USER;
3528         }
3529
3530         /* if the user is not in the group */
3531         if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3532                 pdb_free_sam(&sam_pass);
3533                 return NT_STATUS_MEMBER_IN_ALIAS;
3534         }
3535
3536         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3537
3538         /* check if the user has been removed then ... */
3539         if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3540                 pdb_free_sam(&sam_pass);
3541                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3542         }
3543
3544         pdb_free_sam(&sam_pass);
3545         return NT_STATUS_OK;
3546 }
3547
3548 /*********************************************************************
3549  _samr_add_groupmem
3550 *********************************************************************/
3551
3552 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3553 {
3554         DOM_SID group_sid;
3555         DOM_SID user_sid;
3556         fstring group_sid_str;
3557         struct passwd *pwd;
3558         struct group *grp;
3559         fstring grp_name;
3560         GROUP_MAP map;
3561         uid_t uid;
3562         NTSTATUS ret;
3563         SAM_ACCOUNT *sam_user=NULL;
3564         BOOL check;
3565         uint32 acc_granted;
3566
3567         /* Find the policy handle. Open a policy on it. */
3568         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3569                 return NT_STATUS_INVALID_HANDLE;
3570         
3571         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3572                 return r_u->status;
3573         }
3574
3575         sid_to_string(group_sid_str, &group_sid);
3576         DEBUG(10, ("sid is %s\n", group_sid_str));
3577
3578         if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3579                 return NT_STATUS_NO_SUCH_GROUP;
3580
3581         DEBUG(10, ("lookup on Domain SID\n"));
3582
3583         if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3584                 return NT_STATUS_NO_SUCH_GROUP;
3585
3586         sid_copy(&user_sid, get_global_sam_sid());
3587         sid_append_rid(&user_sid, q_u->rid);
3588
3589         ret = pdb_init_sam(&sam_user);
3590         if (!NT_STATUS_IS_OK(ret))
3591                 return ret;
3592         
3593         check = pdb_getsampwsid(sam_user, &user_sid);
3594         
3595         if (check != True) {
3596                 pdb_free_sam(&sam_user);
3597                 return NT_STATUS_NO_SUCH_USER;
3598         }
3599         
3600         uid = pdb_get_uid(sam_user);
3601         if (uid == -1) {
3602                 pdb_free_sam(&sam_user);
3603                 return NT_STATUS_NO_SUCH_USER;
3604         }
3605
3606         pdb_free_sam(&sam_user);
3607
3608         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3609                 return NT_STATUS_NO_SUCH_USER;
3610         }
3611
3612         if ((grp=getgrgid(map.gid)) == NULL) {
3613                 passwd_free(&pwd);
3614                 return NT_STATUS_NO_SUCH_GROUP;
3615         }
3616
3617         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3618         fstrcpy(grp_name, grp->gr_name);
3619
3620         /* if the user is already in the group */
3621         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3622                 passwd_free(&pwd);
3623                 return NT_STATUS_MEMBER_IN_GROUP;
3624         }
3625
3626         /* 
3627          * ok, the group exist, the user exist, the user is not in the group,
3628          *
3629          * we can (finally) add it to the group !
3630          */
3631
3632         smb_add_user_group(grp_name, pwd->pw_name);
3633
3634         /* check if the user has been added then ... */
3635         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3636                 passwd_free(&pwd);
3637                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
3638         }
3639
3640         passwd_free(&pwd);
3641         return NT_STATUS_OK;
3642 }
3643
3644 /*********************************************************************
3645  _samr_del_groupmem
3646 *********************************************************************/
3647
3648 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3649 {
3650         DOM_SID group_sid;
3651         DOM_SID user_sid;
3652         SAM_ACCOUNT *sam_pass=NULL;
3653         GROUP_MAP map;
3654         fstring grp_name;
3655         struct group *grp;
3656         uint32 acc_granted;
3657
3658         /*
3659          * delete the group member named q_u->rid
3660          * who is a member of the sid associated with the handle
3661          * the rid is a user's rid as the group is a domain group.
3662          */
3663
3664         /* Find the policy handle. Open a policy on it. */
3665         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3666                 return NT_STATUS_INVALID_HANDLE;
3667         
3668         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3669                 return r_u->status;
3670         }
3671                 
3672         if (!sid_check_is_in_our_domain(&group_sid))
3673                 return NT_STATUS_NO_SUCH_GROUP;
3674
3675         sid_copy(&user_sid, get_global_sam_sid());
3676         sid_append_rid(&user_sid, q_u->rid);
3677
3678         if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3679                 return NT_STATUS_NO_SUCH_GROUP;
3680
3681         if ((grp=getgrgid(map.gid)) == NULL)
3682                 return NT_STATUS_NO_SUCH_GROUP;
3683
3684         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3685         fstrcpy(grp_name, grp->gr_name);
3686
3687         /* check if the user exists before trying to remove it from the group */
3688         pdb_init_sam(&sam_pass);
3689         if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3690                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3691                 pdb_free_sam(&sam_pass);
3692                 return NT_STATUS_NO_SUCH_USER;
3693         }
3694
3695         /* if the user is not in the group */
3696         if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3697                 pdb_free_sam(&sam_pass);
3698                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3699         }
3700
3701         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3702
3703         /* check if the user has been removed then ... */
3704         if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3705                 pdb_free_sam(&sam_pass);
3706                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3707         }
3708         
3709         pdb_free_sam(&sam_pass);
3710         return NT_STATUS_OK;
3711
3712 }
3713
3714 /****************************************************************************
3715  Delete a UNIX user on demand.
3716 ****************************************************************************/
3717
3718 static int smb_delete_user(const char *unix_user)
3719 {
3720         pstring del_script;
3721         int ret;
3722
3723         pstrcpy(del_script, lp_deluser_script());
3724         if (! *del_script)
3725                 return -1;
3726         all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3727         ret = smbrun(del_script,NULL);
3728         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3729         return ret;
3730 }
3731
3732 /*********************************************************************
3733  _samr_delete_dom_user
3734 *********************************************************************/
3735
3736 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3737 {
3738         DOM_SID user_sid;
3739         SAM_ACCOUNT *sam_pass=NULL;
3740         uint32 acc_granted;
3741
3742         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3743
3744         /* Find the policy handle. Open a policy on it. */
3745         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
3746                 return NT_STATUS_INVALID_HANDLE;
3747                 
3748         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3749                 return r_u->status;
3750         }
3751                 
3752         if (!sid_check_is_in_our_domain(&user_sid))
3753                 return NT_STATUS_CANNOT_DELETE;
3754
3755         /* check if the user exists before trying to delete */
3756         pdb_init_sam(&sam_pass);
3757         if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3758                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3759                 pdb_free_sam(&sam_pass);
3760                 return NT_STATUS_NO_SUCH_USER;
3761         }
3762
3763         /* delete the unix side */
3764         /*
3765          * note: we don't check if the delete really happened
3766          * as the script is not necessary present
3767          * and maybe the sysadmin doesn't want to delete the unix side
3768          */
3769         smb_delete_user(pdb_get_username(sam_pass));
3770
3771         /* and delete the samba side */
3772         if (!pdb_delete_sam_account(sam_pass)) {
3773                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3774                 pdb_free_sam(&sam_pass);
3775                 return NT_STATUS_CANNOT_DELETE;
3776         }
3777         
3778         pdb_free_sam(&sam_pass);
3779
3780         if (!close_policy_hnd(p, &q_u->user_pol))
3781                 return NT_STATUS_OBJECT_NAME_INVALID;
3782
3783         return NT_STATUS_OK;
3784 }
3785
3786 /*********************************************************************