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