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