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