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