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