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