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