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