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