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