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