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