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