s3-samr: simplify _samr_QueryUserInfo a lot and fix some few potential memleaks.
[samba.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-2008,
9  *  Copyright (C) Jean François Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *  Copyright (C) Guenther Deschner                 2008.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /*
31  * This is the implementation of the SAMR code.
32  */
33
34 #include "includes.h"
35
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
38
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40                 ( READ_CONTROL_ACCESS           | \
41                   SAMR_USER_ACCESS_CHANGE_PASSWORD      | \
42                   SAMR_USER_ACCESS_SET_LOC_COM)
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44                 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
45
46 #define DISP_INFO_CACHE_TIMEOUT 10
47
48 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
49 #define MAX_SAM_ENTRIES_W95 50
50
51 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->server_info->ptok, &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->server_info->ptok,
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         *r->out.sam = samr_array;
1016
1017         become_root();
1018
1019         /* AS ROOT !!!! */
1020
1021         if ((info->disp_info->enum_users != NULL) &&
1022             (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1023                 pdb_search_destroy(info->disp_info->enum_users);
1024                 info->disp_info->enum_users = NULL;
1025         }
1026
1027         if (info->disp_info->enum_users == NULL) {
1028                 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
1029                 info->disp_info->enum_acb_mask = r->in.acct_flags;
1030         }
1031
1032         if (info->disp_info->enum_users == NULL) {
1033                 /* END AS ROOT !!!! */
1034                 unbecome_root();
1035                 return NT_STATUS_ACCESS_DENIED;
1036         }
1037
1038         num_account = pdb_search_entries(info->disp_info->enum_users,
1039                                          enum_context, max_entries,
1040                                          &entries);
1041
1042         /* END AS ROOT !!!! */
1043
1044         unbecome_root();
1045
1046         if (num_account == 0) {
1047                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1048                           "total entries\n"));
1049                 *r->out.resume_handle = *r->in.resume_handle;
1050                 return NT_STATUS_OK;
1051         }
1052
1053         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1054                                           num_account, enum_context,
1055                                           entries);
1056         if (!NT_STATUS_IS_OK(status)) {
1057                 return status;
1058         }
1059
1060         if (max_entries <= num_account) {
1061                 status = STATUS_MORE_ENTRIES;
1062         } else {
1063                 status = NT_STATUS_OK;
1064         }
1065
1066         /* Ensure we cache this enumeration. */
1067         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1068
1069         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1070
1071         samr_array->count = num_account;
1072         samr_array->entries = samr_entries;
1073
1074         *r->out.resume_handle = *r->in.resume_handle + num_account;
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         if (info->builtin_domain) {
1488                 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1489                 return NT_STATUS_OK;
1490         }
1491
1492         status = access_check_samr_function(info->acc_granted,
1493                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1494                                             "_samr_QueryDisplayInfo");
1495         if (!NT_STATUS_IS_OK(status)) {
1496                 return status;
1497         }
1498
1499         /*
1500          * calculate how many entries we will return.
1501          * based on
1502          * - the number of entries the client asked
1503          * - our limit on that
1504          * - the starting point (enumeration context)
1505          * - the buffer size the client will accept
1506          */
1507
1508         /*
1509          * We are a lot more like W2K. Instead of reading the SAM
1510          * each time to find the records we need to send back,
1511          * we read it once and link that copy to the sam handle.
1512          * For large user list (over the MAX_SAM_ENTRIES)
1513          * it's a definitive win.
1514          * second point to notice: between enumerations
1515          * our sam is now the same as it's a snapshoot.
1516          * third point: got rid of the static SAM_USER_21 struct
1517          * no more intermediate.
1518          * con: it uses much more memory, as a full copy is stored
1519          * in memory.
1520          *
1521          * If you want to change it, think twice and think
1522          * of the second point , that's really important.
1523          *
1524          * JFM, 12/20/2001
1525          */
1526
1527         if ((r->in.level < 1) || (r->in.level > 5)) {
1528                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1529                          (unsigned int)r->in.level ));
1530                 return NT_STATUS_INVALID_INFO_CLASS;
1531         }
1532
1533         /* first limit the number of entries we will return */
1534         if(max_entries > max_sam_entries) {
1535                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1536                           "entries, limiting to %d\n", max_entries,
1537                           max_sam_entries));
1538                 max_entries = max_sam_entries;
1539         }
1540
1541         /* calculate the size and limit on the number of entries we will
1542          * return */
1543
1544         temp_size=max_entries*struct_size;
1545
1546         if (temp_size>max_size) {
1547                 max_entries=MIN((max_size/struct_size),max_entries);;
1548                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1549                           "only %d entries\n", max_entries));
1550         }
1551
1552         become_root();
1553
1554         /* THe following done as ROOT. Don't return without unbecome_root(). */
1555
1556         switch (r->in.level) {
1557         case 0x1:
1558         case 0x4:
1559                 if (info->disp_info->users == NULL) {
1560                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
1561                         if (info->disp_info->users == NULL) {
1562                                 unbecome_root();
1563                                 return NT_STATUS_ACCESS_DENIED;
1564                         }
1565                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1566                                 (unsigned  int)enum_context ));
1567                 } else {
1568                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1569                                 (unsigned  int)enum_context ));
1570                 }
1571
1572                 num_account = pdb_search_entries(info->disp_info->users,
1573                                                  enum_context, max_entries,
1574                                                  &entries);
1575                 break;
1576         case 0x2:
1577                 if (info->disp_info->machines == NULL) {
1578                         info->disp_info->machines =
1579                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1580                         if (info->disp_info->machines == NULL) {
1581                                 unbecome_root();
1582                                 return NT_STATUS_ACCESS_DENIED;
1583                         }
1584                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1585                                 (unsigned  int)enum_context ));
1586                 } else {
1587                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1588                                 (unsigned  int)enum_context ));
1589                 }
1590
1591                 num_account = pdb_search_entries(info->disp_info->machines,
1592                                                  enum_context, max_entries,
1593                                                  &entries);
1594                 break;
1595         case 0x3:
1596         case 0x5:
1597                 if (info->disp_info->groups == NULL) {
1598                         info->disp_info->groups = pdb_search_groups();
1599                         if (info->disp_info->groups == NULL) {
1600                                 unbecome_root();
1601                                 return NT_STATUS_ACCESS_DENIED;
1602                         }
1603                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1604                                 (unsigned  int)enum_context ));
1605                 } else {
1606                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1607                                 (unsigned  int)enum_context ));
1608                 }
1609
1610                 num_account = pdb_search_entries(info->disp_info->groups,
1611                                                  enum_context, max_entries,
1612                                                  &entries);
1613                 break;
1614         default:
1615                 unbecome_root();
1616                 smb_panic("info class changed");
1617                 break;
1618         }
1619         unbecome_root();
1620
1621
1622         /* Now create reply structure */
1623         switch (r->in.level) {
1624         case 0x1:
1625                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1626                                                 num_account, enum_context,
1627                                                 entries);
1628                 break;
1629         case 0x2:
1630                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1631                                                 num_account, enum_context,
1632                                                 entries);
1633                 break;
1634         case 0x3:
1635                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1636                                                 num_account, enum_context,
1637                                                 entries);
1638                 break;
1639         case 0x4:
1640                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1641                                                 num_account, enum_context,
1642                                                 entries);
1643                 break;
1644         case 0x5:
1645                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1646                                                 num_account, enum_context,
1647                                                 entries);
1648                 break;
1649         default:
1650                 smb_panic("info class changed");
1651                 break;
1652         }
1653
1654         if (!NT_STATUS_IS_OK(disp_ret))
1655                 return disp_ret;
1656
1657         /* calculate the total size */
1658         total_data_size=num_account*struct_size;
1659
1660         if (max_entries <= num_account) {
1661                 status = STATUS_MORE_ENTRIES;
1662         } else {
1663                 status = NT_STATUS_OK;
1664         }
1665
1666         /* Ensure we cache this enumeration. */
1667         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1668
1669         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1670
1671         *r->out.total_size = total_data_size;
1672         *r->out.returned_size = temp_size;
1673
1674         return status;
1675 }
1676
1677 /****************************************************************
1678  _samr_QueryDisplayInfo2
1679 ****************************************************************/
1680
1681 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1682                                  struct samr_QueryDisplayInfo2 *r)
1683 {
1684         struct samr_QueryDisplayInfo q;
1685
1686         q.in.domain_handle      = r->in.domain_handle;
1687         q.in.level              = r->in.level;
1688         q.in.start_idx          = r->in.start_idx;
1689         q.in.max_entries        = r->in.max_entries;
1690         q.in.buf_size           = r->in.buf_size;
1691
1692         q.out.total_size        = r->out.total_size;
1693         q.out.returned_size     = r->out.returned_size;
1694         q.out.info              = r->out.info;
1695
1696         return _samr_QueryDisplayInfo(p, &q);
1697 }
1698
1699 /****************************************************************
1700  _samr_QueryDisplayInfo3
1701 ****************************************************************/
1702
1703 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1704                                  struct samr_QueryDisplayInfo3 *r)
1705 {
1706         struct samr_QueryDisplayInfo q;
1707
1708         q.in.domain_handle      = r->in.domain_handle;
1709         q.in.level              = r->in.level;
1710         q.in.start_idx          = r->in.start_idx;
1711         q.in.max_entries        = r->in.max_entries;
1712         q.in.buf_size           = r->in.buf_size;
1713
1714         q.out.total_size        = r->out.total_size;
1715         q.out.returned_size     = r->out.returned_size;
1716         q.out.info              = r->out.info;
1717
1718         return _samr_QueryDisplayInfo(p, &q);
1719 }
1720
1721 /*******************************************************************
1722  _samr_QueryAliasInfo
1723  ********************************************************************/
1724
1725 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1726                               struct samr_QueryAliasInfo *r)
1727 {
1728         DOM_SID   sid;
1729         struct acct_info info;
1730         uint32    acc_granted;
1731         NTSTATUS status;
1732         union samr_AliasInfo *alias_info = NULL;
1733         const char *alias_name = NULL;
1734         const char *alias_description = NULL;
1735
1736         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1737
1738         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1739         if (!alias_info) {
1740                 return NT_STATUS_NO_MEMORY;
1741         }
1742
1743         /* find the policy handle.  open a policy on it. */
1744         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1745                 return NT_STATUS_INVALID_HANDLE;
1746
1747         status = access_check_samr_function(acc_granted,
1748                                             SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1749                                             "_samr_QueryAliasInfo");
1750         if (!NT_STATUS_IS_OK(status)) {
1751                 return status;
1752         }
1753
1754         become_root();
1755         status = pdb_get_aliasinfo(&sid, &info);
1756         unbecome_root();
1757
1758         if ( !NT_STATUS_IS_OK(status))
1759                 return status;
1760
1761         /* FIXME: info contains fstrings */
1762         alias_name = talloc_strdup(r, info.acct_name);
1763         alias_description = talloc_strdup(r, info.acct_desc);
1764
1765         switch (r->in.level) {
1766         case ALIASINFOALL:
1767                 init_samr_alias_info1(&alias_info->all,
1768                                       alias_name,
1769                                       1,
1770                                       alias_description);
1771                 break;
1772         case ALIASINFODESCRIPTION:
1773                 init_samr_alias_info3(&alias_info->description,
1774                                       alias_description);
1775                 break;
1776         default:
1777                 return NT_STATUS_INVALID_INFO_CLASS;
1778         }
1779
1780         *r->out.info = alias_info;
1781
1782         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1783
1784         return NT_STATUS_OK;
1785 }
1786
1787 /*******************************************************************
1788  _samr_LookupNames
1789  ********************************************************************/
1790
1791 NTSTATUS _samr_LookupNames(pipes_struct *p,
1792                            struct samr_LookupNames *r)
1793 {
1794         NTSTATUS status;
1795         uint32 *rid;
1796         enum lsa_SidType *type;
1797         int i;
1798         int num_rids = r->in.num_names;
1799         DOM_SID pol_sid;
1800         uint32  acc_granted;
1801         struct samr_Ids rids, types;
1802         uint32_t num_mapped = 0;
1803
1804         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1805
1806         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1807                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1808         }
1809
1810         status = access_check_samr_function(acc_granted,
1811                                             0, /* Don't know the acc_bits yet */
1812                                             "_samr_LookupNames");
1813         if (!NT_STATUS_IS_OK(status)) {
1814                 return status;
1815         }
1816
1817         if (num_rids > MAX_SAM_ENTRIES) {
1818                 num_rids = MAX_SAM_ENTRIES;
1819                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1820         }
1821
1822         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1823         NT_STATUS_HAVE_NO_MEMORY(rid);
1824
1825         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1826         NT_STATUS_HAVE_NO_MEMORY(type);
1827
1828         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1829                  sid_string_dbg(&pol_sid)));
1830
1831         for (i = 0; i < num_rids; i++) {
1832
1833                 status = NT_STATUS_NONE_MAPPED;
1834                 type[i] = SID_NAME_UNKNOWN;
1835
1836                 rid[i] = 0xffffffff;
1837
1838                 if (sid_check_is_builtin(&pol_sid)) {
1839                         if (lookup_builtin_name(r->in.names[i].string,
1840                                                 &rid[i]))
1841                         {
1842                                 type[i] = SID_NAME_ALIAS;
1843                         }
1844                 } else {
1845                         lookup_global_sam_name(r->in.names[i].string, 0,
1846                                                &rid[i], &type[i]);
1847                 }
1848
1849                 if (type[i] != SID_NAME_UNKNOWN) {
1850                         num_mapped++;
1851                 }
1852         }
1853
1854         if (num_mapped == num_rids) {
1855                 status = NT_STATUS_OK;
1856         } else if (num_mapped == 0) {
1857                 status = NT_STATUS_NONE_MAPPED;
1858         } else {
1859                 status = STATUS_SOME_UNMAPPED;
1860         }
1861
1862         rids.count = num_rids;
1863         rids.ids = rid;
1864
1865         types.count = num_rids;
1866         types.ids = type;
1867
1868         *r->out.rids = rids;
1869         *r->out.types = types;
1870
1871         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1872
1873         return status;
1874 }
1875
1876 /*******************************************************************
1877  _samr_ChangePasswordUser2
1878  ********************************************************************/
1879
1880 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1881                                    struct samr_ChangePasswordUser2 *r)
1882 {
1883         NTSTATUS status;
1884         fstring user_name;
1885         fstring wks;
1886
1887         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1888
1889         fstrcpy(user_name, r->in.account->string);
1890         fstrcpy(wks, r->in.server->string);
1891
1892         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1893
1894         /*
1895          * Pass the user through the NT -> unix user mapping
1896          * function.
1897          */
1898
1899         (void)map_username(user_name);
1900
1901         /*
1902          * UNIX username case mangling not required, pass_oem_change
1903          * is case insensitive.
1904          */
1905
1906         status = pass_oem_change(user_name,
1907                                  r->in.lm_password->data,
1908                                  r->in.lm_verifier->hash,
1909                                  r->in.nt_password->data,
1910                                  r->in.nt_verifier->hash,
1911                                  NULL);
1912
1913         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1914
1915         return status;
1916 }
1917
1918 /*******************************************************************
1919  _samr_ChangePasswordUser3
1920  ********************************************************************/
1921
1922 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1923                                    struct samr_ChangePasswordUser3 *r)
1924 {
1925         NTSTATUS status;
1926         fstring user_name;
1927         const char *wks = NULL;
1928         uint32 reject_reason;
1929         struct samr_DomInfo1 *dominfo = NULL;
1930         struct samr_ChangeReject *reject = NULL;
1931
1932         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1933
1934         fstrcpy(user_name, r->in.account->string);
1935         if (r->in.server && r->in.server->string) {
1936                 wks = r->in.server->string;
1937         }
1938
1939         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1940
1941         /*
1942          * Pass the user through the NT -> unix user mapping
1943          * function.
1944          */
1945
1946         (void)map_username(user_name);
1947
1948         /*
1949          * UNIX username case mangling not required, pass_oem_change
1950          * is case insensitive.
1951          */
1952
1953         status = pass_oem_change(user_name,
1954                                  r->in.lm_password->data,
1955                                  r->in.lm_verifier->hash,
1956                                  r->in.nt_password->data,
1957                                  r->in.nt_verifier->hash,
1958                                  &reject_reason);
1959
1960         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1961             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1962
1963                 uint32 min_pass_len,pass_hist,password_properties;
1964                 time_t u_expire, u_min_age;
1965                 NTTIME nt_expire, nt_min_age;
1966                 uint32 account_policy_temp;
1967
1968                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1969                 if (!dominfo) {
1970                         return NT_STATUS_NO_MEMORY;
1971                 }
1972
1973                 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1974                 if (!reject) {
1975                         return NT_STATUS_NO_MEMORY;
1976                 }
1977
1978                 become_root();
1979
1980                 /* AS ROOT !!! */
1981
1982                 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1983                 min_pass_len = account_policy_temp;
1984
1985                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1986                 pass_hist = account_policy_temp;
1987
1988                 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1989                 password_properties = account_policy_temp;
1990
1991                 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1992                 u_expire = account_policy_temp;
1993
1994                 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1995                 u_min_age = account_policy_temp;
1996
1997                 /* !AS ROOT */
1998
1999                 unbecome_root();
2000
2001                 unix_to_nt_time_abs(&nt_expire, u_expire);
2002                 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2003
2004                 if (lp_check_password_script() && *lp_check_password_script()) {
2005                         password_properties |= DOMAIN_PASSWORD_COMPLEX;
2006                 }
2007
2008                 init_samr_DomInfo1(dominfo,
2009                                    min_pass_len,
2010                                    pass_hist,
2011                                    password_properties,
2012                                    u_expire,
2013                                    u_min_age);
2014
2015                 reject->reason = reject_reason;
2016
2017                 *r->out.dominfo = dominfo;
2018                 *r->out.reject = reject;
2019         }
2020
2021         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2022
2023         return status;
2024 }
2025
2026 /*******************************************************************
2027 makes a SAMR_R_LOOKUP_RIDS structure.
2028 ********************************************************************/
2029
2030 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2031                                   const char **names,
2032                                   struct lsa_String **lsa_name_array_p)
2033 {
2034         struct lsa_String *lsa_name_array = NULL;
2035         uint32_t i;
2036
2037         *lsa_name_array_p = NULL;
2038
2039         if (num_names != 0) {
2040                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2041                 if (!lsa_name_array) {
2042                         return false;
2043                 }
2044         }
2045
2046         for (i = 0; i < num_names; i++) {
2047                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2048                 init_lsa_String(&lsa_name_array[i], names[i]);
2049         }
2050
2051         *lsa_name_array_p = lsa_name_array;
2052
2053         return true;
2054 }
2055
2056 /*******************************************************************
2057  _samr_LookupRids
2058  ********************************************************************/
2059
2060 NTSTATUS _samr_LookupRids(pipes_struct *p,
2061                           struct samr_LookupRids *r)
2062 {
2063         NTSTATUS status;
2064         const char **names;
2065         enum lsa_SidType *attrs = NULL;
2066         uint32 *wire_attrs = NULL;
2067         DOM_SID pol_sid;
2068         int num_rids = (int)r->in.num_rids;
2069         uint32 acc_granted;
2070         int i;
2071         struct lsa_Strings names_array;
2072         struct samr_Ids types_array;
2073         struct lsa_String *lsa_names = NULL;
2074
2075         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2076
2077         /* find the policy handle.  open a policy on it. */
2078         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2079                 return NT_STATUS_INVALID_HANDLE;
2080
2081         status = access_check_samr_function(acc_granted,
2082                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
2083                                             "_samr_LookupRids");
2084         if (!NT_STATUS_IS_OK(status)) {
2085                 return status;
2086         }
2087
2088         if (num_rids > 1000) {
2089                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2090                           "to samba4 idl this is not possible\n", num_rids));
2091                 return NT_STATUS_UNSUCCESSFUL;
2092         }
2093
2094         if (num_rids) {
2095                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2096                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2097                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2098
2099                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2100                         return NT_STATUS_NO_MEMORY;
2101         } else {
2102                 names = NULL;
2103                 attrs = NULL;
2104                 wire_attrs = NULL;
2105         }
2106
2107         become_root();  /* lookup_sid can require root privs */
2108         status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2109                                  names, attrs);
2110         unbecome_root();
2111
2112         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2113                 status = NT_STATUS_OK;
2114         }
2115
2116         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2117                                    &lsa_names)) {
2118                 return NT_STATUS_NO_MEMORY;
2119         }
2120
2121         /* Convert from enum lsa_SidType to uint32 for wire format. */
2122         for (i = 0; i < num_rids; i++) {
2123                 wire_attrs[i] = (uint32)attrs[i];
2124         }
2125
2126         names_array.count = num_rids;
2127         names_array.names = lsa_names;
2128
2129         types_array.count = num_rids;
2130         types_array.ids = wire_attrs;
2131
2132         *r->out.names = names_array;
2133         *r->out.types = types_array;
2134
2135         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2136
2137         return status;
2138 }
2139
2140 /*******************************************************************
2141  _samr_OpenUser
2142 ********************************************************************/
2143
2144 NTSTATUS _samr_OpenUser(pipes_struct *p,
2145                         struct samr_OpenUser *r)
2146 {
2147         struct samu *sampass=NULL;
2148         DOM_SID sid;
2149         POLICY_HND domain_pol = *r->in.domain_handle;
2150         POLICY_HND *user_pol = r->out.user_handle;
2151         struct samr_info *info = NULL;
2152         SEC_DESC *psd = NULL;
2153         uint32    acc_granted;
2154         uint32    des_access = r->in.access_mask;
2155         size_t    sd_size;
2156         bool ret;
2157         NTSTATUS nt_status;
2158         SE_PRIV se_rights;
2159
2160         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2161
2162         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2163                 return NT_STATUS_INVALID_HANDLE;
2164
2165         nt_status = access_check_samr_function(acc_granted,
2166                                                SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2167                                                "_samr_OpenUser" );
2168
2169         if ( !NT_STATUS_IS_OK(nt_status) )
2170                 return nt_status;
2171
2172         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2173                 return NT_STATUS_NO_MEMORY;
2174         }
2175
2176         /* append the user's RID to it */
2177
2178         if (!sid_append_rid(&sid, r->in.rid))
2179                 return NT_STATUS_NO_SUCH_USER;
2180
2181         /* check if access can be granted as requested by client. */
2182
2183         map_max_allowed_access(p->server_info->ptok, &des_access);
2184
2185         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2186         se_map_generic(&des_access, &usr_generic_mapping);
2187
2188         se_priv_copy( &se_rights, &se_machine_account );
2189         se_priv_add( &se_rights, &se_add_users );
2190
2191         nt_status = access_check_samr_object(psd, p->server_info->ptok,
2192                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2193                 &acc_granted, "_samr_OpenUser");
2194
2195         if ( !NT_STATUS_IS_OK(nt_status) )
2196                 return nt_status;
2197
2198         become_root();
2199         ret=pdb_getsampwsid(sampass, &sid);
2200         unbecome_root();
2201
2202         /* check that the SID exists in our domain. */
2203         if (ret == False) {
2204                 return NT_STATUS_NO_SUCH_USER;
2205         }
2206
2207         TALLOC_FREE(sampass);
2208
2209         /* associate the user's SID and access bits with the new handle. */
2210         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2211                 return NT_STATUS_NO_MEMORY;
2212         info->acc_granted = acc_granted;
2213
2214         /* get a (unique) handle.  open a policy on it. */
2215         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2216                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2217
2218         return NT_STATUS_OK;
2219 }
2220
2221 /*************************************************************************
2222  *************************************************************************/
2223
2224 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2225                                             DATA_BLOB *blob,
2226                                             struct lsa_BinaryString **_r)
2227 {
2228         struct lsa_BinaryString *r;
2229
2230         if (!blob || !_r) {
2231                 return NT_STATUS_INVALID_PARAMETER;
2232         }
2233
2234         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2235         if (!r) {
2236                 return NT_STATUS_NO_MEMORY;
2237         }
2238
2239         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2240         if (!r->array) {
2241                 return NT_STATUS_NO_MEMORY;
2242         }
2243         memcpy(r->array, blob->data, blob->length);
2244         r->size = blob->length;
2245         r->length = blob->length;
2246
2247         if (!r->array) {
2248                 return NT_STATUS_NO_MEMORY;
2249         }
2250
2251         *_r = r;
2252
2253         return NT_STATUS_OK;
2254 }
2255
2256 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2257                                 struct samr_UserInfo5 *r,
2258                                 struct samu *pw,
2259                                 DOM_SID *domain_sid)
2260 {
2261         const DOM_SID *sid_user, *sid_group;
2262         uint32_t rid, primary_gid;
2263         NTTIME last_logon, last_logoff, last_password_change,
2264                acct_expiry;
2265         const char *account_name, *full_name, *home_directory, *home_drive,
2266                    *logon_script, *profile_path, *description,
2267                    *workstations, *comment;
2268         struct samr_LogonHours logon_hours;
2269
2270         ZERO_STRUCTP(r);
2271
2272         sid_user = pdb_get_user_sid(pw);
2273
2274         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2275                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2276                           "the domain sid %s.  Failing operation.\n",
2277                           pdb_get_username(pw), sid_string_dbg(sid_user),
2278                           sid_string_dbg(domain_sid)));
2279                 return NT_STATUS_UNSUCCESSFUL;
2280         }
2281
2282         become_root();
2283         sid_group = pdb_get_group_sid(pw);
2284         unbecome_root();
2285
2286         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2287                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2288                           "which conflicts with the domain sid %s.  Failing operation.\n",
2289                           pdb_get_username(pw), sid_string_dbg(sid_group),
2290                           sid_string_dbg(domain_sid)));
2291                 return NT_STATUS_UNSUCCESSFUL;
2292         }
2293
2294         unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2295         unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2296         unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2297         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2298
2299         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2300         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2301         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2302         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2303         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2304         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2305         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2306         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2307         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2308
2309         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2310
2311         init_samr_user_info5(r,
2312                              account_name,
2313                              full_name,
2314                              rid,
2315                              primary_gid,
2316                              home_directory,
2317                              home_drive,
2318                              logon_script,
2319                              profile_path,
2320                              description,
2321                              workstations,
2322                              last_logon,
2323                              last_logoff,
2324                              logon_hours,
2325                              pdb_get_bad_password_count(pw),
2326                              pdb_get_logon_count(pw),
2327                              last_password_change,
2328                              acct_expiry,
2329                              pdb_get_acct_ctrl(pw));
2330
2331         return NT_STATUS_OK;
2332 }
2333
2334 /*************************************************************************
2335  get_user_info_7. Safe. Only gives out account_name.
2336  *************************************************************************/
2337
2338 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2339                                 struct samr_UserInfo7 *r,
2340                                 struct samu *smbpass)
2341 {
2342         const char *account_name = NULL;
2343
2344         ZERO_STRUCTP(r);
2345
2346         account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2347         if (!account_name) {
2348                 return NT_STATUS_NO_MEMORY;
2349         }
2350
2351         init_samr_user_info7(r, account_name);
2352
2353         return NT_STATUS_OK;
2354 }
2355
2356 /*************************************************************************
2357  get_user_info_9. Only gives out primary group SID.
2358  *************************************************************************/
2359
2360 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2361                                 struct samr_UserInfo9 *r,
2362                                 struct samu *smbpass)
2363 {
2364         ZERO_STRUCTP(r);
2365
2366         init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2367
2368         return NT_STATUS_OK;
2369 }
2370
2371 /*************************************************************************
2372  get_user_info_16. Safe. Only gives out acb bits.
2373  *************************************************************************/
2374
2375 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2376                                  struct samr_UserInfo16 *r,
2377                                  struct samu *smbpass)
2378 {
2379         ZERO_STRUCTP(r);
2380
2381         init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2382
2383         return NT_STATUS_OK;
2384 }
2385
2386 /*************************************************************************
2387  get_user_info_18. OK - this is the killer as it gives out password info.
2388  Ensure that this is only allowed on an encrypted connection with a root
2389  user. JRA.
2390  *************************************************************************/
2391
2392 static NTSTATUS get_user_info_18(pipes_struct *p,
2393                                  TALLOC_CTX *mem_ctx,
2394                                  struct samr_UserInfo18 *r,
2395                                  DOM_SID *user_sid)
2396 {
2397         struct samu *smbpass=NULL;
2398         bool ret;
2399
2400         ZERO_STRUCTP(r);
2401
2402         if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2403                 return NT_STATUS_ACCESS_DENIED;
2404         }
2405
2406         if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2407                 return NT_STATUS_ACCESS_DENIED;
2408         }
2409
2410         /*
2411          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2412          */
2413
2414         if ( !(smbpass = samu_new( mem_ctx )) ) {
2415                 return NT_STATUS_NO_MEMORY;
2416         }
2417
2418         ret = pdb_getsampwsid(smbpass, user_sid);
2419
2420         if (ret == False) {
2421                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2422                 TALLOC_FREE(smbpass);
2423                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2424         }
2425
2426         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2427
2428         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2429                 TALLOC_FREE(smbpass);
2430                 return NT_STATUS_ACCOUNT_DISABLED;
2431         }
2432
2433         init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2434                               pdb_get_nt_passwd(smbpass));
2435
2436         TALLOC_FREE(smbpass);
2437
2438         return NT_STATUS_OK;
2439 }
2440
2441 /*************************************************************************
2442  get_user_info_20
2443  *************************************************************************/
2444
2445 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2446                                  struct samr_UserInfo20 *r,
2447                                  struct samu *sampass)
2448 {
2449         const char *munged_dial = NULL;
2450         DATA_BLOB blob;
2451         NTSTATUS status;
2452         struct lsa_BinaryString *parameters = NULL;
2453
2454         ZERO_STRUCTP(r);
2455
2456         munged_dial = pdb_get_munged_dial(sampass);
2457
2458         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2459                 munged_dial, (int)strlen(munged_dial)));
2460
2461         if (munged_dial) {
2462                 blob = base64_decode_data_blob(munged_dial);
2463         } else {
2464                 blob = data_blob_string_const_null("");
2465         }
2466
2467         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2468         data_blob_free(&blob);
2469         if (!NT_STATUS_IS_OK(status)) {
2470                 return status;
2471         }
2472
2473         init_samr_user_info20(r, parameters);
2474
2475         return NT_STATUS_OK;
2476 }
2477
2478
2479 /*************************************************************************
2480  get_user_info_21
2481  *************************************************************************/
2482
2483 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2484                                  struct samr_UserInfo21 *r,
2485                                  struct samu *pw,
2486                                  DOM_SID *domain_sid)
2487 {
2488         NTSTATUS status;
2489         const DOM_SID *sid_user, *sid_group;
2490         uint32_t rid, primary_gid;
2491         NTTIME last_logon, last_logoff, last_password_change,
2492                acct_expiry, allow_password_change, force_password_change;
2493         time_t must_change_time;
2494         uint8_t password_expired;
2495         const char *account_name, *full_name, *home_directory, *home_drive,
2496                    *logon_script, *profile_path, *description,
2497                    *workstations, *comment;
2498         struct samr_LogonHours logon_hours;
2499         struct lsa_BinaryString *parameters = NULL;
2500         const char *munged_dial = NULL;
2501         DATA_BLOB blob;
2502
2503         ZERO_STRUCTP(r);
2504
2505         sid_user = pdb_get_user_sid(pw);
2506
2507         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2508                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2509                           "the domain sid %s.  Failing operation.\n",
2510                           pdb_get_username(pw), sid_string_dbg(sid_user),
2511                           sid_string_dbg(domain_sid)));
2512                 return NT_STATUS_UNSUCCESSFUL;
2513         }
2514
2515         become_root();
2516         sid_group = pdb_get_group_sid(pw);
2517         unbecome_root();
2518
2519         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2520                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2521                           "which conflicts with the domain sid %s.  Failing operation.\n",
2522                           pdb_get_username(pw), sid_string_dbg(sid_group),
2523                           sid_string_dbg(domain_sid)));
2524                 return NT_STATUS_UNSUCCESSFUL;
2525         }
2526
2527         unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2528         unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2529         unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2530         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2531         unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2532
2533         must_change_time = pdb_get_pass_must_change_time(pw);
2534         if (must_change_time == get_time_t_max()) {
2535                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2536         } else {
2537                 unix_to_nt_time(&force_password_change, must_change_time);
2538         }
2539
2540         if (pdb_get_pass_must_change_time(pw) == 0) {
2541                 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2542         } else {
2543                 password_expired = 0;
2544         }
2545
2546         munged_dial = pdb_get_munged_dial(pw);
2547         if (munged_dial) {
2548                 blob = base64_decode_data_blob(munged_dial);
2549         } else {
2550                 blob = data_blob_string_const_null("");
2551         }
2552
2553         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2554         data_blob_free(&blob);
2555         if (!NT_STATUS_IS_OK(status)) {
2556                 return status;
2557         }
2558
2559         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2560         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2561         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2562         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2563         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2564         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2565         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2566         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2567         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2568
2569         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2570 #if 0
2571
2572         /*
2573           Look at a user on a real NT4 PDC with usrmgr, press
2574           'ok'. Then you will see that fields_present is set to
2575           0x08f827fa. Look at the user immediately after that again,
2576           and you will see that 0x00fffff is returned. This solves
2577           the problem that you get access denied after having looked
2578           at the user.
2579           -- Volker
2580         */
2581
2582 #endif
2583
2584         init_samr_user_info21(r,
2585                               last_logon,
2586                               last_logoff,
2587                               last_password_change,
2588                               acct_expiry,
2589                               allow_password_change,
2590                               force_password_change,
2591                               account_name,
2592                               full_name,
2593                               home_directory,
2594                               home_drive,
2595                               logon_script,
2596                               profile_path,
2597                               description,
2598                               workstations,
2599                               comment,
2600                               parameters,
2601                               rid,
2602                               primary_gid,
2603                               pdb_get_acct_ctrl(pw),
2604                               pdb_build_fields_present(pw),
2605                               logon_hours,
2606                               pdb_get_bad_password_count(pw),
2607                               pdb_get_logon_count(pw),
2608                               0, /* country_code */
2609                               0, /* code_page */
2610                               0, /* nt_password_set */
2611                               0, /* lm_password_set */
2612                               password_expired);
2613
2614         return NT_STATUS_OK;
2615 }
2616
2617 /*******************************************************************
2618  _samr_QueryUserInfo
2619  ********************************************************************/
2620
2621 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2622                              struct samr_QueryUserInfo *r)
2623 {
2624         NTSTATUS status;
2625         union samr_UserInfo *user_info = NULL;
2626         struct samr_info *info = NULL;
2627         DOM_SID domain_sid;
2628         uint32 rid;
2629         bool ret = false;
2630         struct samu *pwd = NULL;
2631
2632         /* search for the handle */
2633         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2634                 return NT_STATUS_INVALID_HANDLE;
2635
2636         status = access_check_samr_function(info->acc_granted,
2637                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2638                                             "_samr_QueryUserInfo");
2639         if (!NT_STATUS_IS_OK(status)) {
2640                 return status;
2641         }
2642
2643         domain_sid = info->sid;
2644
2645         sid_split_rid(&domain_sid, &rid);
2646
2647         if (!sid_check_is_in_our_domain(&info->sid))
2648                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2649
2650         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2651                  sid_string_dbg(&info->sid)));
2652
2653         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2654         if (!user_info) {
2655                 return NT_STATUS_NO_MEMORY;
2656         }
2657
2658         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2659
2660         if (!(pwd = samu_new(p->mem_ctx))) {
2661                 return NT_STATUS_NO_MEMORY;
2662         }
2663
2664         become_root();
2665         ret = pdb_getsampwsid(pwd, &info->sid);
2666         unbecome_root();
2667
2668         if (ret == false) {
2669                 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2670                 TALLOC_FREE(pwd);
2671                 return NT_STATUS_NO_SUCH_USER;
2672         }
2673
2674         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2675
2676         samr_clear_sam_passwd(pwd);
2677
2678         switch (r->in.level) {
2679         case 5:
2680                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2681                 break;
2682         case 7:
2683                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2684                 break;
2685         case 9:
2686                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2687                 break;
2688         case 16:
2689                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2690                 break;
2691         case 18:
2692                 /* level 18 is special */
2693                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2694                 break;
2695         case 20:
2696                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
2697                 break;
2698         case 21:
2699                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
2700                 break;
2701         default:
2702                 status = NT_STATUS_INVALID_INFO_CLASS;
2703                 break;
2704         }
2705
2706         TALLOC_FREE(pwd);
2707
2708         *r->out.info = user_info;
2709
2710         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2711
2712         return status;
2713 }
2714
2715 /****************************************************************
2716 ****************************************************************/
2717
2718 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2719                               struct samr_QueryUserInfo2 *r)
2720 {
2721         struct samr_QueryUserInfo u;
2722
2723         u.in.user_handle        = r->in.user_handle;
2724         u.in.level              = r->in.level;
2725         u.out.info              = r->out.info;
2726
2727         return _samr_QueryUserInfo(p, &u);
2728 }
2729
2730 /*******************************************************************
2731  _samr_GetGroupsForUser
2732  ********************************************************************/
2733
2734 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2735                                 struct samr_GetGroupsForUser *r)
2736 {
2737         struct samu *sam_pass=NULL;
2738         DOM_SID  sid;
2739         DOM_SID *sids;
2740         struct samr_RidWithAttribute dom_gid;
2741         struct samr_RidWithAttribute *gids = NULL;
2742         uint32 primary_group_rid;
2743         size_t num_groups = 0;
2744         gid_t *unix_gids;
2745         size_t i, num_gids;
2746         uint32 acc_granted;
2747         bool ret;
2748         NTSTATUS result;
2749         bool success = False;
2750
2751         struct samr_RidWithAttributeArray *rids = NULL;
2752
2753         /*
2754          * from the SID in the request:
2755          * we should send back the list of DOMAIN GROUPS
2756          * the user is a member of
2757          *
2758          * and only the DOMAIN GROUPS
2759          * no ALIASES !!! neither aliases of the domain
2760          * nor aliases of the builtin SID
2761          *
2762          * JFM, 12/2/2001
2763          */
2764
2765         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2766
2767         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2768         if (!rids) {
2769                 return NT_STATUS_NO_MEMORY;
2770         }
2771
2772         /* find the policy handle.  open a policy on it. */
2773         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2774                 return NT_STATUS_INVALID_HANDLE;
2775
2776         result = access_check_samr_function(acc_granted,
2777                                             SAMR_USER_ACCESS_GET_GROUPS,
2778                                             "_samr_GetGroupsForUser");
2779         if (!NT_STATUS_IS_OK(result)) {
2780                 return result;
2781         }
2782
2783         if (!sid_check_is_in_our_domain(&sid))
2784                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2785
2786         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2787                 return NT_STATUS_NO_MEMORY;
2788         }
2789
2790         become_root();
2791         ret = pdb_getsampwsid(sam_pass, &sid);
2792         unbecome_root();
2793
2794         if (!ret) {
2795                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2796                            sid_string_dbg(&sid)));
2797                 return NT_STATUS_NO_SUCH_USER;
2798         }
2799
2800         sids = NULL;
2801
2802         /* make both calls inside the root block */
2803         become_root();
2804         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2805                                             &sids, &unix_gids, &num_groups);
2806         if ( NT_STATUS_IS_OK(result) ) {
2807                 success = sid_peek_check_rid(get_global_sam_sid(),
2808                                              pdb_get_group_sid(sam_pass),
2809                                              &primary_group_rid);
2810         }
2811         unbecome_root();
2812
2813         if (!NT_STATUS_IS_OK(result)) {
2814                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2815                            sid_string_dbg(&sid)));
2816                 return result;
2817         }
2818
2819         if ( !success ) {
2820                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2821                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
2822                           pdb_get_username(sam_pass)));
2823                 TALLOC_FREE(sam_pass);
2824                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2825         }
2826
2827         gids = NULL;
2828         num_gids = 0;
2829
2830         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2831                               SE_GROUP_ENABLED);
2832         dom_gid.rid = primary_group_rid;
2833         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2834
2835         for (i=0; i<num_groups; i++) {
2836
2837                 if (!sid_peek_check_rid(get_global_sam_sid(),
2838                                         &(sids[i]), &dom_gid.rid)) {
2839                         DEBUG(10, ("Found sid %s not in our domain\n",
2840                                    sid_string_dbg(&sids[i])));
2841                         continue;
2842                 }
2843
2844                 if (dom_gid.rid == primary_group_rid) {
2845                         /* We added the primary group directly from the
2846                          * sam_account. The other SIDs are unique from
2847                          * enum_group_memberships */
2848                         continue;
2849                 }
2850
2851                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2852         }
2853
2854         rids->count = num_gids;
2855         rids->rids = gids;
2856
2857         *r->out.rids = rids;
2858
2859         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2860
2861         return result;
2862 }
2863
2864 /*******************************************************************
2865  _samr_QueryDomainInfo
2866  ********************************************************************/
2867
2868 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2869                                struct samr_QueryDomainInfo *r)
2870 {
2871         NTSTATUS status = NT_STATUS_OK;
2872         struct samr_info *info = NULL;
2873         union samr_DomainInfo *dom_info;
2874         uint32 min_pass_len,pass_hist,password_properties;
2875         time_t u_expire, u_min_age;
2876         NTTIME nt_expire, nt_min_age;
2877
2878         time_t u_lock_duration, u_reset_time;
2879         NTTIME nt_lock_duration, nt_reset_time;
2880         uint32 lockout;
2881         time_t u_logout;
2882         NTTIME nt_logout;
2883
2884         uint32 account_policy_temp;
2885
2886         time_t seq_num;
2887         uint32 server_role;
2888
2889         uint32 num_users=0, num_groups=0, num_aliases=0;
2890
2891         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2892
2893         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2894         if (!dom_info) {
2895                 return NT_STATUS_NO_MEMORY;
2896         }
2897
2898         /* find the policy handle.  open a policy on it. */
2899         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
2900                 return NT_STATUS_INVALID_HANDLE;
2901         }
2902
2903         status = access_check_samr_function(info->acc_granted,
2904                                             SAMR_ACCESS_OPEN_DOMAIN,
2905                                             "_samr_QueryDomainInfo" );
2906
2907         if ( !NT_STATUS_IS_OK(status) )
2908                 return status;
2909
2910         switch (r->in.level) {
2911                 case 0x01:
2912
2913                         become_root();
2914
2915                         /* AS ROOT !!! */
2916
2917                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2918                         min_pass_len = account_policy_temp;
2919
2920                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2921                         pass_hist = account_policy_temp;
2922
2923                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2924                         password_properties = account_policy_temp;
2925
2926                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2927                         u_expire = account_policy_temp;
2928
2929                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2930                         u_min_age = account_policy_temp;
2931
2932                         /* !AS ROOT */
2933
2934                         unbecome_root();
2935
2936                         unix_to_nt_time_abs(&nt_expire, u_expire);
2937                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2938
2939                         if (lp_check_password_script() && *lp_check_password_script()) {
2940                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2941                         }
2942
2943                         init_samr_DomInfo1(&dom_info->info1,
2944                                            (uint16)min_pass_len,
2945                                            (uint16)pass_hist,
2946                                            password_properties,
2947                                            nt_expire,
2948                                            nt_min_age);
2949                         break;
2950                 case 0x02:
2951
2952                         become_root();
2953
2954                         /* AS ROOT !!! */
2955
2956                         num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2957                         num_groups = count_sam_groups(info->disp_info);
2958                         num_aliases = count_sam_aliases(info->disp_info);
2959
2960                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2961                         u_logout = account_policy_temp;
2962
2963                         unix_to_nt_time_abs(&nt_logout, u_logout);
2964
2965                         if (!pdb_get_seq_num(&seq_num))
2966                                 seq_num = time(NULL);
2967
2968                         /* !AS ROOT */
2969
2970                         unbecome_root();
2971
2972                         server_role = ROLE_DOMAIN_PDC;
2973                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2974                                 server_role = ROLE_DOMAIN_BDC;
2975
2976                         init_samr_DomGeneralInformation(&dom_info->general,
2977                                                         nt_logout,
2978                                                         lp_serverstring(),
2979                                                         lp_workgroup(),
2980                                                         global_myname(),
2981                                                         seq_num,
2982                                                         DOMAIN_SERVER_ENABLED,
2983                                                         server_role,
2984                                                         1,
2985                                                         num_users,
2986                                                         num_groups,
2987                                                         num_aliases);
2988                         break;
2989                 case 0x03:
2990
2991                         become_root();
2992
2993                         /* AS ROOT !!! */
2994
2995                         {
2996                                 uint32 ul;
2997                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2998                                 u_logout = (time_t)ul;
2999                         }
3000
3001                         /* !AS ROOT */
3002
3003                         unbecome_root();
3004
3005                         unix_to_nt_time_abs(&nt_logout, u_logout);
3006
3007                         init_samr_DomInfo3(&dom_info->info3,
3008                                            nt_logout);
3009
3010                         break;
3011                 case 0x04:
3012                         init_samr_DomOEMInformation(&dom_info->oem,
3013                                                     lp_serverstring());
3014                         break;
3015                 case 0x05:
3016                         init_samr_DomInfo5(&dom_info->info5,
3017                                            get_global_sam_name());
3018                         break;
3019                 case 0x06:
3020                         /* NT returns its own name when a PDC. win2k and later
3021                          * only the name of the PDC if itself is a BDC (samba4
3022                          * idl) */
3023                         init_samr_DomInfo6(&dom_info->info6,
3024                                            global_myname());
3025                         break;
3026                 case 0x07:
3027                         server_role = ROLE_DOMAIN_PDC;
3028                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3029                                 server_role = ROLE_DOMAIN_BDC;
3030
3031                         init_samr_DomInfo7(&dom_info->info7,
3032                                            server_role);
3033                         break;
3034                 case 0x08:
3035
3036                         become_root();
3037
3038                         /* AS ROOT !!! */
3039
3040                         if (!pdb_get_seq_num(&seq_num)) {
3041                                 seq_num = time(NULL);
3042                         }
3043
3044                         /* !AS ROOT */
3045
3046                         unbecome_root();
3047
3048                         init_samr_DomInfo8(&dom_info->info8,
3049                                            seq_num,
3050                                            0);
3051                         break;
3052                 case 0x0c:
3053
3054                         become_root();
3055
3056                         /* AS ROOT !!! */
3057
3058                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3059                         u_lock_duration = account_policy_temp;
3060                         if (u_lock_duration != -1) {
3061                                 u_lock_duration *= 60;
3062                         }
3063
3064                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3065                         u_reset_time = account_policy_temp * 60;
3066
3067                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3068                         lockout = account_policy_temp;
3069
3070                         /* !AS ROOT */
3071
3072                         unbecome_root();
3073
3074                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3075                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3076
3077                         init_samr_DomInfo12(&dom_info->info12,
3078                                             nt_lock_duration,
3079                                             nt_reset_time,
3080                                             (uint16)lockout);
3081                         break;
3082                 default:
3083                         return NT_STATUS_INVALID_INFO_CLASS;
3084         }
3085
3086         *r->out.info = dom_info;
3087
3088         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3089
3090         return status;
3091 }
3092
3093 /* W2k3 seems to use the same check for all 3 objects that can be created via
3094  * SAMR, if you try to create for example "Dialup" as an alias it says
3095  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3096  * database. */
3097
3098 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3099 {
3100         enum lsa_SidType type;
3101         bool result;
3102
3103         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3104
3105         become_root();
3106         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3107          * whether the name already exists */
3108         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3109                              NULL, NULL, NULL, &type);
3110         unbecome_root();
3111
3112         if (!result) {
3113                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3114                 return NT_STATUS_OK;
3115         }
3116
3117         DEBUG(5, ("trying to create %s, exists as %s\n",
3118                   new_name, sid_type_lookup(type)));
3119
3120         if (type == SID_NAME_DOM_GRP) {
3121                 return NT_STATUS_GROUP_EXISTS;
3122         }
3123         if (type == SID_NAME_ALIAS) {
3124                 return NT_STATUS_ALIAS_EXISTS;
3125         }
3126
3127         /* Yes, the default is NT_STATUS_USER_EXISTS */
3128         return NT_STATUS_USER_EXISTS;
3129 }
3130
3131 /*******************************************************************
3132  _samr_CreateUser2
3133  ********************************************************************/
3134
3135 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3136                            struct samr_CreateUser2 *r)
3137 {
3138         const char *account = NULL;
3139         DOM_SID sid;
3140         POLICY_HND dom_pol = *r->in.domain_handle;
3141         uint32_t acb_info = r->in.acct_flags;
3142         POLICY_HND *user_pol = r->out.user_handle;
3143         struct samr_info *info = NULL;
3144         NTSTATUS nt_status;
3145         uint32 acc_granted;
3146         SEC_DESC *psd;
3147         size_t    sd_size;
3148         /* check this, when giving away 'add computer to domain' privs */
3149         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3150         bool can_add_account = False;
3151         SE_PRIV se_rights;
3152         DISP_INFO *disp_info = NULL;
3153
3154         /* Get the domain SID stored in the domain policy */
3155         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3156                                      &disp_info))
3157                 return NT_STATUS_INVALID_HANDLE;
3158
3159         if (disp_info->builtin_domain) {
3160                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3161                 return NT_STATUS_ACCESS_DENIED;
3162         }
3163
3164         nt_status = access_check_samr_function(acc_granted,
3165                                                SAMR_DOMAIN_ACCESS_CREATE_USER,
3166                                                "_samr_CreateUser2");
3167         if (!NT_STATUS_IS_OK(nt_status)) {
3168                 return nt_status;
3169         }
3170
3171         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3172               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3173                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3174                    this parameter is not an account type */
3175                 return NT_STATUS_INVALID_PARAMETER;
3176         }
3177
3178         account = r->in.account_name->string;
3179         if (account == NULL) {
3180                 return NT_STATUS_NO_MEMORY;
3181         }
3182
3183         nt_status = can_create(p->mem_ctx, account);
3184         if (!NT_STATUS_IS_OK(nt_status)) {
3185                 return nt_status;
3186         }
3187
3188         /* determine which user right we need to check based on the acb_info */
3189
3190         if ( acb_info & ACB_WSTRUST )
3191         {
3192                 se_priv_copy( &se_rights, &se_machine_account );
3193                 can_add_account = user_has_privileges(
3194                         p->server_info->ptok, &se_rights );
3195         }
3196         /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3197            account for domain trusts and changes the ACB flags later */
3198         else if ( acb_info & ACB_NORMAL &&
3199                   (account[strlen(account)-1] != '$') )
3200         {
3201                 se_priv_copy( &se_rights, &se_add_users );
3202                 can_add_account = user_has_privileges(
3203                         p->server_info->ptok, &se_rights );
3204         }
3205         else    /* implicit assumption of a BDC or domain trust account here
3206                  * (we already check the flags earlier) */
3207         {
3208                 if ( lp_enable_privileges() ) {
3209                         /* only Domain Admins can add a BDC or domain trust */
3210                         se_priv_copy( &se_rights, &se_priv_none );
3211                         can_add_account = nt_token_check_domain_rid(
3212                                 p->server_info->ptok,
3213                                 DOMAIN_GROUP_RID_ADMINS );
3214                 }
3215         }
3216
3217         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3218                   uidtoname(p->server_info->utok.uid),
3219                   can_add_account ? "True":"False" ));
3220
3221         /********** BEGIN Admin BLOCK **********/
3222
3223         if ( can_add_account )
3224                 become_root();
3225
3226         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3227                                     r->out.rid);
3228
3229         if ( can_add_account )
3230                 unbecome_root();
3231
3232         /********** END Admin BLOCK **********/
3233
3234         /* now check for failure */
3235
3236         if ( !NT_STATUS_IS_OK(nt_status) )
3237                 return nt_status;
3238
3239         /* Get the user's SID */
3240
3241         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3242
3243         map_max_allowed_access(p->server_info->ptok, &des_access);
3244
3245         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3246                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3247         se_map_generic(&des_access, &usr_generic_mapping);
3248
3249         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3250                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3251                 &acc_granted, "_samr_CreateUser2");
3252
3253         if ( !NT_STATUS_IS_OK(nt_status) ) {
3254                 return nt_status;
3255         }
3256
3257         /* associate the user's SID with the new handle. */
3258         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3259                 return NT_STATUS_NO_MEMORY;
3260         }
3261
3262         ZERO_STRUCTP(info);
3263         info->sid = sid;
3264         info->acc_granted = acc_granted;
3265
3266         /* get a (unique) handle.  open a policy on it. */
3267         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3268                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3269         }
3270
3271         /* After a "set" ensure we have no cached display info. */
3272         force_flush_samr_cache(info->disp_info);
3273
3274         *r->out.access_granted = acc_granted;
3275
3276         return NT_STATUS_OK;
3277 }
3278
3279 /****************************************************************
3280 ****************************************************************/
3281
3282 NTSTATUS _samr_CreateUser(pipes_struct *p,
3283                           struct samr_CreateUser *r)
3284 {
3285         struct samr_CreateUser2 c;
3286         uint32_t access_granted;
3287
3288         c.in.domain_handle      = r->in.domain_handle;
3289         c.in.account_name       = r->in.account_name;
3290         c.in.acct_flags         = ACB_NORMAL;
3291         c.in.access_mask        = r->in.access_mask;
3292         c.out.user_handle       = r->out.user_handle;
3293         c.out.access_granted    = &access_granted;
3294         c.out.rid               = r->out.rid;
3295
3296         return _samr_CreateUser2(p, &c);
3297 }
3298
3299 /*******************************************************************
3300  _samr_Connect
3301  ********************************************************************/
3302
3303 NTSTATUS _samr_Connect(pipes_struct *p,
3304                        struct samr_Connect *r)
3305 {
3306         struct samr_info *info = NULL;
3307         uint32    des_access = r->in.access_mask;
3308
3309         /* Access check */
3310
3311         if (!pipe_access_check(p)) {
3312                 DEBUG(3, ("access denied to _samr_Connect\n"));
3313                 return NT_STATUS_ACCESS_DENIED;
3314         }
3315
3316         /* set up the SAMR connect_anon response */
3317
3318         /* associate the user's SID with the new handle. */
3319         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3320                 return NT_STATUS_NO_MEMORY;
3321
3322         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
3323            was observed from a win98 client trying to enumerate users (when configured
3324            user level access control on shares)   --jerry */
3325
3326         map_max_allowed_access(p->server_info->ptok, &des_access);
3327
3328         se_map_generic( &des_access, &sam_generic_mapping );
3329         info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN);
3330
3331         /* get a (unique) handle.  open a policy on it. */
3332         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3333                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3334
3335         return NT_STATUS_OK;
3336 }
3337
3338 /*******************************************************************
3339  _samr_Connect2
3340  ********************************************************************/
3341
3342 NTSTATUS _samr_Connect2(pipes_struct *p,
3343                         struct samr_Connect2 *r)
3344 {
3345         struct samr_info *info = NULL;
3346         SEC_DESC *psd = NULL;
3347         uint32    acc_granted;
3348         uint32    des_access = r->in.access_mask;
3349         NTSTATUS  nt_status;
3350         size_t    sd_size;
3351         const char *fn = "_samr_Connect2";
3352
3353         switch (p->hdr_req.opnum) {
3354         case NDR_SAMR_CONNECT2:
3355                 fn = "_samr_Connect2";
3356                 break;
3357         case NDR_SAMR_CONNECT4:
3358                 fn = "_samr_Connect4";
3359                 break;
3360         case NDR_SAMR_CONNECT5:
3361                 fn = "_samr_Connect5";
3362                 break;
3363         }
3364
3365         DEBUG(5,("%s: %d\n", fn, __LINE__));
3366
3367         /* Access check */
3368
3369         if (!pipe_access_check(p)) {
3370                 DEBUG(3, ("access denied to %s\n", fn));
3371                 return NT_STATUS_ACCESS_DENIED;
3372         }
3373
3374         map_max_allowed_access(p->server_info->ptok, &des_access);
3375
3376         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3377         se_map_generic(&des_access, &sam_generic_mapping);
3378
3379         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3380                 NULL, 0, des_access, &acc_granted, fn);
3381
3382         if ( !NT_STATUS_IS_OK(nt_status) )
3383                 return nt_status;
3384
3385         /* associate the user's SID and access granted with the new handle. */
3386         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3387                 return NT_STATUS_NO_MEMORY;
3388
3389         info->acc_granted = acc_granted;
3390         info->status = r->in.access_mask; /* this looks so wrong... - gd */
3391
3392         /* get a (unique) handle.  open a policy on it. */
3393         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3394                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3395
3396         DEBUG(5,("%s: %d\n", fn, __LINE__));
3397
3398         return nt_status;
3399 }
3400
3401 /*******************************************************************
3402  _samr_Connect4
3403  ********************************************************************/
3404
3405 NTSTATUS _samr_Connect4(pipes_struct *p,
3406                         struct samr_Connect4 *r)
3407 {
3408         struct samr_Connect2 c;
3409
3410         c.in.system_name        = r->in.system_name;
3411         c.in.access_mask        = r->in.access_mask;
3412         c.out.connect_handle    = r->out.connect_handle;
3413
3414         return _samr_Connect2(p, &c);
3415 }
3416
3417 /*******************************************************************
3418  _samr_Connect5
3419  ********************************************************************/
3420
3421 NTSTATUS _samr_Connect5(pipes_struct *p,
3422                         struct samr_Connect5 *r)
3423 {
3424         NTSTATUS status;
3425         struct samr_Connect2 c;
3426         struct samr_ConnectInfo1 info1;
3427
3428         info1.client_version = SAMR_CONNECT_AFTER_W2K;
3429         info1.unknown2 = 0;
3430
3431         c.in.system_name        = r->in.system_name;
3432         c.in.access_mask        = r->in.access_mask;
3433         c.out.connect_handle    = r->out.connect_handle;
3434
3435         status = _samr_Connect2(p, &c);
3436         if (!NT_STATUS_IS_OK(status)) {
3437                 return status;
3438         }
3439
3440         *r->out.level_out = 1;
3441         r->out.info_out->info1 = info1;
3442
3443         return NT_STATUS_OK;
3444 }
3445
3446 /**********************************************************************
3447  _samr_LookupDomain
3448  **********************************************************************/
3449
3450 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3451                             struct samr_LookupDomain *r)
3452 {
3453         NTSTATUS status = NT_STATUS_OK;
3454         struct samr_info *info;
3455         const char *domain_name;
3456         DOM_SID *sid = NULL;
3457
3458         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3459                 return NT_STATUS_INVALID_HANDLE;
3460
3461         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3462            Reverted that change so we will work with RAS servers again */
3463
3464         status = access_check_samr_function(info->acc_granted,
3465                                             SAMR_ACCESS_OPEN_DOMAIN,
3466                                             "_samr_LookupDomain");
3467         if (!NT_STATUS_IS_OK(status)) {
3468                 return status;
3469         }
3470
3471         domain_name = r->in.domain_name->string;
3472         if (!domain_name) {
3473                 return NT_STATUS_INVALID_PARAMETER;
3474         }
3475
3476         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3477         if (!sid) {
3478                 return NT_STATUS_NO_MEMORY;
3479         }
3480
3481         if (strequal(domain_name, builtin_domain_name())) {
3482                 sid_copy(sid, &global_sid_Builtin);
3483         } else {
3484                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3485                         status = NT_STATUS_NO_SUCH_DOMAIN;
3486                 }
3487         }
3488
3489         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3490                  sid_string_dbg(sid)));
3491
3492         *r->out.sid = sid;
3493
3494         return status;
3495 }
3496
3497 /**********************************************************************
3498  _samr_EnumDomains
3499  **********************************************************************/
3500
3501 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3502                            struct samr_EnumDomains *r)
3503 {
3504         NTSTATUS status;
3505         struct samr_info *info;
3506         uint32_t num_entries = 2;
3507         struct samr_SamEntry *entry_array = NULL;
3508         struct samr_SamArray *sam;
3509
3510         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3511                 return NT_STATUS_INVALID_HANDLE;
3512
3513         status = access_check_samr_function(info->acc_granted,
3514                                             SAMR_ACCESS_ENUM_DOMAINS,
3515                                             "_samr_EnumDomains");
3516         if (!NT_STATUS_IS_OK(status)) {
3517                 return status;
3518         }
3519
3520         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3521         if (!sam) {
3522                 return NT_STATUS_NO_MEMORY;
3523         }
3524
3525         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3526                                         struct samr_SamEntry,
3527                                         num_entries);
3528         if (!entry_array) {
3529                 return NT_STATUS_NO_MEMORY;
3530         }
3531
3532         entry_array[0].idx = 0;
3533         init_lsa_String(&entry_array[0].name, get_global_sam_name());
3534
3535         entry_array[1].idx = 1;
3536         init_lsa_String(&entry_array[1].name, "Builtin");
3537
3538         sam->count = num_entries;
3539         sam->entries = entry_array;
3540
3541         *r->out.sam = sam;
3542         *r->out.num_entries = num_entries;
3543
3544         return status;
3545 }
3546
3547 /*******************************************************************
3548  _samr_OpenAlias
3549  ********************************************************************/
3550
3551 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3552                          struct samr_OpenAlias *r)
3553 {
3554         DOM_SID sid;
3555         POLICY_HND domain_pol = *r->in.domain_handle;
3556         uint32 alias_rid = r->in.rid;
3557         POLICY_HND *alias_pol = r->out.alias_handle;
3558         struct    samr_info *info = NULL;
3559         SEC_DESC *psd = NULL;
3560         uint32    acc_granted;
3561         uint32    des_access = r->in.access_mask;
3562         size_t    sd_size;
3563         NTSTATUS  status;
3564         SE_PRIV se_rights;
3565
3566         /* find the domain policy and get the SID / access bits stored in the domain policy */
3567
3568         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3569                 return NT_STATUS_INVALID_HANDLE;
3570
3571         status = access_check_samr_function(acc_granted,
3572                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3573                                             "_samr_OpenAlias");
3574
3575         if ( !NT_STATUS_IS_OK(status) )
3576                 return status;
3577
3578         /* append the alias' RID to it */
3579
3580         if (!sid_append_rid(&sid, alias_rid))
3581                 return NT_STATUS_NO_SUCH_ALIAS;
3582
3583         /*check if access can be granted as requested by client. */
3584
3585         map_max_allowed_access(p->server_info->ptok, &des_access);
3586
3587         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3588         se_map_generic(&des_access,&ali_generic_mapping);
3589
3590         se_priv_copy( &se_rights, &se_add_users );
3591
3592
3593         status = access_check_samr_object(psd, p->server_info->ptok,
3594                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3595                 &acc_granted, "_samr_OpenAlias");
3596
3597         if ( !NT_STATUS_IS_OK(status) )
3598                 return status;
3599
3600         {
3601                 /* Check we actually have the requested alias */
3602                 enum lsa_SidType type;
3603                 bool result;
3604                 gid_t gid;
3605
3606                 become_root();
3607                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3608                 unbecome_root();
3609
3610                 if (!result || (type != SID_NAME_ALIAS)) {
3611                         return NT_STATUS_NO_SUCH_ALIAS;
3612                 }
3613
3614                 /* make sure there is a mapping */
3615
3616                 if ( !sid_to_gid( &sid, &gid ) ) {
3617                         return NT_STATUS_NO_SUCH_ALIAS;
3618                 }
3619
3620         }
3621
3622         /* associate the alias SID with the new handle. */
3623         if ((info = get_samr_info_by_sid(&sid)) == NULL)
3624                 return NT_STATUS_NO_MEMORY;
3625
3626         info->acc_granted = acc_granted;
3627
3628         /* get a (unique) handle.  open a policy on it. */
3629         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3630                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3631
3632         return NT_STATUS_OK;
3633 }
3634
3635 /*******************************************************************
3636  set_user_info_7
3637  ********************************************************************/
3638
3639 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3640                                 struct samr_UserInfo7 *id7,
3641                                 struct samu *pwd)
3642 {
3643         NTSTATUS rc;
3644
3645         if (id7 == NULL) {
3646                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3647                 return NT_STATUS_ACCESS_DENIED;
3648         }
3649
3650         if (!id7->account_name.string) {
3651                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3652                 return NT_STATUS_ACCESS_DENIED;
3653         }
3654
3655         /* check to see if the new username already exists.  Note: we can't
3656            reliably lock all backends, so there is potentially the
3657            possibility that a user can be created in between this check and
3658            the rename.  The rename should fail, but may not get the
3659            exact same failure status code.  I think this is small enough
3660            of a window for this type of operation and the results are
3661            simply that the rename fails with a slightly different status
3662            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3663
3664         rc = can_create(mem_ctx, id7->account_name.string);
3665         if (!NT_STATUS_IS_OK(rc)) {
3666                 return rc;
3667         }
3668
3669         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3670
3671         return rc;
3672 }
3673
3674 /*******************************************************************
3675  set_user_info_16
3676  ********************************************************************/
3677
3678 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3679                              struct samu *pwd)
3680 {
3681         if (id16 == NULL) {
3682                 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3683                 return False;
3684         }
3685
3686         /* FIX ME: check if the value is really changed --metze */
3687         if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3688                 return False;
3689         }
3690
3691         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3692                 return False;
3693         }
3694
3695         return True;
3696 }
3697
3698 /*******************************************************************
3699  set_user_info_18
3700  ********************************************************************/
3701
3702 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3703                              struct samu *pwd)
3704 {
3705         if (id18 == NULL) {
3706                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3707                 return False;
3708         }
3709
3710         if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3711                 return False;
3712         }
3713         if (!pdb_set_nt_passwd     (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3714                 return False;
3715         }
3716         if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3717                 return False;
3718         }
3719
3720         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3721                 return False;
3722         }
3723
3724         return True;
3725 }
3726
3727 /*******************************************************************
3728  set_user_info_20
3729  ********************************************************************/
3730
3731 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3732                              struct samu *pwd)
3733 {
3734         if (id20 == NULL) {
3735                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3736                 return False;
3737         }
3738
3739         copy_id20_to_sam_passwd(pwd, id20);
3740
3741         /* write the change out */
3742         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3743                 return False;
3744         }
3745
3746         return True;
3747 }
3748
3749 /*******************************************************************
3750  set_user_info_21
3751  ********************************************************************/
3752
3753 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3754                                  struct samr_UserInfo21 *id21,
3755                                  struct samu *pwd)
3756 {
3757         NTSTATUS status;
3758
3759         if (id21 == NULL) {
3760                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3761                 return NT_STATUS_INVALID_PARAMETER;
3762         }
3763
3764         if (id21->fields_present == 0) {
3765                 return NT_STATUS_INVALID_PARAMETER;
3766         }
3767
3768         if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3769                 return NT_STATUS_ACCESS_DENIED;
3770         }
3771
3772         /* we need to separately check for an account rename first */
3773
3774         if (id21->account_name.string &&
3775             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3776         {
3777
3778                 /* check to see if the new username already exists.  Note: we can't
3779                    reliably lock all backends, so there is potentially the
3780                    possibility that a user can be created in between this check and
3781                    the rename.  The rename should fail, but may not get the
3782                    exact same failure status code.  I think this is small enough
3783                    of a window for this type of operation and the results are
3784                    simply that the rename fails with a slightly different status
3785                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3786
3787                 status = can_create(mem_ctx, id21->account_name.string);
3788                 if (!NT_STATUS_IS_OK(status)) {
3789                         return status;
3790                 }
3791
3792                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3793
3794                 if (!NT_STATUS_IS_OK(status)) {
3795                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3796                                 nt_errstr(status)));
3797                         return status;
3798                 }
3799
3800                 /* set the new username so that later
3801                    functions can work on the new account */
3802                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3803         }
3804
3805         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3806
3807         /*
3808          * The funny part about the previous two calls is
3809          * that pwd still has the password hashes from the
3810          * passdb entry.  These have not been updated from
3811          * id21.  I don't know if they need to be set.    --jerry
3812          */
3813
3814         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3815                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3816                 if ( !NT_STATUS_IS_OK(status) ) {
3817                         return status;
3818                 }
3819         }
3820
3821         /* Don't worry about writing out the user account since the
3822            primary group SID is generated solely from the user's Unix
3823            primary group. */
3824
3825         /* write the change out */
3826         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3827                 return status;
3828         }
3829
3830         return NT_STATUS_OK;
3831 }
3832
3833 /*******************************************************************
3834  set_user_info_23
3835  ********************************************************************/
3836
3837 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3838                                  struct samr_UserInfo23 *id23,
3839                                  struct samu *pwd)
3840 {
3841         char *plaintext_buf = NULL;
3842         uint32 len = 0;
3843         uint32_t acct_ctrl;
3844         NTSTATUS status;
3845
3846         if (id23 == NULL) {
3847                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3848                 return NT_STATUS_INVALID_PARAMETER;
3849         }
3850
3851         if (id23->info.fields_present == 0) {
3852                 return NT_STATUS_INVALID_PARAMETER;
3853         }
3854
3855         if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3856                 return NT_STATUS_ACCESS_DENIED;
3857         }
3858
3859         if ((id23->info.fields_present & SAMR_FIELD_PASSWORD) ||
3860             (id23->info.fields_present & SAMR_FIELD_PASSWORD2)) {
3861
3862                 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3863                           pdb_get_username(pwd)));
3864
3865                 if (!decode_pw_buffer(mem_ctx,
3866                                       id23->password.data,
3867                                       &plaintext_buf,
3868                                       &len,
3869                                       STR_UNICODE)) {
3870                         return NT_STATUS_WRONG_PASSWORD;
3871                 }
3872
3873                 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3874                         return NT_STATUS_ACCESS_DENIED;
3875                 }
3876         }
3877
3878         copy_id23_to_sam_passwd(pwd, id23);
3879
3880         acct_ctrl = pdb_get_acct_ctrl(pwd);
3881
3882         /* if it's a trust account, don't update /etc/passwd */
3883         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3884                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
3885                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
3886                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
3887         } else if (plaintext_buf) {
3888                 /* update the UNIX password */
3889                 if (lp_unix_password_sync() ) {
3890                         struct passwd *passwd;
3891                         if (pdb_get_username(pwd) == NULL) {
3892                                 DEBUG(1, ("chgpasswd: User without name???\n"));
3893                                 return NT_STATUS_ACCESS_DENIED;
3894                         }
3895
3896                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3897                         if (passwd == NULL) {
3898                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3899                         }
3900
3901                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3902                                 return NT_STATUS_ACCESS_DENIED;
3903                         }
3904                         TALLOC_FREE(passwd);
3905                 }
3906         }
3907
3908         if (plaintext_buf) {
3909                 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3910         }
3911
3912         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3913             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
3914                                                                    pwd)))) {
3915                 return status;
3916         }
3917
3918         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3919                 return status;
3920         }
3921
3922         return NT_STATUS_OK;
3923 }
3924
3925 /*******************************************************************
3926  set_user_info_pw
3927  ********************************************************************/
3928
3929 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
3930                              int level)
3931 {
3932         uint32 len = 0;
3933         char *plaintext_buf = NULL;
3934         uint32 acct_ctrl;
3935         time_t last_set_time;
3936         enum pdb_value_state last_set_state;
3937
3938         DEBUG(5, ("Attempting administrator password change for user %s\n",
3939                   pdb_get_username(pwd)));
3940
3941         acct_ctrl = pdb_get_acct_ctrl(pwd);
3942         /* we need to know if it's expired, because this is an admin change, not a
3943            user change, so it's still expired when we're done */
3944         last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3945         last_set_time = pdb_get_pass_last_set_time(pwd);
3946
3947         if (!decode_pw_buffer(talloc_tos(),
3948                                 pass,
3949                                 &plaintext_buf,
3950                                 &len,
3951                                 STR_UNICODE)) {
3952                 return False;
3953         }
3954
3955         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3956                 return False;
3957         }
3958
3959         /* if it's a trust account, don't update /etc/passwd */
3960         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3961                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
3962                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
3963                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3964         } else {
3965                 /* update the UNIX password */
3966                 if (lp_unix_password_sync()) {
3967                         struct passwd *passwd;
3968
3969                         if (pdb_get_username(pwd) == NULL) {
3970                                 DEBUG(1, ("chgpasswd: User without name???\n"));
3971                                 return False;
3972                         }
3973
3974                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3975                         if (passwd == NULL) {
3976                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3977                         }
3978
3979                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3980                                 return False;
3981                         }
3982                         TALLOC_FREE(passwd);
3983                 }
3984         }
3985
3986         memset(plaintext_buf, '\0', strlen(plaintext_buf));
3987
3988         /*
3989          * A level 25 change does reset the pwdlastset field, a level 24
3990          * change does not. I know this is probably not the full story, but
3991          * it is needed to make XP join LDAP correctly, without it the later
3992          * auth2 check can fail with PWD_MUST_CHANGE.
3993          */
3994         if (level != 25) {
3995                 /*
3996                  * restore last set time as this is an admin change, not a
3997                  * user pw change
3998                  */
3999                 pdb_set_pass_last_set_time (pwd, last_set_time,
4000                                             last_set_state);
4001         }
4002
4003         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4004
4005         /* update the SAMBA password */
4006         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4007                 return False;
4008         }
4009
4010         return True;
4011 }
4012
4013 /*******************************************************************
4014  set_user_info_25
4015  ********************************************************************/
4016
4017 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4018                                  struct samr_UserInfo25 *id25,
4019                                  struct samu *pwd)
4020 {
4021         NTSTATUS status;
4022
4023         if (id25 == NULL) {
4024                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4025                 return NT_STATUS_INVALID_PARAMETER;
4026         }
4027
4028         if (id25->info.fields_present == 0) {
4029                 return NT_STATUS_INVALID_PARAMETER;
4030         }
4031
4032         if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4033                 return NT_STATUS_ACCESS_DENIED;
4034         }
4035
4036         copy_id25_to_sam_passwd(pwd, id25);
4037
4038         /* write the change out */
4039         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4040                 return status;
4041         }
4042
4043         /*
4044          * We need to "pdb_update_sam_account" before the unix primary group
4045          * is set, because the idealx scripts would also change the
4046          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4047          * the delete explicit / add explicit, which would then fail to find
4048          * the previous primaryGroupSid value.
4049          */
4050
4051         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4052                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4053                 if ( !NT_STATUS_IS_OK(status) ) {
4054                         return status;
4055                 }
4056         }
4057
4058         return NT_STATUS_OK;
4059 }
4060
4061 /*******************************************************************
4062  samr_SetUserInfo
4063  ********************************************************************/
4064
4065 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4066                            struct samr_SetUserInfo *r)
4067 {
4068         NTSTATUS status;
4069         struct samu *pwd = NULL;
4070         DOM_SID sid;
4071         POLICY_HND *pol = r->in.user_handle;
4072         union samr_UserInfo *info = r->in.info;
4073         uint16_t switch_value = r->in.level;
4074         uint32_t acc_granted;
4075         uint32_t acc_required;
4076         bool ret;
4077         bool has_enough_rights = False;
4078         uint32_t acb_info;
4079         DISP_INFO *disp_info = NULL;
4080
4081         DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4082
4083         /* find the policy handle.  open a policy on it. */
4084         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4085                 return NT_STATUS_INVALID_HANDLE;
4086         }
4087
4088         /* This is tricky.  A WinXP domain join sets
4089           (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4090           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
4091           standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4092           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
4093           we'll use the set from the WinXP join as the basis. */
4094
4095         switch (switch_value) {
4096         case 18:
4097         case 24:
4098         case 25:
4099         case 26:
4100                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4101                 break;
4102         default:
4103                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4104                                SAMR_USER_ACCESS_SET_ATTRIBUTES |
4105                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
4106                 break;
4107         }
4108
4109         status = access_check_samr_function(acc_granted,
4110                                             acc_required,
4111                                             "_samr_SetUserInfo");
4112         if (!NT_STATUS_IS_OK(status)) {
4113                 return status;
4114         }
4115
4116         DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4117                   sid_string_dbg(&sid), switch_value));
4118
4119         if (info == NULL) {
4120                 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4121                 return NT_STATUS_INVALID_INFO_CLASS;
4122         }
4123
4124         if (!(pwd = samu_new(NULL))) {
4125                 return NT_STATUS_NO_MEMORY;
4126         }
4127
4128         become_root();
4129         ret = pdb_getsampwsid(pwd, &sid);
4130         unbecome_root();
4131
4132         if (!ret) {
4133                 TALLOC_FREE(pwd);
4134                 return NT_STATUS_NO_SUCH_USER;
4135         }
4136
4137         /* deal with machine password changes differently from userinfo changes */
4138         /* check to see if we have the sufficient rights */
4139
4140         acb_info = pdb_get_acct_ctrl(pwd);
4141         if (acb_info & ACB_WSTRUST)
4142                 has_enough_rights = user_has_privileges(p->server_info->ptok,
4143                                                         &se_machine_account);
4144         else if (acb_info & ACB_NORMAL)
4145                 has_enough_rights = user_has_privileges(p->server_info->ptok,
4146                                                         &se_add_users);
4147         else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4148                 if (lp_enable_privileges()) {
4149                         has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
4150                                                                       DOMAIN_GROUP_RID_ADMINS);
4151                 }
4152         }
4153
4154         DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4155                   uidtoname(p->server_info->utok.uid),
4156                   has_enough_rights ? "" : " not"));
4157
4158         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4159
4160         if (has_enough_rights) {
4161                 become_root();
4162         }
4163
4164         /* ok!  user info levels (lots: see MSDEV help), off we go... */
4165
4166         switch (switch_value) {
4167
4168                 case 7:
4169                         status = set_user_info_7(p->mem_ctx,
4170                                                  &info->info7, pwd);
4171                         break;
4172
4173                 case 16:
4174                         if (!set_user_info_16(&info->info16, pwd)) {
4175                                 status = NT_STATUS_ACCESS_DENIED;
4176                         }
4177                         break;
4178
4179                 case 18:
4180                         /* Used by AS/U JRA. */
4181                         if (!set_user_info_18(&info->info18, pwd)) {
4182                                 status = NT_STATUS_ACCESS_DENIED;
4183                         }
4184                         break;
4185
4186                 case 20:
4187                         if (!set_user_info_20(&info->info20, pwd)) {
4188                                 status = NT_STATUS_ACCESS_DENIED;
4189                         }
4190                         break;
4191
4192                 case 21:
4193                         status = set_user_info_21(p->mem_ctx,
4194                                                   &info->info21, pwd);
4195                         break;
4196
4197                 case 23:
4198                         if (!p->server_info->user_session_key.length) {
4199                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4200                         }
4201                         SamOEMhashBlob(info->info23.password.data, 516,
4202                                        &p->server_info->user_session_key);
4203
4204                         dump_data(100, info->info23.password.data, 516);
4205
4206                         status = set_user_info_23(p->mem_ctx,
4207                                                   &info->info23, pwd);
4208                         break;
4209
4210                 case 24:
4211                         if (!p->server_info->user_session_key.length) {
4212                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4213                         }
4214                         SamOEMhashBlob(info->info24.password.data,
4215                                        516,
4216                                        &p->server_info->user_session_key);
4217
4218                         dump_data(100, info->info24.password.data, 516);
4219
4220                         if (!set_user_info_pw(info->info24.password.data, pwd,
4221                                               switch_value)) {
4222                                 status = NT_STATUS_WRONG_PASSWORD;
4223                         }
4224                         break;
4225
4226                 case 25:
4227                         if (!p->server_info->user_session_key.length) {
4228                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4229                         }
4230                         encode_or_decode_arc4_passwd_buffer(
4231                                 info->info25.password.data,
4232                                 &p->server_info->user_session_key);
4233
4234                         dump_data(100, info->info25.password.data, 532);
4235
4236                         status = set_user_info_25(p->mem_ctx,
4237                                                   &info->info25, pwd);
4238                         if (!NT_STATUS_IS_OK(status)) {
4239                                 goto done;
4240                         }
4241                         if (!set_user_info_pw(info->info25.password.data, pwd,
4242                                               switch_value)) {
4243                                 status = NT_STATUS_WRONG_PASSWORD;
4244                         }
4245                         break;
4246
4247                 case 26:
4248                         if (!p->server_info->user_session_key.length) {
4249                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4250                         }
4251                         encode_or_decode_arc4_passwd_buffer(
4252                                 info->info26.password.data,
4253                                 &p->server_info->user_session_key);
4254
4255                         dump_data(100, info->info26.password.data, 516);
4256
4257                         if (!set_user_info_pw(info->info26.password.data, pwd,
4258                                               switch_value)) {
4259                                 status = NT_STATUS_WRONG_PASSWORD;
4260                         }
4261                         break;
4262
4263                 default:
4264                         status = NT_STATUS_INVALID_INFO_CLASS;
4265         }
4266
4267  done:
4268
4269         TALLOC_FREE(pwd);
4270
4271         if (has_enough_rights) {
4272                 unbecome_root();
4273         }
4274
4275         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4276
4277         if (NT_STATUS_IS_OK(status)) {
4278                 force_flush_samr_cache(disp_info);
4279         }
4280
4281         return status;
4282 }
4283
4284 /*******************************************************************
4285  _samr_SetUserInfo2
4286  ********************************************************************/
4287
4288 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4289                             struct samr_SetUserInfo2 *r)
4290 {
4291         struct samr_SetUserInfo q;
4292
4293         q.in.user_handle        = r->in.user_handle;
4294         q.in.level              = r->in.level;
4295         q.in.info               = r->in.info;
4296
4297         return _samr_SetUserInfo(p, &q);
4298 }
4299
4300 /*********************************************************************
4301  _samr_GetAliasMembership
4302 *********************************************************************/
4303
4304 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4305                                   struct samr_GetAliasMembership *r)
4306 {
4307         size_t num_alias_rids;
4308         uint32 *alias_rids;
4309         struct samr_info *info = NULL;
4310         size_t i;
4311
4312         NTSTATUS ntstatus1;
4313         NTSTATUS ntstatus2;
4314
4315         DOM_SID *members;
4316
4317         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4318
4319         /* find the policy handle.  open a policy on it. */
4320         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4321                 return NT_STATUS_INVALID_HANDLE;
4322
4323         ntstatus1 = access_check_samr_function(info->acc_granted,
4324                                                SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
4325                                                "_samr_GetAliasMembership");
4326         ntstatus2 = access_check_samr_function(info->acc_granted,
4327                                                SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4328                                                "_samr_GetAliasMembership");
4329
4330         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4331                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4332                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4333                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4334                 }
4335         }
4336
4337         if (!sid_check_is_domain(&info->sid) &&
4338             !sid_check_is_builtin(&info->sid))
4339                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4340
4341         if (r->in.sids->num_sids) {
4342                 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4343
4344                 if (members == NULL)
4345                         return NT_STATUS_NO_MEMORY;
4346         } else {
4347                 members = NULL;
4348         }
4349
4350         for (i=0; i<r->in.sids->num_sids; i++)
4351                 sid_copy(&members[i], r->in.sids->sids[i].sid);
4352
4353         alias_rids = NULL;
4354         num_alias_rids = 0;
4355
4356         become_root();
4357         ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4358                                                r->in.sids->num_sids,
4359                                                &alias_rids, &num_alias_rids);
4360         unbecome_root();
4361
4362         if (!NT_STATUS_IS_OK(ntstatus1)) {
4363                 return ntstatus1;
4364         }
4365
4366         r->out.rids->count = num_alias_rids;
4367         r->out.rids->ids = alias_rids;
4368
4369         return NT_STATUS_OK;
4370 }
4371
4372 /*********************************************************************
4373  _samr_GetMembersInAlias
4374 *********************************************************************/
4375
4376 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4377                                  struct samr_GetMembersInAlias *r)
4378 {
4379         NTSTATUS status;
4380         size_t i;
4381         size_t num_sids = 0;
4382         struct lsa_SidPtr *sids = NULL;
4383         DOM_SID *pdb_sids = NULL;
4384
4385         DOM_SID alias_sid;
4386
4387         uint32 acc_granted;
4388
4389         /* find the policy handle.  open a policy on it. */
4390         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4391                 return NT_STATUS_INVALID_HANDLE;
4392
4393         status = access_check_samr_function(acc_granted,
4394                                             SAMR_ALIAS_ACCESS_GET_MEMBERS,
4395                                             "_samr_GetMembersInAlias");
4396         if (!NT_STATUS_IS_OK(status)) {
4397                 return status;
4398         }
4399
4400         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4401
4402         become_root();
4403         status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4404         unbecome_root();
4405
4406         if (!NT_STATUS_IS_OK(status)) {
4407                 return status;
4408         }
4409
4410         if (num_sids) {
4411                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4412                 if (sids == NULL) {
4413                         TALLOC_FREE(pdb_sids);
4414                         return NT_STATUS_NO_MEMORY;
4415                 }
4416         }
4417
4418         for (i = 0; i < num_sids; i++) {
4419                 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4420                 if (!sids[i].sid) {
4421                         TALLOC_FREE(pdb_sids);
4422                         return NT_STATUS_NO_MEMORY;
4423                 }
4424         }
4425
4426         r->out.sids->num_sids = num_sids;
4427         r->out.sids->sids = sids;
4428
4429         TALLOC_FREE(pdb_sids);
4430
4431         return NT_STATUS_OK;
4432 }
4433
4434 /*********************************************************************
4435  _samr_QueryGroupMember
4436 *********************************************************************/
4437
4438 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4439                                 struct samr_QueryGroupMember *r)
4440 {
4441         DOM_SID group_sid;
4442         size_t i, num_members;
4443
4444         uint32 *rid=NULL;
4445         uint32 *attr=NULL;
4446
4447         uint32 acc_granted;
4448
4449         NTSTATUS status;
4450         struct samr_RidTypeArray *rids = NULL;
4451
4452         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4453         if (!rids) {
4454                 return NT_STATUS_NO_MEMORY;
4455         }
4456
4457         /* find the policy handle.  open a policy on it. */
4458         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4459                 return NT_STATUS_INVALID_HANDLE;
4460
4461         status = access_check_samr_function(acc_granted,
4462                                             SAMR_GROUP_ACCESS_GET_MEMBERS,
4463                                             "_samr_QueryGroupMember");
4464         if (!NT_STATUS_IS_OK(status)) {
4465                 return status;
4466         }
4467
4468         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4469
4470         if (!sid_check_is_in_our_domain(&group_sid)) {
4471                 DEBUG(3, ("sid %s is not in our domain\n",
4472                           sid_string_dbg(&group_sid)));
4473                 return NT_STATUS_NO_SUCH_GROUP;
4474         }
4475
4476         DEBUG(10, ("lookup on Domain SID\n"));
4477
4478         become_root();
4479         status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4480                                         &rid, &num_members);
4481         unbecome_root();
4482
4483         if (!NT_STATUS_IS_OK(status))
4484                 return status;
4485
4486         if (num_members) {
4487                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4488                 if (attr == NULL) {
4489                         return NT_STATUS_NO_MEMORY;
4490                 }
4491         } else {
4492                 attr = NULL;
4493         }
4494
4495         for (i=0; i<num_members; i++)
4496                 attr[i] = SID_NAME_USER;
4497
4498         rids->count = num_members;
4499         rids->types = attr;
4500         rids->rids = rid;
4501
4502         *r->out.rids = rids;
4503
4504         return NT_STATUS_OK;
4505 }
4506
4507 /*********************************************************************
4508  _samr_AddAliasMember
4509 *********************************************************************/
4510
4511 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4512                               struct samr_AddAliasMember *r)
4513 {
4514         DOM_SID alias_sid;
4515         uint32 acc_granted;
4516         SE_PRIV se_rights;
4517         bool can_add_accounts;
4518         NTSTATUS status;
4519         DISP_INFO *disp_info = NULL;
4520
4521         /* Find the policy handle. Open a policy on it. */
4522         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4523                 return NT_STATUS_INVALID_HANDLE;
4524
4525         status = access_check_samr_function(acc_granted,
4526                                             SAMR_ALIAS_ACCESS_ADD_MEMBER,
4527                                             "_samr_AddAliasMember");
4528         if (!NT_STATUS_IS_OK(status)) {
4529                 return status;
4530         }
4531
4532         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4533
4534         se_priv_copy( &se_rights, &se_add_users );
4535         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4536
4537         /******** BEGIN SeAddUsers BLOCK *********/
4538
4539         if ( can_add_accounts )
4540                 become_root();
4541
4542         status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4543
4544         if ( can_add_accounts )
4545                 unbecome_root();
4546
4547         /******** END SeAddUsers BLOCK *********/
4548
4549         if (NT_STATUS_IS_OK(status)) {
4550                 force_flush_samr_cache(disp_info);
4551         }
4552
4553         return status;
4554 }
4555
4556 /*********************************************************************
4557  _samr_DeleteAliasMember
4558 *********************************************************************/
4559
4560 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4561                                  struct samr_DeleteAliasMember *r)
4562 {
4563         DOM_SID alias_sid;
4564         uint32 acc_granted;
4565         SE_PRIV se_rights;
4566         bool can_add_accounts;
4567         NTSTATUS status;
4568         DISP_INFO *disp_info = NULL;
4569
4570         /* Find the policy handle. Open a policy on it. */
4571         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4572                 return NT_STATUS_INVALID_HANDLE;
4573
4574         status = access_check_samr_function(acc_granted,
4575                                             SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
4576                                             "_samr_DeleteAliasMember");
4577         if (!NT_STATUS_IS_OK(status)) {
4578                 return status;
4579         }
4580
4581         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4582                    sid_string_dbg(&alias_sid)));
4583
4584         se_priv_copy( &se_rights, &se_add_users );
4585         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4586
4587         /******** BEGIN SeAddUsers BLOCK *********/
4588
4589         if ( can_add_accounts )
4590                 become_root();
4591
4592         status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4593
4594         if ( can_add_accounts )
4595                 unbecome_root();
4596
4597         /******** END SeAddUsers BLOCK *********/
4598
4599         if (NT_STATUS_IS_OK(status)) {
4600                 force_flush_samr_cache(disp_info);
4601         }
4602
4603         return status;
4604 }
4605
4606 /*********************************************************************
4607  _samr_AddGroupMember
4608 *********************************************************************/
4609
4610 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4611                               struct samr_AddGroupMember *r)
4612 {
4613         NTSTATUS status;
4614         DOM_SID group_sid;
4615         uint32 group_rid;
4616         uint32 acc_granted;
4617         SE_PRIV se_rights;
4618         bool can_add_accounts;
4619         DISP_INFO *disp_info = NULL;
4620
4621         /* Find the policy handle. Open a policy on it. */
4622         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4623                 return NT_STATUS_INVALID_HANDLE;
4624
4625         status = access_check_samr_function(acc_granted,
4626                                             SAMR_GROUP_ACCESS_ADD_MEMBER,
4627                                             "_samr_AddGroupMember");
4628         if (!NT_STATUS_IS_OK(status)) {
4629                 return status;
4630         }
4631
4632         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4633
4634         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4635                                 &group_rid)) {
4636                 return NT_STATUS_INVALID_HANDLE;
4637         }
4638
4639         se_priv_copy( &se_rights, &se_add_users );
4640         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4641
4642         /******** BEGIN SeAddUsers BLOCK *********/
4643
4644         if ( can_add_accounts )
4645                 become_root();
4646
4647         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4648
4649         if ( can_add_accounts )
4650                 unbecome_root();
4651
4652         /******** END SeAddUsers BLOCK *********/
4653
4654         force_flush_samr_cache(disp_info);
4655
4656         return status;
4657 }
4658
4659 /*********************************************************************
4660  _samr_DeleteGroupMember
4661 *********************************************************************/
4662
4663 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4664                                  struct samr_DeleteGroupMember *r)
4665
4666 {
4667         NTSTATUS status;
4668         DOM_SID group_sid;
4669         uint32 group_rid;
4670         uint32 acc_granted;
4671         SE_PRIV se_rights;
4672         bool can_add_accounts;
4673         DISP_INFO *disp_info = NULL;
4674
4675         /*
4676          * delete the group member named r->in.rid
4677          * who is a member of the sid associated with the handle
4678          * the rid is a user's rid as the group is a domain group.
4679          */
4680
4681         /* Find the policy handle. Open a policy on it. */
4682         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4683                 return NT_STATUS_INVALID_HANDLE;
4684
4685         status = access_check_samr_function(acc_granted,
4686                                             SAMR_GROUP_ACCESS_REMOVE_MEMBER,
4687                                             "_samr_DeleteGroupMember");
4688         if (!NT_STATUS_IS_OK(status)) {
4689                 return status;
4690         }
4691
4692         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4693                                 &group_rid)) {
4694                 return NT_STATUS_INVALID_HANDLE;
4695         }
4696
4697         se_priv_copy( &se_rights, &se_add_users );
4698         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4699
4700         /******** BEGIN SeAddUsers BLOCK *********/
4701
4702         if ( can_add_accounts )
4703                 become_root();
4704
4705         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4706
4707         if ( can_add_accounts )
4708                 unbecome_root();
4709
4710         /******** END SeAddUsers BLOCK *********/
4711
4712         force_flush_samr_cache(disp_info);
4713
4714         return status;
4715 }
4716
4717 /*********************************************************************
4718  _samr_DeleteUser
4719 *********************************************************************/
4720
4721 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4722                           struct samr_DeleteUser *r)
4723 {
4724         NTSTATUS status;
4725         DOM_SID user_sid;
4726         struct samu *sam_pass=NULL;
4727         uint32 acc_granted;
4728         bool can_add_accounts;
4729         uint32 acb_info;
4730         DISP_INFO *disp_info = NULL;
4731         bool ret;
4732
4733         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4734
4735         /* Find the policy handle. Open a policy on it. */
4736         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4737                 return NT_STATUS_INVALID_HANDLE;
4738
4739         status = access_check_samr_function(acc_granted,
4740                                             STD_RIGHT_DELETE_ACCESS,
4741                                             "_samr_DeleteUser");
4742         if (!NT_STATUS_IS_OK(status)) {
4743                 return status;
4744         }
4745
4746         if (!sid_check_is_in_our_domain(&user_sid))
4747                 return NT_STATUS_CANNOT_DELETE;
4748
4749         /* check if the user exists before trying to delete */
4750         if ( !(sam_pass = samu_new( NULL )) ) {
4751                 return NT_STATUS_NO_MEMORY;
4752         }
4753
4754         become_root();
4755         ret = pdb_getsampwsid(sam_pass, &user_sid);
4756         unbecome_root();
4757
4758         if( !ret ) {
4759                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4760                         sid_string_dbg(&user_sid)));
4761                 TALLOC_FREE(sam_pass);
4762                 return NT_STATUS_NO_SUCH_USER;
4763         }
4764
4765         acb_info = pdb_get_acct_ctrl(sam_pass);
4766
4767         /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4768         if ( acb_info & ACB_WSTRUST ) {
4769                 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
4770         } else {
4771                 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
4772         }
4773
4774         /******** BEGIN SeAddUsers BLOCK *********/
4775
4776         if ( can_add_accounts )
4777                 become_root();
4778
4779         status = pdb_delete_user(p->mem_ctx, sam_pass);
4780
4781         if ( can_add_accounts )
4782                 unbecome_root();
4783
4784         /******** END SeAddUsers BLOCK *********/
4785
4786         if ( !NT_STATUS_IS_OK(status) ) {
4787                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4788                          "user %s: %s.\n", pdb_get_username(sam_pass),
4789                          nt_errstr(status)));
4790                 TALLOC_FREE(sam_pass);
4791                 return status;
4792         }
4793
4794
4795         TALLOC_FREE(sam_pass);
4796
4797         if (!close_policy_hnd(p, r->in.user_handle))
4798                 return NT_STATUS_OBJECT_NAME_INVALID;
4799
4800         ZERO_STRUCTP(r->out.user_handle);
4801
4802         force_flush_samr_cache(disp_info);
4803
4804         return NT_STATUS_OK;
4805 }
4806
4807 /*********************************************************************
4808  _samr_DeleteDomainGroup
4809 *********************************************************************/
4810
4811 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4812                                  struct samr_DeleteDomainGroup *r)
4813 {
4814         NTSTATUS status;
4815         DOM_SID group_sid;
4816         uint32 group_rid;
4817         uint32 acc_granted;
4818         SE_PRIV se_rights;
4819         bool can_add_accounts;
4820         DISP_INFO *disp_info = NULL;
4821
4822         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4823
4824         /* Find the policy handle. Open a policy on it. */
4825         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4826                 return NT_STATUS_INVALID_HANDLE;
4827
4828         status = access_check_samr_function(acc_granted,
4829                                             STD_RIGHT_DELETE_ACCESS,
4830                                             "_samr_DeleteDomainGroup");
4831         if (!NT_STATUS_IS_OK(status)) {
4832                 return status;
4833         }
4834
4835         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4836
4837         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4838                                 &group_rid)) {
4839                 return NT_STATUS_NO_SUCH_GROUP;
4840         }
4841
4842         se_priv_copy( &se_rights, &se_add_users );
4843         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4844
4845         /******** BEGIN SeAddUsers BLOCK *********/
4846
4847         if ( can_add_accounts )
4848                 become_root();
4849
4850         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4851
4852         if ( can_add_accounts )
4853                 unbecome_root();
4854
4855         /******** END SeAddUsers BLOCK *********/
4856
4857         if ( !NT_STATUS_IS_OK(status) ) {
4858                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4859                          "entry for group %s: %s\n",
4860                          sid_string_dbg(&group_sid),
4861                          nt_errstr(status)));
4862                 return status;
4863         }
4864
4865         if (!close_policy_hnd(p, r->in.group_handle))
4866                 return NT_STATUS_OBJECT_NAME_INVALID;
4867
4868         force_flush_samr_cache(disp_info);
4869
4870         return NT_STATUS_OK;
4871 }
4872
4873 /*********************************************************************
4874  _samr_DeleteDomAlias
4875 *********************************************************************/
4876
4877 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4878                               struct samr_DeleteDomAlias *r)
4879 {
4880         DOM_SID alias_sid;
4881         uint32 acc_granted;
4882         SE_PRIV se_rights;
4883         bool can_add_accounts;
4884         NTSTATUS status;
4885         DISP_INFO *disp_info = NULL;
4886
4887         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4888
4889         /* Find the policy handle. Open a policy on it. */
4890         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4891                 return NT_STATUS_INVALID_HANDLE;
4892
4893         /* copy the handle to the outgoing reply */
4894
4895         memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4896
4897         status = access_check_samr_function(acc_granted,
4898                                             STD_RIGHT_DELETE_ACCESS,
4899                                             "_samr_DeleteDomAlias");
4900         if (!NT_STATUS_IS_OK(status)) {
4901                 return status;
4902         }
4903
4904         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4905
4906         /* Don't let Windows delete builtin groups */
4907
4908         if ( sid_check_is_in_builtin( &alias_sid ) ) {
4909                 return NT_STATUS_SPECIAL_ACCOUNT;
4910         }
4911
4912         if (!sid_check_is_in_our_domain(&alias_sid))
4913                 return NT_STATUS_NO_SUCH_ALIAS;
4914
4915         DEBUG(10, ("lookup on Local SID\n"));
4916
4917         se_priv_copy( &se_rights, &se_add_users );
4918         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4919
4920         /******** BEGIN SeAddUsers BLOCK *********/
4921
4922         if ( can_add_accounts )
4923                 become_root();
4924
4925         /* Have passdb delete the alias */
4926         status = pdb_delete_alias(&alias_sid);
4927
4928         if ( can_add_accounts )
4929                 unbecome_root();
4930
4931         /******** END SeAddUsers BLOCK *********/
4932
4933         if ( !NT_STATUS_IS_OK(status))
4934                 return status;
4935
4936         if (!close_policy_hnd(p, r->in.alias_handle))
4937                 return NT_STATUS_OBJECT_NAME_INVALID;
4938
4939         force_flush_samr_cache(disp_info);
4940
4941         return NT_STATUS_OK;
4942 }
4943
4944 /*********************************************************************
4945  _samr_CreateDomainGroup
4946 *********************************************************************/
4947
4948 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4949                                  struct samr_CreateDomainGroup *r)
4950
4951 {
4952         NTSTATUS status;
4953         DOM_SID dom_sid;
4954         DOM_SID info_sid;
4955         const char *name;
4956         struct samr_info *info;
4957         uint32 acc_granted;
4958         SE_PRIV se_rights;
4959         bool can_add_accounts;
4960         DISP_INFO *disp_info = NULL;
4961
4962         /* Find the policy handle. Open a policy on it. */
4963         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4964                 return NT_STATUS_INVALID_HANDLE;
4965
4966         status = access_check_samr_function(acc_granted,
4967                                             SAMR_DOMAIN_ACCESS_CREATE_GROUP,
4968                                             "_samr_CreateDomainGroup");
4969         if (!NT_STATUS_IS_OK(status)) {
4970                 return status;
4971         }
4972
4973         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4974                 return NT_STATUS_ACCESS_DENIED;
4975
4976         name = r->in.name->string;
4977         if (name == NULL) {
4978                 return NT_STATUS_NO_MEMORY;
4979         }
4980
4981         status = can_create(p->mem_ctx, name);
4982         if (!NT_STATUS_IS_OK(status)) {
4983                 return status;
4984         }
4985
4986         se_priv_copy( &se_rights, &se_add_users );
4987         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4988
4989         /******** BEGIN SeAddUsers BLOCK *********/
4990
4991         if ( can_add_accounts )
4992                 become_root();
4993
4994         /* check that we successfully create the UNIX group */
4995
4996         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
4997
4998         if ( can_add_accounts )
4999                 unbecome_root();
5000
5001         /******** END SeAddUsers BLOCK *********/
5002
5003         /* check if we should bail out here */
5004
5005         if ( !NT_STATUS_IS_OK(status) )
5006                 return status;
5007
5008         sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5009
5010         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5011                 return NT_STATUS_NO_MEMORY;
5012
5013         /* they created it; let the user do what he wants with it */
5014
5015         info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5016
5017         /* get a (unique) handle.  open a policy on it. */
5018         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5019                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5020
5021         force_flush_samr_cache(disp_info);
5022
5023         return NT_STATUS_OK;
5024 }
5025
5026 /*********************************************************************
5027  _samr_CreateDomAlias
5028 *********************************************************************/
5029
5030 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5031                               struct samr_CreateDomAlias *r)
5032 {
5033         DOM_SID dom_sid;
5034         DOM_SID info_sid;
5035         const char *name = NULL;
5036         struct samr_info *info;
5037         uint32 acc_granted;
5038         gid_t gid;
5039         NTSTATUS result;
5040         SE_PRIV se_rights;
5041         bool can_add_accounts;
5042         DISP_INFO *disp_info = NULL;
5043
5044         /* Find the policy handle. Open a policy on it. */
5045         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5046                 return NT_STATUS_INVALID_HANDLE;
5047
5048         result = access_check_samr_function(acc_granted,
5049                                             SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
5050                                             "_samr_CreateDomAlias");
5051         if (!NT_STATUS_IS_OK(result)) {
5052                 return result;
5053         }
5054
5055         if (!sid_equal(&dom_sid, get_global_sam_sid()))
5056                 return NT_STATUS_ACCESS_DENIED;
5057
5058         name = r->in.alias_name->string;
5059
5060         se_priv_copy( &se_rights, &se_add_users );
5061         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5062
5063         result = can_create(p->mem_ctx, name);
5064         if (!NT_STATUS_IS_OK(result)) {
5065                 return result;
5066         }
5067
5068         /******** BEGIN SeAddUsers BLOCK *********/
5069
5070         if ( can_add_accounts )
5071                 become_root();
5072
5073         /* Have passdb create the alias */
5074         result = pdb_create_alias(name, r->out.rid);
5075
5076         if ( can_add_accounts )
5077                 unbecome_root();
5078
5079         /******** END SeAddUsers BLOCK *********/
5080
5081         if (!NT_STATUS_IS_OK(result)) {
5082                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5083                            nt_errstr(result)));
5084                 return result;
5085         }
5086
5087         sid_copy(&info_sid, get_global_sam_sid());
5088         sid_append_rid(&info_sid, *r->out.rid);
5089
5090         if (!sid_to_gid(&info_sid, &gid)) {
5091                 DEBUG(10, ("Could not find alias just created\n"));
5092                 return NT_STATUS_ACCESS_DENIED;
5093         }
5094
5095         /* check if the group has been successfully created */
5096         if ( getgrgid(gid) == NULL ) {
5097                 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5098                            gid));
5099                 return NT_STATUS_ACCESS_DENIED;
5100         }
5101
5102         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5103                 return NT_STATUS_NO_MEMORY;
5104
5105         /* they created it; let the user do what he wants with it */
5106
5107         info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5108
5109         /* get a (unique) handle.  open a policy on it. */
5110         if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5111                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5112
5113         force_flush_samr_cache(disp_info);
5114
5115         return NT_STATUS_OK;
5116 }
5117
5118 /*********************************************************************
5119  _samr_QueryGroupInfo
5120 *********************************************************************/
5121
5122 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5123                               struct samr_QueryGroupInfo *r)
5124 {
5125         NTSTATUS status;
5126         DOM_SID group_sid;
5127         GROUP_MAP map;
5128         union samr_GroupInfo *info = NULL;
5129         uint32 acc_granted;
5130         bool ret;
5131         uint32_t attributes = SE_GROUP_MANDATORY |
5132                               SE_GROUP_ENABLED_BY_DEFAULT |
5133                               SE_GROUP_ENABLED;
5134         const char *group_name = NULL;
5135         const char *group_description = NULL;
5136
5137         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5138                 return NT_STATUS_INVALID_HANDLE;
5139
5140         status = access_check_samr_function(acc_granted,
5141                                             SAMR_GROUP_ACCESS_LOOKUP_INFO,
5142                                             "_samr_QueryGroupInfo");
5143         if (!NT_STATUS_IS_OK(status)) {
5144                 return status;
5145         }
5146
5147         become_root();
5148         ret = get_domain_group_from_sid(group_sid, &map);
5149         unbecome_root();
5150         if (!ret)
5151                 return NT_STATUS_INVALID_HANDLE;
5152
5153         /* FIXME: map contains fstrings */
5154         group_name = talloc_strdup(r, map.nt_name);
5155         group_description = talloc_strdup(r, map.comment);
5156
5157         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5158         if (!info) {
5159                 return NT_STATUS_NO_MEMORY;
5160         }
5161
5162         switch (r->in.level) {
5163                 case 1: {
5164                         uint32 *members;
5165                         size_t num_members;
5166
5167                         become_root();
5168                         status = pdb_enum_group_members(
5169                                 p->mem_ctx, &group_sid, &members, &num_members);
5170                         unbecome_root();
5171
5172                         if (!NT_STATUS_IS_OK(status)) {
5173                                 return status;
5174                         }
5175
5176                         init_samr_group_info1(&info->all,
5177                                               group_name,
5178                                               attributes,
5179                                               num_members,
5180                                               group_description);
5181                         break;
5182                 }
5183                 case 2:
5184                         init_samr_group_info2(&info->name,
5185                                               group_name);
5186                         break;
5187                 case 3:
5188                         init_samr_group_info3(&info->attributes,
5189                                               attributes);
5190                         break;
5191                 case 4:
5192                         init_samr_group_info4(&info->description,
5193                                               group_description);
5194                         break;
5195                 case 5: {
5196                         /*
5197                         uint32 *members;
5198                         size_t num_members;
5199                         */
5200
5201                         /*
5202                         become_root();
5203                         status = pdb_enum_group_members(
5204                                 p->mem_ctx, &group_sid, &members, &num_members);
5205                         unbecome_root();
5206
5207                         if (!NT_STATUS_IS_OK(status)) {
5208                                 return status;
5209                         }
5210                         */
5211                         init_samr_group_info5(&info->all2,
5212                                               group_name,
5213                                               attributes,
5214                                               0, /* num_members - in w2k3 this is always 0 */
5215                                               group_description);
5216
5217                         break;
5218                 }
5219                 default:
5220                         return NT_STATUS_INVALID_INFO_CLASS;
5221         }
5222
5223         *r->out.info = info;
5224
5225         return NT_STATUS_OK;
5226 }
5227
5228 /*********************************************************************
5229  _samr_SetGroupInfo
5230 *********************************************************************/
5231
5232 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5233                             struct samr_SetGroupInfo *r)
5234 {
5235         DOM_SID group_sid;
5236         GROUP_MAP map;
5237         uint32 acc_granted;
5238         NTSTATUS status;
5239         bool ret;
5240         bool can_mod_accounts;
5241         DISP_INFO *disp_info = NULL;
5242
5243         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5244                 return NT_STATUS_INVALID_HANDLE;
5245
5246         status = access_check_samr_function(acc_granted,
5247                                             SAMR_GROUP_ACCESS_SET_INFO,
5248                                             "_samr_SetGroupInfo");
5249         if (!NT_STATUS_IS_OK(status)) {
5250                 return status;
5251         }
5252
5253         become_root();
5254         ret = get_domain_group_from_sid(group_sid, &map);
5255         unbecome_root();
5256         if (!ret)
5257                 return NT_STATUS_NO_SUCH_GROUP;
5258
5259         switch (r->in.level) {
5260                 case 1:
5261                         fstrcpy(map.comment, r->in.info->all.description.string);
5262                         break;
5263                 case 2:
5264                         /* group rename is not supported yet */
5265                         return NT_STATUS_NOT_SUPPORTED;
5266                 case 4:
5267                         fstrcpy(map.comment, r->in.info->description.string);
5268                         break;
5269                 default:
5270                         return NT_STATUS_INVALID_INFO_CLASS;
5271         }
5272
5273         can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5274
5275         /******** BEGIN SeAddUsers BLOCK *********/
5276
5277         if ( can_mod_accounts )
5278                 become_root();
5279
5280         status = pdb_update_group_mapping_entry(&map);
5281
5282         if ( can_mod_accounts )
5283                 unbecome_root();
5284
5285         /******** End SeAddUsers BLOCK *********/
5286
5287         if (NT_STATUS_IS_OK(status)) {
5288                 force_flush_samr_cache(disp_info);
5289         }
5290
5291         return status;
5292 }
5293
5294 /*********************************************************************
5295  _samr_SetAliasInfo
5296 *********************************************************************/
5297
5298 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5299                             struct samr_SetAliasInfo *r)
5300 {
5301         DOM_SID group_sid;
5302         struct acct_info info;
5303         uint32 acc_granted;
5304         bool can_mod_accounts;
5305         NTSTATUS status;
5306         DISP_INFO *disp_info = NULL;
5307
5308         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5309                 return NT_STATUS_INVALID_HANDLE;
5310
5311         status = access_check_samr_function(acc_granted,
5312                                             SAMR_ALIAS_ACCESS_SET_INFO,
5313                                             "_samr_SetAliasInfo");
5314         if (!NT_STATUS_IS_OK(status)) {
5315                 return status;
5316         }
5317
5318         /* get the current group information */
5319
5320         become_root();
5321         status = pdb_get_aliasinfo( &group_sid, &info );
5322         unbecome_root();
5323
5324         if ( !NT_STATUS_IS_OK(status))
5325                 return status;
5326
5327         switch (r->in.level) {
5328                 case ALIASINFONAME:
5329                 {
5330                         fstring group_name;
5331
5332                         /* We currently do not support renaming groups in the
5333                            the BUILTIN domain.  Refer to util_builtin.c to understand
5334                            why.  The eventually needs to be fixed to be like Windows
5335                            where you can rename builtin groups, just not delete them */
5336
5337                         if ( sid_check_is_in_builtin( &group_sid ) ) {
5338                                 return NT_STATUS_SPECIAL_ACCOUNT;
5339                         }
5340
5341                         /* There has to be a valid name (and it has to be different) */
5342
5343                         if ( !r->in.info->name.string )
5344                                 return NT_STATUS_INVALID_PARAMETER;
5345
5346                         /* If the name is the same just reply "ok".  Yes this
5347                            doesn't allow you to change the case of a group name. */
5348
5349                         if ( strequal( r->in.info->name.string, info.acct_name ) )
5350                                 return NT_STATUS_OK;
5351
5352                         fstrcpy( info.acct_name, r->in.info->name.string);
5353
5354                         /* make sure the name doesn't already exist as a user
5355                            or local group */
5356
5357                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5358                         status = can_create( p->mem_ctx, group_name );
5359                         if ( !NT_STATUS_IS_OK( status ) )
5360                                 return status;
5361                         break;
5362                 }
5363                 case ALIASINFODESCRIPTION:
5364                         if (r->in.info->description.string) {
5365                                 fstrcpy(info.acct_desc,
5366                                         r->in.info->description.string);
5367                         } else {
5368                                 fstrcpy( info.acct_desc, "" );
5369                         }
5370                         break;
5371                 default:
5372                         return NT_STATUS_INVALID_INFO_CLASS;
5373         }
5374
5375         can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5376
5377         /******** BEGIN SeAddUsers BLOCK *********/
5378
5379         if ( can_mod_accounts )
5380                 become_root();
5381
5382         status = pdb_set_aliasinfo( &group_sid, &info );
5383
5384         if ( can_mod_accounts )
5385                 unbecome_root();
5386
5387         /******** End SeAddUsers BLOCK *********/
5388
5389         if (NT_STATUS_IS_OK(status))
5390                 force_flush_samr_cache(disp_info);
5391
5392         return status;
5393 }
5394
5395 /****************************************************************
5396  _samr_GetDomPwInfo
5397 ****************************************************************/
5398
5399 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5400                             struct samr_GetDomPwInfo *r)
5401 {
5402         uint32_t min_password_length = 0;
5403         uint32_t password_properties = 0;
5404
5405         /* Perform access check.  Since this rpc does not require a
5406            policy handle it will not be caught by the access checks on
5407            SAMR_CONNECT or SAMR_CONNECT_ANON. */
5408
5409         if (!pipe_access_check(p)) {
5410                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5411                 return NT_STATUS_ACCESS_DENIED;
5412         }
5413
5414         become_root();
5415         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5416                                &min_password_length);
5417         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5418                                &password_properties);
5419         unbecome_root();
5420
5421         if (lp_check_password_script() && *lp_check_password_script()) {
5422                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5423         }
5424
5425         r->out.info->min_password_length = min_password_length;
5426         r->out.info->password_properties = password_properties;
5427
5428         return NT_STATUS_OK;
5429 }
5430
5431 /*********************************************************************
5432  _samr_OpenGroup
5433 *********************************************************************/
5434
5435 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5436                          struct samr_OpenGroup *r)
5437
5438 {
5439         DOM_SID sid;
5440         DOM_SID info_sid;
5441         GROUP_MAP map;
5442         struct samr_info *info;
5443         SEC_DESC         *psd = NULL;
5444         uint32            acc_granted;
5445         uint32            des_access = r->in.access_mask;
5446         size_t            sd_size;
5447         NTSTATUS          status;
5448         fstring sid_string;
5449         bool ret;
5450         SE_PRIV se_rights;
5451
5452         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5453                 return NT_STATUS_INVALID_HANDLE;
5454
5455         status = access_check_samr_function(acc_granted,
5456                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
5457                                             "_samr_OpenGroup");
5458
5459         if ( !NT_STATUS_IS_OK(status) )
5460                 return status;
5461
5462         /*check if access can be granted as requested by client. */
5463         map_max_allowed_access(p->server_info->ptok, &des_access);
5464
5465         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5466         se_map_generic(&des_access,&grp_generic_mapping);
5467
5468         se_priv_copy( &se_rights, &se_add_users );
5469
5470         status = access_check_samr_object(psd, p->server_info->ptok,
5471                 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5472                 &acc_granted, "_samr_OpenGroup");
5473
5474         if ( !NT_STATUS_IS_OK(status) )
5475                 return status;
5476
5477         /* this should not be hard-coded like this */
5478
5479         if (!sid_equal(&sid, get_global_sam_sid()))
5480                 return NT_STATUS_ACCESS_DENIED;
5481
5482         sid_copy(&info_sid, get_global_sam_sid());
5483         sid_append_rid(&info_sid, r->in.rid);
5484         sid_to_fstring(sid_string, &info_sid);
5485
5486         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5487                 return NT_STATUS_NO_MEMORY;
5488
5489         info->acc_granted = acc_granted;
5490
5491         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5492
5493         /* check if that group really exists */
5494         become_root();
5495         ret = get_domain_group_from_sid(info->sid, &map);
5496         unbecome_root();
5497         if (!ret)
5498                 return NT_STATUS_NO_SUCH_GROUP;
5499
5500         /* get a (unique) handle.  open a policy on it. */
5501         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5502                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5503
5504         return NT_STATUS_OK;
5505 }
5506
5507 /*********************************************************************
5508  _samr_RemoveMemberFromForeignDomain
5509 *********************************************************************/
5510
5511 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5512                                              struct samr_RemoveMemberFromForeignDomain *r)
5513 {
5514         DOM_SID                 delete_sid, domain_sid;
5515         uint32                  acc_granted;
5516         NTSTATUS                result;
5517         DISP_INFO *disp_info = NULL;
5518
5519         sid_copy( &delete_sid, r->in.sid );
5520
5521         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5522                 sid_string_dbg(&delete_sid)));
5523
5524         /* Find the policy handle. Open a policy on it. */
5525
5526         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5527                                      &acc_granted, &disp_info))
5528                 return NT_STATUS_INVALID_HANDLE;
5529
5530         result = access_check_samr_function(acc_granted,
5531                                             STD_RIGHT_DELETE_ACCESS,
5532                                             "_samr_RemoveMemberFromForeignDomain");
5533
5534         if (!NT_STATUS_IS_OK(result))
5535                 return result;
5536
5537         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5538                   sid_string_dbg(&domain_sid)));
5539
5540         /* we can only delete a user from a group since we don't have
5541            nested groups anyways.  So in the latter case, just say OK */
5542
5543         /* TODO: The above comment nowadays is bogus. Since we have nested
5544          * groups now, and aliases members are never reported out of the unix
5545          * group membership, the "just say OK" makes this call a no-op. For
5546          * us. This needs fixing however. */
5547
5548         /* I've only ever seen this in the wild when deleting a user from
5549          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5550          * is the user about to be deleted. I very much suspect this is the
5551          * only application of this call. To verify this, let people report
5552          * other cases. */
5553
5554         if (!sid_check_is_builtin(&domain_sid)) {
5555                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5556                          "global_sam_sid() = %s\n",
5557                          sid_string_dbg(&domain_sid),
5558                          sid_string_dbg(get_global_sam_sid())));
5559                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5560                 return NT_STATUS_OK;
5561         }
5562
5563         force_flush_samr_cache(disp_info);
5564
5565         result = NT_STATUS_OK;
5566
5567         return result;
5568 }
5569
5570 /*******************************************************************
5571  _samr_QueryDomainInfo2
5572  ********************************************************************/
5573
5574 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5575                                 struct samr_QueryDomainInfo2 *r)
5576 {
5577         struct samr_QueryDomainInfo q;
5578
5579         q.in.domain_handle      = r->in.domain_handle;
5580         q.in.level              = r->in.level;
5581
5582         q.out.info              = r->out.info;
5583
5584         return _samr_QueryDomainInfo(p, &q);
5585 }
5586
5587 /*******************************************************************
5588  _samr_SetDomainInfo
5589  ********************************************************************/
5590
5591 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5592                              struct samr_SetDomainInfo *r)
5593 {
5594         struct samr_info *info = NULL;
5595         time_t u_expire, u_min_age;
5596         time_t u_logout;
5597         time_t u_lock_duration, u_reset_time;
5598         NTSTATUS result;
5599
5600         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5601
5602         /* find the policy handle.  open a policy on it. */
5603         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5604                 return NT_STATUS_INVALID_HANDLE;
5605
5606         /* We do have different access bits for info
5607          * levels here, but we're really just looking for
5608          * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5609          * this maps to different specific bits. So
5610          * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
5611          * set we are ok. */
5612
5613         result = access_check_samr_function(info->acc_granted,
5614                                             SAMR_DOMAIN_ACCESS_SET_INFO_1,
5615                                             "_samr_SetDomainInfo");
5616
5617         if (!NT_STATUS_IS_OK(result))
5618                 return result;
5619
5620         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5621
5622         switch (r->in.level) {
5623                 case 0x01:
5624                         u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5625                         u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5626                         pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5627                         pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5628                         pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5629                         pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5630                         pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5631                         break;
5632                 case 0x02:
5633                         break;
5634                 case 0x03:
5635                         u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5636                         pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5637                         break;
5638                 case 0x05:
5639                         break;
5640                 case 0x06:
5641                         break;
5642                 case 0x07:
5643                         break;
5644                 case 0x0c:
5645                         u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5646                         if (u_lock_duration != -1)
5647                                 u_lock_duration /= 60;
5648
5649                         u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5650
5651                         pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5652                         pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5653                         pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5654                         break;
5655                 default:
5656                         return NT_STATUS_INVALID_INFO_CLASS;
5657         }
5658
5659         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5660
5661         return NT_STATUS_OK;
5662 }
5663
5664 /****************************************************************
5665  _samr_GetDisplayEnumerationIndex
5666 ****************************************************************/
5667
5668 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5669                                           struct samr_GetDisplayEnumerationIndex *r)
5670 {
5671         struct samr_info *info = NULL;
5672         uint32_t max_entries = (uint32_t) -1;
5673         uint32_t enum_context = 0;
5674         int i;
5675         uint32_t num_account = 0;
5676         struct samr_displayentry *entries = NULL;
5677         NTSTATUS status;
5678
5679         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5680
5681         /* find the policy handle.  open a policy on it. */
5682         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5683                 return NT_STATUS_INVALID_HANDLE;
5684         }
5685
5686         status = access_check_samr_function(info->acc_granted,
5687                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
5688                                             "_samr_GetDisplayEnumerationIndex");
5689         if (!NT_STATUS_IS_OK(status)) {
5690                 return status;
5691         }
5692
5693         if ((r->in.level < 1) || (r->in.level > 3)) {
5694                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5695                         "Unknown info level (%u)\n",
5696                         r->in.level));
5697                 return NT_STATUS_INVALID_INFO_CLASS;
5698         }
5699
5700         become_root();
5701
5702         /* The following done as ROOT. Don't return without unbecome_root(). */
5703
5704         switch (r->in.level) {
5705         case 1:
5706                 if (info->disp_info->users == NULL) {
5707                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
5708                         if (info->disp_info->users == NULL) {
5709                                 unbecome_root();
5710                                 return NT_STATUS_ACCESS_DENIED;
5711                         }
5712                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5713                                 "starting user enumeration at index %u\n",
5714                                 (unsigned int)enum_context));
5715                 } else {
5716                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5717                                 "using cached user enumeration at index %u\n",
5718                                 (unsigned int)enum_context));
5719                 }
5720                 num_account = pdb_search_entries(info->disp_info->users,
5721                                                  enum_context, max_entries,
5722                                                  &entries);
5723                 break;
5724         case 2:
5725                 if (info->disp_info->machines == NULL) {
5726                         info->disp_info->machines =
5727                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5728                         if (info->disp_info->machines == NULL) {
5729                                 unbecome_root();
5730                                 return NT_STATUS_ACCESS_DENIED;
5731                         }
5732                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5733                                 "starting machine enumeration at index %u\n",
5734                                 (unsigned int)enum_context));
5735                 } else {
5736                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5737                                 "using cached machine enumeration at index %u\n",
5738                                 (unsigned int)enum_context));
5739                 }
5740                 num_account = pdb_search_entries(info->disp_info->machines,
5741                                                  enum_context, max_entries,
5742                                                  &entries);
5743                 break;
5744         case 3:
5745                 if (info->disp_info->groups == NULL) {
5746                         info->disp_info->groups = pdb_search_groups();
5747                         if (info->disp_info->groups == NULL) {
5748                                 unbecome_root();
5749                                 return NT_STATUS_ACCESS_DENIED;
5750                         }
5751                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5752                                 "starting group enumeration at index %u\n",
5753                                 (unsigned int)enum_context));
5754                 } else {
5755                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5756                                 "using cached group enumeration at index %u\n",
5757                                 (unsigned int)enum_context));
5758                 }
5759                 num_account = pdb_search_entries(info->disp_info->groups,
5760                                                  enum_context, max_entries,
5761                                                  &entries);
5762                 break;
5763         default:
5764                 unbecome_root();
5765                 smb_panic("info class changed");
5766                 break;
5767         }
5768
5769         unbecome_root();
5770
5771         /* Ensure we cache this enumeration. */
5772         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5773
5774         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5775                 r->in.name->string));
5776
5777         for (i=0; i<num_account; i++) {
5778                 if (strequal(entries[i].account_name, r->in.name->string)) {
5779                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5780                                 "found %s at idx %d\n",
5781                                 r->in.name->string, i));
5782                         *r->out.idx = i;
5783                         return NT_STATUS_OK;
5784                 }
5785         }
5786
5787         /* assuming account_name lives at the very end */
5788         *r->out.idx = num_account;
5789
5790         return NT_STATUS_NO_MORE_ENTRIES;
5791 }
5792
5793 /****************************************************************
5794  _samr_GetDisplayEnumerationIndex2
5795 ****************************************************************/
5796
5797 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5798                                            struct samr_GetDisplayEnumerationIndex2 *r)
5799 {
5800         struct samr_GetDisplayEnumerationIndex q;
5801
5802         q.in.domain_handle      = r->in.domain_handle;
5803         q.in.level              = r->in.level;
5804         q.in.name               = r->in.name;
5805
5806         q.out.idx               = r->out.idx;
5807
5808         return _samr_GetDisplayEnumerationIndex(p, &q);
5809 }
5810
5811 /****************************************************************
5812 ****************************************************************/
5813
5814 NTSTATUS _samr_Shutdown(pipes_struct *p,
5815                         struct samr_Shutdown *r)
5816 {
5817         p->rng_fault_state = true;
5818         return NT_STATUS_NOT_IMPLEMENTED;
5819 }
5820
5821 /****************************************************************
5822 ****************************************************************/
5823
5824 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5825                                           struct samr_SetMemberAttributesOfGroup *r)
5826 {
5827         p->rng_fault_state = true;
5828         return NT_STATUS_NOT_IMPLEMENTED;
5829 }
5830
5831 /****************************************************************
5832 ****************************************************************/
5833
5834 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5835                                   struct samr_ChangePasswordUser *r)
5836 {
5837         p->rng_fault_state = true;
5838         return NT_STATUS_NOT_IMPLEMENTED;
5839 }
5840
5841 /****************************************************************
5842 ****************************************************************/
5843
5844 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5845                                           struct samr_TestPrivateFunctionsDomain *r)
5846 {
5847         p->rng_fault_state = true;
5848         return NT_STATUS_NOT_IMPLEMENTED;
5849 }
5850
5851 /****************************************************************
5852 ****************************************************************/
5853
5854 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5855                                         struct samr_TestPrivateFunctionsUser *r)
5856 {
5857         p->rng_fault_state = true;
5858         return NT_STATUS_NOT_IMPLEMENTED;
5859 }
5860
5861 /****************************************************************
5862 ****************************************************************/
5863
5864 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5865                                          struct samr_AddMultipleMembersToAlias *r)
5866 {
5867         p->rng_fault_state = true;
5868         return NT_STATUS_NOT_IMPLEMENTED;
5869 }
5870
5871 /****************************************************************
5872 ****************************************************************/
5873
5874 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5875                                               struct samr_RemoveMultipleMembersFromAlias *r)
5876 {
5877         p->rng_fault_state = true;
5878         return NT_STATUS_NOT_IMPLEMENTED;
5879 }
5880
5881 /****************************************************************
5882 ****************************************************************/
5883
5884 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5885                                       struct samr_OemChangePasswordUser2 *r)
5886 {
5887         p->rng_fault_state = true;
5888         return NT_STATUS_NOT_IMPLEMENTED;
5889 }
5890
5891 /****************************************************************
5892 ****************************************************************/
5893
5894 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5895                                      struct samr_SetBootKeyInformation *r)
5896 {
5897         p->rng_fault_state = true;
5898         return NT_STATUS_NOT_IMPLEMENTED;
5899 }
5900
5901 /****************************************************************
5902 ****************************************************************/
5903
5904 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5905                                      struct samr_GetBootKeyInformation *r)
5906 {
5907         p->rng_fault_state = true;
5908         return NT_STATUS_NOT_IMPLEMENTED;
5909 }
5910
5911 /****************************************************************
5912 ****************************************************************/
5913
5914 NTSTATUS _samr_Connect3(pipes_struct *p,
5915                         struct samr_Connect3 *r)
5916 {
5917         p->rng_fault_state = true;
5918         return NT_STATUS_NOT_IMPLEMENTED;
5919 }
5920
5921 /****************************************************************
5922 ****************************************************************/
5923
5924 NTSTATUS _samr_RidToSid(pipes_struct *p,
5925                         struct samr_RidToSid *r)
5926 {
5927         p->rng_fault_state = true;
5928         return NT_STATUS_NOT_IMPLEMENTED;
5929 }
5930
5931 /****************************************************************
5932 ****************************************************************/
5933
5934 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5935                                struct samr_SetDsrmPassword *r)
5936 {
5937         p->rng_fault_state = true;
5938         return NT_STATUS_NOT_IMPLEMENTED;
5939 }
5940
5941 /****************************************************************
5942 ****************************************************************/
5943
5944 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5945                                 struct samr_ValidatePassword *r)
5946 {
5947         p->rng_fault_state = true;
5948         return NT_STATUS_NOT_IMPLEMENTED;
5949 }