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