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