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