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