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