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