Merge branch 'selftest' of git://git.samba.org/jelmer/samba
[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-2005,
9  *  Copyright (C) Jean François Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *  Copyright (C) Guenther Deschner                 2008.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /*
31  * This is the implementation of the SAMR code.
32  */
33
34 #include "includes.h"
35
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
38
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40                 ( READ_CONTROL_ACCESS           | \
41                   SA_RIGHT_USER_CHANGE_PASSWORD | \
42                   SA_RIGHT_USER_SET_LOC_COM )
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44                 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
45
46 #define DISP_INFO_CACHE_TIMEOUT 10
47
48 typedef struct disp_info {
49         DOM_SID sid; /* identify which domain this is. */
50         bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
51         struct pdb_search *users; /* querydispinfo 1 and 4 */
52         struct pdb_search *machines; /* querydispinfo 2 */
53         struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
54         struct pdb_search *aliases; /* enumaliases */
55
56         uint16 enum_acb_mask;
57         struct pdb_search *enum_users; /* enumusers with a mask */
58
59         struct timed_event *cache_timeout_event; /* cache idle timeout
60                                                   * handler. */
61 } DISP_INFO;
62
63 /* We keep a static list of these by SID as modern clients close down
64    all resources between each request in a complete enumeration. */
65
66 struct samr_info {
67         /* for use by the \PIPE\samr policy */
68         DOM_SID sid;
69         bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
70         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
71         uint32 acc_granted;
72         DISP_INFO *disp_info;
73         TALLOC_CTX *mem_ctx;
74 };
75
76 static const struct generic_mapping sam_generic_mapping = {
77         GENERIC_RIGHTS_SAM_READ,
78         GENERIC_RIGHTS_SAM_WRITE,
79         GENERIC_RIGHTS_SAM_EXECUTE,
80         GENERIC_RIGHTS_SAM_ALL_ACCESS};
81 static const struct generic_mapping dom_generic_mapping = {
82         GENERIC_RIGHTS_DOMAIN_READ,
83         GENERIC_RIGHTS_DOMAIN_WRITE,
84         GENERIC_RIGHTS_DOMAIN_EXECUTE,
85         GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
86 static const struct generic_mapping usr_generic_mapping = {
87         GENERIC_RIGHTS_USER_READ,
88         GENERIC_RIGHTS_USER_WRITE,
89         GENERIC_RIGHTS_USER_EXECUTE,
90         GENERIC_RIGHTS_USER_ALL_ACCESS};
91 static const struct generic_mapping usr_nopwchange_generic_mapping = {
92         GENERIC_RIGHTS_USER_READ,
93         GENERIC_RIGHTS_USER_WRITE,
94         GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
95         GENERIC_RIGHTS_USER_ALL_ACCESS};
96 static const struct generic_mapping grp_generic_mapping = {
97         GENERIC_RIGHTS_GROUP_READ,
98         GENERIC_RIGHTS_GROUP_WRITE,
99         GENERIC_RIGHTS_GROUP_EXECUTE,
100         GENERIC_RIGHTS_GROUP_ALL_ACCESS};
101 static const struct generic_mapping ali_generic_mapping = {
102         GENERIC_RIGHTS_ALIAS_READ,
103         GENERIC_RIGHTS_ALIAS_WRITE,
104         GENERIC_RIGHTS_ALIAS_EXECUTE,
105         GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
106
107 /*******************************************************************
108 *******************************************************************/
109
110 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
111                                      const struct generic_mapping *map,
112                                      DOM_SID *sid, uint32 sid_access )
113 {
114         DOM_SID domadmin_sid;
115         SEC_ACE ace[5];         /* at most 5 entries */
116         size_t i = 0;
117
118         SEC_ACL *psa = NULL;
119
120         /* basic access for Everyone */
121
122         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
123                         map->generic_execute | map->generic_read, 0);
124
125         /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
126
127         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
128                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
129         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
130                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
131
132         /* Add Full Access for Domain Admins if we are a DC */
133
134         if ( IS_DC ) {
135                 sid_copy( &domadmin_sid, get_global_sam_sid() );
136                 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
137                 init_sec_ace(&ace[i++], &domadmin_sid,
138                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
139         }
140
141         /* if we have a sid, give it some special access */
142
143         if ( sid ) {
144                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
145         }
146
147         /* create the security descriptor */
148
149         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
150                 return NT_STATUS_NO_MEMORY;
151
152         if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
153                                   SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
154                                   psa, sd_size)) == NULL)
155                 return NT_STATUS_NO_MEMORY;
156
157         return NT_STATUS_OK;
158 }
159
160 /*******************************************************************
161  Checks if access to an object should be granted, and returns that
162  level of access for further checks.
163 ********************************************************************/
164
165 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
166                                           SE_PRIV *rights, uint32 rights_mask,
167                                           uint32 des_access, uint32 *acc_granted,
168                                           const char *debug )
169 {
170         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
171         uint32 saved_mask = 0;
172
173         /* check privileges; certain SAM access bits should be overridden
174            by privileges (mostly having to do with creating/modifying/deleting
175            users and groups) */
176
177         if ( rights && user_has_any_privilege( token, rights ) ) {
178
179                 saved_mask = (des_access & rights_mask);
180                 des_access &= ~saved_mask;
181
182                 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
183                         rights_mask));
184         }
185
186
187         /* check the security descriptor first */
188
189         if ( se_access_check(psd, token, des_access, acc_granted, &status) )
190                 goto done;
191
192         /* give root a free pass */
193
194         if ( geteuid() == sec_initial_uid() ) {
195
196                 DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
197                 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
198
199                 *acc_granted = des_access;
200
201                 status = NT_STATUS_OK;
202                 goto done;
203         }
204
205
206 done:
207         /* add in any bits saved during the privilege check (only
208            matters is status is ok) */
209
210         *acc_granted |= rights_mask;
211
212         DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
213                 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
214                 des_access, *acc_granted));
215
216         return status;
217 }
218
219 /*******************************************************************
220  Checks if access to a function can be granted
221 ********************************************************************/
222
223 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
224 {
225         DEBUG(5,("%s: access check ((granted: %#010x;  required: %#010x)\n",
226                 debug, acc_granted, acc_required));
227
228         /* check the security descriptor first */
229
230         if ( (acc_granted&acc_required) == acc_required )
231                 return NT_STATUS_OK;
232
233         /* give root a free pass */
234
235         if (geteuid() == sec_initial_uid()) {
236
237                 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
238                         debug, acc_granted, acc_required));
239                 DEBUGADD(4,("but overwritten by euid == 0\n"));
240
241                 return NT_STATUS_OK;
242         }
243
244         DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n",
245                 debug, acc_granted, acc_required));
246
247         return NT_STATUS_ACCESS_DENIED;
248 }
249
250 /*******************************************************************
251  Fetch or create a dispinfo struct.
252 ********************************************************************/
253
254 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
255 {
256         /*
257          * We do a static cache for DISP_INFO's here. Explanation can be found
258          * in Jeremy's checkin message to r11793:
259          *
260          * Fix the SAMR cache so it works across completely insane
261          * client behaviour (ie.:
262          * open pipe/open SAMR handle/enumerate 0 - 1024
263          * close SAMR handle, close pipe.
264          * open pipe/open SAMR handle/enumerate 1024 - 2048...
265          * close SAMR handle, close pipe.
266          * And on ad-nausium. Amazing.... probably object-oriented
267          * client side programming in action yet again.
268          * This change should *massively* improve performance when
269          * enumerating users from an LDAP database.
270          * Jeremy.
271          *
272          * "Our" and the builtin domain are the only ones where we ever
273          * enumerate stuff, so just cache 2 entries.
274          */
275
276         static struct disp_info builtin_dispinfo;
277         static struct disp_info domain_dispinfo;
278
279         /* There are two cases to consider here:
280            1) The SID is a domain SID and we look for an equality match, or
281            2) This is an account SID and so we return the DISP_INFO* for our
282               domain */
283
284         if (psid == NULL) {
285                 return NULL;
286         }
287
288         if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
289                 /*
290                  * Necessary only once, but it does not really hurt.
291                  */
292                 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
293
294                 return &builtin_dispinfo;
295         }
296
297         if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
298                 /*
299                  * Necessary only once, but it does not really hurt.
300                  */
301                 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
302
303                 return &domain_dispinfo;
304         }
305
306         return NULL;
307 }
308
309 /*******************************************************************
310  Create a samr_info struct.
311 ********************************************************************/
312
313 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
314 {
315         struct samr_info *info;
316         fstring sid_str;
317         TALLOC_CTX *mem_ctx;
318
319         if (psid) {
320                 sid_to_fstring(sid_str, psid);
321         } else {
322                 fstrcpy(sid_str,"(NULL)");
323         }
324
325         mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
326
327         if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
328                 return NULL;
329
330         DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
331         if (psid) {
332                 sid_copy( &info->sid, psid);
333                 info->builtin_domain = sid_check_is_builtin(psid);
334         } else {
335                 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
336                 info->builtin_domain = False;
337         }
338         info->mem_ctx = mem_ctx;
339
340         info->disp_info = get_samr_dispinfo_by_sid(psid);
341
342         return info;
343 }
344
345 /*******************************************************************
346  Function to free the per SID data.
347  ********************************************************************/
348
349 static void free_samr_cache(DISP_INFO *disp_info)
350 {
351         DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
352                    sid_string_dbg(&disp_info->sid)));
353
354         /* We need to become root here because the paged search might have to
355          * tell the LDAP server we're not interested in the rest anymore. */
356
357         become_root();
358
359         if (disp_info->users) {
360                 DEBUG(10,("free_samr_cache: deleting users cache\n"));
361                 pdb_search_destroy(disp_info->users);
362                 disp_info->users = NULL;
363         }
364         if (disp_info->machines) {
365                 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
366                 pdb_search_destroy(disp_info->machines);
367                 disp_info->machines = NULL;
368         }
369         if (disp_info->groups) {
370                 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
371                 pdb_search_destroy(disp_info->groups);
372                 disp_info->groups = NULL;
373         }
374         if (disp_info->aliases) {
375                 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
376                 pdb_search_destroy(disp_info->aliases);
377                 disp_info->aliases = NULL;
378         }
379         if (disp_info->enum_users) {
380                 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
381                 pdb_search_destroy(disp_info->enum_users);
382                 disp_info->enum_users = NULL;
383         }
384         disp_info->enum_acb_mask = 0;
385
386         unbecome_root();
387 }
388
389 /*******************************************************************
390  Function to free the per handle data.
391  ********************************************************************/
392
393 static void free_samr_info(void *ptr)
394 {
395         struct samr_info *info=(struct samr_info *) ptr;
396
397         /* Only free the dispinfo cache if no one bothered to set up
398            a timeout. */
399
400         if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
401                 free_samr_cache(info->disp_info);
402         }
403
404         talloc_destroy(info->mem_ctx);
405 }
406
407 /*******************************************************************
408  Idle event handler. Throw away the disp info cache.
409  ********************************************************************/
410
411 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
412                                                  struct timed_event *te,
413                                                  const struct timeval *now,
414                                                  void *private_data)
415 {
416         DISP_INFO *disp_info = (DISP_INFO *)private_data;
417
418         TALLOC_FREE(disp_info->cache_timeout_event);
419
420         DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
421                    "out\n"));
422         free_samr_cache(disp_info);
423 }
424
425 /*******************************************************************
426  Setup cache removal idle event handler.
427  ********************************************************************/
428
429 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
430 {
431         /* Remove any pending timeout and update. */
432
433         TALLOC_FREE(disp_info->cache_timeout_event);
434
435         DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
436                   "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
437                   (unsigned int)secs_fromnow ));
438
439         disp_info->cache_timeout_event = event_add_timed(
440                 smbd_event_context(), NULL,
441                 timeval_current_ofs(secs_fromnow, 0),
442                 "disp_info_cache_idle_timeout_handler",
443                 disp_info_cache_idle_timeout_handler, (void *)disp_info);
444 }
445
446 /*******************************************************************
447  Force flush any cache. We do this on any samr_set_xxx call.
448  We must also remove the timeout handler.
449  ********************************************************************/
450
451 static void force_flush_samr_cache(DISP_INFO *disp_info)
452 {
453         if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
454                 return;
455         }
456
457         DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
458         TALLOC_FREE(disp_info->cache_timeout_event);
459         free_samr_cache(disp_info);
460 }
461
462 /*******************************************************************
463  Ensure password info is never given out. Paranioa... JRA.
464  ********************************************************************/
465
466 static void samr_clear_sam_passwd(struct samu *sam_pass)
467 {
468
469         if (!sam_pass)
470                 return;
471
472         /* These now zero out the old password */
473
474         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
475         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
476 }
477
478 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
479 {
480         struct samr_displayentry *entry;
481
482         if (info->builtin_domain) {
483                 /* No users in builtin. */
484                 return 0;
485         }
486
487         if (info->users == NULL) {
488                 info->users = pdb_search_users(acct_flags);
489                 if (info->users == NULL) {
490                         return 0;
491                 }
492         }
493         /* Fetch the last possible entry, thus trigger an enumeration */
494         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
495
496         /* Ensure we cache this enumeration. */
497         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
498
499         return info->users->num_entries;
500 }
501
502 static uint32 count_sam_groups(struct disp_info *info)
503 {
504         struct samr_displayentry *entry;
505
506         if (info->builtin_domain) {
507                 /* No groups in builtin. */
508                 return 0;
509         }
510
511         if (info->groups == NULL) {
512                 info->groups = pdb_search_groups();
513                 if (info->groups == NULL) {
514                         return 0;
515                 }
516         }
517         /* Fetch the last possible entry, thus trigger an enumeration */
518         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
519
520         /* Ensure we cache this enumeration. */
521         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
522
523         return info->groups->num_entries;
524 }
525
526 static uint32 count_sam_aliases(struct disp_info *info)
527 {
528         struct samr_displayentry *entry;
529
530         if (info->aliases == NULL) {
531                 info->aliases = pdb_search_aliases(&info->sid);
532                 if (info->aliases == NULL) {
533                         return 0;
534                 }
535         }
536         /* Fetch the last possible entry, thus trigger an enumeration */
537         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
538
539         /* Ensure we cache this enumeration. */
540         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
541
542         return info->aliases->num_entries;
543 }
544
545 /*******************************************************************
546  _samr_Close
547  ********************************************************************/
548
549 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
550 {
551         if (!close_policy_hnd(p, r->in.handle)) {
552                 return NT_STATUS_INVALID_HANDLE;
553         }
554
555         ZERO_STRUCTP(r->out.handle);
556
557         return NT_STATUS_OK;
558 }
559
560 /*******************************************************************
561  _samr_OpenDomain
562  ********************************************************************/
563
564 NTSTATUS _samr_OpenDomain(pipes_struct *p,
565                           struct samr_OpenDomain *r)
566 {
567         struct    samr_info *info;
568         SEC_DESC *psd = NULL;
569         uint32    acc_granted;
570         uint32    des_access = r->in.access_mask;
571         NTSTATUS  status;
572         size_t    sd_size;
573         SE_PRIV se_rights;
574
575         /* find the connection policy handle. */
576
577         if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
578                 return NT_STATUS_INVALID_HANDLE;
579
580         status = access_check_samr_function(info->acc_granted,
581                                             SA_RIGHT_SAM_OPEN_DOMAIN,
582                                             "_samr_OpenDomain" );
583
584         if ( !NT_STATUS_IS_OK(status) )
585                 return status;
586
587         /*check if access can be granted as requested by client. */
588
589         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
590         se_map_generic( &des_access, &dom_generic_mapping );
591
592         se_priv_copy( &se_rights, &se_machine_account );
593         se_priv_add( &se_rights, &se_add_users );
594
595         status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
596                 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
597                 &acc_granted, "_samr_OpenDomain" );
598
599         if ( !NT_STATUS_IS_OK(status) )
600                 return status;
601
602         if (!sid_check_is_domain(r->in.sid) &&
603             !sid_check_is_builtin(r->in.sid)) {
604                 return NT_STATUS_NO_SUCH_DOMAIN;
605         }
606
607         /* associate the domain SID with the (unique) handle. */
608         if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
609                 return NT_STATUS_NO_MEMORY;
610         info->acc_granted = acc_granted;
611
612         /* get a (unique) handle.  open a policy on it. */
613         if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
614                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
615
616         DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
617
618         return NT_STATUS_OK;
619 }
620
621 /*******************************************************************
622  _samr_GetUserPwInfo
623  ********************************************************************/
624
625 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
626                              struct samr_GetUserPwInfo *r)
627 {
628         struct samr_info *info = NULL;
629         enum lsa_SidType sid_type;
630         uint32_t min_password_length = 0;
631         uint32_t password_properties = 0;
632         bool ret = false;
633         NTSTATUS status;
634
635         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
636
637         /* find the policy handle.  open a policy on it. */
638         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
639                 return NT_STATUS_INVALID_HANDLE;
640         }
641
642         status = access_check_samr_function(info->acc_granted,
643                                             SAMR_USER_ACCESS_GET_ATTRIBUTES,
644                                             "_samr_GetUserPwInfo" );
645         if (!NT_STATUS_IS_OK(status)) {
646                 return status;
647         }
648
649         if (!sid_check_is_in_our_domain(&info->sid)) {
650                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
651         }
652
653         become_root();
654         ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
655         unbecome_root();
656         if (ret == false) {
657                 return NT_STATUS_NO_SUCH_USER;
658         }
659
660         switch (sid_type) {
661                 case SID_NAME_USER:
662                         become_root();
663                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
664                                                &min_password_length);
665                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
666                                                &password_properties);
667                         unbecome_root();
668
669                         if (lp_check_password_script() && *lp_check_password_script()) {
670                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
671                         }
672
673                         break;
674                 default:
675                         break;
676         }
677
678         r->out.info->min_password_length = min_password_length;
679         r->out.info->password_properties = password_properties;
680
681         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
682
683         return NT_STATUS_OK;
684 }
685
686 /*******************************************************************
687 ********************************************************************/
688
689 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
690                                         DOM_SID *sid, uint32 *acc_granted,
691                                         DISP_INFO **ppdisp_info)
692 {
693         struct samr_info *info = NULL;
694
695         /* find the policy handle.  open a policy on it. */
696         if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
697                 return False;
698
699         if (!info)
700                 return False;
701
702         *sid = info->sid;
703         *acc_granted = info->acc_granted;
704         if (ppdisp_info) {
705                 *ppdisp_info = info->disp_info;
706         }
707
708         return True;
709 }
710
711 /*******************************************************************
712  _samr_SetSecurity
713  ********************************************************************/
714
715 NTSTATUS _samr_SetSecurity(pipes_struct *p,
716                            struct samr_SetSecurity *r)
717 {
718         DOM_SID pol_sid;
719         uint32 acc_granted, i;
720         SEC_ACL *dacl;
721         bool ret;
722         struct samu *sampass=NULL;
723         NTSTATUS status;
724
725         if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
726                 return NT_STATUS_INVALID_HANDLE;
727
728         if (!(sampass = samu_new( p->mem_ctx))) {
729                 DEBUG(0,("No memory!\n"));
730                 return NT_STATUS_NO_MEMORY;
731         }
732
733         /* get the user record */
734         become_root();
735         ret = pdb_getsampwsid(sampass, &pol_sid);
736         unbecome_root();
737
738         if (!ret) {
739                 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
740                 TALLOC_FREE(sampass);
741                 return NT_STATUS_INVALID_HANDLE;
742         }
743
744         dacl = r->in.sdbuf->sd->dacl;
745         for (i=0; i < dacl->num_aces; i++) {
746                 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
747                         ret = pdb_set_pass_can_change(sampass,
748                                 (dacl->aces[i].access_mask &
749                                  SA_RIGHT_USER_CHANGE_PASSWORD) ?
750                                                       True: False);
751                         break;
752                 }
753         }
754
755         if (!ret) {
756                 TALLOC_FREE(sampass);
757                 return NT_STATUS_ACCESS_DENIED;
758         }
759
760         status = access_check_samr_function(acc_granted,
761                                             SA_RIGHT_USER_SET_ATTRIBUTES,
762                                             "_samr_SetSecurity");
763         if (NT_STATUS_IS_OK(status)) {
764                 become_root();
765                 status = pdb_update_sam_account(sampass);
766                 unbecome_root();
767         }
768
769         TALLOC_FREE(sampass);
770
771         return status;
772 }
773
774 /*******************************************************************
775   build correct perms based on policies and password times for _samr_query_sec_obj
776 *******************************************************************/
777 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
778 {
779         struct samu *sampass=NULL;
780         bool ret;
781
782         if ( !(sampass = samu_new( mem_ctx )) ) {
783                 DEBUG(0,("No memory!\n"));
784                 return False;
785         }
786
787         become_root();
788         ret = pdb_getsampwsid(sampass, user_sid);
789         unbecome_root();
790
791         if (ret == False) {
792                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
793                 TALLOC_FREE(sampass);
794                 return False;
795         }
796
797         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
798
799         if (pdb_get_pass_can_change(sampass)) {
800                 TALLOC_FREE(sampass);
801                 return True;
802         }
803         TALLOC_FREE(sampass);
804         return False;
805 }
806
807
808 /*******************************************************************
809  _samr_QuerySecurity
810  ********************************************************************/
811
812 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
813                              struct samr_QuerySecurity *r)
814 {
815         NTSTATUS status;
816         DOM_SID pol_sid;
817         SEC_DESC * psd = NULL;
818         uint32 acc_granted;
819         size_t sd_size;
820
821         /* Get the SID. */
822         if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
823                 return NT_STATUS_INVALID_HANDLE;
824
825         DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
826                   sid_string_dbg(&pol_sid)));
827
828         /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
829
830         /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
831         if (pol_sid.sid_rev_num == 0) {
832                 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
833                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
834         } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
835                 /* check if it is our domain SID */
836                 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
837                          "with SID: %s\n", sid_string_dbg(&pol_sid)));
838                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
839         } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
840                 /* check if it is the Builtin  Domain */
841                 /* TODO: Builtin probably needs a different SD with restricted write access*/
842                 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
843                          "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
844                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
845         } else if (sid_check_is_in_our_domain(&pol_sid) ||
846                  sid_check_is_in_builtin(&pol_sid)) {
847                 /* TODO: different SDs have to be generated for aliases groups and users.
848                          Currently all three get a default user SD  */
849                 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
850                           "with SID: %s\n", sid_string_dbg(&pol_sid)));
851                 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
852                         status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
853                                                           &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
854                 } else {
855                         status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
856                                                           &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
857                 }
858         } else {
859                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
860         }
861
862         if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
863                 return NT_STATUS_NO_MEMORY;
864
865         return status;
866 }
867
868 /*******************************************************************
869 makes a SAM_ENTRY / UNISTR2* structure from a user list.
870 ********************************************************************/
871
872 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
873                                          struct samr_SamEntry **sam_pp,
874                                          uint32_t num_entries,
875                                          uint32_t start_idx,
876                                          struct samr_displayentry *entries)
877 {
878         uint32_t i;
879         struct samr_SamEntry *sam;
880
881         *sam_pp = NULL;
882
883         if (num_entries == 0) {
884                 return NT_STATUS_OK;
885         }
886
887         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
888         if (sam == NULL) {
889                 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
890                 return NT_STATUS_NO_MEMORY;
891         }
892
893         for (i = 0; i < num_entries; i++) {
894 #if 0
895                 /*
896                  * usrmgr expects a non-NULL terminated string with
897                  * trust relationships
898                  */
899                 if (entries[i].acct_flags & ACB_DOMTRUST) {
900                         init_unistr2(&uni_temp_name, entries[i].account_name,
901                                      UNI_FLAGS_NONE);
902                 } else {
903                         init_unistr2(&uni_temp_name, entries[i].account_name,
904                                      UNI_STR_TERMINATE);
905                 }
906 #endif
907                 init_lsa_String(&sam[i].name, entries[i].account_name);
908                 sam[i].idx = entries[i].rid;
909         }
910
911         *sam_pp = sam;
912
913         return NT_STATUS_OK;
914 }
915
916 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
917
918 /*******************************************************************
919  _samr_EnumDomainUsers
920  ********************************************************************/
921
922 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
923                                struct samr_EnumDomainUsers *r)
924 {
925         NTSTATUS status;
926         struct samr_info *info = NULL;
927         int num_account;
928         uint32 enum_context = *r->in.resume_handle;
929         enum remote_arch_types ra_type = get_remote_arch();
930         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
931         uint32 max_entries = max_sam_entries;
932         struct samr_displayentry *entries = NULL;
933         struct samr_SamArray *samr_array = NULL;
934         struct samr_SamEntry *samr_entries = NULL;
935
936         /* find the policy handle.  open a policy on it. */
937         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
938                 return NT_STATUS_INVALID_HANDLE;
939
940         status = access_check_samr_function(info->acc_granted,
941                                             SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
942                                             "_samr_EnumDomainUsers");
943         if (!NT_STATUS_IS_OK(status)) {
944                 return status;
945         }
946
947         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
948
949         if (info->builtin_domain) {
950                 /* No users in builtin. */
951                 *r->out.resume_handle = *r->in.resume_handle;
952                 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
953                 return status;
954         }
955
956         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
957         if (!samr_array) {
958                 return NT_STATUS_NO_MEMORY;
959         }
960
961         become_root();
962
963         /* AS ROOT !!!! */
964
965         if ((info->disp_info->enum_users != NULL) &&
966             (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
967                 pdb_search_destroy(info->disp_info->enum_users);
968                 info->disp_info->enum_users = NULL;
969         }
970
971         if (info->disp_info->enum_users == NULL) {
972                 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
973                 info->disp_info->enum_acb_mask = r->in.acct_flags;
974         }
975
976         if (info->disp_info->enum_users == NULL) {
977                 /* END AS ROOT !!!! */
978                 unbecome_root();
979                 return NT_STATUS_ACCESS_DENIED;
980         }
981
982         num_account = pdb_search_entries(info->disp_info->enum_users,
983                                          enum_context, max_entries,
984                                          &entries);
985
986         /* END AS ROOT !!!! */
987
988         unbecome_root();
989
990         if (num_account == 0) {
991                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
992                           "total entries\n"));
993                 *r->out.resume_handle = *r->in.resume_handle;
994                 return NT_STATUS_OK;
995         }
996
997         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
998                                           num_account, enum_context,
999                                           entries);
1000         if (!NT_STATUS_IS_OK(status)) {
1001                 return status;
1002         }
1003
1004         if (max_entries <= num_account) {
1005                 status = STATUS_MORE_ENTRIES;
1006         } else {
1007                 status = NT_STATUS_OK;
1008         }
1009
1010         /* Ensure we cache this enumeration. */
1011         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1012
1013         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1014
1015         samr_array->count = num_account;
1016         samr_array->entries = samr_entries;
1017
1018         *r->out.resume_handle = *r->in.resume_handle + num_account;
1019         *r->out.sam = samr_array;
1020         *r->out.num_entries = num_account;
1021
1022         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1023
1024         return status;
1025 }
1026
1027 /*******************************************************************
1028 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1029 ********************************************************************/
1030
1031 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1032                                       struct samr_SamEntry **sam_pp,
1033                                       uint32_t num_sam_entries,
1034                                       struct samr_displayentry *entries)
1035 {
1036         struct samr_SamEntry *sam;
1037         uint32_t i;
1038
1039         *sam_pp = NULL;
1040
1041         if (num_sam_entries == 0) {
1042                 return;
1043         }
1044
1045         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1046         if (sam == NULL) {
1047                 return;
1048         }
1049
1050         for (i = 0; i < num_sam_entries; i++) {
1051                 /*
1052                  * JRA. I think this should include the null. TNG does not.
1053                  */
1054                 init_lsa_String(&sam[i].name, entries[i].account_name);
1055                 sam[i].idx = entries[i].rid;
1056         }
1057
1058         *sam_pp = sam;
1059 }
1060
1061 /*******************************************************************
1062  _samr_EnumDomainGroups
1063  ********************************************************************/
1064
1065 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1066                                 struct samr_EnumDomainGroups *r)
1067 {
1068         NTSTATUS status;
1069         struct samr_info *info = NULL;
1070         struct samr_displayentry *groups;
1071         uint32 num_groups;
1072         struct samr_SamArray *samr_array = NULL;
1073         struct samr_SamEntry *samr_entries = NULL;
1074
1075         /* find the policy handle.  open a policy on it. */
1076         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1077                 return NT_STATUS_INVALID_HANDLE;
1078
1079         status = access_check_samr_function(info->acc_granted,
1080                                             SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1081                                             "_samr_EnumDomainGroups");
1082         if (!NT_STATUS_IS_OK(status)) {
1083                 return status;
1084         }
1085
1086         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1087
1088         if (info->builtin_domain) {
1089                 /* No groups in builtin. */
1090                 *r->out.resume_handle = *r->in.resume_handle;
1091                 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1092                 return status;
1093         }
1094
1095         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1096         if (!samr_array) {
1097                 return NT_STATUS_NO_MEMORY;
1098         }
1099
1100         /* the domain group array is being allocated in the function below */
1101
1102         become_root();
1103
1104         if (info->disp_info->groups == NULL) {
1105                 info->disp_info->groups = pdb_search_groups();
1106
1107                 if (info->disp_info->groups == NULL) {
1108                         unbecome_root();
1109                         return NT_STATUS_ACCESS_DENIED;
1110                 }
1111         }
1112
1113         num_groups = pdb_search_entries(info->disp_info->groups,
1114                                         *r->in.resume_handle,
1115                                         MAX_SAM_ENTRIES, &groups);
1116         unbecome_root();
1117
1118         /* Ensure we cache this enumeration. */
1119         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1120
1121         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1122                                   num_groups, groups);
1123
1124         samr_array->count = num_groups;
1125         samr_array->entries = samr_entries;
1126
1127         *r->out.sam = samr_array;
1128         *r->out.num_entries = num_groups;
1129         /* this was missing, IMHO:
1130         *r->out.resume_handle = num_groups + *r->in.resume_handle;
1131         */
1132
1133         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1134
1135         return status;
1136 }
1137
1138 /*******************************************************************
1139  _samr_EnumDomainAliases
1140  ********************************************************************/
1141
1142 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1143                                  struct samr_EnumDomainAliases *r)
1144 {
1145         NTSTATUS status;
1146         struct samr_info *info;
1147         struct samr_displayentry *aliases;
1148         uint32 num_aliases = 0;
1149         struct samr_SamArray *samr_array = NULL;
1150         struct samr_SamEntry *samr_entries = NULL;
1151
1152         /* find the policy handle.  open a policy on it. */
1153         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1154                 return NT_STATUS_INVALID_HANDLE;
1155
1156         status = access_check_samr_function(info->acc_granted,
1157                                             SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1158                                             "_samr_EnumDomainAliases");
1159         if (!NT_STATUS_IS_OK(status)) {
1160                 return status;
1161         }
1162
1163         DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1164                  sid_string_dbg(&info->sid)));
1165
1166         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1167         if (!samr_array) {
1168                 return NT_STATUS_NO_MEMORY;
1169         }
1170
1171         become_root();
1172
1173         if (info->disp_info->aliases == NULL) {
1174                 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1175                 if (info->disp_info->aliases == NULL) {
1176                         unbecome_root();
1177                         return NT_STATUS_ACCESS_DENIED;
1178                 }
1179         }
1180
1181         num_aliases = pdb_search_entries(info->disp_info->aliases,
1182                                          *r->in.resume_handle,
1183                                          MAX_SAM_ENTRIES, &aliases);
1184         unbecome_root();
1185
1186         /* Ensure we cache this enumeration. */
1187         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1188
1189         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1190                                   num_aliases, aliases);
1191
1192         DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1193
1194         samr_array->count = num_aliases;
1195         samr_array->entries = samr_entries;
1196
1197         *r->out.sam = samr_array;
1198         *r->out.num_entries = num_aliases;
1199         *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1200
1201         return status;
1202 }
1203
1204 /*******************************************************************
1205  inits a samr_DispInfoGeneral structure.
1206 ********************************************************************/
1207
1208 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1209                                      struct samr_DispInfoGeneral *r,
1210                                      uint32_t num_entries,
1211                                      uint32_t start_idx,
1212                                      struct samr_displayentry *entries)
1213 {
1214         uint32 i;
1215
1216         DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1217
1218         if (num_entries == 0) {
1219                 return NT_STATUS_OK;
1220         }
1221
1222         r->count = num_entries;
1223
1224         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1225         if (!r->entries) {
1226                 return NT_STATUS_NO_MEMORY;
1227         }
1228
1229         for (i = 0; i < num_entries ; i++) {
1230
1231                 init_lsa_String(&r->entries[i].account_name,
1232                                 entries[i].account_name);
1233
1234                 init_lsa_String(&r->entries[i].description,
1235                                 entries[i].description);
1236
1237                 init_lsa_String(&r->entries[i].full_name,
1238                                 entries[i].fullname);
1239
1240                 r->entries[i].rid = entries[i].rid;
1241                 r->entries[i].acct_flags = entries[i].acct_flags;
1242                 r->entries[i].idx = start_idx+i+1;
1243         }
1244
1245         return NT_STATUS_OK;
1246 }
1247
1248 /*******************************************************************
1249  inits a samr_DispInfoFull structure.
1250 ********************************************************************/
1251
1252 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1253                                      struct samr_DispInfoFull *r,
1254                                      uint32_t num_entries,
1255                                      uint32_t start_idx,
1256                                      struct samr_displayentry *entries)
1257 {
1258         uint32_t i;
1259
1260         DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1261
1262         if (num_entries == 0) {
1263                 return NT_STATUS_OK;
1264         }
1265
1266         r->count = num_entries;
1267
1268         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1269         if (!r->entries) {
1270                 return NT_STATUS_NO_MEMORY;
1271         }
1272
1273         for (i = 0; i < num_entries ; i++) {
1274
1275                 init_lsa_String(&r->entries[i].account_name,
1276                                 entries[i].account_name);
1277
1278                 init_lsa_String(&r->entries[i].description,
1279                                 entries[i].description);
1280
1281                 r->entries[i].rid = entries[i].rid;
1282                 r->entries[i].acct_flags = entries[i].acct_flags;
1283                 r->entries[i].idx = start_idx+i+1;
1284         }
1285
1286         return NT_STATUS_OK;
1287 }
1288
1289 /*******************************************************************
1290  inits a samr_DispInfoFullGroups structure.
1291 ********************************************************************/
1292
1293 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1294                                      struct samr_DispInfoFullGroups *r,
1295                                      uint32_t num_entries,
1296                                      uint32_t start_idx,
1297                                      struct samr_displayentry *entries)
1298 {
1299         uint32_t i;
1300
1301         DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1302
1303         if (num_entries == 0) {
1304                 return NT_STATUS_OK;
1305         }
1306
1307         r->count = num_entries;
1308
1309         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1310         if (!r->entries) {
1311                 return NT_STATUS_NO_MEMORY;
1312         }
1313
1314         for (i = 0; i < num_entries ; i++) {
1315
1316                 init_lsa_String(&r->entries[i].account_name,
1317                                 entries[i].account_name);
1318
1319                 init_lsa_String(&r->entries[i].description,
1320                                 entries[i].description);
1321
1322                 r->entries[i].rid = entries[i].rid;
1323                 r->entries[i].acct_flags = entries[i].acct_flags;
1324                 r->entries[i].idx = start_idx+i+1;
1325         }
1326
1327         return NT_STATUS_OK;
1328 }
1329
1330 /*******************************************************************
1331  inits a samr_DispInfoAscii structure.
1332 ********************************************************************/
1333
1334 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1335                                      struct samr_DispInfoAscii *r,
1336                                      uint32_t num_entries,
1337                                      uint32_t start_idx,
1338                                      struct samr_displayentry *entries)
1339 {
1340         uint32_t i;
1341
1342         DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1343
1344         if (num_entries == 0) {
1345                 return NT_STATUS_OK;
1346         }
1347
1348         r->count = num_entries;
1349
1350         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1351         if (!r->entries) {
1352                 return NT_STATUS_NO_MEMORY;
1353         }
1354
1355         for (i = 0; i < num_entries ; i++) {
1356
1357                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1358                                           entries[i].account_name);
1359
1360                 r->entries[i].idx = start_idx+i+1;
1361         }
1362
1363         return NT_STATUS_OK;
1364 }
1365
1366 /*******************************************************************
1367  inits a samr_DispInfoAscii structure.
1368 ********************************************************************/
1369
1370 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1371                                      struct samr_DispInfoAscii *r,
1372                                      uint32_t num_entries,
1373                                      uint32_t start_idx,
1374                                      struct samr_displayentry *entries)
1375 {
1376         uint32_t i;
1377
1378         DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1379
1380         if (num_entries == 0) {
1381                 return NT_STATUS_OK;
1382         }
1383
1384         r->count = num_entries;
1385
1386         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1387         if (!r->entries) {
1388                 return NT_STATUS_NO_MEMORY;
1389         }
1390
1391         for (i = 0; i < num_entries ; i++) {
1392
1393                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1394                                           entries[i].account_name);
1395
1396                 r->entries[i].idx = start_idx+i+1;
1397         }
1398
1399         return NT_STATUS_OK;
1400 }
1401
1402 /*******************************************************************
1403  _samr_QueryDisplayInfo
1404  ********************************************************************/
1405
1406 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1407                                 struct samr_QueryDisplayInfo *r)
1408 {
1409         NTSTATUS status;
1410         struct samr_info *info = NULL;
1411         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1412
1413         uint32 max_entries = r->in.max_entries;
1414         uint32 enum_context = r->in.start_idx;
1415         uint32 max_size = r->in.buf_size;
1416
1417         union samr_DispInfo *disp_info = r->out.info;
1418
1419         uint32 temp_size=0, total_data_size=0;
1420         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1421         uint32 num_account = 0;
1422         enum remote_arch_types ra_type = get_remote_arch();
1423         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1424         struct samr_displayentry *entries = NULL;
1425
1426         DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1427
1428         /* find the policy handle.  open a policy on it. */
1429         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1430                 return NT_STATUS_INVALID_HANDLE;
1431
1432         /*
1433          * calculate how many entries we will return.
1434          * based on
1435          * - the number of entries the client asked
1436          * - our limit on that
1437          * - the starting point (enumeration context)
1438          * - the buffer size the client will accept
1439          */
1440
1441         /*
1442          * We are a lot more like W2K. Instead of reading the SAM
1443          * each time to find the records we need to send back,
1444          * we read it once and link that copy to the sam handle.
1445          * For large user list (over the MAX_SAM_ENTRIES)
1446          * it's a definitive win.
1447          * second point to notice: between enumerations
1448          * our sam is now the same as it's a snapshoot.
1449          * third point: got rid of the static SAM_USER_21 struct
1450          * no more intermediate.
1451          * con: it uses much more memory, as a full copy is stored
1452          * in memory.
1453          *
1454          * If you want to change it, think twice and think
1455          * of the second point , that's really important.
1456          *
1457          * JFM, 12/20/2001
1458          */
1459
1460         if ((r->in.level < 1) || (r->in.level > 5)) {
1461                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1462                          (unsigned int)r->in.level ));
1463                 return NT_STATUS_INVALID_INFO_CLASS;
1464         }
1465
1466         /* first limit the number of entries we will return */
1467         if(max_entries > max_sam_entries) {
1468                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1469                           "entries, limiting to %d\n", max_entries,
1470                           max_sam_entries));
1471                 max_entries = max_sam_entries;
1472         }
1473
1474         /* calculate the size and limit on the number of entries we will
1475          * return */
1476
1477         temp_size=max_entries*struct_size;
1478
1479         if (temp_size>max_size) {
1480                 max_entries=MIN((max_size/struct_size),max_entries);;
1481                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1482                           "only %d entries\n", max_entries));
1483         }
1484
1485         become_root();
1486
1487         /* THe following done as ROOT. Don't return without unbecome_root(). */
1488
1489         switch (r->in.level) {
1490         case 0x1:
1491         case 0x4:
1492                 if (info->disp_info->users == NULL) {
1493                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
1494                         if (info->disp_info->users == NULL) {
1495                                 unbecome_root();
1496                                 return NT_STATUS_ACCESS_DENIED;
1497                         }
1498                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1499                                 (unsigned  int)enum_context ));
1500                 } else {
1501                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1502                                 (unsigned  int)enum_context ));
1503                 }
1504
1505                 num_account = pdb_search_entries(info->disp_info->users,
1506                                                  enum_context, max_entries,
1507                                                  &entries);
1508                 break;
1509         case 0x2:
1510                 if (info->disp_info->machines == NULL) {
1511                         info->disp_info->machines =
1512                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1513                         if (info->disp_info->machines == NULL) {
1514                                 unbecome_root();
1515                                 return NT_STATUS_ACCESS_DENIED;
1516                         }
1517                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1518                                 (unsigned  int)enum_context ));
1519                 } else {
1520                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1521                                 (unsigned  int)enum_context ));
1522                 }
1523
1524                 num_account = pdb_search_entries(info->disp_info->machines,
1525                                                  enum_context, max_entries,
1526                                                  &entries);
1527                 break;
1528         case 0x3:
1529         case 0x5:
1530                 if (info->disp_info->groups == NULL) {
1531                         info->disp_info->groups = pdb_search_groups();
1532                         if (info->disp_info->groups == NULL) {
1533                                 unbecome_root();
1534                                 return NT_STATUS_ACCESS_DENIED;
1535                         }
1536                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1537                                 (unsigned  int)enum_context ));
1538                 } else {
1539                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1540                                 (unsigned  int)enum_context ));
1541                 }
1542
1543                 num_account = pdb_search_entries(info->disp_info->groups,
1544                                                  enum_context, max_entries,
1545                                                  &entries);
1546                 break;
1547         default:
1548                 unbecome_root();
1549                 smb_panic("info class changed");
1550                 break;
1551         }
1552         unbecome_root();
1553
1554
1555         /* Now create reply structure */
1556         switch (r->in.level) {
1557         case 0x1:
1558                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1559                                                 num_account, enum_context,
1560                                                 entries);
1561                 break;
1562         case 0x2:
1563                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1564                                                 num_account, enum_context,
1565                                                 entries);
1566                 break;
1567         case 0x3:
1568                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1569                                                 num_account, enum_context,
1570                                                 entries);
1571                 break;
1572         case 0x4:
1573                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1574                                                 num_account, enum_context,
1575                                                 entries);
1576                 break;
1577         case 0x5:
1578                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1579                                                 num_account, enum_context,
1580                                                 entries);
1581                 break;
1582         default:
1583                 smb_panic("info class changed");
1584                 break;
1585         }
1586
1587         if (!NT_STATUS_IS_OK(disp_ret))
1588                 return disp_ret;
1589
1590         /* calculate the total size */
1591         total_data_size=num_account*struct_size;
1592
1593         if (num_account) {
1594                 status = STATUS_MORE_ENTRIES;
1595         } else {
1596                 status = NT_STATUS_OK;
1597         }
1598
1599         /* Ensure we cache this enumeration. */
1600         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1601
1602         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1603
1604         *r->out.total_size = total_data_size;
1605         *r->out.returned_size = temp_size;
1606
1607         return status;
1608 }
1609
1610 /****************************************************************
1611  _samr_QueryDisplayInfo2
1612 ****************************************************************/
1613
1614 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1615                                  struct samr_QueryDisplayInfo2 *r)
1616 {
1617         struct samr_QueryDisplayInfo q;
1618
1619         q.in.domain_handle      = r->in.domain_handle;
1620         q.in.level              = r->in.level;
1621         q.in.start_idx          = r->in.start_idx;
1622         q.in.max_entries        = r->in.max_entries;
1623         q.in.buf_size           = r->in.buf_size;
1624
1625         q.out.total_size        = r->out.total_size;
1626         q.out.returned_size     = r->out.returned_size;
1627         q.out.info              = r->out.info;
1628
1629         return _samr_QueryDisplayInfo(p, &q);
1630 }
1631
1632 /****************************************************************
1633  _samr_QueryDisplayInfo3
1634 ****************************************************************/
1635
1636 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1637                                  struct samr_QueryDisplayInfo3 *r)
1638 {
1639         struct samr_QueryDisplayInfo q;
1640
1641         q.in.domain_handle      = r->in.domain_handle;
1642         q.in.level              = r->in.level;
1643         q.in.start_idx          = r->in.start_idx;
1644         q.in.max_entries        = r->in.max_entries;
1645         q.in.buf_size           = r->in.buf_size;
1646
1647         q.out.total_size        = r->out.total_size;
1648         q.out.returned_size     = r->out.returned_size;
1649         q.out.info              = r->out.info;
1650
1651         return _samr_QueryDisplayInfo(p, &q);
1652 }
1653
1654 /*******************************************************************
1655  _samr_QueryAliasInfo
1656  ********************************************************************/
1657
1658 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1659                               struct samr_QueryAliasInfo *r)
1660 {
1661         DOM_SID   sid;
1662         struct acct_info info;
1663         uint32    acc_granted;
1664         NTSTATUS status;
1665         union samr_AliasInfo *alias_info = NULL;
1666         const char *alias_name = NULL;
1667         const char *alias_description = NULL;
1668
1669         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1670
1671         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1672         if (!alias_info) {
1673                 return NT_STATUS_NO_MEMORY;
1674         }
1675
1676         /* find the policy handle.  open a policy on it. */
1677         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1678                 return NT_STATUS_INVALID_HANDLE;
1679
1680         status = access_check_samr_function(acc_granted,
1681                                             SA_RIGHT_ALIAS_LOOKUP_INFO,
1682                                             "_samr_QueryAliasInfo");
1683         if (!NT_STATUS_IS_OK(status)) {
1684                 return status;
1685         }
1686
1687         become_root();
1688         status = pdb_get_aliasinfo(&sid, &info);
1689         unbecome_root();
1690
1691         if ( !NT_STATUS_IS_OK(status))
1692                 return status;
1693
1694         /* FIXME: info contains fstrings */
1695         alias_name = talloc_strdup(r, info.acct_name);
1696         alias_description = talloc_strdup(r, info.acct_desc);
1697
1698         switch (r->in.level) {
1699         case ALIASINFOALL:
1700                 init_samr_alias_info1(&alias_info->all,
1701                                       alias_name,
1702                                       1,
1703                                       alias_description);
1704                 break;
1705         case ALIASINFODESCRIPTION:
1706                 init_samr_alias_info3(&alias_info->description,
1707                                       alias_description);
1708                 break;
1709         default:
1710                 return NT_STATUS_INVALID_INFO_CLASS;
1711         }
1712
1713         *r->out.info = alias_info;
1714
1715         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1716
1717         return NT_STATUS_OK;
1718 }
1719
1720 #if 0
1721 /*******************************************************************
1722  samr_reply_lookup_ids
1723  ********************************************************************/
1724
1725  uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1726 {
1727     uint32 rid[MAX_SAM_ENTRIES];
1728     int num_rids = q_u->num_sids1;
1729
1730     r_u->status = NT_STATUS_OK;
1731
1732     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1733
1734     if (num_rids > MAX_SAM_ENTRIES) {
1735         num_rids = MAX_SAM_ENTRIES;
1736         DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1737     }
1738
1739 #if 0
1740     int i;
1741     SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1742
1743     for (i = 0; i < num_rids && status == 0; i++)
1744     {
1745         struct sam_passwd *sam_pass;
1746         fstring user_name;
1747
1748
1749         fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1750                                     q_u->uni_user_name[i].uni_str_len));
1751
1752         /* find the user account */
1753         become_root();
1754         sam_pass = get_smb21pwd_entry(user_name, 0);
1755         unbecome_root();
1756
1757         if (sam_pass == NULL)
1758         {
1759             status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1760             rid[i] = 0;
1761         }
1762         else
1763         {
1764             rid[i] = sam_pass->user_rid;
1765         }
1766     }
1767 #endif
1768
1769     num_rids = 1;
1770     rid[0] = BUILTIN_ALIAS_RID_USERS;
1771
1772     init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1773
1774     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1775
1776     return r_u->status;
1777 }
1778 #endif
1779
1780 /*******************************************************************
1781  _samr_LookupNames
1782  ********************************************************************/
1783
1784 NTSTATUS _samr_LookupNames(pipes_struct *p,
1785                            struct samr_LookupNames *r)
1786 {
1787         NTSTATUS status;
1788         uint32 *rid;
1789         enum lsa_SidType *type;
1790         int i;
1791         int num_rids = r->in.num_names;
1792         DOM_SID pol_sid;
1793         uint32  acc_granted;
1794         struct samr_Ids rids, types;
1795
1796         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1797
1798         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1799                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1800         }
1801
1802         status = access_check_samr_function(acc_granted,
1803                                             0, /* Don't know the acc_bits yet */
1804                                             "_samr_LookupNames");
1805         if (!NT_STATUS_IS_OK(status)) {
1806                 return status;
1807         }
1808
1809         if (num_rids > MAX_SAM_ENTRIES) {
1810                 num_rids = MAX_SAM_ENTRIES;
1811                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1812         }
1813
1814         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1815         NT_STATUS_HAVE_NO_MEMORY(rid);
1816
1817         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1818         NT_STATUS_HAVE_NO_MEMORY(type);
1819
1820         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1821                  sid_string_dbg(&pol_sid)));
1822
1823         for (i = 0; i < num_rids; i++) {
1824
1825                 status = NT_STATUS_NONE_MAPPED;
1826                 type[i] = SID_NAME_UNKNOWN;
1827
1828                 rid[i] = 0xffffffff;
1829
1830                 if (sid_check_is_builtin(&pol_sid)) {
1831                         if (lookup_builtin_name(r->in.names[i].string,
1832                                                 &rid[i]))
1833                         {
1834                                 type[i] = SID_NAME_ALIAS;
1835                         }
1836                 } else {
1837                         lookup_global_sam_name(r->in.names[i].string, 0,
1838                                                &rid[i], &type[i]);
1839                 }
1840
1841                 if (type[i] != SID_NAME_UNKNOWN) {
1842                         status = NT_STATUS_OK;
1843                 }
1844         }
1845
1846         rids.count = num_rids;
1847         rids.ids = rid;
1848
1849         types.count = num_rids;
1850         types.ids = type;
1851
1852         *r->out.rids = rids;
1853         *r->out.types = types;
1854
1855         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1856
1857         return status;
1858 }
1859
1860 /*******************************************************************
1861  _samr_ChangePasswordUser2
1862  ********************************************************************/
1863
1864 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1865                                    struct samr_ChangePasswordUser2 *r)
1866 {
1867         NTSTATUS status;
1868         fstring user_name;
1869         fstring wks;
1870
1871         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1872
1873         fstrcpy(user_name, r->in.account->string);
1874         fstrcpy(wks, r->in.server->string);
1875
1876         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1877
1878         /*
1879          * Pass the user through the NT -> unix user mapping
1880          * function.
1881          */
1882
1883         (void)map_username(user_name);
1884
1885         /*
1886          * UNIX username case mangling not required, pass_oem_change
1887          * is case insensitive.
1888          */
1889
1890         status = pass_oem_change(user_name,
1891                                  r->in.lm_password->data,
1892                                  r->in.lm_verifier->hash,
1893                                  r->in.nt_password->data,
1894                                  r->in.nt_verifier->hash,
1895                                  NULL);
1896
1897         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1898
1899         return status;
1900 }
1901
1902 /*******************************************************************
1903  _samr_ChangePasswordUser3
1904  ********************************************************************/
1905
1906 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1907                                    struct samr_ChangePasswordUser3 *r)
1908 {
1909         NTSTATUS status;
1910         fstring user_name;
1911         const char *wks = NULL;
1912         uint32 reject_reason;
1913         struct samr_DomInfo1 *dominfo = NULL;
1914         struct samr_ChangeReject *reject = NULL;
1915
1916         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1917
1918         fstrcpy(user_name, r->in.account->string);
1919         if (r->in.server && r->in.server->string) {
1920                 wks = r->in.server->string;
1921         }
1922
1923         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1924
1925         /*
1926          * Pass the user through the NT -> unix user mapping
1927          * function.
1928          */
1929
1930         (void)map_username(user_name);
1931
1932         /*
1933          * UNIX username case mangling not required, pass_oem_change
1934          * is case insensitive.
1935          */
1936
1937         status = pass_oem_change(user_name,
1938                                  r->in.lm_password->data,
1939                                  r->in.lm_verifier->hash,
1940                                  r->in.nt_password->data,
1941                                  r->in.nt_verifier->hash,
1942                                  &reject_reason);
1943
1944         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1945             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1946
1947                 uint32 min_pass_len,pass_hist,password_properties;
1948                 time_t u_expire, u_min_age;
1949                 NTTIME nt_expire, nt_min_age;
1950                 uint32 account_policy_temp;
1951
1952                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1953                 if (!dominfo) {
1954                         return NT_STATUS_NO_MEMORY;
1955                 }
1956
1957                 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1958                 if (!reject) {
1959                         return NT_STATUS_NO_MEMORY;
1960                 }
1961
1962                 become_root();
1963
1964                 /* AS ROOT !!! */
1965
1966                 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1967                 min_pass_len = account_policy_temp;
1968
1969                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1970                 pass_hist = account_policy_temp;
1971
1972                 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1973                 password_properties = account_policy_temp;
1974
1975                 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1976                 u_expire = account_policy_temp;
1977
1978                 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1979                 u_min_age = account_policy_temp;
1980
1981                 /* !AS ROOT */
1982
1983                 unbecome_root();
1984
1985                 unix_to_nt_time_abs(&nt_expire, u_expire);
1986                 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1987
1988                 if (lp_check_password_script() && *lp_check_password_script()) {
1989                         password_properties |= DOMAIN_PASSWORD_COMPLEX;
1990                 }
1991
1992                 init_samr_DomInfo1(dominfo,
1993                                    min_pass_len,
1994                                    pass_hist,
1995                                    password_properties,
1996                                    u_expire,
1997                                    u_min_age);
1998
1999                 reject->reason = reject_reason;
2000
2001                 *r->out.dominfo = dominfo;
2002                 *r->out.reject = reject;
2003         }
2004
2005         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2006
2007         return status;
2008 }
2009
2010 /*******************************************************************
2011 makes a SAMR_R_LOOKUP_RIDS structure.
2012 ********************************************************************/
2013
2014 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2015                                   const char **names,
2016                                   struct lsa_String **lsa_name_array_p)
2017 {
2018         struct lsa_String *lsa_name_array = NULL;
2019         uint32_t i;
2020
2021         *lsa_name_array_p = NULL;
2022
2023         if (num_names != 0) {
2024                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2025                 if (!lsa_name_array) {
2026                         return false;
2027                 }
2028         }
2029
2030         for (i = 0; i < num_names; i++) {
2031                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2032                 init_lsa_String(&lsa_name_array[i], names[i]);
2033         }
2034
2035         *lsa_name_array_p = lsa_name_array;
2036
2037         return true;
2038 }
2039
2040 /*******************************************************************
2041  _samr_LookupRids
2042  ********************************************************************/
2043
2044 NTSTATUS _samr_LookupRids(pipes_struct *p,
2045                           struct samr_LookupRids *r)
2046 {
2047         NTSTATUS status;
2048         const char **names;
2049         enum lsa_SidType *attrs = NULL;
2050         uint32 *wire_attrs = NULL;
2051         DOM_SID pol_sid;
2052         int num_rids = (int)r->in.num_rids;
2053         uint32 acc_granted;
2054         int i;
2055         struct lsa_Strings names_array;
2056         struct samr_Ids types_array;
2057         struct lsa_String *lsa_names = NULL;
2058
2059         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2060
2061         /* find the policy handle.  open a policy on it. */
2062         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2063                 return NT_STATUS_INVALID_HANDLE;
2064
2065         if (num_rids > 1000) {
2066                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2067                           "to samba4 idl this is not possible\n", num_rids));
2068                 return NT_STATUS_UNSUCCESSFUL;
2069         }
2070
2071         if (num_rids) {
2072                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2073                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2074                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2075
2076                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2077                         return NT_STATUS_NO_MEMORY;
2078         } else {
2079                 names = NULL;
2080                 attrs = NULL;
2081                 wire_attrs = NULL;
2082         }
2083
2084         become_root();  /* lookup_sid can require root privs */
2085         status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2086                                  names, attrs);
2087         unbecome_root();
2088
2089         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2090                 status = NT_STATUS_OK;
2091         }
2092
2093         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2094                                    &lsa_names)) {
2095                 return NT_STATUS_NO_MEMORY;
2096         }
2097
2098         /* Convert from enum lsa_SidType to uint32 for wire format. */
2099         for (i = 0; i < num_rids; i++) {
2100                 wire_attrs[i] = (uint32)attrs[i];
2101         }
2102
2103         names_array.count = num_rids;
2104         names_array.names = lsa_names;
2105
2106         types_array.count = num_rids;
2107         types_array.ids = wire_attrs;
2108
2109         *r->out.names = names_array;
2110         *r->out.types = types_array;
2111
2112         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2113
2114         return status;
2115 }
2116
2117 /*******************************************************************
2118  _samr_OpenUser
2119 ********************************************************************/
2120
2121 NTSTATUS _samr_OpenUser(pipes_struct *p,
2122                         struct samr_OpenUser *r)
2123 {
2124         struct samu *sampass=NULL;
2125         DOM_SID sid;
2126         POLICY_HND domain_pol = *r->in.domain_handle;
2127         POLICY_HND *user_pol = r->out.user_handle;
2128         struct samr_info *info = NULL;
2129         SEC_DESC *psd = NULL;
2130         uint32    acc_granted;
2131         uint32    des_access = r->in.access_mask;
2132         size_t    sd_size;
2133         bool ret;
2134         NTSTATUS nt_status;
2135         SE_PRIV se_rights;
2136
2137         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2138
2139         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2140                 return NT_STATUS_INVALID_HANDLE;
2141
2142         nt_status = access_check_samr_function(acc_granted,
2143                                                SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2144                                                "_samr_OpenUser" );
2145
2146         if ( !NT_STATUS_IS_OK(nt_status) )
2147                 return nt_status;
2148
2149         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2150                 return NT_STATUS_NO_MEMORY;
2151         }
2152
2153         /* append the user's RID to it */
2154
2155         if (!sid_append_rid(&sid, r->in.rid))
2156                 return NT_STATUS_NO_SUCH_USER;
2157
2158         /* check if access can be granted as requested by client. */
2159
2160         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2161         se_map_generic(&des_access, &usr_generic_mapping);
2162
2163         se_priv_copy( &se_rights, &se_machine_account );
2164         se_priv_add( &se_rights, &se_add_users );
2165
2166         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2167                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2168                 &acc_granted, "_samr_OpenUser");
2169
2170         if ( !NT_STATUS_IS_OK(nt_status) )
2171                 return nt_status;
2172
2173         become_root();
2174         ret=pdb_getsampwsid(sampass, &sid);
2175         unbecome_root();
2176
2177         /* check that the SID exists in our domain. */
2178         if (ret == False) {
2179                 return NT_STATUS_NO_SUCH_USER;
2180         }
2181
2182         TALLOC_FREE(sampass);
2183
2184         /* associate the user's SID and access bits with the new handle. */
2185         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2186                 return NT_STATUS_NO_MEMORY;
2187         info->acc_granted = acc_granted;
2188
2189         /* get a (unique) handle.  open a policy on it. */
2190         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2191                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2192
2193         return NT_STATUS_OK;
2194 }
2195
2196 /*************************************************************************
2197  *************************************************************************/
2198
2199 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2200                                             DATA_BLOB *blob,
2201                                             struct lsa_BinaryString **_r)
2202 {
2203         struct lsa_BinaryString *r;
2204
2205         if (!blob || !_r) {
2206                 return NT_STATUS_INVALID_PARAMETER;
2207         }
2208
2209         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2210         if (!r) {
2211                 return NT_STATUS_NO_MEMORY;
2212         }
2213
2214         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2215         if (!r->array) {
2216                 return NT_STATUS_NO_MEMORY;
2217         }
2218         memcpy(r->array, blob->data, blob->length);
2219         r->size = blob->length;
2220         r->length = blob->length;
2221
2222         if (!r->array) {
2223                 return NT_STATUS_NO_MEMORY;
2224         }
2225
2226         *_r = r;
2227
2228         return NT_STATUS_OK;
2229 }
2230
2231 /*************************************************************************
2232  get_user_info_7. Safe. Only gives out account_name.
2233  *************************************************************************/
2234
2235 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2236                                 struct samr_UserInfo7 *r,
2237                                 DOM_SID *user_sid)
2238 {
2239         struct samu *smbpass=NULL;
2240         bool ret;
2241         const char *account_name = NULL;
2242
2243         ZERO_STRUCTP(r);
2244
2245         if ( !(smbpass = samu_new( mem_ctx )) ) {
2246                 return NT_STATUS_NO_MEMORY;
2247         }
2248
2249         become_root();
2250         ret = pdb_getsampwsid(smbpass, user_sid);
2251         unbecome_root();
2252
2253         if ( !ret ) {
2254                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2255                 return NT_STATUS_NO_SUCH_USER;
2256         }
2257
2258         account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2259         if (!account_name) {
2260                 TALLOC_FREE(smbpass);
2261                 return NT_STATUS_NO_MEMORY;
2262         }
2263         TALLOC_FREE(smbpass);
2264
2265         DEBUG(3,("User:[%s]\n", account_name));
2266
2267         init_samr_user_info7(r, account_name);
2268
2269         return NT_STATUS_OK;
2270 }
2271
2272 /*************************************************************************
2273  get_user_info_9. Only gives out primary group SID.
2274  *************************************************************************/
2275
2276 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2277                                 struct samr_UserInfo9 *r,
2278                                 DOM_SID *user_sid)
2279 {
2280         struct samu *smbpass=NULL;
2281         bool ret;
2282
2283         ZERO_STRUCTP(r);
2284
2285         if ( !(smbpass = samu_new( mem_ctx )) ) {
2286                 return NT_STATUS_NO_MEMORY;
2287         }
2288
2289         become_root();
2290         ret = pdb_getsampwsid(smbpass, user_sid);
2291         unbecome_root();
2292
2293         if (ret==False) {
2294                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2295                 TALLOC_FREE(smbpass);
2296                 return NT_STATUS_NO_SUCH_USER;
2297         }
2298
2299         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2300
2301         init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2302
2303         TALLOC_FREE(smbpass);
2304
2305         return NT_STATUS_OK;
2306 }
2307
2308 /*************************************************************************
2309  get_user_info_16. Safe. Only gives out acb bits.
2310  *************************************************************************/
2311
2312 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2313                                  struct samr_UserInfo16 *r,
2314                                  DOM_SID *user_sid)
2315 {
2316         struct samu *smbpass=NULL;
2317         bool ret;
2318
2319         ZERO_STRUCTP(r);
2320
2321         if ( !(smbpass = samu_new( mem_ctx )) ) {
2322                 return NT_STATUS_NO_MEMORY;
2323         }
2324
2325         become_root();
2326         ret = pdb_getsampwsid(smbpass, user_sid);
2327         unbecome_root();
2328
2329         if (ret==False) {
2330                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2331                 TALLOC_FREE(smbpass);
2332                 return NT_STATUS_NO_SUCH_USER;
2333         }
2334
2335         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2336
2337         init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2338
2339         TALLOC_FREE(smbpass);
2340
2341         return NT_STATUS_OK;
2342 }
2343
2344 /*************************************************************************
2345  get_user_info_18. OK - this is the killer as it gives out password info.
2346  Ensure that this is only allowed on an encrypted connection with a root
2347  user. JRA.
2348  *************************************************************************/
2349
2350 static NTSTATUS get_user_info_18(pipes_struct *p,
2351                                  TALLOC_CTX *mem_ctx,
2352                                  struct samr_UserInfo18 *r,
2353                                  DOM_SID *user_sid)
2354 {
2355         struct samu *smbpass=NULL;
2356         bool ret;
2357
2358         ZERO_STRUCTP(r);
2359
2360         if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2361                 return NT_STATUS_ACCESS_DENIED;
2362         }
2363
2364         if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2365                 return NT_STATUS_ACCESS_DENIED;
2366         }
2367
2368         /*
2369          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2370          */
2371
2372         if ( !(smbpass = samu_new( mem_ctx )) ) {
2373                 return NT_STATUS_NO_MEMORY;
2374         }
2375
2376         ret = pdb_getsampwsid(smbpass, user_sid);
2377
2378         if (ret == False) {
2379                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2380                 TALLOC_FREE(smbpass);
2381                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2382         }
2383
2384         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2385
2386         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2387                 TALLOC_FREE(smbpass);
2388                 return NT_STATUS_ACCOUNT_DISABLED;
2389         }
2390
2391         init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2392                               pdb_get_nt_passwd(smbpass));
2393
2394         TALLOC_FREE(smbpass);
2395
2396         return NT_STATUS_OK;
2397 }
2398
2399 /*************************************************************************
2400  get_user_info_20
2401  *************************************************************************/
2402
2403 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2404                                  struct samr_UserInfo20 *r,
2405                                  DOM_SID *user_sid)
2406 {
2407         struct samu *sampass=NULL;
2408         bool ret;
2409         const char *munged_dial = NULL;
2410         DATA_BLOB blob;
2411         NTSTATUS status;
2412         struct lsa_BinaryString *parameters = NULL;
2413
2414         ZERO_STRUCTP(r);
2415
2416         if ( !(sampass = samu_new( mem_ctx )) ) {
2417                 return NT_STATUS_NO_MEMORY;
2418         }
2419
2420         become_root();
2421         ret = pdb_getsampwsid(sampass, user_sid);
2422         unbecome_root();
2423
2424         if (ret == False) {
2425                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2426                 TALLOC_FREE(sampass);
2427                 return NT_STATUS_NO_SUCH_USER;
2428         }
2429
2430         munged_dial = pdb_get_munged_dial(sampass);
2431
2432         samr_clear_sam_passwd(sampass);
2433
2434         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2435                 munged_dial, (int)strlen(munged_dial)));
2436
2437         if (munged_dial) {
2438                 blob = base64_decode_data_blob(munged_dial);
2439         } else {
2440                 blob = data_blob_string_const_null("");
2441         }
2442
2443         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2444         data_blob_free(&blob);
2445         TALLOC_FREE(sampass);
2446         if (!NT_STATUS_IS_OK(status)) {
2447                 return status;
2448         }
2449
2450         init_samr_user_info20(r, parameters);
2451
2452         return NT_STATUS_OK;
2453 }
2454
2455
2456 /*************************************************************************
2457  get_user_info_21
2458  *************************************************************************/
2459
2460 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2461                                  struct samr_UserInfo21 *r,
2462                                  DOM_SID *user_sid,
2463                                  DOM_SID *domain_sid)
2464 {
2465         NTSTATUS status;
2466         struct samu *pw = NULL;
2467         bool ret;
2468         const DOM_SID *sid_user, *sid_group;
2469         uint32_t rid, primary_gid;
2470         NTTIME last_logon, last_logoff, last_password_change,
2471                acct_expiry, allow_password_change, force_password_change;
2472         time_t must_change_time;
2473         uint8_t password_expired;
2474         const char *account_name, *full_name, *home_directory, *home_drive,
2475                    *logon_script, *profile_path, *description,
2476                    *workstations, *comment;
2477         struct samr_LogonHours logon_hours;
2478         struct lsa_BinaryString *parameters = NULL;
2479         const char *munged_dial = NULL;
2480         DATA_BLOB blob;
2481
2482         ZERO_STRUCTP(r);
2483
2484         if (!(pw = samu_new(mem_ctx))) {
2485                 return NT_STATUS_NO_MEMORY;
2486         }
2487
2488         become_root();
2489         ret = pdb_getsampwsid(pw, user_sid);
2490         unbecome_root();
2491
2492         if (ret == False) {
2493                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2494                 TALLOC_FREE(pw);
2495                 return NT_STATUS_NO_SUCH_USER;
2496         }
2497
2498         samr_clear_sam_passwd(pw);
2499
2500         DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2501
2502         sid_user = pdb_get_user_sid(pw);
2503
2504         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2505                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2506                           "the domain sid %s.  Failing operation.\n",
2507                           pdb_get_username(pw), sid_string_dbg(sid_user),
2508                           sid_string_dbg(domain_sid)));
2509                 TALLOC_FREE(pw);
2510                 return NT_STATUS_UNSUCCESSFUL;
2511         }
2512
2513         become_root();
2514         sid_group = pdb_get_group_sid(pw);
2515         unbecome_root();
2516
2517         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2518                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2519                           "which conflicts with the domain sid %s.  Failing operation.\n",
2520                           pdb_get_username(pw), sid_string_dbg(sid_group),
2521                           sid_string_dbg(domain_sid)));
2522                 TALLOC_FREE(pw);
2523                 return NT_STATUS_UNSUCCESSFUL;
2524         }
2525
2526         unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2527         unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2528         unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2529         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2530         unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2531
2532         must_change_time = pdb_get_pass_must_change_time(pw);
2533         if (must_change_time == get_time_t_max()) {
2534                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2535         } else {
2536                 unix_to_nt_time(&force_password_change, must_change_time);
2537         }
2538
2539         if (pdb_get_pass_must_change_time(pw) == 0) {
2540                 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2541         } else {
2542                 password_expired = 0;
2543         }
2544
2545         munged_dial = pdb_get_munged_dial(pw);
2546         if (munged_dial) {
2547                 blob = base64_decode_data_blob(munged_dial);
2548         } else {
2549                 blob = data_blob_string_const_null("");
2550         }
2551
2552         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2553         data_blob_free(&blob);
2554         if (!NT_STATUS_IS_OK(status)) {
2555                 TALLOC_FREE(pw);
2556                 return status;
2557         }
2558
2559         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2560         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2561         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2562         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2563         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2564         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2565         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2566         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2567         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2568
2569         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2570 #if 0
2571
2572         /*
2573           Look at a user on a real NT4 PDC with usrmgr, press
2574           'ok'. Then you will see that fields_present is set to
2575           0x08f827fa. Look at the user immediately after that again,
2576           and you will see that 0x00fffff is returned. This solves
2577           the problem that you get access denied after having looked
2578           at the user.
2579           -- Volker
2580         */
2581
2582 #endif
2583
2584         init_samr_user_info21(r,
2585                               last_logon,
2586                               last_logoff,
2587                               last_password_change,
2588                               acct_expiry,
2589                               allow_password_change,
2590                               force_password_change,
2591                               account_name,
2592                               full_name,
2593                               home_directory,
2594                               home_drive,
2595                               logon_script,
2596                               profile_path,
2597                               description,
2598                               workstations,
2599                               comment,
2600                               parameters,
2601                               rid,
2602                               primary_gid,
2603                               pdb_get_acct_ctrl(pw),
2604                               pdb_build_fields_present(pw),
2605                               logon_hours,
2606                               pdb_get_bad_password_count(pw),
2607                               pdb_get_logon_count(pw),
2608                               0, /* country_code */
2609                               0, /* code_page */
2610                               0, /* nt_password_set */
2611                               0, /* lm_password_set */
2612                               password_expired);
2613         TALLOC_FREE(pw);
2614
2615         return NT_STATUS_OK;
2616 }
2617
2618 /*******************************************************************
2619  _samr_QueryUserInfo
2620  ********************************************************************/
2621
2622 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2623                              struct samr_QueryUserInfo *r)
2624 {
2625         NTSTATUS status;
2626         union samr_UserInfo *user_info = NULL;
2627         struct samr_info *info = NULL;
2628         DOM_SID domain_sid;
2629         uint32 rid;
2630
2631         /* search for the handle */
2632         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2633                 return NT_STATUS_INVALID_HANDLE;
2634
2635         domain_sid = info->sid;
2636
2637         sid_split_rid(&domain_sid, &rid);
2638
2639         if (!sid_check_is_in_our_domain(&info->sid))
2640                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2641
2642         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2643                  sid_string_dbg(&info->sid)));
2644
2645         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2646         if (!user_info) {
2647                 return NT_STATUS_NO_MEMORY;
2648         }
2649
2650         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2651
2652         switch (r->in.level) {
2653         case 7:
2654                 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2655                 if (!NT_STATUS_IS_OK(status)) {
2656                         return status;
2657                 }
2658                 break;
2659         case 9:
2660                 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2661                 if (!NT_STATUS_IS_OK(status)) {
2662                         return status;
2663                 }
2664                 break;
2665         case 16:
2666                 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2667                 if (!NT_STATUS_IS_OK(status)) {
2668                         return status;
2669                 }
2670                 break;
2671
2672         case 18:
2673                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2674                 if (!NT_STATUS_IS_OK(status)) {
2675                         return status;
2676                 }
2677                 break;
2678
2679         case 20:
2680                 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2681                 if (!NT_STATUS_IS_OK(status)) {
2682                         return status;
2683                 }
2684                 break;
2685
2686         case 21:
2687                 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2688                                           &info->sid, &domain_sid);
2689                 if (!NT_STATUS_IS_OK(status)) {
2690                         return status;
2691                 }
2692                 break;
2693
2694         default:
2695                 return NT_STATUS_INVALID_INFO_CLASS;
2696         }
2697
2698         *r->out.info = user_info;
2699
2700         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2701
2702         return status;
2703 }
2704
2705 /*******************************************************************
2706  _samr_GetGroupsForUser
2707  ********************************************************************/
2708
2709 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2710                                 struct samr_GetGroupsForUser *r)
2711 {
2712         struct samu *sam_pass=NULL;
2713         DOM_SID  sid;
2714         DOM_SID *sids;
2715         struct samr_RidWithAttribute dom_gid;
2716         struct samr_RidWithAttribute *gids = NULL;
2717         uint32 primary_group_rid;
2718         size_t num_groups = 0;
2719         gid_t *unix_gids;
2720         size_t i, num_gids;
2721         uint32 acc_granted;
2722         bool ret;
2723         NTSTATUS result;
2724         bool success = False;
2725
2726         struct samr_RidWithAttributeArray *rids = NULL;
2727
2728         /*
2729          * from the SID in the request:
2730          * we should send back the list of DOMAIN GROUPS
2731          * the user is a member of
2732          *
2733          * and only the DOMAIN GROUPS
2734          * no ALIASES !!! neither aliases of the domain
2735          * nor aliases of the builtin SID
2736          *
2737          * JFM, 12/2/2001
2738          */
2739
2740         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2741
2742         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2743         if (!rids) {
2744                 return NT_STATUS_NO_MEMORY;
2745         }
2746
2747         /* find the policy handle.  open a policy on it. */
2748         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2749                 return NT_STATUS_INVALID_HANDLE;
2750
2751         result = access_check_samr_function(acc_granted,
2752                                             SA_RIGHT_USER_GET_GROUPS,
2753                                             "_samr_GetGroupsForUser");
2754         if (!NT_STATUS_IS_OK(result)) {
2755                 return result;
2756         }
2757
2758         if (!sid_check_is_in_our_domain(&sid))
2759                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2760
2761         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2762                 return NT_STATUS_NO_MEMORY;
2763         }
2764
2765         become_root();
2766         ret = pdb_getsampwsid(sam_pass, &sid);
2767         unbecome_root();
2768
2769         if (!ret) {
2770                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2771                            sid_string_dbg(&sid)));
2772                 return NT_STATUS_NO_SUCH_USER;
2773         }
2774
2775         sids = NULL;
2776
2777         /* make both calls inside the root block */
2778         become_root();
2779         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2780                                             &sids, &unix_gids, &num_groups);
2781         if ( NT_STATUS_IS_OK(result) ) {
2782                 success = sid_peek_check_rid(get_global_sam_sid(),
2783                                              pdb_get_group_sid(sam_pass),
2784                                              &primary_group_rid);
2785         }
2786         unbecome_root();
2787
2788         if (!NT_STATUS_IS_OK(result)) {
2789                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2790                            sid_string_dbg(&sid)));
2791                 return result;
2792         }
2793
2794         if ( !success ) {
2795                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2796                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
2797                           pdb_get_username(sam_pass)));
2798                 TALLOC_FREE(sam_pass);
2799                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2800         }
2801
2802         gids = NULL;
2803         num_gids = 0;
2804
2805         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2806                               SE_GROUP_ENABLED);
2807         dom_gid.rid = primary_group_rid;
2808         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2809
2810         for (i=0; i<num_groups; i++) {
2811
2812                 if (!sid_peek_check_rid(get_global_sam_sid(),
2813                                         &(sids[i]), &dom_gid.rid)) {
2814                         DEBUG(10, ("Found sid %s not in our domain\n",
2815                                    sid_string_dbg(&sids[i])));
2816                         continue;
2817                 }
2818
2819                 if (dom_gid.rid == primary_group_rid) {
2820                         /* We added the primary group directly from the
2821                          * sam_account. The other SIDs are unique from
2822                          * enum_group_memberships */
2823                         continue;
2824                 }
2825
2826                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2827         }
2828
2829         rids->count = num_gids;
2830         rids->rids = gids;
2831
2832         *r->out.rids = rids;
2833
2834         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2835
2836         return result;
2837 }
2838
2839 /*******************************************************************
2840  samr_QueryDomainInfo_internal
2841  ********************************************************************/
2842
2843 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2844                                               pipes_struct *p,
2845                                               struct policy_handle *handle,
2846                                               uint32_t level,
2847                                               union samr_DomainInfo **dom_info_ptr)
2848 {
2849         NTSTATUS status = NT_STATUS_OK;
2850         struct samr_info *info = NULL;
2851         union samr_DomainInfo *dom_info;
2852         uint32 min_pass_len,pass_hist,password_properties;
2853         time_t u_expire, u_min_age;
2854         NTTIME nt_expire, nt_min_age;
2855
2856         time_t u_lock_duration, u_reset_time;
2857         NTTIME nt_lock_duration, nt_reset_time;
2858         uint32 lockout;
2859         time_t u_logout;
2860         NTTIME nt_logout;
2861
2862         uint32 account_policy_temp;
2863
2864         time_t seq_num;
2865         uint32 server_role;
2866
2867         uint32 num_users=0, num_groups=0, num_aliases=0;
2868
2869         DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2870
2871         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2872         if (!dom_info) {
2873                 return NT_STATUS_NO_MEMORY;
2874         }
2875
2876         *dom_info_ptr = dom_info;
2877
2878         /* find the policy handle.  open a policy on it. */
2879         if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2880                 return NT_STATUS_INVALID_HANDLE;
2881         }
2882
2883         switch (level) {
2884                 case 0x01:
2885
2886                         become_root();
2887
2888                         /* AS ROOT !!! */
2889
2890                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2891                         min_pass_len = account_policy_temp;
2892
2893                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2894                         pass_hist = account_policy_temp;
2895
2896                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2897                         password_properties = account_policy_temp;
2898
2899                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2900                         u_expire = account_policy_temp;
2901
2902                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2903                         u_min_age = account_policy_temp;
2904
2905                         /* !AS ROOT */
2906
2907                         unbecome_root();
2908
2909                         unix_to_nt_time_abs(&nt_expire, u_expire);
2910                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2911
2912                         init_samr_DomInfo1(&dom_info->info1,
2913                                            (uint16)min_pass_len,
2914                                            (uint16)pass_hist,
2915                                            password_properties,
2916                                            nt_expire,
2917                                            nt_min_age);
2918                         break;
2919                 case 0x02:
2920
2921                         become_root();
2922
2923                         /* AS ROOT !!! */
2924
2925                         num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2926                         num_groups = count_sam_groups(info->disp_info);
2927                         num_aliases = count_sam_aliases(info->disp_info);
2928
2929                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2930                         u_logout = account_policy_temp;
2931
2932                         unix_to_nt_time_abs(&nt_logout, u_logout);
2933
2934                         if (!pdb_get_seq_num(&seq_num))
2935                                 seq_num = time(NULL);
2936
2937                         /* !AS ROOT */
2938
2939                         unbecome_root();
2940
2941                         server_role = ROLE_DOMAIN_PDC;
2942                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2943                                 server_role = ROLE_DOMAIN_BDC;
2944
2945                         init_samr_DomGeneralInformation(&dom_info->general,
2946                                                         nt_logout,
2947                                                         lp_serverstring(),
2948                                                         lp_workgroup(),
2949                                                         global_myname(),
2950                                                         seq_num,
2951                                                         1,
2952                                                         server_role,
2953                                                         1,
2954                                                         num_users,
2955                                                         num_groups,
2956                                                         num_aliases);
2957                         break;
2958                 case 0x03:
2959
2960                         become_root();
2961
2962                         /* AS ROOT !!! */
2963
2964                         {
2965                                 uint32 ul;
2966                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2967                                 u_logout = (time_t)ul;
2968                         }
2969
2970                         /* !AS ROOT */
2971
2972                         unbecome_root();
2973
2974                         unix_to_nt_time_abs(&nt_logout, u_logout);
2975
2976                         init_samr_DomInfo3(&dom_info->info3,
2977                                            nt_logout);
2978
2979                         break;
2980                 case 0x04:
2981                         init_samr_DomOEMInformation(&dom_info->oem,
2982                                                     lp_serverstring());
2983                         break;
2984                 case 0x05:
2985                         init_samr_DomInfo5(&dom_info->info5,
2986                                            get_global_sam_name());
2987                         break;
2988                 case 0x06:
2989                         /* NT returns its own name when a PDC. win2k and later
2990                          * only the name of the PDC if itself is a BDC (samba4
2991                          * idl) */
2992                         init_samr_DomInfo6(&dom_info->info6,
2993                                            global_myname());
2994                         break;
2995                 case 0x07:
2996                         server_role = ROLE_DOMAIN_PDC;
2997                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2998                                 server_role = ROLE_DOMAIN_BDC;
2999
3000                         init_samr_DomInfo7(&dom_info->info7,
3001                                            server_role);
3002                         break;
3003                 case 0x08:
3004
3005                         become_root();
3006
3007                         /* AS ROOT !!! */
3008
3009                         if (!pdb_get_seq_num(&seq_num)) {
3010                                 seq_num = time(NULL);
3011                         }
3012
3013                         /* !AS ROOT */
3014
3015                         unbecome_root();
3016
3017                         init_samr_DomInfo8(&dom_info->info8,
3018                                            seq_num,
3019                                            0);
3020                         break;
3021                 case 0x0c:
3022
3023                         become_root();
3024
3025                         /* AS ROOT !!! */
3026
3027                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3028                         u_lock_duration = account_policy_temp;
3029                         if (u_lock_duration != -1) {
3030                                 u_lock_duration *= 60;
3031                         }
3032
3033                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3034                         u_reset_time = account_policy_temp * 60;
3035
3036                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3037                         lockout = account_policy_temp;
3038
3039                         /* !AS ROOT */
3040
3041                         unbecome_root();
3042
3043                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3044                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3045
3046                         init_samr_DomInfo12(&dom_info->info12,
3047                                             nt_lock_duration,
3048                                             nt_reset_time,
3049                                             (uint16)lockout);
3050                         break;
3051                 default:
3052                         return NT_STATUS_INVALID_INFO_CLASS;
3053         }
3054
3055         DEBUG(5,("%s: %d\n", fn_name, __LINE__));
3056
3057         return status;
3058 }
3059
3060 /*******************************************************************
3061  _samr_QueryDomainInfo
3062  ********************************************************************/
3063
3064 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3065                                struct samr_QueryDomainInfo *r)
3066 {
3067         return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
3068                                              p,
3069                                              r->in.domain_handle,
3070                                              r->in.level,
3071                                              r->out.info);
3072 }
3073
3074 /* W2k3 seems to use the same check for all 3 objects that can be created via
3075  * SAMR, if you try to create for example "Dialup" as an alias it says
3076  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3077  * database. */
3078
3079 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3080 {
3081         enum lsa_SidType type;
3082         bool result;
3083
3084         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3085
3086         become_root();
3087         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3088          * whether the name already exists */
3089         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3090                              NULL, NULL, NULL, &type);
3091         unbecome_root();
3092
3093         if (!result) {
3094                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3095                 return NT_STATUS_OK;
3096         }
3097
3098         DEBUG(5, ("trying to create %s, exists as %s\n",
3099                   new_name, sid_type_lookup(type)));
3100
3101         if (type == SID_NAME_DOM_GRP) {
3102                 return NT_STATUS_GROUP_EXISTS;
3103         }
3104         if (type == SID_NAME_ALIAS) {
3105                 return NT_STATUS_ALIAS_EXISTS;
3106         }
3107
3108         /* Yes, the default is NT_STATUS_USER_EXISTS */
3109         return NT_STATUS_USER_EXISTS;
3110 }
3111
3112 /*******************************************************************
3113  _samr_CreateUser2
3114  ********************************************************************/
3115
3116 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3117                            struct samr_CreateUser2 *r)
3118 {
3119         const char *account = NULL;
3120         DOM_SID sid;
3121         POLICY_HND dom_pol = *r->in.domain_handle;
3122         uint32_t acb_info = r->in.acct_flags;
3123         POLICY_HND *user_pol = r->out.user_handle;
3124         struct samr_info *info = NULL;
3125         NTSTATUS nt_status;
3126         uint32 acc_granted;
3127         SEC_DESC *psd;
3128         size_t    sd_size;
3129         /* check this, when giving away 'add computer to domain' privs */
3130         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3131         bool can_add_account = False;
3132         SE_PRIV se_rights;
3133         DISP_INFO *disp_info = NULL;
3134
3135         /* Get the domain SID stored in the domain policy */
3136         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3137                                      &disp_info))
3138                 return NT_STATUS_INVALID_HANDLE;
3139
3140         nt_status = access_check_samr_function(acc_granted,
3141                                                SA_RIGHT_DOMAIN_CREATE_USER,
3142                                                "_samr_CreateUser2");
3143         if (!NT_STATUS_IS_OK(nt_status)) {
3144                 return nt_status;
3145         }
3146
3147         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3148               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3149                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3150                    this parameter is not an account type */
3151                 return NT_STATUS_INVALID_PARAMETER;
3152         }
3153
3154         account = r->in.account_name->string;
3155         if (account == NULL) {
3156                 return NT_STATUS_NO_MEMORY;
3157         }
3158
3159         nt_status = can_create(p->mem_ctx, account);
3160         if (!NT_STATUS_IS_OK(nt_status)) {
3161                 return nt_status;
3162         }
3163
3164         /* determine which user right we need to check based on the acb_info */
3165
3166         if ( acb_info & ACB_WSTRUST )
3167         {
3168                 se_priv_copy( &se_rights, &se_machine_account );
3169                 can_add_account = user_has_privileges(
3170                         p->pipe_user.nt_user_token, &se_rights );
3171         }
3172         /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3173            account for domain trusts and changes the ACB flags later */
3174         else if ( acb_info & ACB_NORMAL &&
3175                   (account[strlen(account)-1] != '$') )
3176         {
3177                 se_priv_copy( &se_rights, &se_add_users );
3178                 can_add_account = user_has_privileges(
3179                         p->pipe_user.nt_user_token, &se_rights );
3180         }
3181         else    /* implicit assumption of a BDC or domain trust account here
3182                  * (we already check the flags earlier) */
3183         {
3184                 if ( lp_enable_privileges() ) {
3185                         /* only Domain Admins can add a BDC or domain trust */
3186                         se_priv_copy( &se_rights, &se_priv_none );
3187                         can_add_account = nt_token_check_domain_rid(
3188                                 p->pipe_user.nt_user_token,
3189                                 DOMAIN_GROUP_RID_ADMINS );
3190                 }
3191         }
3192
3193         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3194                   uidtoname(p->pipe_user.ut.uid),
3195                   can_add_account ? "True":"False" ));
3196
3197         /********** BEGIN Admin BLOCK **********/
3198
3199         if ( can_add_account )
3200                 become_root();
3201
3202         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3203                                     r->out.rid);
3204
3205         if ( can_add_account )
3206                 unbecome_root();
3207
3208         /********** END Admin BLOCK **********/
3209
3210         /* now check for failure */
3211
3212         if ( !NT_STATUS_IS_OK(nt_status) )
3213                 return nt_status;
3214
3215         /* Get the user's SID */
3216
3217         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3218
3219         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3220                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3221         se_map_generic(&des_access, &usr_generic_mapping);
3222
3223         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3224                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3225                 &acc_granted, "_samr_CreateUser2");
3226
3227         if ( !NT_STATUS_IS_OK(nt_status) ) {
3228                 return nt_status;
3229         }
3230
3231         /* associate the user's SID with the new handle. */
3232         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3233                 return NT_STATUS_NO_MEMORY;
3234         }
3235
3236         ZERO_STRUCTP(info);
3237         info->sid = sid;
3238         info->acc_granted = acc_granted;
3239
3240         /* get a (unique) handle.  open a policy on it. */
3241         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3242                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3243         }
3244
3245         /* After a "set" ensure we have no cached display info. */
3246         force_flush_samr_cache(info->disp_info);
3247
3248         *r->out.access_granted = acc_granted;
3249
3250         return NT_STATUS_OK;
3251 }
3252
3253 /*******************************************************************
3254  _samr_Connect
3255  ********************************************************************/
3256
3257 NTSTATUS _samr_Connect(pipes_struct *p,
3258                        struct samr_Connect *r)
3259 {
3260         struct samr_info *info = NULL;
3261         uint32    des_access = r->in.access_mask;
3262
3263         /* Access check */
3264
3265         if (!pipe_access_check(p)) {
3266                 DEBUG(3, ("access denied to _samr_Connect\n"));
3267                 return NT_STATUS_ACCESS_DENIED;
3268         }
3269
3270         /* set up the SAMR connect_anon response */
3271
3272         /* associate the user's SID with the new handle. */
3273         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3274                 return NT_STATUS_NO_MEMORY;
3275
3276         /* don't give away the farm but this is probably ok.  The SA_RIGHT_SAM_ENUM_DOMAINS
3277            was observed from a win98 client trying to enumerate users (when configured
3278            user level access control on shares)   --jerry */
3279
3280         if (des_access == MAXIMUM_ALLOWED_ACCESS) {
3281                 /* Map to max possible knowing we're filtered below. */
3282                 des_access = GENERIC_ALL_ACCESS;
3283         }
3284
3285         se_map_generic( &des_access, &sam_generic_mapping );
3286         info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3287
3288         /* get a (unique) handle.  open a policy on it. */
3289         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3290                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3291
3292         return NT_STATUS_OK;
3293 }
3294
3295 /*******************************************************************
3296  _samr_Connect2
3297  ********************************************************************/
3298
3299 NTSTATUS _samr_Connect2(pipes_struct *p,
3300                         struct samr_Connect2 *r)
3301 {
3302         struct samr_info *info = NULL;
3303         SEC_DESC *psd = NULL;
3304         uint32    acc_granted;
3305         uint32    des_access = r->in.access_mask;
3306         NTSTATUS  nt_status;
3307         size_t    sd_size;
3308
3309
3310         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3311
3312         /* Access check */
3313
3314         if (!pipe_access_check(p)) {
3315                 DEBUG(3, ("access denied to _samr_Connect2\n"));
3316                 return NT_STATUS_ACCESS_DENIED;
3317         }
3318
3319         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3320         se_map_generic(&des_access, &sam_generic_mapping);
3321
3322         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3323                 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3324
3325         if ( !NT_STATUS_IS_OK(nt_status) )
3326                 return nt_status;
3327
3328         /* associate the user's SID and access granted with the new handle. */
3329         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3330                 return NT_STATUS_NO_MEMORY;
3331
3332         info->acc_granted = acc_granted;
3333         info->status = r->in.access_mask; /* this looks so wrong... - gd */
3334
3335         /* get a (unique) handle.  open a policy on it. */
3336         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3337                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3338
3339         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3340
3341         return nt_status;
3342 }
3343
3344 /*******************************************************************
3345  _samr_Connect4
3346  ********************************************************************/
3347
3348 NTSTATUS _samr_Connect4(pipes_struct *p,
3349                         struct samr_Connect4 *r)
3350 {
3351         struct samr_info *info = NULL;
3352         SEC_DESC *psd = NULL;
3353         uint32    acc_granted;
3354         uint32    des_access = r->in.access_mask;
3355         NTSTATUS  nt_status;
3356         size_t    sd_size;
3357
3358
3359         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3360
3361         /* Access check */
3362
3363         if (!pipe_access_check(p)) {
3364                 DEBUG(3, ("access denied to samr_Connect4\n"));
3365                 return NT_STATUS_ACCESS_DENIED;
3366         }
3367
3368         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3369         se_map_generic(&des_access, &sam_generic_mapping);
3370
3371         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3372                 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3373
3374         if ( !NT_STATUS_IS_OK(nt_status) )
3375                 return nt_status;
3376
3377         /* associate the user's SID and access granted with the new handle. */
3378         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3379                 return NT_STATUS_NO_MEMORY;
3380
3381         info->acc_granted = acc_granted;
3382         info->status = r->in.access_mask; /* ??? */
3383
3384         /* get a (unique) handle.  open a policy on it. */
3385         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3386                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3387
3388         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3389
3390         return NT_STATUS_OK;
3391 }
3392
3393 /*******************************************************************
3394  _samr_Connect5
3395  ********************************************************************/
3396
3397 NTSTATUS _samr_Connect5(pipes_struct *p,
3398                         struct samr_Connect5 *r)
3399 {
3400         struct samr_info *info = NULL;
3401         SEC_DESC *psd = NULL;
3402         uint32    acc_granted;
3403         uint32    des_access = r->in.access_mask;
3404         NTSTATUS  nt_status;
3405         size_t    sd_size;
3406         struct samr_ConnectInfo1 info1;
3407
3408         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3409
3410         /* Access check */
3411
3412         if (!pipe_access_check(p)) {
3413                 DEBUG(3, ("access denied to samr_Connect5\n"));
3414                 return NT_STATUS_ACCESS_DENIED;
3415         }
3416
3417         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3418         se_map_generic(&des_access, &sam_generic_mapping);
3419
3420         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3421                 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3422
3423         if ( !NT_STATUS_IS_OK(nt_status) )
3424                 return nt_status;
3425
3426         /* associate the user's SID and access granted with the new handle. */
3427         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3428                 return NT_STATUS_NO_MEMORY;
3429
3430         info->acc_granted = acc_granted;
3431         info->status = r->in.access_mask; /* ??? */
3432
3433         /* get a (unique) handle.  open a policy on it. */
3434         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3435                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3436
3437         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3438
3439         info1.client_version = SAMR_CONNECT_AFTER_W2K;
3440         info1.unknown2 = 0;
3441
3442         *r->out.level_out = 1;
3443         r->out.info_out->info1 = info1;
3444
3445         return NT_STATUS_OK;
3446 }
3447
3448 /**********************************************************************
3449  _samr_LookupDomain
3450  **********************************************************************/
3451
3452 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3453                             struct samr_LookupDomain *r)
3454 {
3455         NTSTATUS status = NT_STATUS_OK;
3456         struct samr_info *info;
3457         const char *domain_name;
3458         DOM_SID *sid = NULL;
3459
3460         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3461                 return NT_STATUS_INVALID_HANDLE;
3462
3463         /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3464            Reverted that change so we will work with RAS servers again */
3465
3466         status = access_check_samr_function(info->acc_granted,
3467                                             SA_RIGHT_SAM_OPEN_DOMAIN,
3468                                             "_samr_LookupDomain");
3469         if (!NT_STATUS_IS_OK(status)) {
3470                 return status;
3471         }
3472
3473         domain_name = r->in.domain_name->string;
3474
3475         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3476         if (!sid) {
3477                 return NT_STATUS_NO_MEMORY;
3478         }
3479
3480         if (strequal(domain_name, builtin_domain_name())) {
3481                 sid_copy(sid, &global_sid_Builtin);
3482         } else {
3483                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3484                         status = NT_STATUS_NO_SUCH_DOMAIN;
3485                 }
3486         }
3487
3488         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3489                  sid_string_dbg(sid)));
3490
3491         *r->out.sid = sid;
3492
3493         return status;
3494 }
3495
3496 /**********************************************************************
3497  _samr_EnumDomains
3498  **********************************************************************/
3499
3500 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3501                            struct samr_EnumDomains *r)
3502 {
3503         NTSTATUS status;
3504         struct samr_info *info;
3505         uint32_t num_entries = 2;
3506         struct samr_SamEntry *entry_array = NULL;
3507         struct samr_SamArray *sam;
3508
3509         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3510                 return NT_STATUS_INVALID_HANDLE;
3511
3512         status = access_check_samr_function(info->acc_granted,
3513                                             SA_RIGHT_SAM_ENUM_DOMAINS,
3514                                             "_samr_EnumDomains");
3515         if (!NT_STATUS_IS_OK(status)) {
3516                 return status;
3517         }
3518
3519         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3520         if (!sam) {
3521                 return NT_STATUS_NO_MEMORY;
3522         }
3523
3524         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3525                                         struct samr_SamEntry,
3526                                         num_entries);
3527         if (!entry_array) {
3528                 return NT_STATUS_NO_MEMORY;
3529         }
3530
3531         entry_array[0].idx = 0;
3532         init_lsa_String(&entry_array[0].name, get_global_sam_name());
3533
3534         entry_array[1].idx = 1;
3535         init_lsa_String(&entry_array[1].name, "Builtin");
3536
3537         sam->count = num_entries;
3538         sam->entries = entry_array;
3539
3540         *r->out.sam = sam;
3541         *r->out.num_entries = num_entries;
3542
3543         return status;
3544 }
3545
3546 /*******************************************************************
3547  _samr_OpenAlias
3548  ********************************************************************/
3549
3550 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3551                          struct samr_OpenAlias *r)
3552 {
3553         DOM_SID sid;
3554         POLICY_HND domain_pol = *r->in.domain_handle;
3555         uint32 alias_rid = r->in.rid;
3556         POLICY_HND *alias_pol = r->out.alias_handle;
3557         struct    samr_info *info = NULL;
3558         SEC_DESC *psd = NULL;
3559         uint32    acc_granted;
3560         uint32    des_access = r->in.access_mask;
3561         size_t    sd_size;
3562         NTSTATUS  status;
3563         SE_PRIV se_rights;
3564
3565         /* find the domain policy and get the SID / access bits stored in the domain policy */
3566
3567         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3568                 return NT_STATUS_INVALID_HANDLE;
3569
3570         status = access_check_samr_function(acc_granted,
3571                                             SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3572                                             "_samr_OpenAlias");
3573
3574         if ( !NT_STATUS_IS_OK(status) )
3575                 return status;
3576
3577         /* append the alias' RID to it */
3578
3579         if (!sid_append_rid(&sid, alias_rid))
3580                 return NT_STATUS_NO_SUCH_ALIAS;
3581
3582         /*check if access can be granted as requested by client. */
3583
3584         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3585         se_map_generic(&des_access,&ali_generic_mapping);
3586
3587         se_priv_copy( &se_rights, &se_add_users );
3588
3589
3590         status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3591                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3592                 &acc_granted, "_samr_OpenAlias");
3593
3594         if ( !NT_STATUS_IS_OK(status) )
3595                 return status;
3596
3597         {
3598                 /* Check we actually have the requested alias */
3599                 enum lsa_SidType type;
3600                 bool result;
3601                 gid_t gid;
3602
3603                 become_root();
3604                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3605                 unbecome_root();
3606
3607                 if (!result || (type != SID_NAME_ALIAS)) {
3608                         return NT_STATUS_NO_SUCH_ALIAS;
3609                 }
3610
3611                 /* make sure there is a mapping */
3612
3613                 if ( !sid_to_gid( &sid, &gid ) ) {
3614                         return NT_STATUS_NO_SUCH_ALIAS;
3615                 }
3616
3617         }
3618
3619         /* associate the alias SID with the new handle. */
3620         if ((info = get_samr_info_by_sid(&sid)) == NULL)
3621                 return NT_STATUS_NO_MEMORY;
3622
3623         info->acc_granted = acc_granted;
3624
3625         /* get a (unique) handle.  open a policy on it. */
3626         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3627                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3628
3629         return NT_STATUS_OK;
3630 }
3631
3632 /*******************************************************************
3633  set_user_info_7
3634  ********************************************************************/
3635
3636 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3637                                 struct samr_UserInfo7 *id7,
3638                                 struct samu *pwd)
3639 {
3640         NTSTATUS rc;
3641
3642         if (id7 == NULL) {
3643                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3644                 TALLOC_FREE(pwd);
3645                 return NT_STATUS_ACCESS_DENIED;
3646         }
3647
3648         if (!id7->account_name.string) {
3649                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3650                 TALLOC_FREE(pwd);
3651                 return NT_STATUS_ACCESS_DENIED;
3652         }
3653
3654         /* check to see if the new username already exists.  Note: we can't
3655            reliably lock all backends, so there is potentially the
3656            possibility that a user can be created in between this check and
3657            the rename.  The rename should fail, but may not get the
3658            exact same failure status code.  I think this is small enough
3659            of a window for this type of operation and the results are
3660            simply that the rename fails with a slightly different status
3661            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3662
3663         rc = can_create(mem_ctx, id7->account_name.string);
3664         if (!NT_STATUS_IS_OK(rc)) {
3665                 return rc;
3666         }
3667
3668         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3669
3670         TALLOC_FREE(pwd);
3671         return rc;
3672 }
3673
3674 /*******************************************************************
3675  set_user_info_16
3676  ********************************************************************/
3677
3678 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3679                              struct samu *pwd)
3680 {
3681         if (id16 == NULL) {
3682                 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3683                 TALLOC_FREE(pwd);
3684                 return False;
3685         }
3686
3687         /* FIX ME: check if the value is really changed --metze */
3688         if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3689                 TALLOC_FREE(pwd);
3690                 return False;
3691         }
3692
3693         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3694                 TALLOC_FREE(pwd);
3695                 return False;
3696         }
3697
3698         TALLOC_FREE(pwd);
3699
3700         return True;
3701 }
3702
3703 /*******************************************************************
3704  set_user_info_18
3705  ********************************************************************/
3706
3707 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3708                              struct samu *pwd)
3709 {
3710         if (id18 == NULL) {
3711                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3712                 TALLOC_FREE(pwd);
3713                 return False;
3714         }
3715
3716         if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3717                 TALLOC_FREE(pwd);
3718                 return False;
3719         }
3720         if (!pdb_set_nt_passwd     (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3721                 TALLOC_FREE(pwd);
3722                 return False;
3723         }
3724         if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3725                 TALLOC_FREE(pwd);
3726                 return False;
3727         }
3728
3729         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3730                 TALLOC_FREE(pwd);
3731                 return False;
3732         }
3733
3734         TALLOC_FREE(pwd);
3735         return True;
3736 }
3737
3738 /*******************************************************************
3739  set_user_info_20
3740  ********************************************************************/
3741
3742 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3743                              struct samu *pwd)
3744 {
3745         if (id20 == NULL) {
3746                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3747                 return False;
3748         }
3749
3750         copy_id20_to_sam_passwd(pwd, id20);
3751
3752         /* write the change out */
3753         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3754                 TALLOC_FREE(pwd);
3755                 return False;
3756         }
3757
3758         TALLOC_FREE(pwd);
3759
3760         return True;
3761 }
3762
3763 /*******************************************************************
3764  set_user_info_21
3765  ********************************************************************/
3766
3767 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3768                                  struct samr_UserInfo21 *id21,
3769                                  struct samu *pwd)
3770 {
3771         NTSTATUS status;
3772
3773         if (id21 == NULL) {
3774                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3775                 return NT_STATUS_INVALID_PARAMETER;
3776         }
3777
3778         /* we need to separately check for an account rename first */
3779
3780         if (id21->account_name.string &&
3781             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3782         {
3783
3784                 /* check to see if the new username already exists.  Note: we can't
3785                    reliably lock all backends, so there is potentially the
3786                    possibility that a user can be created in between this check and
3787                    the rename.  The rename should fail, but may not get the
3788                    exact same failure status code.  I think this is small enough
3789                    of a window for this type of operation and the results are
3790                    simply that the rename fails with a slightly different status
3791                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3792
3793                 status = can_create(mem_ctx, id21->account_name.string);
3794                 if (!NT_STATUS_IS_OK(status)) {
3795                         return status;
3796                 }
3797
3798                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3799
3800                 if (!NT_STATUS_IS_OK(status)) {
3801                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3802                                 nt_errstr(status)));
3803                         TALLOC_FREE(pwd);
3804                         return status;
3805                 }
3806
3807                 /* set the new username so that later
3808                    functions can work on the new account */
3809                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3810         }
3811
3812         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3813
3814         /*
3815          * The funny part about the previous two calls is
3816          * that pwd still has the password hashes from the
3817          * passdb entry.  These have not been updated from
3818          * id21.  I don't know if they need to be set.    --jerry
3819          */
3820
3821         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3822                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3823                 if ( !NT_STATUS_IS_OK(status) ) {
3824                         return status;
3825                 }
3826         }
3827
3828         /* Don't worry about writing out the user account since the
3829            primary group SID is generated solely from the user's Unix
3830            primary group. */
3831
3832         /* write the change out */
3833         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3834                 TALLOC_FREE(pwd);
3835                 return status;
3836         }
3837
3838         TALLOC_FREE(pwd);
3839
3840         return NT_STATUS_OK;
3841 }
3842
3843 /*******************************************************************
3844  set_user_info_23
3845  ********************************************************************/
3846
3847 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3848                                  struct samr_UserInfo23 *id23,
3849                                  struct samu *pwd)
3850 {
3851         char *plaintext_buf = NULL;
3852         uint32 len = 0;
3853         uint16 acct_ctrl;
3854         NTSTATUS status;
3855
3856         if (id23 == NULL) {
3857                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3858                 return NT_STATUS_INVALID_PARAMETER;
3859         }
3860
3861         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3862                   pdb_get_username(pwd)));
3863
3864         acct_ctrl = pdb_get_acct_ctrl(pwd);
3865
3866         if (!decode_pw_buffer(mem_ctx,
3867                                 id23->password.data,
3868                                 &plaintext_buf,
3869                                 &len,
3870                                 STR_UNICODE)) {
3871                 TALLOC_FREE(pwd);
3872                 return NT_STATUS_INVALID_PARAMETER;
3873         }
3874
3875         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3876                 TALLOC_FREE(pwd);
3877                 return NT_STATUS_ACCESS_DENIED;
3878         }
3879
3880         copy_id23_to_sam_passwd(pwd, id23);
3881
3882         /* if it's a trust account, don't update /etc/passwd */
3883         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3884                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
3885                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
3886                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
3887         } else  {
3888                 /* update the UNIX password */
3889                 if (lp_unix_password_sync() ) {
3890                         struct passwd *passwd;
3891                         if (pdb_get_username(pwd) == NULL) {
3892                                 DEBUG(1, ("chgpasswd: User without name???\n"));
3893                                 TALLOC_FREE(pwd);
3894                                 return NT_STATUS_ACCESS_DENIED;
3895                         }
3896
3897                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3898                         if (passwd == NULL) {
3899                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3900                         }
3901
3902                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3903                                 TALLOC_FREE(pwd);
3904                                 return NT_STATUS_ACCESS_DENIED;
3905                         }
3906                         TALLOC_FREE(passwd);
3907                 }
3908         }
3909
3910         memset(plaintext_buf, '\0', strlen(plaintext_buf));
3911
3912         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3913             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
3914                                                                    pwd)))) {
3915                 TALLOC_FREE(pwd);
3916                 return status;
3917         }
3918
3919         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3920                 TALLOC_FREE(pwd);
3921                 return status;
3922         }
3923
3924         TALLOC_FREE(pwd);
3925
3926         return NT_STATUS_OK;
3927 }
3928
3929 /*******************************************************************
3930  set_user_info_pw
3931  ********************************************************************/
3932
3933 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
3934                              int level)
3935 {
3936         uint32 len = 0;
3937         char *plaintext_buf = NULL;
3938         uint32 acct_ctrl;
3939         time_t last_set_time;
3940         enum pdb_value_state last_set_state;
3941
3942         DEBUG(5, ("Attempting administrator password change for user %s\n",
3943                   pdb_get_username(pwd)));
3944
3945         acct_ctrl = pdb_get_acct_ctrl(pwd);
3946         /* we need to know if it's expired, because this is an admin change, not a
3947            user change, so it's still expired when we're done */
3948         last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3949         last_set_time = pdb_get_pass_last_set_time(pwd);
3950
3951         if (!decode_pw_buffer(talloc_tos(),
3952                                 pass,
3953                                 &plaintext_buf,
3954                                 &len,
3955                                 STR_UNICODE)) {
3956                 TALLOC_FREE(pwd);
3957                 return False;
3958         }
3959
3960         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3961                 TALLOC_FREE(pwd);
3962                 return False;
3963         }
3964
3965         /* if it's a trust account, don't update /etc/passwd */
3966         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3967                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
3968                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
3969                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3970         } else {
3971                 /* update the UNIX password */
3972                 if (lp_unix_password_sync()) {
3973                         struct passwd *passwd;
3974
3975                         if (pdb_get_username(pwd) == NULL) {
3976                                 DEBUG(1, ("chgpasswd: User without name???\n"));
3977                                 TALLOC_FREE(pwd);
3978                                 return False;
3979                         }
3980
3981                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3982                         if (passwd == NULL) {
3983                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3984                         }
3985
3986                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3987                                 TALLOC_FREE(pwd);
3988                                 return False;
3989                         }
3990                         TALLOC_FREE(passwd);
3991                 }
3992         }
3993
3994         memset(plaintext_buf, '\0', strlen(plaintext_buf));
3995
3996         /*
3997          * A level 25 change does reset the pwdlastset field, a level 24
3998          * change does not. I know this is probably not the full story, but
3999          * it is needed to make XP join LDAP correctly, without it the later
4000          * auth2 check can fail with PWD_MUST_CHANGE.
4001          */
4002         if (level != 25) {
4003                 /*
4004                  * restore last set time as this is an admin change, not a
4005                  * user pw change
4006                  */
4007                 pdb_set_pass_last_set_time (pwd, last_set_time,
4008                                             last_set_state);
4009         }
4010
4011         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4012
4013         /* update the SAMBA password */
4014         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4015                 TALLOC_FREE(pwd);
4016                 return False;
4017         }
4018
4019         TALLOC_FREE(pwd);
4020
4021         return True;
4022 }
4023
4024 /*******************************************************************
4025  set_user_info_25
4026  ********************************************************************/
4027
4028 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4029                                  struct samr_UserInfo25 *id25,
4030                                  struct samu *pwd)
4031 {
4032         NTSTATUS status;
4033
4034         if (id25 == NULL) {
4035                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4036                 return NT_STATUS_INVALID_PARAMETER;
4037         }
4038
4039         copy_id25_to_sam_passwd(pwd, id25);
4040
4041         /* write the change out */
4042         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4043                 TALLOC_FREE(pwd);
4044                 return status;
4045         }
4046
4047         /*
4048          * We need to "pdb_update_sam_account" before the unix primary group
4049          * is set, because the idealx scripts would also change the
4050          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4051          * the delete explicit / add explicit, which would then fail to find
4052          * the previous primaryGroupSid value.
4053          */
4054
4055         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4056                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4057                 if ( !NT_STATUS_IS_OK(status) ) {
4058                         return status;
4059                 }
4060         }
4061
4062         /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
4063          * hereafter! */
4064
4065         return NT_STATUS_OK;
4066 }
4067
4068 /*******************************************************************
4069  samr_SetUserInfo_internal
4070  ********************************************************************/
4071
4072 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
4073                                           pipes_struct *p,
4074                                           struct policy_handle *user_handle,
4075                                           uint16_t level,
4076                                           union samr_UserInfo *info)
4077 {
4078         NTSTATUS status;
4079         struct samu *pwd = NULL;
4080         DOM_SID sid;
4081         POLICY_HND *pol = user_handle;
4082         uint16_t switch_value = level;
4083         uint32_t acc_granted;
4084         uint32_t acc_required;
4085         bool ret;
4086         bool has_enough_rights = False;
4087         uint32_t acb_info;
4088         DISP_INFO *disp_info = NULL;
4089
4090         DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4091
4092         /* find the policy handle.  open a policy on it. */
4093         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4094                 return NT_STATUS_INVALID_HANDLE;
4095         }
4096
4097         /* This is tricky.  A WinXP domain join sets
4098           (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4099           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
4100           standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4101           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
4102           we'll use the set from the WinXP join as the basis. */
4103
4104         switch (switch_value) {
4105         case 18:
4106         case 24:
4107         case 25:
4108         case 26:
4109                 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4110                 break;
4111         default:
4112                 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4113                                SA_RIGHT_USER_SET_ATTRIBUTES |
4114                                SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4115                 break;
4116         }
4117
4118         status = access_check_samr_function(acc_granted,
4119                                             acc_required,
4120                                             fn_name);
4121         if (!NT_STATUS_IS_OK(status)) {
4122                 return status;
4123         }
4124
4125         DEBUG(5, ("%s: sid:%s, level:%d\n",
4126                   fn_name, sid_string_dbg(&sid), switch_value));
4127
4128         if (info == NULL) {
4129                 DEBUG(5, ("%s: NULL info level\n", fn_name));
4130                 return NT_STATUS_INVALID_INFO_CLASS;
4131         }
4132
4133         if (!(pwd = samu_new(NULL))) {
4134                 return NT_STATUS_NO_MEMORY;
4135         }
4136
4137         become_root();
4138         ret = pdb_getsampwsid(pwd, &sid);
4139         unbecome_root();
4140
4141         if (!ret) {
4142                 TALLOC_FREE(pwd);
4143                 return NT_STATUS_NO_SUCH_USER;
4144         }
4145
4146         /* deal with machine password changes differently from userinfo changes */
4147         /* check to see if we have the sufficient rights */
4148
4149         acb_info = pdb_get_acct_ctrl(pwd);
4150         if (acb_info & ACB_WSTRUST)
4151                 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4152                                                         &se_machine_account);
4153         else if (acb_info & ACB_NORMAL)
4154                 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4155                                                         &se_add_users);
4156         else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4157                 if (lp_enable_privileges()) {
4158                         has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4159                                                                       DOMAIN_GROUP_RID_ADMINS);
4160                 }
4161         }
4162
4163         DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4164                   fn_name,
4165                   uidtoname(p->pipe_user.ut.uid),
4166                   has_enough_rights ? "" : " not"));
4167
4168         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4169
4170         if (has_enough_rights) {
4171                 become_root();
4172         }
4173
4174         /* ok!  user info levels (lots: see MSDEV help), off we go... */
4175
4176         switch (switch_value) {
4177
4178                 case 7:
4179                         status = set_user_info_7(p->mem_ctx,
4180                                                  &info->info7, pwd);
4181                         break;
4182
4183                 case 16:
4184                         if (!set_user_info_16(&info->info16, pwd)) {
4185                                 status = NT_STATUS_ACCESS_DENIED;
4186                         }
4187                         break;
4188
4189                 case 18:
4190                         /* Used by AS/U JRA. */
4191                         if (!set_user_info_18(&info->info18, pwd)) {
4192                                 status = NT_STATUS_ACCESS_DENIED;
4193                         }
4194                         break;
4195
4196                 case 20:
4197                         if (!set_user_info_20(&info->info20, pwd)) {
4198                                 status = NT_STATUS_ACCESS_DENIED;
4199                         }
4200                         break;
4201
4202                 case 21:
4203                         status = set_user_info_21(p->mem_ctx,
4204                                                   &info->info21, pwd);
4205                         break;
4206
4207                 case 23:
4208                         if (!p->server_info->user_session_key.length) {
4209                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4210                         }
4211                         SamOEMhashBlob(info->info23.password.data, 516,
4212                                        &p->server_info->user_session_key);
4213
4214                         dump_data(100, info->info23.password.data, 516);
4215
4216                         status = set_user_info_23(p->mem_ctx,
4217                                                   &info->info23, pwd);
4218                         break;
4219
4220                 case 24:
4221                         if (!p->server_info->user_session_key.length) {
4222                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4223                         }
4224                         SamOEMhashBlob(info->info24.password.data,
4225                                        516,
4226                                        &p->server_info->user_session_key);
4227
4228                         dump_data(100, info->info24.password.data, 516);
4229
4230                         if (!set_user_info_pw(info->info24.password.data, pwd,
4231                                               switch_value)) {
4232                                 status = NT_STATUS_ACCESS_DENIED;
4233                         }
4234                         break;
4235
4236                 case 25:
4237                         if (!p->server_info->user_session_key.length) {
4238                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4239                         }
4240                         encode_or_decode_arc4_passwd_buffer(
4241                                 info->info25.password.data,
4242                                 &p->server_info->user_session_key);
4243
4244                         dump_data(100, info->info25.password.data, 532);
4245
4246                         status = set_user_info_25(p->mem_ctx,
4247                                                   &info->info25, pwd);
4248                         if (!NT_STATUS_IS_OK(status)) {
4249                                 goto done;
4250                         }
4251                         if (!set_user_info_pw(info->info25.password.data, pwd,
4252                                               switch_value)) {
4253                                 status = NT_STATUS_ACCESS_DENIED;
4254                         }
4255                         break;
4256
4257                 case 26:
4258                         if (!p->server_info->user_session_key.length) {
4259                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4260                         }
4261                         encode_or_decode_arc4_passwd_buffer(
4262                                 info->info26.password.data,
4263                                 &p->server_info->user_session_key);
4264
4265                         dump_data(100, info->info26.password.data, 516);
4266
4267                         if (!set_user_info_pw(info->info26.password.data, pwd,
4268                                               switch_value)) {
4269                                 status = NT_STATUS_ACCESS_DENIED;
4270                         }
4271                         break;
4272
4273                 default:
4274                         status = NT_STATUS_INVALID_INFO_CLASS;
4275         }
4276
4277  done:
4278
4279         if (has_enough_rights) {
4280                 unbecome_root();
4281         }
4282
4283         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4284
4285         if (NT_STATUS_IS_OK(status)) {
4286                 force_flush_samr_cache(disp_info);
4287         }
4288
4289         return status;
4290 }
4291
4292 /*******************************************************************
4293  _samr_SetUserInfo
4294  ********************************************************************/
4295
4296 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4297                            struct samr_SetUserInfo *r)
4298 {
4299         return samr_SetUserInfo_internal("_samr_SetUserInfo",
4300                                          p,
4301                                          r->in.user_handle,
4302                                          r->in.level,
4303                                          r->in.info);
4304 }
4305
4306 /*******************************************************************
4307  _samr_SetUserInfo2
4308  ********************************************************************/
4309
4310 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4311                             struct samr_SetUserInfo2 *r)
4312 {
4313         return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4314                                          p,
4315                                          r->in.user_handle,
4316                                          r->in.level,
4317                                          r->in.info);
4318 }
4319
4320 /*********************************************************************
4321  _samr_GetAliasMembership
4322 *********************************************************************/
4323
4324 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4325                                   struct samr_GetAliasMembership *r)
4326 {
4327         size_t num_alias_rids;
4328         uint32 *alias_rids;
4329         struct samr_info *info = NULL;
4330         size_t i;
4331
4332         NTSTATUS ntstatus1;
4333         NTSTATUS ntstatus2;
4334
4335         DOM_SID *members;
4336
4337         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4338
4339         /* find the policy handle.  open a policy on it. */
4340         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4341                 return NT_STATUS_INVALID_HANDLE;
4342
4343         ntstatus1 = access_check_samr_function(info->acc_granted,
4344                                                SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4345                                                "_samr_GetAliasMembership");
4346         ntstatus2 = access_check_samr_function(info->acc_granted,
4347                                                SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4348                                                "_samr_GetAliasMembership");
4349
4350         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4351                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4352                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4353                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4354                 }
4355         }
4356
4357         if (!sid_check_is_domain(&info->sid) &&
4358             !sid_check_is_builtin(&info->sid))
4359                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4360
4361         if (r->in.sids->num_sids) {
4362                 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4363
4364                 if (members == NULL)
4365                         return NT_STATUS_NO_MEMORY;
4366         } else {
4367                 members = NULL;
4368         }
4369
4370         for (i=0; i<r->in.sids->num_sids; i++)
4371                 sid_copy(&members[i], r->in.sids->sids[i].sid);
4372
4373         alias_rids = NULL;
4374         num_alias_rids = 0;
4375
4376         become_root();
4377         ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4378                                                r->in.sids->num_sids,
4379                                                &alias_rids, &num_alias_rids);
4380         unbecome_root();
4381
4382         if (!NT_STATUS_IS_OK(ntstatus1)) {
4383                 return ntstatus1;
4384         }
4385
4386         r->out.rids->count = num_alias_rids;
4387         r->out.rids->ids = alias_rids;
4388
4389         return NT_STATUS_OK;
4390 }
4391
4392 /*********************************************************************
4393  _samr_GetMembersInAlias
4394 *********************************************************************/
4395
4396 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4397                                  struct samr_GetMembersInAlias *r)
4398 {
4399         NTSTATUS status;
4400         size_t i;
4401         size_t num_sids = 0;
4402         struct lsa_SidPtr *sids = NULL;
4403         DOM_SID *pdb_sids = NULL;
4404
4405         DOM_SID alias_sid;
4406
4407         uint32 acc_granted;
4408
4409         /* find the policy handle.  open a policy on it. */
4410         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4411                 return NT_STATUS_INVALID_HANDLE;
4412
4413         status = access_check_samr_function(acc_granted,
4414                                             SA_RIGHT_ALIAS_GET_MEMBERS,
4415                                             "_samr_GetMembersInAlias");
4416         if (!NT_STATUS_IS_OK(status)) {
4417                 return status;
4418         }
4419
4420         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4421
4422         become_root();
4423         status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4424         unbecome_root();
4425
4426         if (!NT_STATUS_IS_OK(status)) {
4427                 return status;
4428         }
4429
4430         if (num_sids) {
4431                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4432                 if (sids == NULL) {
4433                         TALLOC_FREE(pdb_sids);
4434                         return NT_STATUS_NO_MEMORY;
4435                 }
4436         }
4437
4438         for (i = 0; i < num_sids; i++) {
4439                 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4440                 if (!sids[i].sid) {
4441                         TALLOC_FREE(pdb_sids);
4442                         return NT_STATUS_NO_MEMORY;
4443                 }
4444         }
4445
4446         r->out.sids->num_sids = num_sids;
4447         r->out.sids->sids = sids;
4448
4449         TALLOC_FREE(pdb_sids);
4450
4451         return NT_STATUS_OK;
4452 }
4453
4454 /*********************************************************************
4455  _samr_QueryGroupMember
4456 *********************************************************************/
4457
4458 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4459                                 struct samr_QueryGroupMember *r)
4460 {
4461         DOM_SID group_sid;
4462         size_t i, num_members;
4463
4464         uint32 *rid=NULL;
4465         uint32 *attr=NULL;
4466
4467         uint32 acc_granted;
4468
4469         NTSTATUS status;
4470         struct samr_RidTypeArray *rids = NULL;
4471
4472         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4473         if (!rids) {
4474                 return NT_STATUS_NO_MEMORY;
4475         }
4476
4477         /* find the policy handle.  open a policy on it. */
4478         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4479                 return NT_STATUS_INVALID_HANDLE;
4480
4481         status = access_check_samr_function(acc_granted,
4482                                             SA_RIGHT_GROUP_GET_MEMBERS,
4483                                             "_samr_QueryGroupMember");
4484         if (!NT_STATUS_IS_OK(status)) {
4485                 return status;
4486         }
4487
4488         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4489
4490         if (!sid_check_is_in_our_domain(&group_sid)) {
4491                 DEBUG(3, ("sid %s is not in our domain\n",
4492                           sid_string_dbg(&group_sid)));
4493                 return NT_STATUS_NO_SUCH_GROUP;
4494         }
4495
4496         DEBUG(10, ("lookup on Domain SID\n"));
4497
4498         become_root();
4499         status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4500                                         &rid, &num_members);
4501         unbecome_root();
4502
4503         if (!NT_STATUS_IS_OK(status))
4504                 return status;
4505
4506         if (num_members) {
4507                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4508                 if (attr == NULL) {
4509                         return NT_STATUS_NO_MEMORY;
4510                 }
4511         } else {
4512                 attr = NULL;
4513         }
4514
4515         for (i=0; i<num_members; i++)
4516                 attr[i] = SID_NAME_USER;
4517
4518         rids->count = num_members;
4519         rids->types = attr;
4520         rids->rids = rid;
4521
4522         *r->out.rids = rids;
4523
4524         return NT_STATUS_OK;
4525 }
4526
4527 /*********************************************************************
4528  _samr_AddAliasMember
4529 *********************************************************************/
4530
4531 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4532                               struct samr_AddAliasMember *r)
4533 {
4534         DOM_SID alias_sid;
4535         uint32 acc_granted;
4536         SE_PRIV se_rights;
4537         bool can_add_accounts;
4538         NTSTATUS status;
4539         DISP_INFO *disp_info = NULL;
4540
4541         /* Find the policy handle. Open a policy on it. */
4542         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4543                 return NT_STATUS_INVALID_HANDLE;
4544
4545         status = access_check_samr_function(acc_granted,
4546                                             SA_RIGHT_ALIAS_ADD_MEMBER,
4547                                             "_samr_AddAliasMember");
4548         if (!NT_STATUS_IS_OK(status)) {
4549                 return status;
4550         }
4551
4552         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4553
4554         se_priv_copy( &se_rights, &se_add_users );
4555         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4556
4557         /******** BEGIN SeAddUsers BLOCK *********/
4558
4559         if ( can_add_accounts )
4560                 become_root();
4561
4562         status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4563
4564         if ( can_add_accounts )
4565                 unbecome_root();
4566
4567         /******** END SeAddUsers BLOCK *********/
4568
4569         if (NT_STATUS_IS_OK(status)) {
4570                 force_flush_samr_cache(disp_info);
4571         }
4572
4573         return status;
4574 }
4575
4576 /*********************************************************************
4577  _samr_DeleteAliasMember
4578 *********************************************************************/
4579
4580 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4581                                  struct samr_DeleteAliasMember *r)
4582 {
4583         DOM_SID alias_sid;
4584         uint32 acc_granted;
4585         SE_PRIV se_rights;
4586         bool can_add_accounts;
4587         NTSTATUS status;
4588         DISP_INFO *disp_info = NULL;
4589
4590         /* Find the policy handle. Open a policy on it. */
4591         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4592                 return NT_STATUS_INVALID_HANDLE;
4593
4594         status = access_check_samr_function(acc_granted,
4595                                             SA_RIGHT_ALIAS_REMOVE_MEMBER,
4596                                             "_samr_DeleteAliasMember");
4597         if (!NT_STATUS_IS_OK(status)) {
4598                 return status;
4599         }
4600
4601         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4602                    sid_string_dbg(&alias_sid)));
4603
4604         se_priv_copy( &se_rights, &se_add_users );
4605         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4606
4607         /******** BEGIN SeAddUsers BLOCK *********/
4608
4609         if ( can_add_accounts )
4610                 become_root();
4611
4612         status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4613
4614         if ( can_add_accounts )
4615                 unbecome_root();
4616
4617         /******** END SeAddUsers BLOCK *********/
4618
4619         if (NT_STATUS_IS_OK(status)) {
4620                 force_flush_samr_cache(disp_info);
4621         }
4622
4623         return status;
4624 }
4625
4626 /*********************************************************************
4627  _samr_AddGroupMember
4628 *********************************************************************/
4629
4630 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4631                               struct samr_AddGroupMember *r)
4632 {
4633         NTSTATUS status;
4634         DOM_SID group_sid;
4635         uint32 group_rid;
4636         uint32 acc_granted;
4637         SE_PRIV se_rights;
4638         bool can_add_accounts;
4639         DISP_INFO *disp_info = NULL;
4640
4641         /* Find the policy handle. Open a policy on it. */
4642         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4643                 return NT_STATUS_INVALID_HANDLE;
4644
4645         status = access_check_samr_function(acc_granted,
4646                                             SA_RIGHT_GROUP_ADD_MEMBER,
4647                                             "_samr_AddGroupMember");
4648         if (!NT_STATUS_IS_OK(status)) {
4649                 return status;
4650         }
4651
4652         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4653
4654         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4655                                 &group_rid)) {
4656                 return NT_STATUS_INVALID_HANDLE;
4657         }
4658
4659         se_priv_copy( &se_rights, &se_add_users );
4660         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4661
4662         /******** BEGIN SeAddUsers BLOCK *********/
4663
4664         if ( can_add_accounts )
4665                 become_root();
4666
4667         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4668
4669         if ( can_add_accounts )
4670                 unbecome_root();
4671
4672         /******** END SeAddUsers BLOCK *********/
4673
4674         force_flush_samr_cache(disp_info);
4675
4676         return status;
4677 }
4678
4679 /*********************************************************************
4680  _samr_DeleteGroupMember
4681 *********************************************************************/
4682
4683 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4684                                  struct samr_DeleteGroupMember *r)
4685
4686 {
4687         NTSTATUS status;
4688         DOM_SID group_sid;
4689         uint32 group_rid;
4690         uint32 acc_granted;
4691         SE_PRIV se_rights;
4692         bool can_add_accounts;
4693         DISP_INFO *disp_info = NULL;
4694
4695         /*
4696          * delete the group member named r->in.rid
4697          * who is a member of the sid associated with the handle
4698          * the rid is a user's rid as the group is a domain group.
4699          */
4700
4701         /* Find the policy handle. Open a policy on it. */
4702         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4703                 return NT_STATUS_INVALID_HANDLE;
4704
4705         status = access_check_samr_function(acc_granted,
4706                                             SA_RIGHT_GROUP_REMOVE_MEMBER,
4707                                             "_samr_DeleteGroupMember");
4708         if (!NT_STATUS_IS_OK(status)) {
4709                 return status;
4710         }
4711
4712         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4713                                 &group_rid)) {
4714                 return NT_STATUS_INVALID_HANDLE;
4715         }
4716
4717         se_priv_copy( &se_rights, &se_add_users );
4718         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4719
4720         /******** BEGIN SeAddUsers BLOCK *********/
4721
4722         if ( can_add_accounts )
4723                 become_root();
4724
4725         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4726
4727         if ( can_add_accounts )
4728                 unbecome_root();
4729
4730         /******** END SeAddUsers BLOCK *********/
4731
4732         force_flush_samr_cache(disp_info);
4733
4734         return status;
4735 }
4736
4737 /*********************************************************************
4738  _samr_DeleteUser
4739 *********************************************************************/
4740
4741 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4742                           struct samr_DeleteUser *r)
4743 {
4744         NTSTATUS status;
4745         DOM_SID user_sid;
4746         struct samu *sam_pass=NULL;
4747         uint32 acc_granted;
4748         bool can_add_accounts;
4749         uint32 acb_info;
4750         DISP_INFO *disp_info = NULL;
4751         bool ret;
4752
4753         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4754
4755         /* Find the policy handle. Open a policy on it. */
4756         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4757                 return NT_STATUS_INVALID_HANDLE;
4758
4759         status = access_check_samr_function(acc_granted,
4760                                             STD_RIGHT_DELETE_ACCESS,
4761                                             "_samr_DeleteUser");
4762         if (!NT_STATUS_IS_OK(status)) {
4763                 return status;
4764         }
4765
4766         if (!sid_check_is_in_our_domain(&user_sid))
4767                 return NT_STATUS_CANNOT_DELETE;
4768
4769         /* check if the user exists before trying to delete */
4770         if ( !(sam_pass = samu_new( NULL )) ) {
4771                 return NT_STATUS_NO_MEMORY;
4772         }
4773
4774         become_root();
4775         ret = pdb_getsampwsid(sam_pass, &user_sid);
4776         unbecome_root();
4777
4778         if( !ret ) {
4779                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4780                         sid_string_dbg(&user_sid)));
4781                 TALLOC_FREE(sam_pass);
4782                 return NT_STATUS_NO_SUCH_USER;
4783         }
4784
4785         acb_info = pdb_get_acct_ctrl(sam_pass);
4786
4787         /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4788         if ( acb_info & ACB_WSTRUST ) {
4789                 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4790         } else {
4791                 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4792         }
4793
4794         /******** BEGIN SeAddUsers BLOCK *********/
4795
4796         if ( can_add_accounts )
4797                 become_root();
4798
4799         status = pdb_delete_user(p->mem_ctx, sam_pass);
4800
4801         if ( can_add_accounts )
4802                 unbecome_root();
4803
4804         /******** END SeAddUsers BLOCK *********/
4805
4806         if ( !NT_STATUS_IS_OK(status) ) {
4807                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4808                          "user %s: %s.\n", pdb_get_username(sam_pass),
4809                          nt_errstr(status)));
4810                 TALLOC_FREE(sam_pass);
4811                 return status;
4812         }
4813
4814
4815         TALLOC_FREE(sam_pass);
4816
4817         if (!close_policy_hnd(p, r->in.user_handle))
4818                 return NT_STATUS_OBJECT_NAME_INVALID;
4819
4820         force_flush_samr_cache(disp_info);
4821
4822         return NT_STATUS_OK;
4823 }
4824
4825 /*********************************************************************
4826  _samr_DeleteDomainGroup
4827 *********************************************************************/
4828
4829 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4830                                  struct samr_DeleteDomainGroup *r)
4831 {
4832         NTSTATUS status;
4833         DOM_SID group_sid;
4834         uint32 group_rid;
4835         uint32 acc_granted;
4836         SE_PRIV se_rights;
4837         bool can_add_accounts;
4838         DISP_INFO *disp_info = NULL;
4839
4840         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4841
4842         /* Find the policy handle. Open a policy on it. */
4843         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4844                 return NT_STATUS_INVALID_HANDLE;
4845
4846         status = access_check_samr_function(acc_granted,
4847                                             STD_RIGHT_DELETE_ACCESS,
4848                                             "_samr_DeleteDomainGroup");
4849         if (!NT_STATUS_IS_OK(status)) {
4850                 return status;
4851         }
4852
4853         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4854
4855         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4856                                 &group_rid)) {
4857                 return NT_STATUS_NO_SUCH_GROUP;
4858         }
4859
4860         se_priv_copy( &se_rights, &se_add_users );
4861         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4862
4863         /******** BEGIN SeAddUsers BLOCK *********/
4864
4865         if ( can_add_accounts )
4866                 become_root();
4867
4868         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4869
4870         if ( can_add_accounts )
4871                 unbecome_root();
4872
4873         /******** END SeAddUsers BLOCK *********/
4874
4875         if ( !NT_STATUS_IS_OK(status) ) {
4876                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4877                          "entry for group %s: %s\n",
4878                          sid_string_dbg(&group_sid),
4879                          nt_errstr(status)));
4880                 return status;
4881         }
4882
4883         if (!close_policy_hnd(p, r->in.group_handle))
4884                 return NT_STATUS_OBJECT_NAME_INVALID;
4885
4886         force_flush_samr_cache(disp_info);
4887
4888         return NT_STATUS_OK;
4889 }
4890
4891 /*********************************************************************
4892  _samr_DeleteDomAlias
4893 *********************************************************************/
4894
4895 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4896                               struct samr_DeleteDomAlias *r)
4897 {
4898         DOM_SID alias_sid;
4899         uint32 acc_granted;
4900         SE_PRIV se_rights;
4901         bool can_add_accounts;
4902         NTSTATUS status;
4903         DISP_INFO *disp_info = NULL;
4904
4905         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4906
4907         /* Find the policy handle. Open a policy on it. */
4908         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4909                 return NT_STATUS_INVALID_HANDLE;
4910
4911         /* copy the handle to the outgoing reply */
4912
4913         memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4914
4915         status = access_check_samr_function(acc_granted,
4916                                             STD_RIGHT_DELETE_ACCESS,
4917                                             "_samr_DeleteDomAlias");
4918         if (!NT_STATUS_IS_OK(status)) {
4919                 return status;
4920         }
4921
4922         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4923
4924         /* Don't let Windows delete builtin groups */
4925
4926         if ( sid_check_is_in_builtin( &alias_sid ) ) {
4927                 return NT_STATUS_SPECIAL_ACCOUNT;
4928         }
4929
4930         if (!sid_check_is_in_our_domain(&alias_sid))
4931                 return NT_STATUS_NO_SUCH_ALIAS;
4932
4933         DEBUG(10, ("lookup on Local SID\n"));
4934
4935         se_priv_copy( &se_rights, &se_add_users );
4936         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4937
4938         /******** BEGIN SeAddUsers BLOCK *********/
4939
4940         if ( can_add_accounts )
4941                 become_root();
4942
4943         /* Have passdb delete the alias */
4944         status = pdb_delete_alias(&alias_sid);
4945
4946         if ( can_add_accounts )
4947                 unbecome_root();
4948
4949         /******** END SeAddUsers BLOCK *********/
4950
4951         if ( !NT_STATUS_IS_OK(status))
4952                 return status;
4953
4954         if (!close_policy_hnd(p, r->in.alias_handle))
4955                 return NT_STATUS_OBJECT_NAME_INVALID;
4956
4957         force_flush_samr_cache(disp_info);
4958
4959         return NT_STATUS_OK;
4960 }
4961
4962 /*********************************************************************
4963  _samr_CreateDomainGroup
4964 *********************************************************************/
4965
4966 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4967                                  struct samr_CreateDomainGroup *r)
4968
4969 {
4970         NTSTATUS status;
4971         DOM_SID dom_sid;
4972         DOM_SID info_sid;
4973         const char *name;
4974         struct samr_info *info;
4975         uint32 acc_granted;
4976         SE_PRIV se_rights;
4977         bool can_add_accounts;
4978         DISP_INFO *disp_info = NULL;
4979
4980         /* Find the policy handle. Open a policy on it. */
4981         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4982                 return NT_STATUS_INVALID_HANDLE;
4983
4984         status = access_check_samr_function(acc_granted,
4985                                             SA_RIGHT_DOMAIN_CREATE_GROUP,
4986                                             "_samr_CreateDomainGroup");
4987         if (!NT_STATUS_IS_OK(status)) {
4988                 return status;
4989         }
4990
4991         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4992                 return NT_STATUS_ACCESS_DENIED;
4993
4994         name = r->in.name->string;
4995         if (name == NULL) {
4996                 return NT_STATUS_NO_MEMORY;
4997         }
4998
4999         status = can_create(p->mem_ctx, name);
5000         if (!NT_STATUS_IS_OK(status)) {
5001                 return status;
5002         }
5003
5004         se_priv_copy( &se_rights, &se_add_users );
5005         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5006
5007         /******** BEGIN SeAddUsers BLOCK *********/
5008
5009         if ( can_add_accounts )
5010                 become_root();
5011
5012         /* check that we successfully create the UNIX group */
5013
5014         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5015
5016         if ( can_add_accounts )
5017                 unbecome_root();
5018
5019         /******** END SeAddUsers BLOCK *********/
5020
5021         /* check if we should bail out here */
5022
5023         if ( !NT_STATUS_IS_OK(status) )
5024                 return status;
5025
5026         sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5027
5028         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5029                 return NT_STATUS_NO_MEMORY;
5030
5031         /* they created it; let the user do what he wants with it */
5032
5033         info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5034
5035         /* get a (unique) handle.  open a policy on it. */
5036         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5037                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5038
5039         force_flush_samr_cache(disp_info);
5040
5041         return NT_STATUS_OK;
5042 }
5043
5044 /*********************************************************************
5045  _samr_CreateDomAlias
5046 *********************************************************************/
5047
5048 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5049                               struct samr_CreateDomAlias *r)
5050 {
5051         DOM_SID dom_sid;
5052         DOM_SID info_sid;
5053         const char *name = NULL;
5054         struct samr_info *info;
5055         uint32 acc_granted;
5056         gid_t gid;
5057         NTSTATUS result;
5058         SE_PRIV se_rights;
5059         bool can_add_accounts;
5060         DISP_INFO *disp_info = NULL;
5061
5062         /* Find the policy handle. Open a policy on it. */
5063         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5064                 return NT_STATUS_INVALID_HANDLE;
5065
5066         result = access_check_samr_function(acc_granted,
5067                                             SA_RIGHT_DOMAIN_CREATE_ALIAS,
5068                                             "_samr_CreateDomAlias");
5069         if (!NT_STATUS_IS_OK(result)) {
5070                 return result;
5071         }
5072
5073         if (!sid_equal(&dom_sid, get_global_sam_sid()))
5074                 return NT_STATUS_ACCESS_DENIED;
5075
5076         name = r->in.alias_name->string;
5077
5078         se_priv_copy( &se_rights, &se_add_users );
5079         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5080
5081         result = can_create(p->mem_ctx, name);
5082         if (!NT_STATUS_IS_OK(result)) {
5083                 return result;
5084         }
5085
5086         /******** BEGIN SeAddUsers BLOCK *********/
5087
5088         if ( can_add_accounts )
5089                 become_root();
5090
5091         /* Have passdb create the alias */
5092         result = pdb_create_alias(name, r->out.rid);
5093
5094         if ( can_add_accounts )
5095                 unbecome_root();
5096
5097         /******** END SeAddUsers BLOCK *********/
5098
5099         if (!NT_STATUS_IS_OK(result)) {
5100                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5101                            nt_errstr(result)));
5102                 return result;
5103         }
5104
5105         sid_copy(&info_sid, get_global_sam_sid());
5106         sid_append_rid(&info_sid, *r->out.rid);
5107
5108         if (!sid_to_gid(&info_sid, &gid)) {
5109                 DEBUG(10, ("Could not find alias just created\n"));
5110                 return NT_STATUS_ACCESS_DENIED;
5111         }
5112
5113         /* check if the group has been successfully created */
5114         if ( getgrgid(gid) == NULL ) {
5115                 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5116                            gid));
5117                 return NT_STATUS_ACCESS_DENIED;
5118         }
5119
5120         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5121                 return NT_STATUS_NO_MEMORY;
5122
5123         /* they created it; let the user do what he wants with it */
5124
5125         info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5126
5127         /* get a (unique) handle.  open a policy on it. */
5128         if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5129                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5130
5131         force_flush_samr_cache(disp_info);
5132
5133         return NT_STATUS_OK;
5134 }
5135
5136 /*********************************************************************
5137  _samr_QueryGroupInfo
5138 *********************************************************************/
5139
5140 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5141                               struct samr_QueryGroupInfo *r)
5142 {
5143         NTSTATUS status;
5144         DOM_SID group_sid;
5145         GROUP_MAP map;
5146         union samr_GroupInfo *info = NULL;
5147         uint32 acc_granted;
5148         bool ret;
5149         uint32_t attributes = SE_GROUP_MANDATORY |
5150                               SE_GROUP_ENABLED_BY_DEFAULT |
5151                               SE_GROUP_ENABLED;
5152         const char *group_name = NULL;
5153         const char *group_description = NULL;
5154
5155         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5156                 return NT_STATUS_INVALID_HANDLE;
5157
5158         status = access_check_samr_function(acc_granted,
5159                                             SA_RIGHT_GROUP_LOOKUP_INFO,
5160                                             "_samr_QueryGroupInfo");
5161         if (!NT_STATUS_IS_OK(status)) {
5162                 return status;
5163         }
5164
5165         become_root();
5166         ret = get_domain_group_from_sid(group_sid, &map);
5167         unbecome_root();
5168         if (!ret)
5169                 return NT_STATUS_INVALID_HANDLE;
5170
5171         /* FIXME: map contains fstrings */
5172         group_name = talloc_strdup(r, map.nt_name);
5173         group_description = talloc_strdup(r, map.comment);
5174
5175         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5176         if (!info) {
5177                 return NT_STATUS_NO_MEMORY;
5178         }
5179
5180         switch (r->in.level) {
5181                 case 1: {
5182                         uint32 *members;
5183                         size_t num_members;
5184
5185                         become_root();
5186                         status = pdb_enum_group_members(
5187                                 p->mem_ctx, &group_sid, &members, &num_members);
5188                         unbecome_root();
5189
5190                         if (!NT_STATUS_IS_OK(status)) {
5191                                 return status;
5192                         }
5193
5194                         init_samr_group_info1(&info->all,
5195                                               group_name,
5196                                               attributes,
5197                                               num_members,
5198                                               group_description);
5199                         break;
5200                 }
5201                 case 2:
5202                         init_samr_group_info2(&info->name,
5203                                               group_name);
5204                         break;
5205                 case 3:
5206                         init_samr_group_info3(&info->attributes,
5207                                               attributes);
5208                         break;
5209                 case 4:
5210                         init_samr_group_info4(&info->description,
5211                                               group_description);
5212                         break;
5213                 case 5: {
5214                         /*
5215                         uint32 *members;
5216                         size_t num_members;
5217                         */
5218
5219                         /*
5220                         become_root();
5221                         status = pdb_enum_group_members(
5222                                 p->mem_ctx, &group_sid, &members, &num_members);
5223                         unbecome_root();
5224
5225                         if (!NT_STATUS_IS_OK(status)) {
5226                                 return status;
5227                         }
5228                         */
5229                         init_samr_group_info5(&info->all2,
5230                                               group_name,
5231                                               attributes,
5232                                               0, /* num_members - in w2k3 this is always 0 */
5233                                               group_description);
5234
5235                         break;
5236                 }
5237                 default:
5238                         return NT_STATUS_INVALID_INFO_CLASS;
5239         }
5240
5241         *r->out.info = info;
5242
5243         return NT_STATUS_OK;
5244 }
5245
5246 /*********************************************************************
5247  _samr_SetGroupInfo
5248 *********************************************************************/
5249
5250 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5251                             struct samr_SetGroupInfo *r)
5252 {
5253         DOM_SID group_sid;
5254         GROUP_MAP map;
5255         uint32 acc_granted;
5256         NTSTATUS status;
5257         bool ret;
5258         bool can_mod_accounts;
5259         DISP_INFO *disp_info = NULL;
5260
5261         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5262                 return NT_STATUS_INVALID_HANDLE;
5263
5264         status = access_check_samr_function(acc_granted,
5265                                             SA_RIGHT_GROUP_SET_INFO,
5266                                             "_samr_SetGroupInfo");
5267         if (!NT_STATUS_IS_OK(status)) {
5268                 return status;
5269         }
5270
5271         become_root();
5272         ret = get_domain_group_from_sid(group_sid, &map);
5273         unbecome_root();
5274         if (!ret)
5275                 return NT_STATUS_NO_SUCH_GROUP;
5276
5277         switch (r->in.level) {
5278                 case 1:
5279                         fstrcpy(map.comment, r->in.info->all.description.string);
5280                         break;
5281                 case 4:
5282                         fstrcpy(map.comment, r->in.info->description.string);
5283                         break;
5284                 default:
5285                         return NT_STATUS_INVALID_INFO_CLASS;
5286         }
5287
5288         can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5289
5290         /******** BEGIN SeAddUsers BLOCK *********/
5291
5292         if ( can_mod_accounts )
5293                 become_root();
5294
5295         status = pdb_update_group_mapping_entry(&map);
5296
5297         if ( can_mod_accounts )
5298                 unbecome_root();
5299
5300         /******** End SeAddUsers BLOCK *********/
5301
5302         if (NT_STATUS_IS_OK(status)) {
5303                 force_flush_samr_cache(disp_info);
5304         }
5305
5306         return status;
5307 }
5308
5309 /*********************************************************************
5310  _samr_SetAliasInfo
5311 *********************************************************************/
5312
5313 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5314                             struct samr_SetAliasInfo *r)
5315 {
5316         DOM_SID group_sid;
5317         struct acct_info info;
5318         uint32 acc_granted;
5319         bool can_mod_accounts;
5320         NTSTATUS status;
5321         DISP_INFO *disp_info = NULL;
5322
5323         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5324                 return NT_STATUS_INVALID_HANDLE;
5325
5326         status = access_check_samr_function(acc_granted,
5327                                             SA_RIGHT_ALIAS_SET_INFO,
5328                                             "_samr_SetAliasInfo");
5329         if (!NT_STATUS_IS_OK(status)) {
5330                 return status;
5331         }
5332
5333         /* get the current group information */
5334
5335         become_root();
5336         status = pdb_get_aliasinfo( &group_sid, &info );
5337         unbecome_root();
5338
5339         if ( !NT_STATUS_IS_OK(status))
5340                 return status;
5341
5342         switch (r->in.level) {
5343                 case ALIASINFONAME:
5344                 {
5345                         fstring group_name;
5346
5347                         /* We currently do not support renaming groups in the
5348                            the BUILTIN domain.  Refer to util_builtin.c to understand
5349                            why.  The eventually needs to be fixed to be like Windows
5350                            where you can rename builtin groups, just not delete them */
5351
5352                         if ( sid_check_is_in_builtin( &group_sid ) ) {
5353                                 return NT_STATUS_SPECIAL_ACCOUNT;
5354                         }
5355
5356                         /* There has to be a valid name (and it has to be different) */
5357
5358                         if ( !r->in.info->name.string )
5359                                 return NT_STATUS_INVALID_PARAMETER;
5360
5361                         /* If the name is the same just reply "ok".  Yes this
5362                            doesn't allow you to change the case of a group name. */
5363
5364                         if ( strequal( r->in.info->name.string, info.acct_name ) )
5365                                 return NT_STATUS_OK;
5366
5367                         fstrcpy( info.acct_name, r->in.info->name.string);
5368
5369                         /* make sure the name doesn't already exist as a user
5370                            or local group */
5371
5372                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5373                         status = can_create( p->mem_ctx, group_name );
5374                         if ( !NT_STATUS_IS_OK( status ) )
5375                                 return status;
5376                         break;
5377                 }
5378                 case ALIASINFODESCRIPTION:
5379                         if (r->in.info->description.string) {
5380                                 fstrcpy(info.acct_desc,
5381                                         r->in.info->description.string);
5382                         } else {
5383                                 fstrcpy( info.acct_desc, "" );
5384                         }
5385                         break;
5386                 default:
5387                         return NT_STATUS_INVALID_INFO_CLASS;
5388         }
5389
5390         can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5391
5392         /******** BEGIN SeAddUsers BLOCK *********/
5393
5394         if ( can_mod_accounts )
5395                 become_root();
5396
5397         status = pdb_set_aliasinfo( &group_sid, &info );
5398
5399         if ( can_mod_accounts )
5400                 unbecome_root();
5401
5402         /******** End SeAddUsers BLOCK *********/
5403
5404         if (NT_STATUS_IS_OK(status))
5405                 force_flush_samr_cache(disp_info);
5406
5407         return status;
5408 }
5409
5410 /****************************************************************
5411  _samr_GetDomPwInfo
5412 ****************************************************************/
5413
5414 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5415                             struct samr_GetDomPwInfo *r)
5416 {
5417         uint32_t min_password_length = 0;
5418         uint32_t password_properties = 0;
5419
5420         /* Perform access check.  Since this rpc does not require a
5421            policy handle it will not be caught by the access checks on
5422            SAMR_CONNECT or SAMR_CONNECT_ANON. */
5423
5424         if (!pipe_access_check(p)) {
5425                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5426                 return NT_STATUS_ACCESS_DENIED;
5427         }
5428
5429         become_root();
5430         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5431                                &min_password_length);
5432         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5433                                &password_properties);
5434         unbecome_root();
5435
5436         if (lp_check_password_script() && *lp_check_password_script()) {
5437                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5438         }
5439
5440         r->out.info->min_password_length = min_password_length;
5441         r->out.info->password_properties = password_properties;
5442
5443         return NT_STATUS_OK;
5444 }
5445
5446 /*********************************************************************
5447  _samr_OpenGroup
5448 *********************************************************************/
5449
5450 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5451                          struct samr_OpenGroup *r)
5452
5453 {
5454         DOM_SID sid;
5455         DOM_SID info_sid;
5456         GROUP_MAP map;
5457         struct samr_info *info;
5458         SEC_DESC         *psd = NULL;
5459         uint32            acc_granted;
5460         uint32            des_access = r->in.access_mask;
5461         size_t            sd_size;
5462         NTSTATUS          status;
5463         fstring sid_string;
5464         bool ret;
5465         SE_PRIV se_rights;
5466
5467         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5468                 return NT_STATUS_INVALID_HANDLE;
5469
5470         status = access_check_samr_function(acc_granted,
5471                                             SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5472                                             "_samr_OpenGroup");
5473
5474         if ( !NT_STATUS_IS_OK(status) )
5475                 return status;
5476
5477         /*check if access can be granted as requested by client. */
5478         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5479         se_map_generic(&des_access,&grp_generic_mapping);
5480
5481         se_priv_copy( &se_rights, &se_add_users );
5482
5483         status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5484                 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5485                 &acc_granted, "_samr_OpenGroup");
5486
5487         if ( !NT_STATUS_IS_OK(status) )
5488                 return status;
5489
5490         /* this should not be hard-coded like this */
5491
5492         if (!sid_equal(&sid, get_global_sam_sid()))
5493                 return NT_STATUS_ACCESS_DENIED;
5494
5495         sid_copy(&info_sid, get_global_sam_sid());
5496         sid_append_rid(&info_sid, r->in.rid);
5497         sid_to_fstring(sid_string, &info_sid);
5498
5499         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5500                 return NT_STATUS_NO_MEMORY;
5501
5502         info->acc_granted = acc_granted;
5503
5504         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5505
5506         /* check if that group really exists */
5507         become_root();
5508         ret = get_domain_group_from_sid(info->sid, &map);
5509         unbecome_root();
5510         if (!ret)
5511                 return NT_STATUS_NO_SUCH_GROUP;
5512
5513         /* get a (unique) handle.  open a policy on it. */
5514         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5515                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5516
5517         return NT_STATUS_OK;
5518 }
5519
5520 /*********************************************************************
5521  _samr_RemoveMemberFromForeignDomain
5522 *********************************************************************/
5523
5524 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5525                                              struct samr_RemoveMemberFromForeignDomain *r)
5526 {
5527         DOM_SID                 delete_sid, domain_sid;
5528         uint32                  acc_granted;
5529         NTSTATUS                result;
5530         DISP_INFO *disp_info = NULL;
5531
5532         sid_copy( &delete_sid, r->in.sid );
5533
5534         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5535                 sid_string_dbg(&delete_sid)));
5536
5537         /* Find the policy handle. Open a policy on it. */
5538
5539         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5540                                      &acc_granted, &disp_info))
5541                 return NT_STATUS_INVALID_HANDLE;
5542
5543         result = access_check_samr_function(acc_granted,
5544                                             STD_RIGHT_DELETE_ACCESS,
5545                                             "_samr_RemoveMemberFromForeignDomain");
5546
5547         if (!NT_STATUS_IS_OK(result))
5548                 return result;
5549
5550         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5551                   sid_string_dbg(&domain_sid)));
5552
5553         /* we can only delete a user from a group since we don't have
5554            nested groups anyways.  So in the latter case, just say OK */
5555
5556         /* TODO: The above comment nowadays is bogus. Since we have nested
5557          * groups now, and aliases members are never reported out of the unix
5558          * group membership, the "just say OK" makes this call a no-op. For
5559          * us. This needs fixing however. */
5560
5561         /* I've only ever seen this in the wild when deleting a user from
5562          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5563          * is the user about to be deleted. I very much suspect this is the
5564          * only application of this call. To verify this, let people report
5565          * other cases. */
5566
5567         if (!sid_check_is_builtin(&domain_sid)) {
5568                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5569                          "global_sam_sid() = %s\n",
5570                          sid_string_dbg(&domain_sid),
5571                          sid_string_dbg(get_global_sam_sid())));
5572                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5573                 return NT_STATUS_OK;
5574         }
5575
5576         force_flush_samr_cache(disp_info);
5577
5578         result = NT_STATUS_OK;
5579
5580         return result;
5581 }
5582
5583 /*******************************************************************
5584  _samr_QueryDomainInfo2
5585  ********************************************************************/
5586
5587 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5588                                 struct samr_QueryDomainInfo2 *r)
5589 {
5590         return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5591                                              p,
5592                                              r->in.domain_handle,
5593                                              r->in.level,
5594                                              r->out.info);
5595 }
5596
5597 /*******************************************************************
5598  _samr_SetDomainInfo
5599  ********************************************************************/
5600
5601 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5602                              struct samr_SetDomainInfo *r)
5603 {
5604         time_t u_expire, u_min_age;
5605         time_t u_logout;
5606         time_t u_lock_duration, u_reset_time;
5607
5608         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5609
5610         /* find the policy handle.  open a policy on it. */
5611         if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5612                 return NT_STATUS_INVALID_HANDLE;
5613
5614         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5615
5616         switch (r->in.level) {
5617                 case 0x01:
5618                         u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5619                         u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5620                         pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5621                         pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5622                         pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5623                         pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5624                         pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5625                         break;
5626                 case 0x02:
5627                         break;
5628                 case 0x03:
5629                         u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5630                         pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5631                         break;
5632                 case 0x05:
5633                         break;
5634                 case 0x06:
5635                         break;
5636                 case 0x07:
5637                         break;
5638                 case 0x0c:
5639                         u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5640                         if (u_lock_duration != -1)
5641                                 u_lock_duration /= 60;
5642
5643                         u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5644
5645                         pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5646                         pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5647                         pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5648                         break;
5649                 default:
5650                         return NT_STATUS_INVALID_INFO_CLASS;
5651         }
5652
5653         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5654
5655         return NT_STATUS_OK;
5656 }
5657
5658 /****************************************************************
5659  _samr_GetDisplayEnumerationIndex
5660 ****************************************************************/
5661
5662 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5663                                           struct samr_GetDisplayEnumerationIndex *r)
5664 {
5665         struct samr_info *info = NULL;
5666         uint32_t max_entries = (uint32_t) -1;
5667         uint32_t enum_context = 0;
5668         int i;
5669         uint32_t num_account = 0;
5670         struct samr_displayentry *entries = NULL;
5671
5672         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5673
5674         /* find the policy handle.  open a policy on it. */
5675         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5676                 return NT_STATUS_INVALID_HANDLE;
5677         }
5678
5679         if ((r->in.level < 1) || (r->in.level > 3)) {
5680                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5681                         "Unknown info level (%u)\n",
5682                         r->in.level));
5683                 return NT_STATUS_INVALID_INFO_CLASS;
5684         }
5685
5686         become_root();
5687
5688         /* The following done as ROOT. Don't return without unbecome_root(). */
5689
5690         switch (r->in.level) {
5691         case 1:
5692                 if (info->disp_info->users == NULL) {
5693                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
5694                         if (info->disp_info->users == NULL) {
5695                                 unbecome_root();
5696                                 return NT_STATUS_ACCESS_DENIED;
5697                         }
5698                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5699                                 "starting user enumeration at index %u\n",
5700                                 (unsigned int)enum_context));
5701                 } else {
5702                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5703                                 "using cached user enumeration at index %u\n",
5704                                 (unsigned int)enum_context));
5705                 }
5706                 num_account = pdb_search_entries(info->disp_info->users,
5707                                                  enum_context, max_entries,
5708                                                  &entries);
5709                 break;
5710         case 2:
5711                 if (info->disp_info->machines == NULL) {
5712                         info->disp_info->machines =
5713                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5714                         if (info->disp_info->machines == NULL) {
5715                                 unbecome_root();
5716                                 return NT_STATUS_ACCESS_DENIED;
5717                         }
5718                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5719                                 "starting machine enumeration at index %u\n",
5720                                 (unsigned int)enum_context));
5721                 } else {
5722                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5723                                 "using cached machine enumeration at index %u\n",
5724                                 (unsigned int)enum_context));
5725                 }
5726                 num_account = pdb_search_entries(info->disp_info->machines,
5727                                                  enum_context, max_entries,
5728                                                  &entries);
5729                 break;
5730         case 3:
5731                 if (info->disp_info->groups == NULL) {
5732                         info->disp_info->groups = pdb_search_groups();
5733                         if (info->disp_info->groups == NULL) {
5734                                 unbecome_root();
5735                                 return NT_STATUS_ACCESS_DENIED;
5736                         }
5737                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5738                                 "starting group enumeration at index %u\n",
5739                                 (unsigned int)enum_context));
5740                 } else {
5741                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5742                                 "using cached group enumeration at index %u\n",
5743                                 (unsigned int)enum_context));
5744                 }
5745                 num_account = pdb_search_entries(info->disp_info->groups,
5746                                                  enum_context, max_entries,
5747                                                  &entries);
5748                 break;
5749         default:
5750                 unbecome_root();
5751                 smb_panic("info class changed");
5752                 break;
5753         }
5754
5755         unbecome_root();
5756
5757         /* Ensure we cache this enumeration. */
5758         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5759
5760         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5761                 r->in.name->string));
5762
5763         for (i=0; i<num_account; i++) {
5764                 if (strequal(entries[i].account_name, r->in.name->string)) {
5765                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5766                                 "found %s at idx %d\n",
5767                                 r->in.name->string, i));
5768                         *r->out.idx = i;
5769                         return NT_STATUS_OK;
5770                 }
5771         }
5772
5773         /* assuming account_name lives at the very end */
5774         *r->out.idx = num_account;
5775
5776         return NT_STATUS_NO_MORE_ENTRIES;
5777 }
5778
5779 /****************************************************************
5780  _samr_GetDisplayEnumerationIndex2
5781 ****************************************************************/
5782
5783 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5784                                            struct samr_GetDisplayEnumerationIndex2 *r)
5785 {
5786         struct samr_GetDisplayEnumerationIndex q;
5787
5788         q.in.domain_handle      = r->in.domain_handle;
5789         q.in.level              = r->in.level;
5790         q.in.name               = r->in.name;
5791
5792         q.out.idx               = r->out.idx;
5793
5794         return _samr_GetDisplayEnumerationIndex(p, &q);
5795 }
5796
5797 /****************************************************************
5798 ****************************************************************/
5799
5800 NTSTATUS _samr_Shutdown(pipes_struct *p,
5801                         struct samr_Shutdown *r)
5802 {
5803         p->rng_fault_state = true;
5804         return NT_STATUS_NOT_IMPLEMENTED;
5805 }
5806
5807 /****************************************************************
5808 ****************************************************************/
5809
5810 NTSTATUS _samr_CreateUser(pipes_struct *p,
5811                           struct samr_CreateUser *r)
5812 {
5813         p->rng_fault_state = true;
5814         return NT_STATUS_NOT_IMPLEMENTED;
5815 }
5816
5817 /****************************************************************
5818 ****************************************************************/
5819
5820 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5821                                           struct samr_SetMemberAttributesOfGroup *r)
5822 {
5823         p->rng_fault_state = true;
5824         return NT_STATUS_NOT_IMPLEMENTED;
5825 }
5826
5827 /****************************************************************
5828 ****************************************************************/
5829
5830 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5831                                   struct samr_ChangePasswordUser *r)
5832 {
5833         p->rng_fault_state = true;
5834         return NT_STATUS_NOT_IMPLEMENTED;
5835 }
5836
5837 /****************************************************************
5838 ****************************************************************/
5839
5840 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5841                                           struct samr_TestPrivateFunctionsDomain *r)
5842 {
5843         p->rng_fault_state = true;
5844         return NT_STATUS_NOT_IMPLEMENTED;
5845 }
5846
5847 /****************************************************************
5848 ****************************************************************/
5849
5850 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5851                                         struct samr_TestPrivateFunctionsUser *r)
5852 {
5853         p->rng_fault_state = true;
5854         return NT_STATUS_NOT_IMPLEMENTED;
5855 }
5856
5857 /****************************************************************
5858 ****************************************************************/
5859
5860 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5861                               struct samr_QueryUserInfo2 *r)
5862 {
5863         p->rng_fault_state = true;
5864         return NT_STATUS_NOT_IMPLEMENTED;
5865 }
5866
5867 /****************************************************************
5868 ****************************************************************/
5869
5870 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5871                                          struct samr_AddMultipleMembersToAlias *r)
5872 {
5873         p->rng_fault_state = true;
5874         return NT_STATUS_NOT_IMPLEMENTED;
5875 }
5876
5877 /****************************************************************
5878 ****************************************************************/
5879
5880 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5881                                               struct samr_RemoveMultipleMembersFromAlias *r)
5882 {
5883         p->rng_fault_state = true;
5884         return NT_STATUS_NOT_IMPLEMENTED;
5885 }
5886
5887 /****************************************************************
5888 ****************************************************************/
5889
5890 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5891                                       struct samr_OemChangePasswordUser2 *r)
5892 {
5893         p->rng_fault_state = true;
5894         return NT_STATUS_NOT_IMPLEMENTED;
5895 }
5896
5897 /****************************************************************
5898 ****************************************************************/
5899
5900 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5901                                      struct samr_SetBootKeyInformation *r)
5902 {
5903         p->rng_fault_state = true;
5904         return NT_STATUS_NOT_IMPLEMENTED;
5905 }
5906
5907 /****************************************************************
5908 ****************************************************************/
5909
5910 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5911                                      struct samr_GetBootKeyInformation *r)
5912 {
5913         p->rng_fault_state = true;
5914         return NT_STATUS_NOT_IMPLEMENTED;
5915 }
5916
5917 /****************************************************************
5918 ****************************************************************/
5919
5920 NTSTATUS _samr_Connect3(pipes_struct *p,
5921                         struct samr_Connect3 *r)
5922 {
5923         p->rng_fault_state = true;
5924         return NT_STATUS_NOT_IMPLEMENTED;
5925 }
5926
5927 /****************************************************************
5928 ****************************************************************/
5929
5930 NTSTATUS _samr_RidToSid(pipes_struct *p,
5931                         struct samr_RidToSid *r)
5932 {
5933         p->rng_fault_state = true;
5934         return NT_STATUS_NOT_IMPLEMENTED;
5935 }
5936
5937 /****************************************************************
5938 ****************************************************************/
5939
5940 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5941                                struct samr_SetDsrmPassword *r)
5942 {
5943         p->rng_fault_state = true;
5944         return NT_STATUS_NOT_IMPLEMENTED;
5945 }
5946
5947 /****************************************************************
5948 ****************************************************************/
5949
5950 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5951                                 struct samr_ValidatePassword *r)
5952 {
5953         p->rng_fault_state = true;
5954         return NT_STATUS_NOT_IMPLEMENTED;
5955 }