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