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