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