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