Now that we have p->server_info, use p->server_info->user_session_key
[samba.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-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(type);
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->server_info->user_session_key.length) {
4210                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4211                         }
4212                         SamOEMhashBlob(info->info23.password.data, 516,
4213                                        &p->server_info->user_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->server_info->user_session_key.length) {
4223                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4224                         }
4225                         SamOEMhashBlob(info->info24.password.data,
4226                                        516,
4227                                        &p->server_info->user_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->server_info->user_session_key.length) {
4239                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4240                         }
4241                         encode_or_decode_arc4_passwd_buffer(
4242                                 info->info25.password.data,
4243                                 &p->server_info->user_session_key);
4244
4245                         dump_data(100, info->info25.password.data, 532);
4246
4247                         status = set_user_info_25(p->mem_ctx,
4248                                                   &info->info25, pwd);
4249                         if (!NT_STATUS_IS_OK(status)) {
4250                                 goto done;
4251                         }
4252                         if (!set_user_info_pw(info->info25.password.data, pwd,
4253                                               switch_value)) {
4254                                 status = NT_STATUS_ACCESS_DENIED;
4255                         }
4256                         break;
4257
4258                 case 26:
4259                         if (!p->server_info->user_session_key.length) {
4260                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4261                         }
4262                         encode_or_decode_arc4_passwd_buffer(
4263                                 info->info26.password.data,
4264                                 &p->server_info->user_session_key);
4265
4266                         dump_data(100, info->info26.password.data, 516);
4267
4268                         if (!set_user_info_pw(info->info26.password.data, pwd,
4269                                               switch_value)) {
4270                                 status = NT_STATUS_ACCESS_DENIED;
4271                         }
4272                         break;
4273
4274                 default:
4275                         status = NT_STATUS_INVALID_INFO_CLASS;
4276         }
4277
4278  done:
4279
4280         if (has_enough_rights) {
4281                 unbecome_root();
4282         }
4283
4284         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4285
4286         if (NT_STATUS_IS_OK(status)) {
4287                 force_flush_samr_cache(disp_info);
4288         }
4289
4290         return status;
4291 }
4292
4293 /*******************************************************************
4294  _samr_SetUserInfo
4295  ********************************************************************/
4296
4297 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4298                            struct samr_SetUserInfo *r)
4299 {
4300         return samr_SetUserInfo_internal("_samr_SetUserInfo",
4301                                          p,
4302                                          r->in.user_handle,
4303                                          r->in.level,
4304                                          r->in.info);
4305 }
4306
4307 /*******************************************************************
4308  _samr_SetUserInfo2
4309  ********************************************************************/
4310
4311 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4312                             struct samr_SetUserInfo2 *r)
4313 {
4314         return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4315                                          p,
4316                                          r->in.user_handle,
4317                                          r->in.level,
4318                                          r->in.info);
4319 }
4320
4321 /*********************************************************************
4322  _samr_GetAliasMembership
4323 *********************************************************************/
4324
4325 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4326                                   struct samr_GetAliasMembership *r)
4327 {
4328         size_t num_alias_rids;
4329         uint32 *alias_rids;
4330         struct samr_info *info = NULL;
4331         size_t i;
4332
4333         NTSTATUS ntstatus1;
4334         NTSTATUS ntstatus2;
4335
4336         DOM_SID *members;
4337
4338         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4339
4340         /* find the policy handle.  open a policy on it. */
4341         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4342                 return NT_STATUS_INVALID_HANDLE;
4343
4344         ntstatus1 = access_check_samr_function(info->acc_granted,
4345                                                SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4346                                                "_samr_GetAliasMembership");
4347         ntstatus2 = access_check_samr_function(info->acc_granted,
4348                                                SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4349                                                "_samr_GetAliasMembership");
4350
4351         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4352                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4353                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4354                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4355                 }
4356         }
4357
4358         if (!sid_check_is_domain(&info->sid) &&
4359             !sid_check_is_builtin(&info->sid))
4360                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4361
4362         if (r->in.sids->num_sids) {
4363                 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4364
4365                 if (members == NULL)
4366                         return NT_STATUS_NO_MEMORY;
4367         } else {
4368                 members = NULL;
4369         }
4370
4371         for (i=0; i<r->in.sids->num_sids; i++)
4372                 sid_copy(&members[i], r->in.sids->sids[i].sid);
4373
4374         alias_rids = NULL;
4375         num_alias_rids = 0;
4376
4377         become_root();
4378         ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4379                                                r->in.sids->num_sids,
4380                                                &alias_rids, &num_alias_rids);
4381         unbecome_root();
4382
4383         if (!NT_STATUS_IS_OK(ntstatus1)) {
4384                 return ntstatus1;
4385         }
4386
4387         r->out.rids->count = num_alias_rids;
4388         r->out.rids->ids = alias_rids;
4389
4390         return NT_STATUS_OK;
4391 }
4392
4393 /*********************************************************************
4394  _samr_GetMembersInAlias
4395 *********************************************************************/
4396
4397 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4398                                  struct samr_GetMembersInAlias *r)
4399 {
4400         NTSTATUS status;
4401         size_t i;
4402         size_t num_sids = 0;
4403         struct lsa_SidPtr *sids = NULL;
4404         DOM_SID *pdb_sids = NULL;
4405
4406         DOM_SID alias_sid;
4407
4408         uint32 acc_granted;
4409
4410         /* find the policy handle.  open a policy on it. */
4411         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4412                 return NT_STATUS_INVALID_HANDLE;
4413
4414         status = access_check_samr_function(acc_granted,
4415                                             SA_RIGHT_ALIAS_GET_MEMBERS,
4416                                             "_samr_GetMembersInAlias");
4417         if (!NT_STATUS_IS_OK(status)) {
4418                 return status;
4419         }
4420
4421         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4422
4423         become_root();
4424         status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4425         unbecome_root();
4426
4427         if (!NT_STATUS_IS_OK(status)) {
4428                 return status;
4429         }
4430
4431         if (num_sids) {
4432                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4433                 if (sids == NULL) {
4434                         TALLOC_FREE(pdb_sids);
4435                         return NT_STATUS_NO_MEMORY;
4436                 }
4437         }
4438
4439         for (i = 0; i < num_sids; i++) {
4440                 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4441                 if (!sids[i].sid) {
4442                         TALLOC_FREE(pdb_sids);
4443                         return NT_STATUS_NO_MEMORY;
4444                 }
4445         }
4446
4447         r->out.sids->num_sids = num_sids;
4448         r->out.sids->sids = sids;
4449
4450         TALLOC_FREE(pdb_sids);
4451
4452         return NT_STATUS_OK;
4453 }
4454
4455 /*********************************************************************
4456  _samr_QueryGroupMember
4457 *********************************************************************/
4458
4459 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4460                                 struct samr_QueryGroupMember *r)
4461 {
4462         DOM_SID group_sid;
4463         size_t i, num_members;
4464
4465         uint32 *rid=NULL;
4466         uint32 *attr=NULL;
4467
4468         uint32 acc_granted;
4469
4470         NTSTATUS status;
4471         struct samr_RidTypeArray *rids = NULL;
4472
4473         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4474         if (!rids) {
4475                 return NT_STATUS_NO_MEMORY;
4476         }
4477
4478         /* find the policy handle.  open a policy on it. */
4479         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4480                 return NT_STATUS_INVALID_HANDLE;
4481
4482         status = access_check_samr_function(acc_granted,
4483                                             SA_RIGHT_GROUP_GET_MEMBERS,
4484                                             "_samr_QueryGroupMember");
4485         if (!NT_STATUS_IS_OK(status)) {
4486                 return status;
4487         }
4488
4489         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4490
4491         if (!sid_check_is_in_our_domain(&group_sid)) {
4492                 DEBUG(3, ("sid %s is not in our domain\n",
4493                           sid_string_dbg(&group_sid)));
4494                 return NT_STATUS_NO_SUCH_GROUP;
4495         }
4496
4497         DEBUG(10, ("lookup on Domain SID\n"));
4498
4499         become_root();
4500         status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4501                                         &rid, &num_members);
4502         unbecome_root();
4503
4504         if (!NT_STATUS_IS_OK(status))
4505                 return status;
4506
4507         if (num_members) {
4508                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4509                 if (attr == NULL) {
4510                         return NT_STATUS_NO_MEMORY;
4511                 }
4512         } else {
4513                 attr = NULL;
4514         }
4515
4516         for (i=0; i<num_members; i++)
4517                 attr[i] = SID_NAME_USER;
4518
4519         rids->count = num_members;
4520         rids->types = attr;
4521         rids->rids = rid;
4522
4523         *r->out.rids = rids;
4524
4525         return NT_STATUS_OK;
4526 }
4527
4528 /*********************************************************************
4529  _samr_AddAliasMember
4530 *********************************************************************/
4531
4532 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4533                               struct samr_AddAliasMember *r)
4534 {
4535         DOM_SID alias_sid;
4536         uint32 acc_granted;
4537         SE_PRIV se_rights;
4538         bool can_add_accounts;
4539         NTSTATUS status;
4540         DISP_INFO *disp_info = NULL;
4541
4542         /* Find the policy handle. Open a policy on it. */
4543         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4544                 return NT_STATUS_INVALID_HANDLE;
4545
4546         status = access_check_samr_function(acc_granted,
4547                                             SA_RIGHT_ALIAS_ADD_MEMBER,
4548                                             "_samr_AddAliasMember");
4549         if (!NT_STATUS_IS_OK(status)) {
4550                 return status;
4551         }
4552
4553         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4554
4555         se_priv_copy( &se_rights, &se_add_users );
4556         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4557
4558         /******** BEGIN SeAddUsers BLOCK *********/
4559
4560         if ( can_add_accounts )
4561                 become_root();
4562
4563         status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4564
4565         if ( can_add_accounts )
4566                 unbecome_root();
4567
4568         /******** END SeAddUsers BLOCK *********/
4569
4570         if (NT_STATUS_IS_OK(status)) {
4571                 force_flush_samr_cache(disp_info);
4572         }
4573
4574         return status;
4575 }
4576
4577 /*********************************************************************
4578  _samr_DeleteAliasMember
4579 *********************************************************************/
4580
4581 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4582                                  struct samr_DeleteAliasMember *r)
4583 {
4584         DOM_SID alias_sid;
4585         uint32 acc_granted;
4586         SE_PRIV se_rights;
4587         bool can_add_accounts;
4588         NTSTATUS status;
4589         DISP_INFO *disp_info = NULL;
4590
4591         /* Find the policy handle. Open a policy on it. */
4592         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4593                 return NT_STATUS_INVALID_HANDLE;
4594
4595         status = access_check_samr_function(acc_granted,
4596                                             SA_RIGHT_ALIAS_REMOVE_MEMBER,
4597                                             "_samr_DeleteAliasMember");
4598         if (!NT_STATUS_IS_OK(status)) {
4599                 return status;
4600         }
4601
4602         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4603                    sid_string_dbg(&alias_sid)));
4604
4605         se_priv_copy( &se_rights, &se_add_users );
4606         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4607
4608         /******** BEGIN SeAddUsers BLOCK *********/
4609
4610         if ( can_add_accounts )
4611                 become_root();
4612
4613         status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4614
4615         if ( can_add_accounts )
4616                 unbecome_root();
4617
4618         /******** END SeAddUsers BLOCK *********/
4619
4620         if (NT_STATUS_IS_OK(status)) {
4621                 force_flush_samr_cache(disp_info);
4622         }
4623
4624         return status;
4625 }
4626
4627 /*********************************************************************
4628  _samr_AddGroupMember
4629 *********************************************************************/
4630
4631 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4632                               struct samr_AddGroupMember *r)
4633 {
4634         NTSTATUS status;
4635         DOM_SID group_sid;
4636         uint32 group_rid;
4637         uint32 acc_granted;
4638         SE_PRIV se_rights;
4639         bool can_add_accounts;
4640         DISP_INFO *disp_info = NULL;
4641
4642         /* Find the policy handle. Open a policy on it. */
4643         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4644                 return NT_STATUS_INVALID_HANDLE;
4645
4646         status = access_check_samr_function(acc_granted,
4647                                             SA_RIGHT_GROUP_ADD_MEMBER,
4648                                             "_samr_AddGroupMember");
4649         if (!NT_STATUS_IS_OK(status)) {
4650                 return status;
4651         }
4652
4653         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4654
4655         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4656                                 &group_rid)) {
4657                 return NT_STATUS_INVALID_HANDLE;
4658         }
4659
4660         se_priv_copy( &se_rights, &se_add_users );
4661         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4662
4663         /******** BEGIN SeAddUsers BLOCK *********/
4664
4665         if ( can_add_accounts )
4666                 become_root();
4667
4668         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4669
4670         if ( can_add_accounts )
4671                 unbecome_root();
4672
4673         /******** END SeAddUsers BLOCK *********/
4674
4675         force_flush_samr_cache(disp_info);
4676
4677         return status;
4678 }
4679
4680 /*********************************************************************
4681  _samr_DeleteGroupMember
4682 *********************************************************************/
4683
4684 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4685                                  struct samr_DeleteGroupMember *r)
4686
4687 {
4688         NTSTATUS status;
4689         DOM_SID group_sid;
4690         uint32 group_rid;
4691         uint32 acc_granted;
4692         SE_PRIV se_rights;
4693         bool can_add_accounts;
4694         DISP_INFO *disp_info = NULL;
4695
4696         /*
4697          * delete the group member named r->in.rid
4698          * who is a member of the sid associated with the handle
4699          * the rid is a user's rid as the group is a domain group.
4700          */
4701
4702         /* Find the policy handle. Open a policy on it. */
4703         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4704                 return NT_STATUS_INVALID_HANDLE;
4705
4706         status = access_check_samr_function(acc_granted,
4707                                             SA_RIGHT_GROUP_REMOVE_MEMBER,
4708                                             "_samr_DeleteGroupMember");
4709         if (!NT_STATUS_IS_OK(status)) {
4710                 return status;
4711         }
4712
4713         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4714                                 &group_rid)) {
4715                 return NT_STATUS_INVALID_HANDLE;
4716         }
4717
4718         se_priv_copy( &se_rights, &se_add_users );
4719         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4720
4721         /******** BEGIN SeAddUsers BLOCK *********/
4722
4723         if ( can_add_accounts )
4724                 become_root();
4725
4726         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4727
4728         if ( can_add_accounts )
4729                 unbecome_root();
4730
4731         /******** END SeAddUsers BLOCK *********/
4732
4733         force_flush_samr_cache(disp_info);
4734
4735         return status;
4736 }
4737
4738 /*********************************************************************
4739  _samr_DeleteUser
4740 *********************************************************************/
4741
4742 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4743                           struct samr_DeleteUser *r)
4744 {
4745         NTSTATUS status;
4746         DOM_SID user_sid;
4747         struct samu *sam_pass=NULL;
4748         uint32 acc_granted;
4749         bool can_add_accounts;
4750         uint32 acb_info;
4751         DISP_INFO *disp_info = NULL;
4752         bool ret;
4753
4754         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4755
4756         /* Find the policy handle. Open a policy on it. */
4757         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4758                 return NT_STATUS_INVALID_HANDLE;
4759
4760         status = access_check_samr_function(acc_granted,
4761                                             STD_RIGHT_DELETE_ACCESS,
4762                                             "_samr_DeleteUser");
4763         if (!NT_STATUS_IS_OK(status)) {
4764                 return status;
4765         }
4766
4767         if (!sid_check_is_in_our_domain(&user_sid))
4768                 return NT_STATUS_CANNOT_DELETE;
4769
4770         /* check if the user exists before trying to delete */
4771         if ( !(sam_pass = samu_new( NULL )) ) {
4772                 return NT_STATUS_NO_MEMORY;
4773         }
4774
4775         become_root();
4776         ret = pdb_getsampwsid(sam_pass, &user_sid);
4777         unbecome_root();
4778
4779         if( !ret ) {
4780                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4781                         sid_string_dbg(&user_sid)));
4782                 TALLOC_FREE(sam_pass);
4783                 return NT_STATUS_NO_SUCH_USER;
4784         }
4785
4786         acb_info = pdb_get_acct_ctrl(sam_pass);
4787
4788         /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4789         if ( acb_info & ACB_WSTRUST ) {
4790                 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4791         } else {
4792                 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4793         }
4794
4795         /******** BEGIN SeAddUsers BLOCK *********/
4796
4797         if ( can_add_accounts )
4798                 become_root();
4799
4800         status = pdb_delete_user(p->mem_ctx, sam_pass);
4801
4802         if ( can_add_accounts )
4803                 unbecome_root();
4804
4805         /******** END SeAddUsers BLOCK *********/
4806
4807         if ( !NT_STATUS_IS_OK(status) ) {
4808                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4809                          "user %s: %s.\n", pdb_get_username(sam_pass),
4810                          nt_errstr(status)));
4811                 TALLOC_FREE(sam_pass);
4812                 return status;
4813         }
4814
4815
4816         TALLOC_FREE(sam_pass);
4817
4818         if (!close_policy_hnd(p, r->in.user_handle))
4819                 return NT_STATUS_OBJECT_NAME_INVALID;
4820
4821         force_flush_samr_cache(disp_info);
4822
4823         return NT_STATUS_OK;
4824 }
4825
4826 /*********************************************************************
4827  _samr_DeleteDomainGroup
4828 *********************************************************************/
4829
4830 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4831                                  struct samr_DeleteDomainGroup *r)
4832 {
4833         NTSTATUS status;
4834         DOM_SID group_sid;
4835         uint32 group_rid;
4836         uint32 acc_granted;
4837         SE_PRIV se_rights;
4838         bool can_add_accounts;
4839         DISP_INFO *disp_info = NULL;
4840
4841         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4842
4843         /* Find the policy handle. Open a policy on it. */
4844         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4845                 return NT_STATUS_INVALID_HANDLE;
4846
4847         status = access_check_samr_function(acc_granted,
4848                                             STD_RIGHT_DELETE_ACCESS,
4849                                             "_samr_DeleteDomainGroup");
4850         if (!NT_STATUS_IS_OK(status)) {
4851                 return status;
4852         }
4853
4854         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4855
4856         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4857                                 &group_rid)) {
4858                 return NT_STATUS_NO_SUCH_GROUP;
4859         }
4860
4861         se_priv_copy( &se_rights, &se_add_users );
4862         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4863
4864         /******** BEGIN SeAddUsers BLOCK *********/
4865
4866         if ( can_add_accounts )
4867                 become_root();
4868
4869         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4870
4871         if ( can_add_accounts )
4872                 unbecome_root();
4873
4874         /******** END SeAddUsers BLOCK *********/
4875
4876         if ( !NT_STATUS_IS_OK(status) ) {
4877                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4878                          "entry for group %s: %s\n",
4879                          sid_string_dbg(&group_sid),
4880                          nt_errstr(status)));
4881                 return status;
4882         }
4883
4884         if (!close_policy_hnd(p, r->in.group_handle))
4885                 return NT_STATUS_OBJECT_NAME_INVALID;
4886
4887         force_flush_samr_cache(disp_info);
4888
4889         return NT_STATUS_OK;
4890 }
4891
4892 /*********************************************************************
4893  _samr_DeleteDomAlias
4894 *********************************************************************/
4895
4896 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4897                               struct samr_DeleteDomAlias *r)
4898 {
4899         DOM_SID alias_sid;
4900         uint32 acc_granted;
4901         SE_PRIV se_rights;
4902         bool can_add_accounts;
4903         NTSTATUS status;
4904         DISP_INFO *disp_info = NULL;
4905
4906         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4907
4908         /* Find the policy handle. Open a policy on it. */
4909         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4910                 return NT_STATUS_INVALID_HANDLE;
4911
4912         /* copy the handle to the outgoing reply */
4913
4914         memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4915
4916         status = access_check_samr_function(acc_granted,
4917                                             STD_RIGHT_DELETE_ACCESS,
4918                                             "_samr_DeleteDomAlias");
4919         if (!NT_STATUS_IS_OK(status)) {
4920                 return status;
4921         }
4922
4923         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4924
4925         /* Don't let Windows delete builtin groups */
4926
4927         if ( sid_check_is_in_builtin( &alias_sid ) ) {
4928                 return NT_STATUS_SPECIAL_ACCOUNT;
4929         }
4930
4931         if (!sid_check_is_in_our_domain(&alias_sid))
4932                 return NT_STATUS_NO_SUCH_ALIAS;
4933
4934         DEBUG(10, ("lookup on Local SID\n"));
4935
4936         se_priv_copy( &se_rights, &se_add_users );
4937         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4938
4939         /******** BEGIN SeAddUsers BLOCK *********/
4940
4941         if ( can_add_accounts )
4942                 become_root();
4943
4944         /* Have passdb delete the alias */
4945         status = pdb_delete_alias(&alias_sid);
4946
4947         if ( can_add_accounts )
4948                 unbecome_root();
4949
4950         /******** END SeAddUsers BLOCK *********/
4951
4952         if ( !NT_STATUS_IS_OK(status))
4953                 return status;
4954
4955         if (!close_policy_hnd(p, r->in.alias_handle))
4956                 return NT_STATUS_OBJECT_NAME_INVALID;
4957
4958         force_flush_samr_cache(disp_info);
4959
4960         return NT_STATUS_OK;
4961 }
4962
4963 /*********************************************************************
4964  _samr_CreateDomainGroup
4965 *********************************************************************/
4966
4967 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4968                                  struct samr_CreateDomainGroup *r)
4969
4970 {
4971         NTSTATUS status;
4972         DOM_SID dom_sid;
4973         DOM_SID info_sid;
4974         const char *name;
4975         struct samr_info *info;
4976         uint32 acc_granted;
4977         SE_PRIV se_rights;
4978         bool can_add_accounts;
4979         DISP_INFO *disp_info = NULL;
4980
4981         /* Find the policy handle. Open a policy on it. */
4982         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4983                 return NT_STATUS_INVALID_HANDLE;
4984
4985         status = access_check_samr_function(acc_granted,
4986                                             SA_RIGHT_DOMAIN_CREATE_GROUP,
4987                                             "_samr_CreateDomainGroup");
4988         if (!NT_STATUS_IS_OK(status)) {
4989                 return status;
4990         }
4991
4992         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4993                 return NT_STATUS_ACCESS_DENIED;
4994
4995         name = r->in.name->string;
4996         if (name == NULL) {
4997                 return NT_STATUS_NO_MEMORY;
4998         }
4999
5000         status = can_create(p->mem_ctx, name);
5001         if (!NT_STATUS_IS_OK(status)) {
5002                 return status;
5003         }
5004
5005         se_priv_copy( &se_rights, &se_add_users );
5006         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5007
5008         /******** BEGIN SeAddUsers BLOCK *********/
5009
5010         if ( can_add_accounts )
5011                 become_root();
5012
5013         /* check that we successfully create the UNIX group */
5014
5015         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5016
5017         if ( can_add_accounts )
5018                 unbecome_root();
5019
5020         /******** END SeAddUsers BLOCK *********/
5021
5022         /* check if we should bail out here */
5023
5024         if ( !NT_STATUS_IS_OK(status) )
5025                 return status;
5026
5027         sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5028
5029         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5030                 return NT_STATUS_NO_MEMORY;
5031
5032         /* they created it; let the user do what he wants with it */
5033
5034         info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5035
5036         /* get a (unique) handle.  open a policy on it. */
5037         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5038                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5039
5040         force_flush_samr_cache(disp_info);
5041
5042         return NT_STATUS_OK;
5043 }
5044
5045 /*********************************************************************
5046  _samr_CreateDomAlias
5047 *********************************************************************/
5048
5049 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5050                               struct samr_CreateDomAlias *r)
5051 {
5052         DOM_SID dom_sid;
5053         DOM_SID info_sid;
5054         const char *name = NULL;
5055         struct samr_info *info;
5056         uint32 acc_granted;
5057         gid_t gid;
5058         NTSTATUS result;
5059         SE_PRIV se_rights;
5060         bool can_add_accounts;
5061         DISP_INFO *disp_info = NULL;
5062
5063         /* Find the policy handle. Open a policy on it. */
5064         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5065                 return NT_STATUS_INVALID_HANDLE;
5066
5067         result = access_check_samr_function(acc_granted,
5068                                             SA_RIGHT_DOMAIN_CREATE_ALIAS,
5069                                             "_samr_CreateDomAlias");
5070         if (!NT_STATUS_IS_OK(result)) {
5071                 return result;
5072         }
5073
5074         if (!sid_equal(&dom_sid, get_global_sam_sid()))
5075                 return NT_STATUS_ACCESS_DENIED;
5076
5077         name = r->in.alias_name->string;
5078
5079         se_priv_copy( &se_rights, &se_add_users );
5080         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5081
5082         result = can_create(p->mem_ctx, name);
5083         if (!NT_STATUS_IS_OK(result)) {
5084                 return result;
5085         }
5086
5087         /******** BEGIN SeAddUsers BLOCK *********/
5088
5089         if ( can_add_accounts )
5090                 become_root();
5091
5092         /* Have passdb create the alias */
5093         result = pdb_create_alias(name, r->out.rid);
5094
5095         if ( can_add_accounts )
5096                 unbecome_root();
5097
5098         /******** END SeAddUsers BLOCK *********/
5099
5100         if (!NT_STATUS_IS_OK(result)) {
5101                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5102                            nt_errstr(result)));
5103                 return result;
5104         }
5105
5106         sid_copy(&info_sid, get_global_sam_sid());
5107         sid_append_rid(&info_sid, *r->out.rid);
5108
5109         if (!sid_to_gid(&info_sid, &gid)) {
5110                 DEBUG(10, ("Could not find alias just created\n"));
5111                 return NT_STATUS_ACCESS_DENIED;
5112         }
5113
5114         /* check if the group has been successfully created */
5115         if ( getgrgid(gid) == NULL ) {
5116                 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5117                            gid));
5118                 return NT_STATUS_ACCESS_DENIED;
5119         }
5120
5121         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5122                 return NT_STATUS_NO_MEMORY;
5123
5124         /* they created it; let the user do what he wants with it */
5125
5126         info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5127
5128         /* get a (unique) handle.  open a policy on it. */
5129         if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5130                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5131
5132         force_flush_samr_cache(disp_info);
5133
5134         return NT_STATUS_OK;
5135 }
5136
5137 /*********************************************************************
5138  _samr_QueryGroupInfo
5139 *********************************************************************/
5140
5141 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5142                               struct samr_QueryGroupInfo *r)
5143 {
5144         NTSTATUS status;
5145         DOM_SID group_sid;
5146         GROUP_MAP map;
5147         union samr_GroupInfo *info = NULL;
5148         uint32 acc_granted;
5149         bool ret;
5150         uint32_t attributes = SE_GROUP_MANDATORY |
5151                               SE_GROUP_ENABLED_BY_DEFAULT |
5152                               SE_GROUP_ENABLED;
5153         const char *group_name = NULL;
5154         const char *group_description = NULL;
5155
5156         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5157                 return NT_STATUS_INVALID_HANDLE;
5158
5159         status = access_check_samr_function(acc_granted,
5160                                             SA_RIGHT_GROUP_LOOKUP_INFO,
5161                                             "_samr_QueryGroupInfo");
5162         if (!NT_STATUS_IS_OK(status)) {
5163                 return status;
5164         }
5165
5166         become_root();
5167         ret = get_domain_group_from_sid(group_sid, &map);
5168         unbecome_root();
5169         if (!ret)
5170                 return NT_STATUS_INVALID_HANDLE;
5171
5172         /* FIXME: map contains fstrings */
5173         group_name = talloc_strdup(r, map.nt_name);
5174         group_description = talloc_strdup(r, map.comment);
5175
5176         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5177         if (!info) {
5178                 return NT_STATUS_NO_MEMORY;
5179         }
5180
5181         switch (r->in.level) {
5182                 case 1: {
5183                         uint32 *members;
5184                         size_t num_members;
5185
5186                         become_root();
5187                         status = pdb_enum_group_members(
5188                                 p->mem_ctx, &group_sid, &members, &num_members);
5189                         unbecome_root();
5190
5191                         if (!NT_STATUS_IS_OK(status)) {
5192                                 return status;
5193                         }
5194
5195                         init_samr_group_info1(&info->all,
5196                                               group_name,
5197                                               attributes,
5198                                               num_members,
5199                                               group_description);
5200                         break;
5201                 }
5202                 case 2:
5203                         init_samr_group_info2(&info->name,
5204                                               group_name);
5205                         break;
5206                 case 3:
5207                         init_samr_group_info3(&info->attributes,
5208                                               attributes);
5209                         break;
5210                 case 4:
5211                         init_samr_group_info4(&info->description,
5212                                               group_description);
5213                         break;
5214                 case 5: {
5215                         /*
5216                         uint32 *members;
5217                         size_t num_members;
5218                         */
5219
5220                         /*
5221                         become_root();
5222                         status = pdb_enum_group_members(
5223                                 p->mem_ctx, &group_sid, &members, &num_members);
5224                         unbecome_root();
5225
5226                         if (!NT_STATUS_IS_OK(status)) {
5227                                 return status;
5228                         }
5229                         */
5230                         init_samr_group_info5(&info->all2,
5231                                               group_name,
5232                                               attributes,
5233                                               0, /* num_members - in w2k3 this is always 0 */
5234                                               group_description);
5235
5236                         break;
5237                 }
5238                 default:
5239                         return NT_STATUS_INVALID_INFO_CLASS;
5240         }
5241
5242         *r->out.info = info;
5243
5244         return NT_STATUS_OK;
5245 }
5246
5247 /*********************************************************************
5248  _samr_SetGroupInfo
5249 *********************************************************************/
5250
5251 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5252                             struct samr_SetGroupInfo *r)
5253 {
5254         DOM_SID group_sid;
5255         GROUP_MAP map;
5256         uint32 acc_granted;
5257         NTSTATUS status;
5258         bool ret;
5259         bool can_mod_accounts;
5260         DISP_INFO *disp_info = NULL;
5261
5262         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5263                 return NT_STATUS_INVALID_HANDLE;
5264
5265         status = access_check_samr_function(acc_granted,
5266                                             SA_RIGHT_GROUP_SET_INFO,
5267                                             "_samr_SetGroupInfo");
5268         if (!NT_STATUS_IS_OK(status)) {
5269                 return status;
5270         }
5271
5272         become_root();
5273         ret = get_domain_group_from_sid(group_sid, &map);
5274         unbecome_root();
5275         if (!ret)
5276                 return NT_STATUS_NO_SUCH_GROUP;
5277
5278         switch (r->in.level) {
5279                 case 1:
5280                         fstrcpy(map.comment, r->in.info->all.description.string);
5281                         break;
5282                 case 4:
5283                         fstrcpy(map.comment, r->in.info->description.string);
5284                         break;
5285                 default:
5286                         return NT_STATUS_INVALID_INFO_CLASS;
5287         }
5288
5289         can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5290
5291         /******** BEGIN SeAddUsers BLOCK *********/
5292
5293         if ( can_mod_accounts )
5294                 become_root();
5295
5296         status = pdb_update_group_mapping_entry(&map);
5297
5298         if ( can_mod_accounts )
5299                 unbecome_root();
5300
5301         /******** End SeAddUsers BLOCK *********/
5302
5303         if (NT_STATUS_IS_OK(status)) {
5304                 force_flush_samr_cache(disp_info);
5305         }
5306
5307         return status;
5308 }
5309
5310 /*********************************************************************
5311  _samr_SetAliasInfo
5312 *********************************************************************/
5313
5314 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5315                             struct samr_SetAliasInfo *r)
5316 {
5317         DOM_SID group_sid;
5318         struct acct_info info;
5319         uint32 acc_granted;
5320         bool can_mod_accounts;
5321         NTSTATUS status;
5322         DISP_INFO *disp_info = NULL;
5323
5324         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5325                 return NT_STATUS_INVALID_HANDLE;
5326
5327         status = access_check_samr_function(acc_granted,
5328                                             SA_RIGHT_ALIAS_SET_INFO,
5329                                             "_samr_SetAliasInfo");
5330         if (!NT_STATUS_IS_OK(status)) {
5331                 return status;
5332         }
5333
5334         /* get the current group information */
5335
5336         become_root();
5337         status = pdb_get_aliasinfo( &group_sid, &info );
5338         unbecome_root();
5339
5340         if ( !NT_STATUS_IS_OK(status))
5341                 return status;
5342
5343         switch (r->in.level) {
5344                 case ALIASINFONAME:
5345                 {
5346                         fstring group_name;
5347
5348                         /* We currently do not support renaming groups in the
5349                            the BUILTIN domain.  Refer to util_builtin.c to understand
5350                            why.  The eventually needs to be fixed to be like Windows
5351                            where you can rename builtin groups, just not delete them */
5352
5353                         if ( sid_check_is_in_builtin( &group_sid ) ) {
5354                                 return NT_STATUS_SPECIAL_ACCOUNT;
5355                         }
5356
5357                         /* There has to be a valid name (and it has to be different) */
5358
5359                         if ( !r->in.info->name.string )
5360                                 return NT_STATUS_INVALID_PARAMETER;
5361
5362                         /* If the name is the same just reply "ok".  Yes this
5363                            doesn't allow you to change the case of a group name. */
5364
5365                         if ( strequal( r->in.info->name.string, info.acct_name ) )
5366                                 return NT_STATUS_OK;
5367
5368                         fstrcpy( info.acct_name, r->in.info->name.string);
5369
5370                         /* make sure the name doesn't already exist as a user
5371                            or local group */
5372
5373                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5374                         status = can_create( p->mem_ctx, group_name );
5375                         if ( !NT_STATUS_IS_OK( status ) )
5376                                 return status;
5377                         break;
5378                 }
5379                 case ALIASINFODESCRIPTION:
5380                         if (r->in.info->description.string) {
5381                                 fstrcpy(info.acct_desc,
5382                                         r->in.info->description.string);
5383                         } else {
5384                                 fstrcpy( info.acct_desc, "" );
5385                         }
5386                         break;
5387                 default:
5388                         return NT_STATUS_INVALID_INFO_CLASS;
5389         }
5390
5391         can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5392
5393         /******** BEGIN SeAddUsers BLOCK *********/
5394
5395         if ( can_mod_accounts )
5396                 become_root();
5397
5398         status = pdb_set_aliasinfo( &group_sid, &info );
5399
5400         if ( can_mod_accounts )
5401                 unbecome_root();
5402
5403         /******** End SeAddUsers BLOCK *********/
5404
5405         if (NT_STATUS_IS_OK(status))
5406                 force_flush_samr_cache(disp_info);
5407
5408         return status;
5409 }
5410
5411 /****************************************************************
5412  _samr_GetDomPwInfo
5413 ****************************************************************/
5414
5415 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5416                             struct samr_GetDomPwInfo *r)
5417 {
5418         uint32_t min_password_length = 0;
5419         uint32_t password_properties = 0;
5420
5421         /* Perform access check.  Since this rpc does not require a
5422            policy handle it will not be caught by the access checks on
5423            SAMR_CONNECT or SAMR_CONNECT_ANON. */
5424
5425         if (!pipe_access_check(p)) {
5426                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5427                 return NT_STATUS_ACCESS_DENIED;
5428         }
5429
5430         become_root();
5431         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5432                                &min_password_length);
5433         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5434                                &password_properties);
5435         unbecome_root();
5436
5437         if (lp_check_password_script() && *lp_check_password_script()) {
5438                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5439         }
5440
5441         r->out.info->min_password_length = min_password_length;
5442         r->out.info->password_properties = password_properties;
5443
5444         return NT_STATUS_OK;
5445 }
5446
5447 /*********************************************************************
5448  _samr_OpenGroup
5449 *********************************************************************/
5450
5451 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5452                          struct samr_OpenGroup *r)
5453
5454 {
5455         DOM_SID sid;
5456         DOM_SID info_sid;
5457         GROUP_MAP map;
5458         struct samr_info *info;
5459         SEC_DESC         *psd = NULL;
5460         uint32            acc_granted;
5461         uint32            des_access = r->in.access_mask;
5462         size_t            sd_size;
5463         NTSTATUS          status;
5464         fstring sid_string;
5465         bool ret;
5466         SE_PRIV se_rights;
5467
5468         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5469                 return NT_STATUS_INVALID_HANDLE;
5470
5471         status = access_check_samr_function(acc_granted,
5472                                             SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5473                                             "_samr_OpenGroup");
5474
5475         if ( !NT_STATUS_IS_OK(status) )
5476                 return status;
5477
5478         /*check if access can be granted as requested by client. */
5479         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5480         se_map_generic(&des_access,&grp_generic_mapping);
5481
5482         se_priv_copy( &se_rights, &se_add_users );
5483
5484         status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5485                 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5486                 &acc_granted, "_samr_OpenGroup");
5487
5488         if ( !NT_STATUS_IS_OK(status) )
5489                 return status;
5490
5491         /* this should not be hard-coded like this */
5492
5493         if (!sid_equal(&sid, get_global_sam_sid()))
5494                 return NT_STATUS_ACCESS_DENIED;
5495
5496         sid_copy(&info_sid, get_global_sam_sid());
5497         sid_append_rid(&info_sid, r->in.rid);
5498         sid_to_fstring(sid_string, &info_sid);
5499
5500         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5501                 return NT_STATUS_NO_MEMORY;
5502
5503         info->acc_granted = acc_granted;
5504
5505         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5506
5507         /* check if that group really exists */
5508         become_root();
5509         ret = get_domain_group_from_sid(info->sid, &map);
5510         unbecome_root();
5511         if (!ret)
5512                 return NT_STATUS_NO_SUCH_GROUP;
5513
5514         /* get a (unique) handle.  open a policy on it. */
5515         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5516                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5517
5518         return NT_STATUS_OK;
5519 }
5520
5521 /*********************************************************************
5522  _samr_RemoveMemberFromForeignDomain
5523 *********************************************************************/
5524
5525 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5526                                              struct samr_RemoveMemberFromForeignDomain *r)
5527 {
5528         DOM_SID                 delete_sid, domain_sid;
5529         uint32                  acc_granted;
5530         NTSTATUS                result;
5531         DISP_INFO *disp_info = NULL;
5532
5533         sid_copy( &delete_sid, r->in.sid );
5534
5535         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5536                 sid_string_dbg(&delete_sid)));
5537
5538         /* Find the policy handle. Open a policy on it. */
5539
5540         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5541                                      &acc_granted, &disp_info))
5542                 return NT_STATUS_INVALID_HANDLE;
5543
5544         result = access_check_samr_function(acc_granted,
5545                                             STD_RIGHT_DELETE_ACCESS,
5546                                             "_samr_RemoveMemberFromForeignDomain");
5547
5548         if (!NT_STATUS_IS_OK(result))
5549                 return result;
5550
5551         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5552                   sid_string_dbg(&domain_sid)));
5553
5554         /* we can only delete a user from a group since we don't have
5555            nested groups anyways.  So in the latter case, just say OK */
5556
5557         /* TODO: The above comment nowadays is bogus. Since we have nested
5558          * groups now, and aliases members are never reported out of the unix
5559          * group membership, the "just say OK" makes this call a no-op. For
5560          * us. This needs fixing however. */
5561
5562         /* I've only ever seen this in the wild when deleting a user from
5563          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5564          * is the user about to be deleted. I very much suspect this is the
5565          * only application of this call. To verify this, let people report
5566          * other cases. */
5567
5568         if (!sid_check_is_builtin(&domain_sid)) {
5569                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5570                          "global_sam_sid() = %s\n",
5571                          sid_string_dbg(&domain_sid),
5572                          sid_string_dbg(get_global_sam_sid())));
5573                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5574                 return NT_STATUS_OK;
5575         }
5576
5577         force_flush_samr_cache(disp_info);
5578
5579         result = NT_STATUS_OK;
5580
5581         return result;
5582 }
5583
5584 /*******************************************************************
5585  _samr_QueryDomainInfo2
5586  ********************************************************************/
5587
5588 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5589                                 struct samr_QueryDomainInfo2 *r)
5590 {
5591         return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5592                                              p,
5593                                              r->in.domain_handle,
5594                                              r->in.level,
5595                                              r->out.info);
5596 }
5597
5598 /*******************************************************************
5599  _samr_SetDomainInfo
5600  ********************************************************************/
5601
5602 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5603                              struct samr_SetDomainInfo *r)
5604 {
5605         time_t u_expire, u_min_age;
5606         time_t u_logout;
5607         time_t u_lock_duration, u_reset_time;
5608
5609         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5610
5611         /* find the policy handle.  open a policy on it. */
5612         if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5613                 return NT_STATUS_INVALID_HANDLE;
5614
5615         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5616
5617         switch (r->in.level) {
5618                 case 0x01:
5619                         u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5620                         u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5621                         pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5622                         pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5623                         pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5624                         pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5625                         pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5626                         break;
5627                 case 0x02:
5628                         break;
5629                 case 0x03:
5630                         u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5631                         pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5632                         break;
5633                 case 0x05:
5634                         break;
5635                 case 0x06:
5636                         break;
5637                 case 0x07:
5638                         break;
5639                 case 0x0c:
5640                         u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5641                         if (u_lock_duration != -1)
5642                                 u_lock_duration /= 60;
5643
5644                         u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5645
5646                         pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5647                         pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5648                         pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5649                         break;
5650                 default:
5651                         return NT_STATUS_INVALID_INFO_CLASS;
5652         }
5653
5654         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5655
5656         return NT_STATUS_OK;
5657 }
5658
5659 /****************************************************************
5660  _samr_GetDisplayEnumerationIndex
5661 ****************************************************************/
5662
5663 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5664                                           struct samr_GetDisplayEnumerationIndex *r)
5665 {
5666         struct samr_info *info = NULL;
5667         uint32_t max_entries = (uint32_t) -1;
5668         uint32_t enum_context = 0;
5669         int i;
5670         uint32_t num_account = 0;
5671         struct samr_displayentry *entries = NULL;
5672
5673         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5674
5675         /* find the policy handle.  open a policy on it. */
5676         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5677                 return NT_STATUS_INVALID_HANDLE;
5678         }
5679
5680         if ((r->in.level < 1) || (r->in.level > 3)) {
5681                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5682                         "Unknown info level (%u)\n",
5683                         r->in.level));
5684                 return NT_STATUS_INVALID_INFO_CLASS;
5685         }
5686
5687         become_root();
5688
5689         /* The following done as ROOT. Don't return without unbecome_root(). */
5690
5691         switch (r->in.level) {
5692         case 1:
5693                 if (info->disp_info->users == NULL) {
5694                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
5695                         if (info->disp_info->users == NULL) {
5696                                 unbecome_root();
5697                                 return NT_STATUS_ACCESS_DENIED;
5698                         }
5699                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5700                                 "starting user enumeration at index %u\n",
5701                                 (unsigned int)enum_context));
5702                 } else {
5703                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5704                                 "using cached user enumeration at index %u\n",
5705                                 (unsigned int)enum_context));
5706                 }
5707                 num_account = pdb_search_entries(info->disp_info->users,
5708                                                  enum_context, max_entries,
5709                                                  &entries);
5710                 break;
5711         case 2:
5712                 if (info->disp_info->machines == NULL) {
5713                         info->disp_info->machines =
5714                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5715                         if (info->disp_info->machines == NULL) {
5716                                 unbecome_root();
5717                                 return NT_STATUS_ACCESS_DENIED;
5718                         }
5719                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5720                                 "starting machine enumeration at index %u\n",
5721                                 (unsigned int)enum_context));
5722                 } else {
5723                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5724                                 "using cached machine enumeration at index %u\n",
5725                                 (unsigned int)enum_context));
5726                 }
5727                 num_account = pdb_search_entries(info->disp_info->machines,
5728                                                  enum_context, max_entries,
5729                                                  &entries);
5730                 break;
5731         case 3:
5732                 if (info->disp_info->groups == NULL) {
5733                         info->disp_info->groups = pdb_search_groups();
5734                         if (info->disp_info->groups == NULL) {
5735                                 unbecome_root();
5736                                 return NT_STATUS_ACCESS_DENIED;
5737                         }
5738                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5739                                 "starting group enumeration at index %u\n",
5740                                 (unsigned int)enum_context));
5741                 } else {
5742                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5743                                 "using cached group enumeration at index %u\n",
5744                                 (unsigned int)enum_context));
5745                 }
5746                 num_account = pdb_search_entries(info->disp_info->groups,
5747                                                  enum_context, max_entries,
5748                                                  &entries);
5749                 break;
5750         default:
5751                 unbecome_root();
5752                 smb_panic("info class changed");
5753                 break;
5754         }
5755
5756         unbecome_root();
5757
5758         /* Ensure we cache this enumeration. */
5759         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5760
5761         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5762                 r->in.name->string));
5763
5764         for (i=0; i<num_account; i++) {
5765                 if (strequal(entries[i].account_name, r->in.name->string)) {
5766                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5767                                 "found %s at idx %d\n",
5768                                 r->in.name->string, i));
5769                         *r->out.idx = i;
5770                         return NT_STATUS_OK;
5771                 }
5772         }
5773
5774         /* assuming account_name lives at the very end */
5775         *r->out.idx = num_account;
5776
5777         return NT_STATUS_NO_MORE_ENTRIES;
5778 }
5779
5780 /****************************************************************
5781  _samr_GetDisplayEnumerationIndex2
5782 ****************************************************************/
5783
5784 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5785                                            struct samr_GetDisplayEnumerationIndex2 *r)
5786 {
5787         struct samr_GetDisplayEnumerationIndex q;
5788
5789         q.in.domain_handle      = r->in.domain_handle;
5790         q.in.level              = r->in.level;
5791         q.in.name               = r->in.name;
5792
5793         q.out.idx               = r->out.idx;
5794
5795         return _samr_GetDisplayEnumerationIndex(p, &q);
5796 }
5797
5798 /****************************************************************
5799 ****************************************************************/
5800
5801 NTSTATUS _samr_Shutdown(pipes_struct *p,
5802                         struct samr_Shutdown *r)
5803 {
5804         p->rng_fault_state = true;
5805         return NT_STATUS_NOT_IMPLEMENTED;
5806 }
5807
5808 /****************************************************************
5809 ****************************************************************/
5810
5811 NTSTATUS _samr_CreateUser(pipes_struct *p,
5812                           struct samr_CreateUser *r)
5813 {
5814         p->rng_fault_state = true;
5815         return NT_STATUS_NOT_IMPLEMENTED;
5816 }
5817
5818 /****************************************************************
5819 ****************************************************************/
5820
5821 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5822                                           struct samr_SetMemberAttributesOfGroup *r)
5823 {
5824         p->rng_fault_state = true;
5825         return NT_STATUS_NOT_IMPLEMENTED;
5826 }
5827
5828 /****************************************************************
5829 ****************************************************************/
5830
5831 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5832                                   struct samr_ChangePasswordUser *r)
5833 {
5834         p->rng_fault_state = true;
5835         return NT_STATUS_NOT_IMPLEMENTED;
5836 }
5837
5838 /****************************************************************
5839 ****************************************************************/
5840
5841 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5842                                           struct samr_TestPrivateFunctionsDomain *r)
5843 {
5844         p->rng_fault_state = true;
5845         return NT_STATUS_NOT_IMPLEMENTED;
5846 }
5847
5848 /****************************************************************
5849 ****************************************************************/
5850
5851 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5852                                         struct samr_TestPrivateFunctionsUser *r)
5853 {
5854         p->rng_fault_state = true;
5855         return NT_STATUS_NOT_IMPLEMENTED;
5856 }
5857
5858 /****************************************************************
5859 ****************************************************************/
5860
5861 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5862                               struct samr_QueryUserInfo2 *r)
5863 {
5864         p->rng_fault_state = true;
5865         return NT_STATUS_NOT_IMPLEMENTED;
5866 }
5867
5868 /****************************************************************
5869 ****************************************************************/
5870
5871 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5872                                          struct samr_AddMultipleMembersToAlias *r)
5873 {
5874         p->rng_fault_state = true;
5875         return NT_STATUS_NOT_IMPLEMENTED;
5876 }
5877
5878 /****************************************************************
5879 ****************************************************************/
5880
5881 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5882                                               struct samr_RemoveMultipleMembersFromAlias *r)
5883 {
5884         p->rng_fault_state = true;
5885         return NT_STATUS_NOT_IMPLEMENTED;
5886 }
5887
5888 /****************************************************************
5889 ****************************************************************/
5890
5891 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5892                                       struct samr_OemChangePasswordUser2 *r)
5893 {
5894         p->rng_fault_state = true;
5895         return NT_STATUS_NOT_IMPLEMENTED;
5896 }
5897
5898 /****************************************************************
5899 ****************************************************************/
5900
5901 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5902                                      struct samr_SetBootKeyInformation *r)
5903 {
5904         p->rng_fault_state = true;
5905         return NT_STATUS_NOT_IMPLEMENTED;
5906 }
5907
5908 /****************************************************************
5909 ****************************************************************/
5910
5911 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5912                                      struct samr_GetBootKeyInformation *r)
5913 {
5914         p->rng_fault_state = true;
5915         return NT_STATUS_NOT_IMPLEMENTED;
5916 }
5917
5918 /****************************************************************
5919 ****************************************************************/
5920
5921 NTSTATUS _samr_Connect3(pipes_struct *p,
5922                         struct samr_Connect3 *r)
5923 {
5924         p->rng_fault_state = true;
5925         return NT_STATUS_NOT_IMPLEMENTED;
5926 }
5927
5928 /****************************************************************
5929 ****************************************************************/
5930
5931 NTSTATUS _samr_RidToSid(pipes_struct *p,
5932                         struct samr_RidToSid *r)
5933 {
5934         p->rng_fault_state = true;
5935         return NT_STATUS_NOT_IMPLEMENTED;
5936 }
5937
5938 /****************************************************************
5939 ****************************************************************/
5940
5941 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5942                                struct samr_SetDsrmPassword *r)
5943 {
5944         p->rng_fault_state = true;
5945         return NT_STATUS_NOT_IMPLEMENTED;
5946 }
5947
5948 /****************************************************************
5949 ****************************************************************/
5950
5951 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5952                                 struct samr_ValidatePassword *r)
5953 {
5954         p->rng_fault_state = true;
5955         return NT_STATUS_NOT_IMPLEMENTED;
5956 }