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