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