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