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