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