5f1177d3399880e7665a87c89506685e6503a024
[jra/samba/.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-2008,
9  *  Copyright (C) Jean François Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *  Copyright (C) Guenther Deschner                 2008.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /*
31  * This is the implementation of the SAMR code.
32  */
33
34 #include "includes.h"
35 #include "../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                                  uint32_t acc_granted)
2801 {
2802         NTSTATUS status;
2803         const DOM_SID *sid_user, *sid_group;
2804         uint32_t rid, primary_gid;
2805         NTTIME force_password_change;
2806         time_t must_change_time;
2807         struct lsa_BinaryString *parameters = NULL;
2808         const char *munged_dial = NULL;
2809         DATA_BLOB blob;
2810
2811         ZERO_STRUCTP(r);
2812
2813         sid_user = pdb_get_user_sid(pw);
2814
2815         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2816                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2817                           "the domain sid %s.  Failing operation.\n",
2818                           pdb_get_username(pw), sid_string_dbg(sid_user),
2819                           sid_string_dbg(domain_sid)));
2820                 return NT_STATUS_UNSUCCESSFUL;
2821         }
2822
2823         become_root();
2824         sid_group = pdb_get_group_sid(pw);
2825         unbecome_root();
2826
2827         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2828                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2829                           "which conflicts with the domain sid %s.  Failing operation.\n",
2830                           pdb_get_username(pw), sid_string_dbg(sid_group),
2831                           sid_string_dbg(domain_sid)));
2832                 return NT_STATUS_UNSUCCESSFUL;
2833         }
2834
2835         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2836         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2837         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2838         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2839         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2840
2841         must_change_time = pdb_get_pass_must_change_time(pw);
2842         if (must_change_time == get_time_t_max()) {
2843                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2844         } else {
2845                 unix_to_nt_time(&force_password_change, must_change_time);
2846         }
2847
2848         munged_dial = pdb_get_munged_dial(pw);
2849         if (munged_dial) {
2850                 blob = base64_decode_data_blob(munged_dial);
2851         } else {
2852                 blob = data_blob_string_const_null("");
2853         }
2854
2855         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2856         data_blob_free(&blob);
2857         if (!NT_STATUS_IS_OK(status)) {
2858                 return status;
2859         }
2860
2861         r->force_password_change        = force_password_change;
2862
2863         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2864         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2865         r->home_directory.string        = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2866         r->home_drive.string            = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2867         r->logon_script.string          = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2868         r->profile_path.string          = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2869         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2870         r->workstations.string          = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2871         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2872
2873         r->logon_hours                  = get_logon_hours_from_pdb(mem_ctx, pw);
2874         r->parameters                   = *parameters;
2875         r->rid                          = rid;
2876         r->primary_gid                  = primary_gid;
2877         r->acct_flags                   = pdb_get_acct_ctrl(pw);
2878         r->bad_password_count           = pdb_get_bad_password_count(pw);
2879         r->logon_count                  = pdb_get_logon_count(pw);
2880         r->fields_present               = pdb_build_fields_present(pw);
2881         r->password_expired             = (pdb_get_pass_must_change_time(pw) == 0) ?
2882                                                 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2883         r->country_code                 = 0;
2884         r->code_page                    = 0;
2885         r->lm_password_set              = 0;
2886         r->nt_password_set              = 0;
2887
2888 #if 0
2889
2890         /*
2891           Look at a user on a real NT4 PDC with usrmgr, press
2892           'ok'. Then you will see that fields_present is set to
2893           0x08f827fa. Look at the user immediately after that again,
2894           and you will see that 0x00fffff is returned. This solves
2895           the problem that you get access denied after having looked
2896           at the user.
2897           -- Volker
2898         */
2899
2900 #endif
2901
2902
2903         return NT_STATUS_OK;
2904 }
2905
2906 /*******************************************************************
2907  _samr_QueryUserInfo
2908  ********************************************************************/
2909
2910 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2911                              struct samr_QueryUserInfo *r)
2912 {
2913         NTSTATUS status;
2914         union samr_UserInfo *user_info = NULL;
2915         struct samr_user_info *uinfo;
2916         DOM_SID domain_sid;
2917         uint32 rid;
2918         bool ret = false;
2919         struct samu *pwd = NULL;
2920         uint32_t acc_required, acc_granted;
2921
2922         switch (r->in.level) {
2923         case 1: /* UserGeneralInformation */
2924                 /* USER_READ_GENERAL */
2925                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2926                 break;
2927         case 2: /* UserPreferencesInformation */
2928                 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2929                 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2930                                SAMR_USER_ACCESS_GET_NAME_ETC;
2931                 break;
2932         case 3: /* UserLogonInformation */
2933                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2934                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2935                                SAMR_USER_ACCESS_GET_LOCALE |
2936                                SAMR_USER_ACCESS_GET_LOGONINFO |
2937                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
2938                 break;
2939         case 4: /* UserLogonHoursInformation */
2940                 /* USER_READ_LOGON */
2941                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2942                 break;
2943         case 5: /* UserAccountInformation */
2944                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2945                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2946                                SAMR_USER_ACCESS_GET_LOCALE |
2947                                SAMR_USER_ACCESS_GET_LOGONINFO |
2948                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
2949                 break;
2950         case 6: /* UserNameInformation */
2951         case 7: /* UserAccountNameInformation */
2952         case 8: /* UserFullNameInformation */
2953         case 9: /* UserPrimaryGroupInformation */
2954         case 13: /* UserAdminCommentInformation */
2955                 /* USER_READ_GENERAL */
2956                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2957                 break;
2958         case 10: /* UserHomeInformation */
2959         case 11: /* UserScriptInformation */
2960         case 12: /* UserProfileInformation */
2961         case 14: /* UserWorkStationsInformation */
2962                 /* USER_READ_LOGON */
2963                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2964                 break;
2965         case 16: /* UserControlInformation */
2966         case 17: /* UserExpiresInformation */
2967         case 20: /* UserParametersInformation */
2968                 /* USER_READ_ACCOUNT */
2969                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2970                 break;
2971         case 21: /* UserAllInformation */
2972                 /* FIXME! - gd */
2973                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2974                 break;
2975         case 18: /* UserInternal1Information */
2976                 /* FIXME! - gd */
2977                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2978                 break;
2979         case 23: /* UserInternal4Information */
2980         case 24: /* UserInternal4InformationNew */
2981         case 25: /* UserInternal4InformationNew */
2982         case 26: /* UserInternal5InformationNew */
2983         default:
2984                 return NT_STATUS_INVALID_INFO_CLASS;
2985                 break;
2986         }
2987
2988         uinfo = policy_handle_find(p, r->in.user_handle,
2989                                    acc_required, &acc_granted,
2990                                    struct samr_user_info, &status);
2991         if (!NT_STATUS_IS_OK(status)) {
2992                 return status;
2993         }
2994
2995         domain_sid = uinfo->sid;
2996
2997         sid_split_rid(&domain_sid, &rid);
2998
2999         if (!sid_check_is_in_our_domain(&uinfo->sid))
3000                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3001
3002         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3003                  sid_string_dbg(&uinfo->sid)));
3004
3005         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3006         if (!user_info) {
3007                 return NT_STATUS_NO_MEMORY;
3008         }
3009
3010         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3011
3012         if (!(pwd = samu_new(p->mem_ctx))) {
3013                 return NT_STATUS_NO_MEMORY;
3014         }
3015
3016         become_root();
3017         ret = pdb_getsampwsid(pwd, &uinfo->sid);
3018         unbecome_root();
3019
3020         if (ret == false) {
3021                 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3022                 TALLOC_FREE(pwd);
3023                 return NT_STATUS_NO_SUCH_USER;
3024         }
3025
3026         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3027
3028         samr_clear_sam_passwd(pwd);
3029
3030         switch (r->in.level) {
3031         case 1:
3032                 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3033                 break;
3034         case 2:
3035                 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3036                 break;
3037         case 3:
3038                 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3039                 break;
3040         case 4:
3041                 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3042                 break;
3043         case 5:
3044                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3045                 break;
3046         case 6:
3047                 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3048                 break;
3049         case 7:
3050                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3051                 break;
3052         case 8:
3053                 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3054                 break;
3055         case 9:
3056                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3057                 break;
3058         case 10:
3059                 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3060                 break;
3061         case 11:
3062                 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3063                 break;
3064         case 12:
3065                 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3066                 break;
3067         case 13:
3068                 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3069                 break;
3070         case 14:
3071                 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3072                 break;
3073         case 16:
3074                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3075                 break;
3076         case 17:
3077                 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3078                 break;
3079         case 18:
3080                 /* level 18 is special */
3081                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3082                                           &uinfo->sid);
3083                 break;
3084         case 20:
3085                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3086                 break;
3087         case 21:
3088                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3089                 break;
3090         default:
3091                 status = NT_STATUS_INVALID_INFO_CLASS;
3092                 break;
3093         }
3094
3095         if (!NT_STATUS_IS_OK(status)) {
3096                 goto done;
3097         }
3098
3099         *r->out.info = user_info;
3100
3101  done:
3102         TALLOC_FREE(pwd);
3103
3104         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3105
3106         return status;
3107 }
3108
3109 /****************************************************************
3110 ****************************************************************/
3111
3112 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3113                               struct samr_QueryUserInfo2 *r)
3114 {
3115         struct samr_QueryUserInfo u;
3116
3117         u.in.user_handle        = r->in.user_handle;
3118         u.in.level              = r->in.level;
3119         u.out.info              = r->out.info;
3120
3121         return _samr_QueryUserInfo(p, &u);
3122 }
3123
3124 /*******************************************************************
3125  _samr_GetGroupsForUser
3126  ********************************************************************/
3127
3128 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3129                                 struct samr_GetGroupsForUser *r)
3130 {
3131         struct samr_user_info *uinfo;
3132         struct samu *sam_pass=NULL;
3133         DOM_SID *sids;
3134         struct samr_RidWithAttribute dom_gid;
3135         struct samr_RidWithAttribute *gids = NULL;
3136         uint32 primary_group_rid;
3137         size_t num_groups = 0;
3138         gid_t *unix_gids;
3139         size_t i, num_gids;
3140         bool ret;
3141         NTSTATUS result;
3142         bool success = False;
3143
3144         struct samr_RidWithAttributeArray *rids = NULL;
3145
3146         /*
3147          * from the SID in the request:
3148          * we should send back the list of DOMAIN GROUPS
3149          * the user is a member of
3150          *
3151          * and only the DOMAIN GROUPS
3152          * no ALIASES !!! neither aliases of the domain
3153          * nor aliases of the builtin SID
3154          *
3155          * JFM, 12/2/2001
3156          */
3157
3158         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3159
3160         uinfo = policy_handle_find(p, r->in.user_handle,
3161                                    SAMR_USER_ACCESS_GET_GROUPS, NULL,
3162                                    struct samr_user_info, &result);
3163         if (!NT_STATUS_IS_OK(result)) {
3164                 return result;
3165         }
3166
3167         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3168         if (!rids) {
3169                 return NT_STATUS_NO_MEMORY;
3170         }
3171
3172         if (!sid_check_is_in_our_domain(&uinfo->sid))
3173                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3174
3175         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3176                 return NT_STATUS_NO_MEMORY;
3177         }
3178
3179         become_root();
3180         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3181         unbecome_root();
3182
3183         if (!ret) {
3184                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3185                            sid_string_dbg(&uinfo->sid)));
3186                 return NT_STATUS_NO_SUCH_USER;
3187         }
3188
3189         sids = NULL;
3190
3191         /* make both calls inside the root block */
3192         become_root();
3193         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3194                                             &sids, &unix_gids, &num_groups);
3195         if ( NT_STATUS_IS_OK(result) ) {
3196                 success = sid_peek_check_rid(get_global_sam_sid(),
3197                                              pdb_get_group_sid(sam_pass),
3198                                              &primary_group_rid);
3199         }
3200         unbecome_root();
3201
3202         if (!NT_STATUS_IS_OK(result)) {
3203                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3204                            sid_string_dbg(&uinfo->sid)));
3205                 return result;
3206         }
3207
3208         if ( !success ) {
3209                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3210                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
3211                           pdb_get_username(sam_pass)));
3212                 TALLOC_FREE(sam_pass);
3213                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3214         }
3215
3216         gids = NULL;
3217         num_gids = 0;
3218
3219         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3220                               SE_GROUP_ENABLED);
3221         dom_gid.rid = primary_group_rid;
3222         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3223
3224         for (i=0; i<num_groups; i++) {
3225
3226                 if (!sid_peek_check_rid(get_global_sam_sid(),
3227                                         &(sids[i]), &dom_gid.rid)) {
3228                         DEBUG(10, ("Found sid %s not in our domain\n",
3229                                    sid_string_dbg(&sids[i])));
3230                         continue;
3231                 }
3232
3233                 if (dom_gid.rid == primary_group_rid) {
3234                         /* We added the primary group directly from the
3235                          * sam_account. The other SIDs are unique from
3236                          * enum_group_memberships */
3237                         continue;
3238                 }
3239
3240                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3241         }
3242
3243         rids->count = num_gids;
3244         rids->rids = gids;
3245
3246         *r->out.rids = rids;
3247
3248         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3249
3250         return result;
3251 }
3252
3253 /*******************************************************************
3254  _samr_QueryDomainInfo
3255  ********************************************************************/
3256
3257 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3258                                struct samr_QueryDomainInfo *r)
3259 {
3260         NTSTATUS status = NT_STATUS_OK;
3261         struct samr_domain_info *dinfo;
3262         union samr_DomainInfo *dom_info;
3263         time_t u_expire, u_min_age;
3264
3265         time_t u_lock_duration, u_reset_time;
3266         uint32_t u_logout;
3267
3268         uint32 account_policy_temp;
3269
3270         time_t seq_num;
3271         uint32 server_role;
3272         uint32_t acc_required;
3273
3274         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3275
3276         switch (r->in.level) {
3277         case 1: /* DomainPasswordInformation */
3278         case 12: /* DomainLockoutInformation */
3279                 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3280                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3281                 break;
3282         case 11: /* DomainGeneralInformation2 */
3283                 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3284                  * DOMAIN_READ_OTHER_PARAMETERS */
3285                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3286                                SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3287                 break;
3288         case 2: /* DomainGeneralInformation */
3289         case 3: /* DomainLogoffInformation */
3290         case 4: /* DomainOemInformation */
3291         case 5: /* DomainReplicationInformation */
3292         case 6: /* DomainReplicationInformation */
3293         case 7: /* DomainServerRoleInformation */
3294         case 8: /* DomainModifiedInformation */
3295         case 9: /* DomainStateInformation */
3296         case 10: /* DomainUasInformation */
3297         case 13: /* DomainModifiedInformation2 */
3298                 /* DOMAIN_READ_OTHER_PARAMETERS */
3299                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3300                 break;
3301         default:
3302                 return NT_STATUS_INVALID_INFO_CLASS;
3303         }
3304
3305         dinfo = policy_handle_find(p, r->in.domain_handle,
3306                                    acc_required, NULL,
3307                                    struct samr_domain_info, &status);
3308         if (!NT_STATUS_IS_OK(status)) {
3309                 return status;
3310         }
3311
3312         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3313         if (!dom_info) {
3314                 return NT_STATUS_NO_MEMORY;
3315         }
3316
3317         switch (r->in.level) {
3318                 case 1:
3319
3320                         become_root();
3321
3322                         /* AS ROOT !!! */
3323
3324                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
3325                                                &account_policy_temp);
3326                         dom_info->info1.min_password_length = account_policy_temp;
3327
3328                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
3329                         dom_info->info1.password_history_length = account_policy_temp;
3330
3331                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
3332                                 &dom_info->info1.password_properties);
3333
3334                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
3335                         u_expire = account_policy_temp;
3336
3337                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
3338                         u_min_age = account_policy_temp;
3339
3340                         /* !AS ROOT */
3341
3342                         unbecome_root();
3343
3344                         unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
3345                         unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
3346
3347                         if (lp_check_password_script() && *lp_check_password_script()) {
3348                                 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
3349                         }
3350
3351                         break;
3352                 case 2:
3353
3354                         become_root();
3355
3356                         /* AS ROOT !!! */
3357
3358                         dom_info->general.num_users     = count_sam_users(
3359                                 dinfo->disp_info, ACB_NORMAL);
3360                         dom_info->general.num_groups    = count_sam_groups(
3361                                 dinfo->disp_info);
3362                         dom_info->general.num_aliases   = count_sam_aliases(
3363                                 dinfo->disp_info);
3364
3365                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3366
3367                         unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
3368
3369                         if (!pdb_get_seq_num(&seq_num))
3370                                 seq_num = time(NULL);
3371
3372                         /* !AS ROOT */
3373
3374                         unbecome_root();
3375
3376                         server_role = ROLE_DOMAIN_PDC;
3377                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3378                                 server_role = ROLE_DOMAIN_BDC;
3379
3380                         dom_info->general.oem_information.string        = lp_serverstring();
3381                         dom_info->general.domain_name.string            = lp_workgroup();
3382                         dom_info->general.primary.string                = global_myname();
3383                         dom_info->general.sequence_num                  = seq_num;
3384                         dom_info->general.domain_server_state           = DOMAIN_SERVER_ENABLED;
3385                         dom_info->general.role                          = server_role;
3386                         dom_info->general.unknown3                      = 1;
3387
3388                         break;
3389                 case 3:
3390
3391                         become_root();
3392
3393                         /* AS ROOT !!! */
3394
3395                         {
3396                                 uint32 ul;
3397                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3398                                 u_logout = (time_t)ul;
3399                         }
3400
3401                         /* !AS ROOT */
3402
3403                         unbecome_root();
3404
3405                         unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
3406
3407                         break;
3408                 case 4:
3409                         dom_info->oem.oem_information.string = lp_serverstring();
3410                         break;
3411                 case 5:
3412                         dom_info->info5.domain_name.string = get_global_sam_name();
3413                         break;
3414                 case 6:
3415                         /* NT returns its own name when a PDC. win2k and later
3416                          * only the name of the PDC if itself is a BDC (samba4
3417                          * idl) */
3418                         dom_info->info6.primary.string = global_myname();
3419                         break;
3420                 case 7:
3421                         server_role = ROLE_DOMAIN_PDC;
3422                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3423                                 server_role = ROLE_DOMAIN_BDC;
3424
3425                         dom_info->info7.role = server_role;
3426                         break;
3427                 case 8:
3428
3429                         become_root();
3430
3431                         /* AS ROOT !!! */
3432
3433                         if (!pdb_get_seq_num(&seq_num)) {
3434                                 seq_num = time(NULL);
3435                         }
3436
3437                         /* !AS ROOT */
3438
3439                         unbecome_root();
3440
3441                         dom_info->info8.sequence_num = seq_num;
3442                         dom_info->info8.domain_create_time = 0;
3443
3444                         break;
3445                 case 9:
3446
3447                         dom_info->info9.domain_server_state             = DOMAIN_SERVER_ENABLED;
3448
3449                         break;
3450                 case 11:
3451
3452                         /* AS ROOT !!! */
3453
3454                         become_root();
3455
3456                         dom_info->general2.general.num_users    = count_sam_users(
3457                                 dinfo->disp_info, ACB_NORMAL);
3458                         dom_info->general2.general.num_groups   = count_sam_groups(
3459                                 dinfo->disp_info);
3460                         dom_info->general2.general.num_aliases  = count_sam_aliases(
3461                                 dinfo->disp_info);
3462
3463                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3464
3465                         unix_to_nt_time_abs(&dom_info->general2.general.force_logoff_time, u_logout);
3466
3467                         if (!pdb_get_seq_num(&seq_num))
3468                                 seq_num = time(NULL);
3469
3470                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3471                         u_lock_duration = account_policy_temp;
3472                         if (u_lock_duration != -1) {
3473                                 u_lock_duration *= 60;
3474                         }
3475
3476                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3477                         u_reset_time = account_policy_temp * 60;
3478
3479                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3480                                                &account_policy_temp);
3481                         dom_info->general2.lockout_threshold = account_policy_temp;
3482
3483                         /* !AS ROOT */
3484
3485                         unbecome_root();
3486
3487                         server_role = ROLE_DOMAIN_PDC;
3488                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3489                                 server_role = ROLE_DOMAIN_BDC;
3490
3491                         dom_info->general2.general.oem_information.string       = lp_serverstring();
3492                         dom_info->general2.general.domain_name.string           = lp_workgroup();
3493                         dom_info->general2.general.primary.string               = global_myname();
3494                         dom_info->general2.general.sequence_num                 = seq_num;
3495                         dom_info->general2.general.domain_server_state          = DOMAIN_SERVER_ENABLED;
3496                         dom_info->general2.general.role                         = server_role;
3497                         dom_info->general2.general.unknown3                     = 1;
3498
3499                         unix_to_nt_time_abs(&dom_info->general2.lockout_duration,
3500                                             u_lock_duration);
3501                         unix_to_nt_time_abs(&dom_info->general2.lockout_window,
3502                                             u_reset_time);
3503
3504                         break;
3505                 case 12:
3506
3507                         become_root();
3508
3509                         /* AS ROOT !!! */
3510
3511                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3512                         u_lock_duration = account_policy_temp;
3513                         if (u_lock_duration != -1) {
3514                                 u_lock_duration *= 60;
3515                         }
3516
3517                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3518                         u_reset_time = account_policy_temp * 60;
3519
3520                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3521                                                &account_policy_temp);
3522                         dom_info->info12.lockout_threshold = account_policy_temp;
3523
3524                         /* !AS ROOT */
3525
3526                         unbecome_root();
3527
3528                         unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
3529                                             u_lock_duration);
3530                         unix_to_nt_time_abs(&dom_info->info12.lockout_window,
3531                                             u_reset_time);
3532
3533                         break;
3534                 case 13:
3535
3536                         become_root();
3537
3538                         /* AS ROOT !!! */
3539
3540                         if (!pdb_get_seq_num(&seq_num)) {
3541                                 seq_num = time(NULL);
3542                         }
3543
3544                         /* !AS ROOT */
3545
3546                         unbecome_root();
3547
3548                         dom_info->info13.sequence_num = seq_num;
3549                         dom_info->info13.domain_create_time = 0;
3550                         dom_info->info13.modified_count_at_last_promotion = 0;
3551
3552                         break;
3553                 default:
3554                         return NT_STATUS_INVALID_INFO_CLASS;
3555         }
3556
3557         *r->out.info = dom_info;
3558
3559         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3560
3561         return status;
3562 }
3563
3564 /* W2k3 seems to use the same check for all 3 objects that can be created via
3565  * SAMR, if you try to create for example "Dialup" as an alias it says
3566  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3567  * database. */
3568
3569 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3570 {
3571         enum lsa_SidType type;
3572         bool result;
3573
3574         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3575
3576         become_root();
3577         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3578          * whether the name already exists */
3579         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3580                              NULL, NULL, NULL, &type);
3581         unbecome_root();
3582
3583         if (!result) {
3584                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3585                 return NT_STATUS_OK;
3586         }
3587
3588         DEBUG(5, ("trying to create %s, exists as %s\n",
3589                   new_name, sid_type_lookup(type)));
3590
3591         if (type == SID_NAME_DOM_GRP) {
3592                 return NT_STATUS_GROUP_EXISTS;
3593         }
3594         if (type == SID_NAME_ALIAS) {
3595                 return NT_STATUS_ALIAS_EXISTS;
3596         }
3597
3598         /* Yes, the default is NT_STATUS_USER_EXISTS */
3599         return NT_STATUS_USER_EXISTS;
3600 }
3601
3602 /*******************************************************************
3603  _samr_CreateUser2
3604  ********************************************************************/
3605
3606 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3607                            struct samr_CreateUser2 *r)
3608 {
3609         const char *account = NULL;
3610         DOM_SID sid;
3611         uint32_t acb_info = r->in.acct_flags;
3612         struct samr_domain_info *dinfo;
3613         struct samr_user_info *uinfo;
3614         NTSTATUS nt_status;
3615         uint32 acc_granted;
3616         SEC_DESC *psd;
3617         size_t    sd_size;
3618         /* check this, when giving away 'add computer to domain' privs */
3619         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3620         bool can_add_account = False;
3621         SE_PRIV se_rights;
3622
3623         dinfo = policy_handle_find(p, r->in.domain_handle,
3624                                    SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3625                                    struct samr_domain_info, &nt_status);
3626         if (!NT_STATUS_IS_OK(nt_status)) {
3627                 return nt_status;
3628         }
3629
3630         if (sid_check_is_builtin(&dinfo->sid)) {
3631                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3632                 return NT_STATUS_ACCESS_DENIED;
3633         }
3634
3635         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3636               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3637                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3638                    this parameter is not an account type */
3639                 return NT_STATUS_INVALID_PARAMETER;
3640         }
3641
3642         account = r->in.account_name->string;
3643         if (account == NULL) {
3644                 return NT_STATUS_NO_MEMORY;
3645         }
3646
3647         nt_status = can_create(p->mem_ctx, account);
3648         if (!NT_STATUS_IS_OK(nt_status)) {
3649                 return nt_status;
3650         }
3651
3652         /* determine which user right we need to check based on the acb_info */
3653
3654         if (geteuid() == sec_initial_uid()) {
3655                 se_priv_copy(&se_rights, &se_priv_none);
3656                 can_add_account = true;
3657         } else if (acb_info & ACB_WSTRUST) {
3658                 se_priv_copy(&se_rights, &se_machine_account);
3659                 can_add_account = user_has_privileges(
3660                         p->server_info->ptok, &se_rights );
3661         } else if (acb_info & ACB_NORMAL &&
3662                   (account[strlen(account)-1] != '$')) {
3663                 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3664                    account for domain trusts and changes the ACB flags later */
3665                 se_priv_copy(&se_rights, &se_add_users);
3666                 can_add_account = user_has_privileges(
3667                         p->server_info->ptok, &se_rights );
3668         } else if (lp_enable_privileges()) {
3669                 /* implicit assumption of a BDC or domain trust account here
3670                  * (we already check the flags earlier) */
3671                 /* only Domain Admins can add a BDC or domain trust */
3672                 se_priv_copy(&se_rights, &se_priv_none);
3673                 can_add_account = nt_token_check_domain_rid(
3674                         p->server_info->ptok,
3675                         DOMAIN_GROUP_RID_ADMINS );
3676         }
3677
3678         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3679                   uidtoname(p->server_info->utok.uid),
3680                   can_add_account ? "True":"False" ));
3681
3682         if (!can_add_account) {
3683                 return NT_STATUS_ACCESS_DENIED;
3684         }
3685
3686         /********** BEGIN Admin BLOCK **********/
3687
3688         become_root();
3689         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3690                                     r->out.rid);
3691         unbecome_root();
3692
3693         /********** END Admin BLOCK **********/
3694
3695         /* now check for failure */
3696
3697         if ( !NT_STATUS_IS_OK(nt_status) )
3698                 return nt_status;
3699
3700         /* Get the user's SID */
3701
3702         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3703
3704         map_max_allowed_access(p->server_info->ptok, &des_access);
3705
3706         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3707                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3708         se_map_generic(&des_access, &usr_generic_mapping);
3709
3710         /*
3711          * JRA - TESTME. We just created this user so we
3712          * had rights to create them. Do we need to check
3713          * any further access on this object ? Can't we
3714          * just assume we have all the rights we need ?
3715          */
3716
3717         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3718                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3719                 &acc_granted, "_samr_CreateUser2");
3720
3721         if ( !NT_STATUS_IS_OK(nt_status) ) {
3722                 return nt_status;
3723         }
3724
3725         uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3726                                      struct samr_user_info, &nt_status);
3727         if (!NT_STATUS_IS_OK(nt_status)) {
3728                 return nt_status;
3729         }
3730         uinfo->sid = sid;
3731
3732         /* After a "set" ensure we have no cached display info. */
3733         force_flush_samr_cache(&sid);
3734
3735         *r->out.access_granted = acc_granted;
3736
3737         return NT_STATUS_OK;
3738 }
3739
3740 /****************************************************************
3741 ****************************************************************/
3742
3743 NTSTATUS _samr_CreateUser(pipes_struct *p,
3744                           struct samr_CreateUser *r)
3745 {
3746         struct samr_CreateUser2 c;
3747         uint32_t access_granted;
3748
3749         c.in.domain_handle      = r->in.domain_handle;
3750         c.in.account_name       = r->in.account_name;
3751         c.in.acct_flags         = ACB_NORMAL;
3752         c.in.access_mask        = r->in.access_mask;
3753         c.out.user_handle       = r->out.user_handle;
3754         c.out.access_granted    = &access_granted;
3755         c.out.rid               = r->out.rid;
3756
3757         return _samr_CreateUser2(p, &c);
3758 }
3759
3760 /*******************************************************************
3761  _samr_Connect
3762  ********************************************************************/
3763
3764 NTSTATUS _samr_Connect(pipes_struct *p,
3765                        struct samr_Connect *r)
3766 {
3767         struct samr_connect_info *info;
3768         uint32_t acc_granted;
3769         struct policy_handle hnd;
3770         uint32    des_access = r->in.access_mask;
3771         NTSTATUS status;
3772
3773         /* Access check */
3774
3775         if (!pipe_access_check(p)) {
3776                 DEBUG(3, ("access denied to _samr_Connect\n"));
3777                 return NT_STATUS_ACCESS_DENIED;
3778         }
3779
3780         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
3781            was observed from a win98 client trying to enumerate users (when configured
3782            user level access control on shares)   --jerry */
3783
3784         map_max_allowed_access(p->server_info->ptok, &des_access);
3785
3786         se_map_generic( &des_access, &sam_generic_mapping );
3787
3788         acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3789                                     |SAMR_ACCESS_LOOKUP_DOMAIN);
3790
3791         /* set up the SAMR connect_anon response */
3792
3793         info = policy_handle_create(p, &hnd, acc_granted,
3794                                     struct samr_connect_info,
3795                                     &status);
3796         if (!NT_STATUS_IS_OK(status)) {
3797                 return status;
3798         }
3799
3800         *r->out.connect_handle = hnd;
3801         return NT_STATUS_OK;
3802 }
3803
3804 /*******************************************************************
3805  _samr_Connect2
3806  ********************************************************************/
3807
3808 NTSTATUS _samr_Connect2(pipes_struct *p,
3809                         struct samr_Connect2 *r)
3810 {
3811         struct samr_connect_info *info = NULL;
3812         struct policy_handle hnd;
3813         SEC_DESC *psd = NULL;
3814         uint32    acc_granted;
3815         uint32    des_access = r->in.access_mask;
3816         NTSTATUS  nt_status;
3817         size_t    sd_size;
3818         const char *fn = "_samr_Connect2";
3819
3820         switch (p->hdr_req.opnum) {
3821         case NDR_SAMR_CONNECT2:
3822                 fn = "_samr_Connect2";
3823                 break;
3824         case NDR_SAMR_CONNECT3:
3825                 fn = "_samr_Connect3";
3826                 break;
3827         case NDR_SAMR_CONNECT4:
3828                 fn = "_samr_Connect4";
3829                 break;
3830         case NDR_SAMR_CONNECT5:
3831                 fn = "_samr_Connect5";
3832                 break;
3833         }
3834
3835         DEBUG(5,("%s: %d\n", fn, __LINE__));
3836
3837         /* Access check */
3838
3839         if (!pipe_access_check(p)) {
3840                 DEBUG(3, ("access denied to %s\n", fn));
3841                 return NT_STATUS_ACCESS_DENIED;
3842         }
3843
3844         map_max_allowed_access(p->server_info->ptok, &des_access);
3845
3846         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3847         se_map_generic(&des_access, &sam_generic_mapping);
3848
3849         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3850                 NULL, 0, des_access, &acc_granted, fn);
3851
3852         if ( !NT_STATUS_IS_OK(nt_status) )
3853                 return nt_status;
3854
3855         info = policy_handle_create(p, &hnd, acc_granted,
3856                                     struct samr_connect_info, &nt_status);
3857         if (!NT_STATUS_IS_OK(nt_status)) {
3858                 return nt_status;
3859         }
3860
3861         DEBUG(5,("%s: %d\n", fn, __LINE__));
3862
3863         *r->out.connect_handle = hnd;
3864         return NT_STATUS_OK;
3865 }
3866
3867 /****************************************************************
3868  _samr_Connect3
3869 ****************************************************************/
3870
3871 NTSTATUS _samr_Connect3(pipes_struct *p,
3872                         struct samr_Connect3 *r)
3873 {
3874         struct samr_Connect2 c;
3875
3876         c.in.system_name        = r->in.system_name;
3877         c.in.access_mask        = r->in.access_mask;
3878         c.out.connect_handle    = r->out.connect_handle;
3879
3880         return _samr_Connect2(p, &c);
3881 }
3882
3883 /*******************************************************************
3884  _samr_Connect4
3885  ********************************************************************/
3886
3887 NTSTATUS _samr_Connect4(pipes_struct *p,
3888                         struct samr_Connect4 *r)
3889 {
3890         struct samr_Connect2 c;
3891
3892         c.in.system_name        = r->in.system_name;
3893         c.in.access_mask        = r->in.access_mask;
3894         c.out.connect_handle    = r->out.connect_handle;
3895
3896         return _samr_Connect2(p, &c);
3897 }
3898
3899 /*******************************************************************
3900  _samr_Connect5
3901  ********************************************************************/
3902
3903 NTSTATUS _samr_Connect5(pipes_struct *p,
3904                         struct samr_Connect5 *r)
3905 {
3906         NTSTATUS status;
3907         struct samr_Connect2 c;
3908         struct samr_ConnectInfo1 info1;
3909
3910         info1.client_version = SAMR_CONNECT_AFTER_W2K;
3911         info1.unknown2 = 0;
3912
3913         c.in.system_name        = r->in.system_name;
3914         c.in.access_mask        = r->in.access_mask;
3915         c.out.connect_handle    = r->out.connect_handle;
3916
3917         *r->out.level_out = 1;
3918
3919         status = _samr_Connect2(p, &c);
3920         if (!NT_STATUS_IS_OK(status)) {
3921                 return status;
3922         }
3923
3924         r->out.info_out->info1 = info1;
3925
3926         return NT_STATUS_OK;
3927 }
3928
3929 /**********************************************************************
3930  _samr_LookupDomain
3931  **********************************************************************/
3932
3933 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3934                             struct samr_LookupDomain *r)
3935 {
3936         NTSTATUS status;
3937         struct samr_connect_info *info;
3938         const char *domain_name;
3939         DOM_SID *sid = NULL;
3940
3941         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3942            Reverted that change so we will work with RAS servers again */
3943
3944         info = policy_handle_find(p, r->in.connect_handle,
3945                                   SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3946                                   struct samr_connect_info,
3947                                   &status);
3948         if (!NT_STATUS_IS_OK(status)) {
3949                 return status;
3950         }
3951
3952         domain_name = r->in.domain_name->string;
3953         if (!domain_name) {
3954                 return NT_STATUS_INVALID_PARAMETER;
3955         }
3956
3957         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3958         if (!sid) {
3959                 return NT_STATUS_NO_MEMORY;
3960         }
3961
3962         if (strequal(domain_name, builtin_domain_name())) {
3963                 sid_copy(sid, &global_sid_Builtin);
3964         } else {
3965                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3966                         status = NT_STATUS_NO_SUCH_DOMAIN;
3967                 }
3968         }
3969
3970         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3971                  sid_string_dbg(sid)));
3972
3973         *r->out.sid = sid;
3974
3975         return status;
3976 }
3977
3978 /**********************************************************************
3979  _samr_EnumDomains
3980  **********************************************************************/
3981
3982 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3983                            struct samr_EnumDomains *r)
3984 {
3985         NTSTATUS status;
3986         struct samr_connect_info *info;
3987         uint32_t num_entries = 2;
3988         struct samr_SamEntry *entry_array = NULL;
3989         struct samr_SamArray *sam;
3990
3991         info = policy_handle_find(p, r->in.connect_handle,
3992                                   SAMR_ACCESS_ENUM_DOMAINS, NULL,
3993                                   struct samr_connect_info, &status);
3994         if (!NT_STATUS_IS_OK(status)) {
3995                 return status;
3996         }
3997
3998         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3999         if (!sam) {
4000                 return NT_STATUS_NO_MEMORY;
4001         }
4002
4003         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4004                                         struct samr_SamEntry,
4005                                         num_entries);
4006         if (!entry_array) {
4007                 return NT_STATUS_NO_MEMORY;
4008         }
4009
4010         entry_array[0].idx = 0;
4011         init_lsa_String(&entry_array[0].name, get_global_sam_name());
4012
4013         entry_array[1].idx = 1;
4014         init_lsa_String(&entry_array[1].name, "Builtin");
4015
4016         sam->count = num_entries;
4017         sam->entries = entry_array;
4018
4019         *r->out.sam = sam;
4020         *r->out.num_entries = num_entries;
4021
4022         return status;
4023 }
4024
4025 /*******************************************************************
4026  _samr_OpenAlias
4027  ********************************************************************/
4028
4029 NTSTATUS _samr_OpenAlias(pipes_struct *p,
4030                          struct samr_OpenAlias *r)
4031 {
4032         DOM_SID sid;
4033         uint32 alias_rid = r->in.rid;
4034         struct samr_alias_info *ainfo;
4035         struct samr_domain_info *dinfo;
4036         SEC_DESC *psd = NULL;
4037         uint32    acc_granted;
4038         uint32    des_access = r->in.access_mask;
4039         size_t    sd_size;
4040         NTSTATUS  status;
4041         SE_PRIV se_rights;
4042
4043         dinfo = policy_handle_find(p, r->in.domain_handle,
4044                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4045                                    struct samr_domain_info, &status);
4046         if (!NT_STATUS_IS_OK(status)) {
4047                 return status;
4048         }
4049
4050         /* append the alias' RID to it */
4051
4052         if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4053                 return NT_STATUS_NO_SUCH_ALIAS;
4054
4055         /*check if access can be granted as requested by client. */
4056
4057         map_max_allowed_access(p->server_info->ptok, &des_access);
4058
4059         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4060         se_map_generic(&des_access,&ali_generic_mapping);
4061
4062         se_priv_copy( &se_rights, &se_add_users );
4063
4064         status = access_check_samr_object(psd, p->server_info->ptok,
4065                 &se_rights, SAMR_ALIAS_ACCESS_ADD_MEMBER,
4066                 des_access, &acc_granted, "_samr_OpenAlias");
4067
4068         if ( !NT_STATUS_IS_OK(status) )
4069                 return status;
4070
4071         {
4072                 /* Check we actually have the requested alias */
4073                 enum lsa_SidType type;
4074                 bool result;
4075                 gid_t gid;
4076
4077                 become_root();
4078                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4079                 unbecome_root();
4080
4081                 if (!result || (type != SID_NAME_ALIAS)) {
4082                         return NT_STATUS_NO_SUCH_ALIAS;
4083                 }
4084
4085                 /* make sure there is a mapping */
4086
4087                 if ( !sid_to_gid( &sid, &gid ) ) {
4088                         return NT_STATUS_NO_SUCH_ALIAS;
4089                 }
4090
4091         }
4092
4093         ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4094                                      struct samr_alias_info, &status);
4095         if (!NT_STATUS_IS_OK(status)) {
4096                 return status;
4097         }
4098         ainfo->sid = sid;
4099
4100         return NT_STATUS_OK;
4101 }
4102
4103 /*******************************************************************
4104  set_user_info_2
4105  ********************************************************************/
4106
4107 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4108                                 struct samr_UserInfo2 *id2,
4109                                 struct samu *pwd)
4110 {
4111         if (id2 == NULL) {
4112                 DEBUG(5,("set_user_info_2: NULL id2\n"));
4113                 return NT_STATUS_ACCESS_DENIED;
4114         }
4115
4116         copy_id2_to_sam_passwd(pwd, id2);
4117
4118         return pdb_update_sam_account(pwd);
4119 }
4120
4121 /*******************************************************************
4122  set_user_info_4
4123  ********************************************************************/
4124
4125 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4126                                 struct samr_UserInfo4 *id4,
4127                                 struct samu *pwd)
4128 {
4129         if (id4 == NULL) {
4130                 DEBUG(5,("set_user_info_2: NULL id4\n"));
4131                 return NT_STATUS_ACCESS_DENIED;
4132         }
4133
4134         copy_id4_to_sam_passwd(pwd, id4);
4135
4136         return pdb_update_sam_account(pwd);
4137 }
4138
4139 /*******************************************************************
4140  set_user_info_6
4141  ********************************************************************/
4142
4143 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4144                                 struct samr_UserInfo6 *id6,
4145                                 struct samu *pwd)
4146 {
4147         if (id6 == NULL) {
4148                 DEBUG(5,("set_user_info_6: NULL id6\n"));
4149                 return NT_STATUS_ACCESS_DENIED;
4150         }
4151
4152         copy_id6_to_sam_passwd(pwd, id6);
4153
4154         return pdb_update_sam_account(pwd);
4155 }
4156
4157 /*******************************************************************
4158  set_user_info_7
4159  ********************************************************************/
4160
4161 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4162                                 struct samr_UserInfo7 *id7,
4163                                 struct samu *pwd)
4164 {
4165         NTSTATUS rc;
4166
4167         if (id7 == NULL) {
4168                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4169                 return NT_STATUS_ACCESS_DENIED;
4170         }
4171
4172         if (!id7->account_name.string) {
4173                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4174                 return NT_STATUS_ACCESS_DENIED;
4175         }
4176
4177         /* check to see if the new username already exists.  Note: we can't
4178            reliably lock all backends, so there is potentially the
4179            possibility that a user can be created in between this check and
4180            the rename.  The rename should fail, but may not get the
4181            exact same failure status code.  I think this is small enough
4182            of a window for this type of operation and the results are
4183            simply that the rename fails with a slightly different status
4184            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4185
4186         rc = can_create(mem_ctx, id7->account_name.string);
4187
4188         /* when there is nothing to change, we're done here */
4189         if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4190             strequal(id7->account_name.string, pdb_get_username(pwd))) {
4191                 return NT_STATUS_OK;
4192         }
4193         if (!NT_STATUS_IS_OK(rc)) {
4194                 return rc;
4195         }
4196
4197         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4198
4199         return rc;
4200 }
4201
4202 /*******************************************************************
4203  set_user_info_8
4204  ********************************************************************/
4205
4206 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4207                                 struct samr_UserInfo8 *id8,
4208                                 struct samu *pwd)
4209 {
4210         if (id8 == NULL) {
4211                 DEBUG(5,("set_user_info_8: NULL id8\n"));
4212                 return NT_STATUS_ACCESS_DENIED;
4213         }
4214
4215         copy_id8_to_sam_passwd(pwd, id8);
4216
4217         return pdb_update_sam_account(pwd);
4218 }
4219
4220 /*******************************************************************
4221  set_user_info_10
4222  ********************************************************************/
4223
4224 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4225                                  struct samr_UserInfo10 *id10,
4226                                  struct samu *pwd)
4227 {
4228         if (id10 == NULL) {
4229                 DEBUG(5,("set_user_info_8: NULL id10\n"));
4230                 return NT_STATUS_ACCESS_DENIED;
4231         }
4232
4233         copy_id10_to_sam_passwd(pwd, id10);
4234
4235         return pdb_update_sam_account(pwd);
4236 }
4237
4238 /*******************************************************************
4239  set_user_info_11
4240  ********************************************************************/
4241
4242 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4243                                  struct samr_UserInfo11 *id11,
4244                                  struct samu *pwd)
4245 {
4246         if (id11 == NULL) {
4247                 DEBUG(5,("set_user_info_11: NULL id11\n"));
4248                 return NT_STATUS_ACCESS_DENIED;
4249         }
4250
4251         copy_id11_to_sam_passwd(pwd, id11);
4252
4253         return pdb_update_sam_account(pwd);
4254 }
4255
4256 /*******************************************************************
4257  set_user_info_12
4258  ********************************************************************/
4259
4260 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4261                                  struct samr_UserInfo12 *id12,
4262                                  struct samu *pwd)
4263 {
4264         if (id12 == NULL) {
4265                 DEBUG(5,("set_user_info_12: NULL id12\n"));
4266                 return NT_STATUS_ACCESS_DENIED;
4267         }
4268
4269         copy_id12_to_sam_passwd(pwd, id12);
4270
4271         return pdb_update_sam_account(pwd);
4272 }
4273
4274 /*******************************************************************
4275  set_user_info_13
4276  ********************************************************************/
4277
4278 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4279                                  struct samr_UserInfo13 *id13,
4280                                  struct samu *pwd)
4281 {
4282         if (id13 == NULL) {
4283                 DEBUG(5,("set_user_info_13: NULL id13\n"));
4284                 return NT_STATUS_ACCESS_DENIED;
4285         }
4286
4287         copy_id13_to_sam_passwd(pwd, id13);
4288
4289         return pdb_update_sam_account(pwd);
4290 }
4291
4292 /*******************************************************************
4293  set_user_info_14
4294  ********************************************************************/
4295
4296 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4297                                  struct samr_UserInfo14 *id14,
4298                                  struct samu *pwd)
4299 {
4300         if (id14 == NULL) {
4301                 DEBUG(5,("set_user_info_14: NULL id14\n"));
4302                 return NT_STATUS_ACCESS_DENIED;
4303         }
4304
4305         copy_id14_to_sam_passwd(pwd, id14);
4306
4307         return pdb_update_sam_account(pwd);
4308 }
4309
4310 /*******************************************************************
4311  set_user_info_16
4312  ********************************************************************/
4313
4314 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4315                                  struct samr_UserInfo16 *id16,
4316                                  struct samu *pwd)
4317 {
4318         if (id16 == NULL) {
4319                 DEBUG(5,("set_user_info_16: NULL id16\n"));
4320                 return NT_STATUS_ACCESS_DENIED;
4321         }
4322
4323         copy_id16_to_sam_passwd(pwd, id16);
4324
4325         return pdb_update_sam_account(pwd);
4326 }
4327
4328 /*******************************************************************
4329  set_user_info_17
4330  ********************************************************************/
4331
4332 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4333                                  struct samr_UserInfo17 *id17,
4334                                  struct samu *pwd)
4335 {
4336         if (id17 == NULL) {
4337                 DEBUG(5,("set_user_info_17: NULL id17\n"));
4338                 return NT_STATUS_ACCESS_DENIED;
4339         }
4340
4341         copy_id17_to_sam_passwd(pwd, id17);
4342
4343         return pdb_update_sam_account(pwd);
4344 }
4345
4346 /*******************************************************************
4347  set_user_info_18
4348  ********************************************************************/
4349
4350 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4351                                  TALLOC_CTX *mem_ctx,
4352                                  DATA_BLOB *session_key,
4353                                  struct samu *pwd)
4354 {
4355         if (id18 == NULL) {
4356                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4357                 return NT_STATUS_INVALID_PARAMETER;
4358         }
4359
4360         if (id18->nt_pwd_active || id18->lm_pwd_active) {
4361                 if (!session_key->length) {
4362                         return NT_STATUS_NO_USER_SESSION_KEY;
4363                 }
4364         }
4365
4366         if (id18->nt_pwd_active) {
4367
4368                 DATA_BLOB in, out;
4369
4370                 in = data_blob_const(id18->nt_pwd.hash, 16);
4371                 out = data_blob_talloc_zero(mem_ctx, 16);
4372
4373                 sess_crypt_blob(&out, &in, session_key, false);
4374
4375                 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4376                         return NT_STATUS_ACCESS_DENIED;
4377                 }
4378
4379                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4380         }
4381
4382         if (id18->lm_pwd_active) {
4383
4384                 DATA_BLOB in, out;
4385
4386                 in = data_blob_const(id18->lm_pwd.hash, 16);
4387                 out = data_blob_talloc_zero(mem_ctx, 16);
4388
4389                 sess_crypt_blob(&out, &in, session_key, false);
4390
4391                 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4392                         return NT_STATUS_ACCESS_DENIED;
4393                 }
4394
4395                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4396         }
4397
4398         copy_id18_to_sam_passwd(pwd, id18);
4399
4400         return pdb_update_sam_account(pwd);
4401 }
4402
4403 /*******************************************************************
4404  set_user_info_20
4405  ********************************************************************/
4406
4407 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4408                                  struct samr_UserInfo20 *id20,
4409                                  struct samu *pwd)
4410 {
4411         if (id20 == NULL) {
4412                 DEBUG(5,("set_user_info_20: NULL id20\n"));
4413                 return NT_STATUS_ACCESS_DENIED;
4414         }
4415
4416         copy_id20_to_sam_passwd(pwd, id20);
4417
4418         return pdb_update_sam_account(pwd);
4419 }
4420
4421 /*******************************************************************
4422  set_user_info_21
4423  ********************************************************************/
4424
4425 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4426                                  TALLOC_CTX *mem_ctx,
4427                                  DATA_BLOB *session_key,
4428                                  struct samu *pwd)
4429 {
4430         NTSTATUS status;
4431
4432         if (id21 == NULL) {
4433                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4434                 return NT_STATUS_INVALID_PARAMETER;
4435         }
4436
4437         if (id21->fields_present == 0) {
4438                 return NT_STATUS_INVALID_PARAMETER;
4439         }
4440
4441         if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4442                 return NT_STATUS_ACCESS_DENIED;
4443         }
4444
4445         if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4446                 if (id21->nt_password_set) {
4447                         DATA_BLOB in, out;
4448
4449                         if ((id21->nt_owf_password.length != 16) ||
4450                             (id21->nt_owf_password.size != 16)) {
4451                                 return NT_STATUS_INVALID_PARAMETER;
4452                         }
4453
4454                         if (!session_key->length) {
4455                                 return NT_STATUS_NO_USER_SESSION_KEY;
4456                         }
4457
4458                         in = data_blob_const(id21->nt_owf_password.array, 16);
4459                         out = data_blob_talloc_zero(mem_ctx, 16);
4460
4461                         sess_crypt_blob(&out, &in, session_key, false);
4462
4463                         pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4464                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4465                 }
4466         }
4467
4468         if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4469                 if (id21->lm_password_set) {
4470                         DATA_BLOB in, out;
4471
4472                         if ((id21->lm_owf_password.length != 16) ||
4473                             (id21->lm_owf_password.size != 16)) {
4474                                 return NT_STATUS_INVALID_PARAMETER;
4475                         }
4476
4477                         if (!session_key->length) {
4478                                 return NT_STATUS_NO_USER_SESSION_KEY;
4479                         }
4480
4481                         in = data_blob_const(id21->lm_owf_password.array, 16);
4482                         out = data_blob_talloc_zero(mem_ctx, 16);
4483
4484                         sess_crypt_blob(&out, &in, session_key, false);
4485
4486                         pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4487                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4488                 }
4489         }
4490
4491         /* we need to separately check for an account rename first */
4492
4493         if (id21->account_name.string &&
4494             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4495         {
4496
4497                 /* check to see if the new username already exists.  Note: we can't
4498                    reliably lock all backends, so there is potentially the
4499                    possibility that a user can be created in between this check and
4500                    the rename.  The rename should fail, but may not get the
4501                    exact same failure status code.  I think this is small enough
4502                    of a window for this type of operation and the results are
4503                    simply that the rename fails with a slightly different status
4504                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4505
4506                 status = can_create(mem_ctx, id21->account_name.string);
4507                 if (!NT_STATUS_IS_OK(status)) {
4508                         return status;
4509                 }
4510
4511                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4512
4513                 if (!NT_STATUS_IS_OK(status)) {
4514                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4515                                 nt_errstr(status)));
4516                         return status;
4517                 }
4518
4519                 /* set the new username so that later
4520                    functions can work on the new account */
4521                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4522         }
4523
4524         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4525
4526         /*
4527          * The funny part about the previous two calls is
4528          * that pwd still has the password hashes from the
4529          * passdb entry.  These have not been updated from
4530          * id21.  I don't know if they need to be set.    --jerry
4531          */
4532
4533         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4534                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4535                 if ( !NT_STATUS_IS_OK(status) ) {
4536                         return status;
4537                 }
4538         }
4539
4540         /* Don't worry about writing out the user account since the
4541            primary group SID is generated solely from the user's Unix
4542            primary group. */
4543
4544         /* write the change out */
4545         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4546                 return status;
4547         }
4548
4549         return NT_STATUS_OK;
4550 }
4551
4552 /*******************************************************************
4553  set_user_info_23
4554  ********************************************************************/
4555
4556 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4557                                  struct samr_UserInfo23 *id23,
4558                                  struct samu *pwd)
4559 {
4560         char *plaintext_buf = NULL;
4561         size_t len = 0;
4562         uint32_t acct_ctrl;
4563         NTSTATUS status;
4564
4565         if (id23 == NULL) {
4566                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4567                 return NT_STATUS_INVALID_PARAMETER;
4568         }
4569
4570         if (id23->info.fields_present == 0) {
4571                 return NT_STATUS_INVALID_PARAMETER;
4572         }
4573
4574         if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4575                 return NT_STATUS_ACCESS_DENIED;
4576         }
4577
4578         if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4579             (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4580
4581                 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4582                           pdb_get_username(pwd)));
4583
4584                 if (!decode_pw_buffer(mem_ctx,
4585                                       id23->password.data,
4586                                       &plaintext_buf,
4587                                       &len,
4588                                       CH_UTF16)) {
4589                         return NT_STATUS_WRONG_PASSWORD;
4590                 }
4591
4592                 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4593                         return NT_STATUS_ACCESS_DENIED;
4594                 }
4595         }
4596
4597         copy_id23_to_sam_passwd(pwd, id23);
4598
4599         acct_ctrl = pdb_get_acct_ctrl(pwd);
4600
4601         /* if it's a trust account, don't update /etc/passwd */
4602         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4603                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4604                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4605                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
4606         } else if (plaintext_buf) {
4607                 /* update the UNIX password */
4608                 if (lp_unix_password_sync() ) {
4609                         struct passwd *passwd;
4610                         if (pdb_get_username(pwd) == NULL) {
4611                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4612                                 return NT_STATUS_ACCESS_DENIED;
4613                         }
4614
4615                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4616                         if (passwd == NULL) {
4617                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4618                         }
4619
4620                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4621                                 return NT_STATUS_ACCESS_DENIED;
4622                         }
4623                         TALLOC_FREE(passwd);
4624                 }
4625         }
4626
4627         if (plaintext_buf) {
4628                 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4629         }
4630
4631         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4632             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
4633                                                                    pwd)))) {
4634                 return status;
4635         }
4636
4637         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4638                 return status;
4639         }
4640
4641         return NT_STATUS_OK;
4642 }
4643
4644 /*******************************************************************
4645  set_user_info_pw
4646  ********************************************************************/
4647
4648 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4649 {
4650         size_t len = 0;
4651         char *plaintext_buf = NULL;
4652         uint32 acct_ctrl;
4653
4654         DEBUG(5, ("Attempting administrator password change for user %s\n",
4655                   pdb_get_username(pwd)));
4656
4657         acct_ctrl = pdb_get_acct_ctrl(pwd);
4658
4659         if (!decode_pw_buffer(talloc_tos(),
4660                                 pass,
4661                                 &plaintext_buf,
4662                                 &len,
4663                                 CH_UTF16)) {
4664                 return False;
4665         }
4666
4667         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4668                 return False;
4669         }
4670
4671         /* if it's a trust account, don't update /etc/passwd */
4672         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4673                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4674                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4675                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4676         } else {
4677                 /* update the UNIX password */
4678                 if (lp_unix_password_sync()) {
4679                         struct passwd *passwd;
4680
4681                         if (pdb_get_username(pwd) == NULL) {
4682                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4683                                 return False;
4684                         }
4685
4686                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4687                         if (passwd == NULL) {
4688                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4689                         }
4690
4691                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4692                                 return False;
4693                         }
4694                         TALLOC_FREE(passwd);
4695                 }
4696         }
4697
4698         memset(plaintext_buf, '\0', strlen(plaintext_buf));
4699
4700         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4701
4702         return True;
4703 }
4704
4705 /*******************************************************************
4706  set_user_info_24
4707  ********************************************************************/
4708
4709 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4710                                  struct samr_UserInfo24 *id24,
4711                                  struct samu *pwd)
4712 {
4713         NTSTATUS status;
4714
4715         if (id24 == NULL) {
4716                 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4717                 return NT_STATUS_INVALID_PARAMETER;
4718         }
4719
4720         if (!set_user_info_pw(id24->password.data, pwd)) {
4721                 return NT_STATUS_WRONG_PASSWORD;
4722         }
4723
4724         copy_id24_to_sam_passwd(pwd, id24);
4725
4726         status = pdb_update_sam_account(pwd);
4727         if (!NT_STATUS_IS_OK(status)) {
4728                 return status;
4729         }
4730
4731         return NT_STATUS_OK;
4732 }
4733
4734 /*******************************************************************
4735  set_user_info_25
4736  ********************************************************************/
4737
4738 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4739                                  struct samr_UserInfo25 *id25,
4740                                  struct samu *pwd)
4741 {
4742         NTSTATUS status;
4743
4744         if (id25 == NULL) {
4745                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4746                 return NT_STATUS_INVALID_PARAMETER;
4747         }
4748
4749         if (id25->info.fields_present == 0) {
4750                 return NT_STATUS_INVALID_PARAMETER;
4751         }
4752
4753         if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4754                 return NT_STATUS_ACCESS_DENIED;
4755         }
4756
4757         if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4758             (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4759
4760                 if (!set_user_info_pw(id25->password.data, pwd)) {
4761                         return NT_STATUS_WRONG_PASSWORD;
4762                 }
4763         }
4764
4765         copy_id25_to_sam_passwd(pwd, id25);
4766
4767         /* write the change out */
4768         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4769                 return status;
4770         }
4771
4772         /*
4773          * We need to "pdb_update_sam_account" before the unix primary group
4774          * is set, because the idealx scripts would also change the
4775          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4776          * the delete explicit / add explicit, which would then fail to find
4777          * the previous primaryGroupSid value.
4778          */
4779
4780         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4781                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4782                 if ( !NT_STATUS_IS_OK(status) ) {
4783                         return status;
4784                 }
4785         }
4786
4787         return NT_STATUS_OK;
4788 }
4789
4790 /*******************************************************************
4791  set_user_info_26
4792  ********************************************************************/
4793
4794 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4795                                  struct samr_UserInfo26 *id26,
4796                                  struct samu *pwd)
4797 {
4798         NTSTATUS status;
4799
4800         if (id26 == NULL) {
4801                 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4802                 return NT_STATUS_INVALID_PARAMETER;
4803         }
4804
4805         if (!set_user_info_pw(id26->password.data, pwd)) {
4806                 return NT_STATUS_WRONG_PASSWORD;
4807         }
4808
4809         copy_id26_to_sam_passwd(pwd, id26);
4810
4811         status = pdb_update_sam_account(pwd);
4812         if (!NT_STATUS_IS_OK(status)) {
4813                 return status;
4814         }
4815
4816         return NT_STATUS_OK;
4817 }
4818
4819
4820 /*******************************************************************
4821  samr_SetUserInfo
4822  ********************************************************************/
4823
4824 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4825                            struct samr_SetUserInfo *r)
4826 {
4827         struct samr_user_info *uinfo;
4828         NTSTATUS status;
4829         struct samu *pwd = NULL;
4830         union samr_UserInfo *info = r->in.info;
4831         uint16_t switch_value = r->in.level;
4832         uint32_t acc_required;
4833         bool ret;
4834
4835         DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4836
4837         /* This is tricky.  A WinXP domain join sets
4838           (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4839           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
4840           standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4841           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
4842           we'll use the set from the WinXP join as the basis. */
4843
4844         switch (switch_value) {
4845         case 7:
4846                 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
4847                 break;
4848         case 18:
4849         case 24:
4850         case 25:
4851         case 26:
4852                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4853                 break;
4854         default:
4855                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4856                                SAMR_USER_ACCESS_SET_ATTRIBUTES |
4857                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
4858                 break;
4859         }
4860
4861         uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
4862                                    struct samr_user_info, &status);
4863         if (!NT_STATUS_IS_OK(status)) {
4864                 return status;
4865         }
4866
4867         DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4868                   sid_string_dbg(&uinfo->sid), switch_value));
4869
4870         if (info == NULL) {
4871                 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4872                 return NT_STATUS_INVALID_INFO_CLASS;
4873         }
4874
4875         if (!(pwd = samu_new(NULL))) {
4876                 return NT_STATUS_NO_MEMORY;
4877         }
4878
4879         become_root();
4880         ret = pdb_getsampwsid(pwd, &uinfo->sid);
4881         unbecome_root();
4882
4883         if (!ret) {
4884                 TALLOC_FREE(pwd);
4885                 return NT_STATUS_NO_SUCH_USER;
4886         }
4887
4888         /* ================ BEGIN Privilege BLOCK ================ */
4889
4890         become_root();
4891
4892         /* ok!  user info levels (lots: see MSDEV help), off we go... */
4893
4894         switch (switch_value) {
4895
4896                 case 2:
4897                         status = set_user_info_2(p->mem_ctx,
4898                                                  &info->info2, pwd);
4899                         break;
4900
4901                 case 4:
4902                         status = set_user_info_4(p->mem_ctx,
4903                                                  &info->info4, pwd);
4904                         break;
4905
4906                 case 6:
4907                         status = set_user_info_6(p->mem_ctx,
4908                                                  &info->info6, pwd);
4909                         break;
4910
4911                 case 7:
4912                         status = set_user_info_7(p->mem_ctx,
4913                                                  &info->info7, pwd);
4914                         break;
4915
4916                 case 8:
4917                         status = set_user_info_8(p->mem_ctx,
4918                                                  &info->info8, pwd);
4919                         break;
4920
4921                 case 10:
4922                         status = set_user_info_10(p->mem_ctx,
4923                                                   &info->info10, pwd);
4924                         break;
4925
4926                 case 11:
4927                         status = set_user_info_11(p->mem_ctx,
4928                                                   &info->info11, pwd);
4929                         break;
4930
4931                 case 12:
4932                         status = set_user_info_12(p->mem_ctx,
4933                                                   &info->info12, pwd);
4934                         break;
4935
4936                 case 13:
4937                         status = set_user_info_13(p->mem_ctx,
4938                                                   &info->info13, pwd);
4939                         break;
4940
4941                 case 14:
4942                         status = set_user_info_14(p->mem_ctx,
4943                                                   &info->info14, pwd);
4944                         break;
4945
4946                 case 16:
4947                         status = set_user_info_16(p->mem_ctx,
4948                                                   &info->info16, pwd);
4949                         break;
4950
4951                 case 17:
4952                         status = set_user_info_17(p->mem_ctx,
4953                                                   &info->info17, pwd);
4954                         break;
4955
4956                 case 18:
4957                         /* Used by AS/U JRA. */
4958                         status = set_user_info_18(&info->info18,
4959                                                   p->mem_ctx,
4960                                                   &p->server_info->user_session_key,
4961                                                   pwd);
4962                         break;
4963
4964                 case 20:
4965                         status = set_user_info_20(p->mem_ctx,
4966                                                   &info->info20, pwd);
4967                         break;
4968
4969                 case 21:
4970                         status = set_user_info_21(&info->info21,
4971                                                   p->mem_ctx,
4972                                                   &p->server_info->user_session_key,
4973                                                   pwd);
4974                         break;
4975
4976                 case 23:
4977                         if (!p->server_info->user_session_key.length) {
4978                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4979                         }
4980                         arcfour_crypt_blob(info->info23.password.data, 516,
4981                                            &p->server_info->user_session_key);
4982
4983                         dump_data(100, info->info23.password.data, 516);
4984
4985                         status = set_user_info_23(p->mem_ctx,
4986                                                   &info->info23, pwd);
4987                         break;
4988
4989                 case 24:
4990                         if (!p->server_info->user_session_key.length) {
4991                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4992                         }
4993                         arcfour_crypt_blob(info->info24.password.data,
4994                                            516,
4995                                            &p->server_info->user_session_key);
4996
4997                         dump_data(100, info->info24.password.data, 516);
4998
4999                         status = set_user_info_24(p->mem_ctx,
5000                                                   &info->info24, pwd);
5001                         break;
5002
5003                 case 25:
5004                         if (!p->server_info->user_session_key.length) {
5005                                 status = NT_STATUS_NO_USER_SESSION_KEY;
5006                         }
5007                         encode_or_decode_arc4_passwd_buffer(
5008                                 info->info25.password.data,
5009                                 &p->server_info->user_session_key);
5010
5011                         dump_data(100, info->info25.password.data, 532);
5012
5013                         status = set_user_info_25(p->mem_ctx,
5014                                                   &info->info25, pwd);
5015                         break;
5016
5017                 case 26:
5018                         if (!p->server_info->user_session_key.length) {
5019                                 status = NT_STATUS_NO_USER_SESSION_KEY;
5020                         }
5021                         encode_or_decode_arc4_passwd_buffer(
5022                                 info->info26.password.data,
5023                                 &p->server_info->user_session_key);
5024
5025                         dump_data(100, info->info26.password.data, 516);
5026
5027                         status = set_user_info_26(p->mem_ctx,
5028                                                   &info->info26, pwd);
5029                         break;
5030
5031                 default:
5032                         status = NT_STATUS_INVALID_INFO_CLASS;
5033         }
5034
5035         TALLOC_FREE(pwd);
5036
5037         unbecome_root();
5038
5039         /* ================ END Privilege BLOCK ================ */
5040
5041         if (NT_STATUS_IS_OK(status)) {
5042                 force_flush_samr_cache(&uinfo->sid);
5043         }
5044
5045         return status;
5046 }
5047
5048 /*******************************************************************
5049  _samr_SetUserInfo2
5050  ********************************************************************/
5051
5052 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
5053                             struct samr_SetUserInfo2 *r)
5054 {
5055         struct samr_SetUserInfo q;
5056
5057         q.in.user_handle        = r->in.user_handle;
5058         q.in.level              = r->in.level;
5059         q.in.info               = r->in.info;
5060
5061         return _samr_SetUserInfo(p, &q);
5062 }
5063
5064 /*********************************************************************
5065  _samr_GetAliasMembership
5066 *********************************************************************/
5067
5068 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
5069                                   struct samr_GetAliasMembership *r)
5070 {
5071         size_t num_alias_rids;
5072         uint32 *alias_rids;
5073         struct samr_domain_info *dinfo;
5074         size_t i;
5075
5076         NTSTATUS status;
5077
5078         DOM_SID *members;
5079
5080         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5081
5082         dinfo = policy_handle_find(p, r->in.domain_handle,
5083                                    SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5084                                    | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5085                                    struct samr_domain_info, &status);
5086         if (!NT_STATUS_IS_OK(status)) {
5087                 return status;
5088         }
5089
5090         if (!sid_check_is_domain(&dinfo->sid) &&
5091             !sid_check_is_builtin(&dinfo->sid))
5092                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5093
5094         if (r->in.sids->num_sids) {
5095                 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
5096
5097                 if (members == NULL)
5098                         return NT_STATUS_NO_MEMORY;
5099         } else {
5100                 members = NULL;
5101         }
5102
5103         for (i=0; i<r->in.sids->num_sids; i++)
5104                 sid_copy(&members[i], r->in.sids->sids[i].sid);
5105
5106         alias_rids = NULL;
5107         num_alias_rids = 0;
5108
5109         become_root();
5110         status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5111                                             r->in.sids->num_sids,
5112                                             &alias_rids, &num_alias_rids);
5113         unbecome_root();
5114
5115         if (!NT_STATUS_IS_OK(status)) {
5116                 return status;
5117         }
5118
5119         r->out.rids->count = num_alias_rids;
5120         r->out.rids->ids = alias_rids;
5121
5122         return NT_STATUS_OK;
5123 }
5124
5125 /*********************************************************************
5126  _samr_GetMembersInAlias
5127 *********************************************************************/
5128
5129 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5130                                  struct samr_GetMembersInAlias *r)
5131 {
5132         struct samr_alias_info *ainfo;
5133         NTSTATUS status;
5134         size_t i;
5135         size_t num_sids = 0;
5136         struct lsa_SidPtr *sids = NULL;
5137         DOM_SID *pdb_sids = NULL;
5138
5139         ainfo = policy_handle_find(p, r->in.alias_handle,
5140                                    SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5141                                    struct samr_alias_info, &status);
5142         if (!NT_STATUS_IS_OK(status)) {
5143                 return status;
5144         }
5145
5146         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5147
5148         become_root();
5149         status = pdb_enum_aliasmem(&ainfo->sid, &pdb_sids, &num_sids);
5150         unbecome_root();
5151
5152         if (!NT_STATUS_IS_OK(status)) {
5153                 return status;
5154         }
5155
5156         if (num_sids) {
5157                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5158                 if (sids == NULL) {
5159                         TALLOC_FREE(pdb_sids);
5160                         return NT_STATUS_NO_MEMORY;
5161                 }
5162         }
5163
5164         for (i = 0; i < num_sids; i++) {
5165                 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5166                 if (!sids[i].sid) {
5167                         TALLOC_FREE(pdb_sids);
5168                         return NT_STATUS_NO_MEMORY;
5169                 }
5170         }
5171
5172         r->out.sids->num_sids = num_sids;
5173         r->out.sids->sids = sids;
5174
5175         TALLOC_FREE(pdb_sids);
5176
5177         return NT_STATUS_OK;
5178 }
5179
5180 /*********************************************************************
5181  _samr_QueryGroupMember
5182 *********************************************************************/
5183
5184 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5185                                 struct samr_QueryGroupMember *r)
5186 {
5187         struct samr_group_info *ginfo;
5188         size_t i, num_members;
5189
5190         uint32 *rid=NULL;
5191         uint32 *attr=NULL;
5192
5193         NTSTATUS status;
5194         struct samr_RidTypeArray *rids = NULL;
5195
5196         ginfo = policy_handle_find(p, r->in.group_handle,
5197                                    SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5198                                    struct samr_group_info, &status);
5199         if (!NT_STATUS_IS_OK(status)) {
5200                 return status;
5201         }
5202
5203         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5204         if (!rids) {
5205                 return NT_STATUS_NO_MEMORY;
5206         }
5207
5208         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5209
5210         if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5211                 DEBUG(3, ("sid %s is not in our domain\n",
5212                           sid_string_dbg(&ginfo->sid)));
5213                 return NT_STATUS_NO_SUCH_GROUP;
5214         }
5215
5216         DEBUG(10, ("lookup on Domain SID\n"));
5217
5218         become_root();
5219         status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5220                                         &rid, &num_members);
5221         unbecome_root();
5222
5223         if (!NT_STATUS_IS_OK(status))
5224                 return status;
5225
5226         if (num_members) {
5227                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5228                 if (attr == NULL) {
5229                         return NT_STATUS_NO_MEMORY;
5230                 }
5231         } else {
5232                 attr = NULL;
5233         }
5234
5235         for (i=0; i<num_members; i++)
5236                 attr[i] = SID_NAME_USER;
5237
5238         rids->count = num_members;
5239         rids->types = attr;
5240         rids->rids = rid;
5241
5242         *r->out.rids = rids;
5243
5244         return NT_STATUS_OK;
5245 }
5246
5247 /*********************************************************************
5248  _samr_AddAliasMember
5249 *********************************************************************/
5250
5251 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5252                               struct samr_AddAliasMember *r)
5253 {
5254         struct samr_alias_info *ainfo;
5255         NTSTATUS status;
5256
5257         ainfo = policy_handle_find(p, r->in.alias_handle,
5258                                    SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5259                                    struct samr_alias_info, &status);
5260         if (!NT_STATUS_IS_OK(status)) {
5261                 return status;
5262         }
5263
5264         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5265
5266         /******** BEGIN SeAddUsers BLOCK *********/
5267
5268         become_root();
5269         status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5270         unbecome_root();
5271
5272         /******** END SeAddUsers BLOCK *********/
5273
5274         if (NT_STATUS_IS_OK(status)) {
5275                 force_flush_samr_cache(&ainfo->sid);
5276         }
5277
5278         return status;
5279 }
5280
5281 /*********************************************************************
5282  _samr_DeleteAliasMember
5283 *********************************************************************/
5284
5285 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5286                                  struct samr_DeleteAliasMember *r)
5287 {
5288         struct samr_alias_info *ainfo;
5289         NTSTATUS status;
5290
5291         ainfo = policy_handle_find(p, r->in.alias_handle,
5292                                    SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5293                                    struct samr_alias_info, &status);
5294         if (!NT_STATUS_IS_OK(status)) {
5295                 return status;
5296         }
5297
5298         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5299                    sid_string_dbg(&ainfo->sid)));
5300
5301         /******** BEGIN SeAddUsers BLOCK *********/
5302
5303         become_root();
5304         status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5305         unbecome_root();
5306
5307         /******** END SeAddUsers BLOCK *********/
5308
5309         if (NT_STATUS_IS_OK(status)) {
5310                 force_flush_samr_cache(&ainfo->sid);
5311         }
5312
5313         return status;
5314 }
5315
5316 /*********************************************************************
5317  _samr_AddGroupMember
5318 *********************************************************************/
5319
5320 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5321                               struct samr_AddGroupMember *r)
5322 {
5323         struct samr_group_info *ginfo;
5324         NTSTATUS status;
5325         uint32 group_rid;
5326
5327         ginfo = policy_handle_find(p, r->in.group_handle,
5328                                    SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5329                                    struct samr_group_info, &status);
5330         if (!NT_STATUS_IS_OK(status)) {
5331                 return status;
5332         }
5333
5334         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5335
5336         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5337                                 &group_rid)) {
5338                 return NT_STATUS_INVALID_HANDLE;
5339         }
5340
5341         /******** BEGIN SeAddUsers BLOCK *********/
5342
5343         become_root();
5344         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5345         unbecome_root();
5346
5347         /******** END SeAddUsers BLOCK *********/
5348
5349         force_flush_samr_cache(&ginfo->sid);
5350
5351         return status;
5352 }
5353
5354 /*********************************************************************
5355  _samr_DeleteGroupMember
5356 *********************************************************************/
5357
5358 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5359                                  struct samr_DeleteGroupMember *r)
5360
5361 {
5362         struct samr_group_info *ginfo;
5363         NTSTATUS status;
5364         uint32 group_rid;
5365
5366         /*
5367          * delete the group member named r->in.rid
5368          * who is a member of the sid associated with the handle
5369          * the rid is a user's rid as the group is a domain group.
5370          */
5371
5372         ginfo = policy_handle_find(p, r->in.group_handle,
5373                                    SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5374                                    struct samr_group_info, &status);
5375         if (!NT_STATUS_IS_OK(status)) {
5376                 return status;
5377         }
5378
5379         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5380                                 &group_rid)) {
5381                 return NT_STATUS_INVALID_HANDLE;
5382         }
5383
5384         /******** BEGIN SeAddUsers BLOCK *********/
5385
5386         become_root();
5387         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5388         unbecome_root();
5389
5390         /******** END SeAddUsers BLOCK *********/
5391
5392         force_flush_samr_cache(&ginfo->sid);
5393
5394         return status;
5395 }
5396
5397 /*********************************************************************
5398  _samr_DeleteUser
5399 *********************************************************************/
5400
5401 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5402                           struct samr_DeleteUser *r)
5403 {
5404         struct samr_user_info *uinfo;
5405         NTSTATUS status;
5406         struct samu *sam_pass=NULL;
5407         bool can_del_accounts = false;
5408         uint32 acb_info = 0;
5409         bool ret;
5410
5411         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5412
5413         uinfo = policy_handle_find(p, r->in.user_handle,
5414                                    STD_RIGHT_DELETE_ACCESS, NULL,
5415                                    struct samr_user_info, &status);
5416         if (!NT_STATUS_IS_OK(status)) {
5417                 return status;
5418         }
5419
5420         if (!sid_check_is_in_our_domain(&uinfo->sid))
5421                 return NT_STATUS_CANNOT_DELETE;
5422
5423         /* check if the user exists before trying to delete */
5424         if ( !(sam_pass = samu_new( NULL )) ) {
5425                 return NT_STATUS_NO_MEMORY;
5426         }
5427
5428         become_root();
5429         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5430         unbecome_root();
5431
5432         if (ret) {
5433                 acb_info = pdb_get_acct_ctrl(sam_pass);
5434         }
5435
5436         /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
5437         if (geteuid() == sec_initial_uid()) {
5438                 can_del_accounts = true;
5439         } else if (acb_info & ACB_WSTRUST) {
5440                 can_del_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
5441         } else {
5442                 can_del_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5443         }
5444
5445         if (!can_del_accounts) {
5446                 TALLOC_FREE(sam_pass);
5447                 return NT_STATUS_ACCESS_DENIED;
5448         }
5449
5450         if(!ret) {
5451                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5452                         sid_string_dbg(&uinfo->sid)));
5453                 TALLOC_FREE(sam_pass);
5454                 return NT_STATUS_NO_SUCH_USER;
5455         }
5456
5457         /******** BEGIN SeAddUsers BLOCK *********/
5458
5459         become_root();
5460         status = pdb_delete_user(p->mem_ctx, sam_pass);
5461         unbecome_root();
5462
5463         /******** END SeAddUsers BLOCK *********/
5464
5465         if ( !NT_STATUS_IS_OK(status) ) {
5466                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5467                          "user %s: %s.\n", pdb_get_username(sam_pass),
5468                          nt_errstr(status)));
5469                 TALLOC_FREE(sam_pass);
5470                 return status;
5471         }
5472
5473
5474         TALLOC_FREE(sam_pass);
5475
5476         if (!close_policy_hnd(p, r->in.user_handle))
5477                 return NT_STATUS_OBJECT_NAME_INVALID;
5478
5479         ZERO_STRUCTP(r->out.user_handle);
5480
5481         force_flush_samr_cache(&uinfo->sid);
5482
5483         return NT_STATUS_OK;
5484 }
5485
5486 /*********************************************************************
5487  _samr_DeleteDomainGroup
5488 *********************************************************************/
5489
5490 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5491                                  struct samr_DeleteDomainGroup *r)
5492 {
5493         struct samr_group_info *ginfo;
5494         NTSTATUS status;
5495         uint32 group_rid;
5496
5497         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5498
5499         ginfo = policy_handle_find(p, r->in.group_handle,
5500                                    STD_RIGHT_DELETE_ACCESS, NULL,
5501                                    struct samr_group_info, &status);
5502         if (!NT_STATUS_IS_OK(status)) {
5503                 return status;
5504         }
5505
5506         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5507
5508         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5509                                 &group_rid)) {
5510                 return NT_STATUS_NO_SUCH_GROUP;
5511         }
5512
5513         /******** BEGIN SeAddUsers BLOCK *********/
5514
5515         become_root();
5516         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5517         unbecome_root();
5518
5519         /******** END SeAddUsers BLOCK *********/
5520
5521         if ( !NT_STATUS_IS_OK(status) ) {
5522                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5523                          "entry for group %s: %s\n",
5524                          sid_string_dbg(&ginfo->sid),
5525                          nt_errstr(status)));
5526                 return status;
5527         }
5528
5529         if (!close_policy_hnd(p, r->in.group_handle))
5530                 return NT_STATUS_OBJECT_NAME_INVALID;
5531
5532         force_flush_samr_cache(&ginfo->sid);
5533
5534         return NT_STATUS_OK;
5535 }
5536
5537 /*********************************************************************
5538  _samr_DeleteDomAlias
5539 *********************************************************************/
5540
5541 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5542                               struct samr_DeleteDomAlias *r)
5543 {
5544         struct samr_alias_info *ainfo;
5545         NTSTATUS status;
5546
5547         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5548
5549         ainfo = policy_handle_find(p, r->in.alias_handle,
5550                                    STD_RIGHT_DELETE_ACCESS, NULL,
5551                                    struct samr_alias_info, &status);
5552         if (!NT_STATUS_IS_OK(status)) {
5553                 return status;
5554         }
5555
5556         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5557
5558         /* Don't let Windows delete builtin groups */
5559
5560         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5561                 return NT_STATUS_SPECIAL_ACCOUNT;
5562         }
5563
5564         if (!sid_check_is_in_our_domain(&ainfo->sid))
5565                 return NT_STATUS_NO_SUCH_ALIAS;
5566
5567         DEBUG(10, ("lookup on Local SID\n"));
5568
5569         /******** BEGIN SeAddUsers BLOCK *********/
5570
5571         become_root();
5572         /* Have passdb delete the alias */
5573         status = pdb_delete_alias(&ainfo->sid);
5574         unbecome_root();
5575
5576         /******** END SeAddUsers BLOCK *********/
5577
5578         if ( !NT_STATUS_IS_OK(status))
5579                 return status;
5580
5581         if (!close_policy_hnd(p, r->in.alias_handle))
5582                 return NT_STATUS_OBJECT_NAME_INVALID;
5583
5584         force_flush_samr_cache(&ainfo->sid);
5585
5586         return NT_STATUS_OK;
5587 }
5588
5589 /*********************************************************************
5590  _samr_CreateDomainGroup
5591 *********************************************************************/
5592
5593 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5594                                  struct samr_CreateDomainGroup *r)
5595
5596 {
5597         NTSTATUS status;
5598         const char *name;
5599         struct samr_domain_info *dinfo;
5600         struct samr_group_info *ginfo;
5601
5602         dinfo = policy_handle_find(p, r->in.domain_handle,
5603                                    SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5604                                    struct samr_domain_info, &status);
5605         if (!NT_STATUS_IS_OK(status)) {
5606                 return status;
5607         }
5608
5609         if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5610                 return NT_STATUS_ACCESS_DENIED;
5611
5612         name = r->in.name->string;
5613         if (name == NULL) {
5614                 return NT_STATUS_NO_MEMORY;
5615         }
5616
5617         status = can_create(p->mem_ctx, name);
5618         if (!NT_STATUS_IS_OK(status)) {
5619                 return status;
5620         }
5621
5622         /******** BEGIN SeAddUsers BLOCK *********/
5623
5624         become_root();
5625         /* check that we successfully create the UNIX group */
5626         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5627         unbecome_root();
5628
5629         /******** END SeAddUsers BLOCK *********/
5630
5631         /* check if we should bail out here */
5632
5633         if ( !NT_STATUS_IS_OK(status) )
5634                 return status;
5635
5636         ginfo = policy_handle_create(p, r->out.group_handle,
5637                                      GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5638                                      struct samr_group_info, &status);
5639         if (!NT_STATUS_IS_OK(status)) {
5640                 return status;
5641         }
5642         sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5643
5644         force_flush_samr_cache(&dinfo->sid);
5645
5646         return NT_STATUS_OK;
5647 }
5648
5649 /*********************************************************************
5650  _samr_CreateDomAlias
5651 *********************************************************************/
5652
5653 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5654                               struct samr_CreateDomAlias *r)
5655 {
5656         DOM_SID info_sid;
5657         const char *name = NULL;
5658         struct samr_domain_info *dinfo;
5659         struct samr_alias_info *ainfo;
5660         gid_t gid;
5661         NTSTATUS result;
5662
5663         dinfo = policy_handle_find(p, r->in.domain_handle,
5664                                    SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5665                                    struct samr_domain_info, &result);
5666         if (!NT_STATUS_IS_OK(result)) {
5667                 return result;
5668         }
5669
5670         if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5671                 return NT_STATUS_ACCESS_DENIED;
5672
5673         name = r->in.alias_name->string;
5674
5675         result = can_create(p->mem_ctx, name);
5676         if (!NT_STATUS_IS_OK(result)) {
5677                 return result;
5678         }
5679
5680         /******** BEGIN SeAddUsers BLOCK *********/
5681
5682         become_root();
5683         /* Have passdb create the alias */
5684         result = pdb_create_alias(name, r->out.rid);
5685         unbecome_root();
5686
5687         /******** END SeAddUsers BLOCK *********/
5688
5689         if (!NT_STATUS_IS_OK(result)) {
5690                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5691                            nt_errstr(result)));
5692                 return result;
5693         }
5694
5695         sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5696
5697         if (!sid_to_gid(&info_sid, &gid)) {
5698                 DEBUG(10, ("Could not find alias just created\n"));
5699                 return NT_STATUS_ACCESS_DENIED;
5700         }
5701
5702         /* check if the group has been successfully created */
5703         if ( getgrgid(gid) == NULL ) {
5704                 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5705                            (unsigned int)gid));
5706                 return NT_STATUS_ACCESS_DENIED;
5707         }
5708
5709         ainfo = policy_handle_create(p, r->out.alias_handle,
5710                                      GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5711                                      struct samr_alias_info, &result);
5712         if (!NT_STATUS_IS_OK(result)) {
5713                 return result;
5714         }
5715         ainfo->sid = info_sid;
5716
5717         force_flush_samr_cache(&info_sid);
5718
5719         return NT_STATUS_OK;
5720 }
5721
5722 /*********************************************************************
5723  _samr_QueryGroupInfo
5724 *********************************************************************/
5725
5726 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5727                               struct samr_QueryGroupInfo *r)
5728 {
5729         struct samr_group_info *ginfo;
5730         NTSTATUS status;
5731         GROUP_MAP map;
5732         union samr_GroupInfo *info = NULL;
5733         bool ret;
5734         uint32_t attributes = SE_GROUP_MANDATORY |
5735                               SE_GROUP_ENABLED_BY_DEFAULT |
5736                               SE_GROUP_ENABLED;
5737         const char *group_name = NULL;
5738         const char *group_description = NULL;
5739
5740         ginfo = policy_handle_find(p, r->in.group_handle,
5741                                    SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5742                                    struct samr_group_info, &status);
5743         if (!NT_STATUS_IS_OK(status)) {
5744                 return status;
5745         }
5746
5747         become_root();
5748         ret = get_domain_group_from_sid(ginfo->sid, &map);
5749         unbecome_root();
5750         if (!ret)
5751                 return NT_STATUS_INVALID_HANDLE;
5752
5753         /* FIXME: map contains fstrings */
5754         group_name = talloc_strdup(r, map.nt_name);
5755         group_description = talloc_strdup(r, map.comment);
5756
5757         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5758         if (!info) {
5759                 return NT_STATUS_NO_MEMORY;
5760         }
5761
5762         switch (r->in.level) {
5763                 case 1: {
5764                         uint32 *members;
5765                         size_t num_members;
5766
5767                         become_root();
5768                         status = pdb_enum_group_members(
5769                                 p->mem_ctx, &ginfo->sid, &members,
5770                                 &num_members);
5771                         unbecome_root();
5772
5773                         if (!NT_STATUS_IS_OK(status)) {
5774                                 return status;
5775                         }
5776
5777                         info->all.name.string           = group_name;
5778                         info->all.attributes            = attributes;
5779                         info->all.num_members           = num_members;
5780                         info->all.description.string    = group_description;
5781                         break;
5782                 }
5783                 case 2:
5784                         info->name.string = group_name;
5785                         break;
5786                 case 3:
5787                         info->attributes.attributes = attributes;
5788                         break;
5789                 case 4:
5790                         info->description.string = group_description;
5791                         break;
5792                 case 5: {
5793                         /*
5794                         uint32 *members;
5795                         size_t num_members;
5796                         */
5797
5798                         /*
5799                         become_root();
5800                         status = pdb_enum_group_members(
5801                                 p->mem_ctx, &ginfo->sid, &members,
5802                                 &num_members);
5803                         unbecome_root();
5804
5805                         if (!NT_STATUS_IS_OK(status)) {
5806                                 return status;
5807                         }
5808                         */
5809                         info->all2.name.string          = group_name;
5810                         info->all2.attributes           = attributes;
5811                         info->all2.num_members          = 0; /* num_members - in w2k3 this is always 0 */
5812                         info->all2.description.string   = group_description;
5813
5814                         break;
5815                 }
5816                 default:
5817                         return NT_STATUS_INVALID_INFO_CLASS;
5818         }
5819
5820         *r->out.info = info;
5821
5822         return NT_STATUS_OK;
5823 }
5824
5825 /*********************************************************************
5826  _samr_SetGroupInfo
5827 *********************************************************************/
5828
5829 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5830                             struct samr_SetGroupInfo *r)
5831 {
5832         struct samr_group_info *ginfo;
5833         GROUP_MAP map;
5834         NTSTATUS status;
5835         bool ret;
5836
5837         ginfo = policy_handle_find(p, r->in.group_handle,
5838                                    SAMR_GROUP_ACCESS_SET_INFO, NULL,
5839                                    struct samr_group_info, &status);
5840         if (!NT_STATUS_IS_OK(status)) {
5841                 return status;
5842         }
5843
5844         become_root();
5845         ret = get_domain_group_from_sid(ginfo->sid, &map);
5846         unbecome_root();
5847         if (!ret)
5848                 return NT_STATUS_NO_SUCH_GROUP;
5849
5850         switch (r->in.level) {
5851                 case 1:
5852                         fstrcpy(map.comment, r->in.info->all.description.string);
5853                         break;
5854                 case 2:
5855                         /* group rename is not supported yet */
5856                         return NT_STATUS_NOT_SUPPORTED;
5857                 case 4:
5858                         fstrcpy(map.comment, r->in.info->description.string);
5859                         break;
5860                 default:
5861                         return NT_STATUS_INVALID_INFO_CLASS;
5862         }
5863
5864         /******** BEGIN SeAddUsers BLOCK *********/
5865
5866         become_root();
5867         status = pdb_update_group_mapping_entry(&map);
5868         unbecome_root();
5869
5870         /******** End SeAddUsers BLOCK *********/
5871
5872         if (NT_STATUS_IS_OK(status)) {
5873                 force_flush_samr_cache(&ginfo->sid);
5874         }
5875
5876         return status;
5877 }
5878
5879 /*********************************************************************
5880  _samr_SetAliasInfo
5881 *********************************************************************/
5882
5883 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5884                             struct samr_SetAliasInfo *r)
5885 {
5886         struct samr_alias_info *ainfo;
5887         struct acct_info info;
5888         NTSTATUS status;
5889
5890         ainfo = policy_handle_find(p, r->in.alias_handle,
5891                                    SAMR_ALIAS_ACCESS_SET_INFO, NULL,
5892                                    struct samr_alias_info, &status);
5893         if (!NT_STATUS_IS_OK(status)) {
5894                 return status;
5895         }
5896
5897         /* get the current group information */
5898
5899         become_root();
5900         status = pdb_get_aliasinfo( &ainfo->sid, &info );
5901         unbecome_root();
5902
5903         if ( !NT_STATUS_IS_OK(status))
5904                 return status;
5905
5906         switch (r->in.level) {
5907                 case ALIASINFONAME:
5908                 {
5909                         fstring group_name;
5910
5911                         /* We currently do not support renaming groups in the
5912                            the BUILTIN domain.  Refer to util_builtin.c to understand
5913                            why.  The eventually needs to be fixed to be like Windows
5914                            where you can rename builtin groups, just not delete them */
5915
5916                         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5917                                 return NT_STATUS_SPECIAL_ACCOUNT;
5918                         }
5919
5920                         /* There has to be a valid name (and it has to be different) */
5921
5922                         if ( !r->in.info->name.string )
5923                                 return NT_STATUS_INVALID_PARAMETER;
5924
5925                         /* If the name is the same just reply "ok".  Yes this
5926                            doesn't allow you to change the case of a group name. */
5927
5928                         if ( strequal( r->in.info->name.string, info.acct_name ) )
5929                                 return NT_STATUS_OK;
5930
5931                         fstrcpy( info.acct_name, r->in.info->name.string);
5932
5933                         /* make sure the name doesn't already exist as a user
5934                            or local group */
5935
5936                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5937                         status = can_create( p->mem_ctx, group_name );
5938                         if ( !NT_STATUS_IS_OK( status ) )
5939                                 return status;
5940                         break;
5941                 }
5942                 case ALIASINFODESCRIPTION:
5943                         if (r->in.info->description.string) {
5944                                 fstrcpy(info.acct_desc,
5945                                         r->in.info->description.string);
5946                         } else {
5947                                 fstrcpy( info.acct_desc, "" );
5948                         }
5949                         break;
5950                 default:
5951                         return NT_STATUS_INVALID_INFO_CLASS;
5952         }
5953
5954         /******** BEGIN SeAddUsers BLOCK *********/
5955
5956         become_root();
5957         status = pdb_set_aliasinfo( &ainfo->sid, &info );
5958         unbecome_root();
5959
5960         /******** End SeAddUsers BLOCK *********/
5961
5962         if (NT_STATUS_IS_OK(status))
5963                 force_flush_samr_cache(&ainfo->sid);
5964
5965         return status;
5966 }
5967
5968 /****************************************************************
5969  _samr_GetDomPwInfo
5970 ****************************************************************/
5971
5972 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5973                             struct samr_GetDomPwInfo *r)
5974 {
5975         uint32_t min_password_length = 0;
5976         uint32_t password_properties = 0;
5977
5978         /* Perform access check.  Since this rpc does not require a
5979            policy handle it will not be caught by the access checks on
5980            SAMR_CONNECT or SAMR_CONNECT_ANON. */
5981
5982         if (!pipe_access_check(p)) {
5983                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5984                 return NT_STATUS_ACCESS_DENIED;
5985         }
5986
5987         become_root();
5988         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5989                                &min_password_length);
5990         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5991                                &password_properties);
5992         unbecome_root();
5993
5994         if (lp_check_password_script() && *lp_check_password_script()) {
5995                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5996         }
5997
5998         r->out.info->min_password_length = min_password_length;
5999         r->out.info->password_properties = password_properties;
6000
6001         return NT_STATUS_OK;
6002 }
6003
6004 /*********************************************************************
6005  _samr_OpenGroup
6006 *********************************************************************/
6007
6008 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6009                          struct samr_OpenGroup *r)
6010
6011 {
6012         DOM_SID info_sid;
6013         GROUP_MAP map;
6014         struct samr_domain_info *dinfo;
6015         struct samr_group_info *ginfo;
6016         SEC_DESC         *psd = NULL;
6017         uint32            acc_granted;
6018         uint32            des_access = r->in.access_mask;
6019         size_t            sd_size;
6020         NTSTATUS          status;
6021         bool ret;
6022         SE_PRIV se_rights;
6023
6024         dinfo = policy_handle_find(p, r->in.domain_handle,
6025                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6026                                    struct samr_domain_info, &status);
6027         if (!NT_STATUS_IS_OK(status)) {
6028                 return status;
6029         }
6030
6031         /*check if access can be granted as requested by client. */
6032         map_max_allowed_access(p->server_info->ptok, &des_access);
6033
6034         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6035         se_map_generic(&des_access,&grp_generic_mapping);
6036
6037         se_priv_copy( &se_rights, &se_add_users );
6038
6039         status = access_check_samr_object(psd, p->server_info->ptok,
6040                 &se_rights, SAMR_GROUP_ACCESS_ADD_MEMBER,
6041                 des_access, &acc_granted, "_samr_OpenGroup");
6042
6043         if ( !NT_STATUS_IS_OK(status) )
6044                 return status;
6045
6046         /* this should not be hard-coded like this */
6047
6048         if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
6049                 return NT_STATUS_ACCESS_DENIED;
6050
6051         sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6052
6053         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6054                    sid_string_dbg(&info_sid)));
6055
6056         /* check if that group really exists */
6057         become_root();
6058         ret = get_domain_group_from_sid(info_sid, &map);
6059         unbecome_root();
6060         if (!ret)
6061                 return NT_STATUS_NO_SUCH_GROUP;
6062
6063         ginfo = policy_handle_create(p, r->out.group_handle,
6064                                      GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6065                                      struct samr_group_info, &status);
6066         if (!NT_STATUS_IS_OK(status)) {
6067                 return status;
6068         }
6069         ginfo->sid = info_sid;
6070
6071         return NT_STATUS_OK;
6072 }
6073
6074 /*********************************************************************
6075  _samr_RemoveMemberFromForeignDomain
6076 *********************************************************************/
6077
6078 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6079                                              struct samr_RemoveMemberFromForeignDomain *r)
6080 {
6081         struct samr_domain_info *dinfo;
6082         NTSTATUS                result;
6083
6084         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6085                  sid_string_dbg(r->in.sid)));
6086
6087         /* Find the policy handle. Open a policy on it. */
6088
6089         dinfo = policy_handle_find(p, r->in.domain_handle,
6090                                    STD_RIGHT_DELETE_ACCESS, NULL,
6091                                    struct samr_domain_info, &result);
6092         if (!NT_STATUS_IS_OK(result)) {
6093                 return result;
6094         }
6095
6096         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6097                   sid_string_dbg(&dinfo->sid)));
6098
6099         /* we can only delete a user from a group since we don't have
6100            nested groups anyways.  So in the latter case, just say OK */
6101
6102         /* TODO: The above comment nowadays is bogus. Since we have nested
6103          * groups now, and aliases members are never reported out of the unix
6104          * group membership, the "just say OK" makes this call a no-op. For
6105          * us. This needs fixing however. */
6106
6107         /* I've only ever seen this in the wild when deleting a user from
6108          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6109          * is the user about to be deleted. I very much suspect this is the
6110          * only application of this call. To verify this, let people report
6111          * other cases. */
6112
6113         if (!sid_check_is_builtin(&dinfo->sid)) {
6114                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6115                          "global_sam_sid() = %s\n",
6116                          sid_string_dbg(&dinfo->sid),
6117                          sid_string_dbg(get_global_sam_sid())));
6118                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6119                 return NT_STATUS_OK;
6120         }
6121
6122         force_flush_samr_cache(&dinfo->sid);
6123
6124         result = NT_STATUS_OK;
6125
6126         return result;
6127 }
6128
6129 /*******************************************************************
6130  _samr_QueryDomainInfo2
6131  ********************************************************************/
6132
6133 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6134                                 struct samr_QueryDomainInfo2 *r)
6135 {
6136         struct samr_QueryDomainInfo q;
6137
6138         q.in.domain_handle      = r->in.domain_handle;
6139         q.in.level              = r->in.level;
6140
6141         q.out.info              = r->out.info;
6142
6143         return _samr_QueryDomainInfo(p, &q);
6144 }
6145
6146 /*******************************************************************
6147  _samr_SetDomainInfo
6148  ********************************************************************/
6149
6150 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6151                              struct samr_SetDomainInfo *r)
6152 {
6153         struct samr_domain_info *dinfo;
6154         time_t u_expire, u_min_age;
6155         time_t u_logout;
6156         time_t u_lock_duration, u_reset_time;
6157         NTSTATUS result;
6158         uint32_t acc_required = 0;
6159
6160         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6161
6162         switch (r->in.level) {
6163         case 1: /* DomainPasswordInformation */
6164         case 12: /* DomainLockoutInformation */
6165                 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6166                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6167                 break;
6168         case 3: /* DomainLogoffInformation */
6169         case 4: /* DomainOemInformation */
6170                 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6171                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6172                 break;
6173         case 6: /* DomainReplicationInformation */
6174         case 9: /* DomainStateInformation */
6175         case 7: /* DomainServerRoleInformation */
6176                 /* DOMAIN_ADMINISTER_SERVER */
6177                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6178                 break;
6179         default:
6180                 return NT_STATUS_INVALID_INFO_CLASS;
6181         }
6182
6183         dinfo = policy_handle_find(p, r->in.domain_handle,
6184                                    acc_required, NULL,
6185                                    struct samr_domain_info, &result);
6186         if (!NT_STATUS_IS_OK(result)) {
6187                 return result;
6188         }
6189
6190         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6191
6192         switch (r->in.level) {
6193                 case 1:
6194                         u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
6195                         u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
6196                         pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
6197                         pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
6198                         pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
6199                         pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
6200                         pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
6201                         break;
6202                 case 3:
6203                         u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
6204                         pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
6205                         break;
6206                 case 4:
6207                         break;
6208                 case 6:
6209                         break;
6210                 case 7:
6211                         break;
6212                 case 9:
6213                         break;
6214                 case 12:
6215                         u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
6216                         if (u_lock_duration != -1)
6217                                 u_lock_duration /= 60;
6218
6219                         u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
6220
6221                         pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6222                         pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
6223                         pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
6224                         break;
6225                 default:
6226                         return NT_STATUS_INVALID_INFO_CLASS;
6227         }
6228
6229         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6230
6231         return NT_STATUS_OK;
6232 }
6233
6234 /****************************************************************
6235  _samr_GetDisplayEnumerationIndex
6236 ****************************************************************/
6237
6238 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6239                                           struct samr_GetDisplayEnumerationIndex *r)
6240 {
6241         struct samr_domain_info *dinfo;
6242         uint32_t max_entries = (uint32_t) -1;
6243         uint32_t enum_context = 0;
6244         int i;
6245         uint32_t num_account = 0;
6246         struct samr_displayentry *entries = NULL;
6247         NTSTATUS status;
6248
6249         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6250
6251         dinfo = policy_handle_find(p, r->in.domain_handle,
6252                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6253                                    struct samr_domain_info, &status);
6254         if (!NT_STATUS_IS_OK(status)) {
6255                 return status;
6256         }
6257
6258         if ((r->in.level < 1) || (r->in.level > 3)) {
6259                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6260                         "Unknown info level (%u)\n",
6261                         r->in.level));
6262                 return NT_STATUS_INVALID_INFO_CLASS;
6263         }
6264
6265         become_root();
6266
6267         /* The following done as ROOT. Don't return without unbecome_root(). */
6268
6269         switch (r->in.level) {
6270         case 1:
6271                 if (dinfo->disp_info->users == NULL) {
6272                         dinfo->disp_info->users = pdb_search_users(
6273                                 dinfo->disp_info, ACB_NORMAL);
6274                         if (dinfo->disp_info->users == NULL) {
6275                                 unbecome_root();
6276                                 return NT_STATUS_ACCESS_DENIED;
6277                         }
6278                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6279                                 "starting user enumeration at index %u\n",
6280                                 (unsigned int)enum_context));
6281                 } else {
6282                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6283                                 "using cached user enumeration at index %u\n",
6284                                 (unsigned int)enum_context));
6285                 }
6286                 num_account = pdb_search_entries(dinfo->disp_info->users,
6287                                                  enum_context, max_entries,
6288                                                  &entries);
6289                 break;
6290         case 2:
6291                 if (dinfo->disp_info->machines == NULL) {
6292                         dinfo->disp_info->machines = pdb_search_users(
6293                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6294                         if (dinfo->disp_info->machines == NULL) {
6295                                 unbecome_root();
6296                                 return NT_STATUS_ACCESS_DENIED;
6297                         }
6298                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6299                                 "starting machine enumeration at index %u\n",
6300                                 (unsigned int)enum_context));
6301                 } else {
6302                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6303                                 "using cached machine enumeration at index %u\n",
6304                                 (unsigned int)enum_context));
6305                 }
6306                 num_account = pdb_search_entries(dinfo->disp_info->machines,
6307                                                  enum_context, max_entries,
6308                                                  &entries);
6309                 break;
6310         case 3:
6311                 if (dinfo->disp_info->groups == NULL) {
6312                         dinfo->disp_info->groups = pdb_search_groups(
6313                                 dinfo->disp_info);
6314                         if (dinfo->disp_info->groups == NULL) {
6315                                 unbecome_root();
6316                                 return NT_STATUS_ACCESS_DENIED;
6317                         }
6318                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6319                                 "starting group enumeration at index %u\n",
6320                                 (unsigned int)enum_context));
6321                 } else {
6322                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6323                                 "using cached group enumeration at index %u\n",
6324                                 (unsigned int)enum_context));
6325                 }
6326                 num_account = pdb_search_entries(dinfo->disp_info->groups,
6327                                                  enum_context, max_entries,
6328                                                  &entries);
6329                 break;
6330         default:
6331                 unbecome_root();
6332                 smb_panic("info class changed");
6333                 break;
6334         }
6335
6336         unbecome_root();
6337
6338         /* Ensure we cache this enumeration. */
6339         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6340
6341         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6342                 r->in.name->string));
6343
6344         for (i=0; i<num_account; i++) {
6345                 if (strequal(entries[i].account_name, r->in.name->string)) {
6346                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6347                                 "found %s at idx %d\n",
6348                                 r->in.name->string, i));
6349                         *r->out.idx = i;
6350                         return NT_STATUS_OK;
6351                 }
6352         }
6353
6354         /* assuming account_name lives at the very end */
6355         *r->out.idx = num_account;
6356
6357         return NT_STATUS_NO_MORE_ENTRIES;
6358 }
6359
6360 /****************************************************************
6361  _samr_GetDisplayEnumerationIndex2
6362 ****************************************************************/
6363
6364 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6365                                            struct samr_GetDisplayEnumerationIndex2 *r)
6366 {
6367         struct samr_GetDisplayEnumerationIndex q;
6368
6369         q.in.domain_handle      = r->in.domain_handle;
6370         q.in.level              = r->in.level;
6371         q.in.name               = r->in.name;
6372
6373         q.out.idx               = r->out.idx;
6374
6375         return _samr_GetDisplayEnumerationIndex(p, &q);
6376 }
6377
6378 /****************************************************************
6379  _samr_RidToSid
6380 ****************************************************************/
6381
6382 NTSTATUS _samr_RidToSid(pipes_struct *p,
6383                         struct samr_RidToSid *r)
6384 {
6385         struct samr_domain_info *dinfo;
6386         NTSTATUS status;
6387         struct dom_sid sid;
6388
6389         dinfo = policy_handle_find(p, r->in.domain_handle,
6390                                    0, NULL,
6391                                    struct samr_domain_info, &status);
6392         if (!NT_STATUS_IS_OK(status)) {
6393                 return status;
6394         }
6395
6396         if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6397                 return NT_STATUS_NO_MEMORY;
6398         }
6399
6400         *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
6401         if (!*r->out.sid) {
6402                 return NT_STATUS_NO_MEMORY;
6403         }
6404
6405         return NT_STATUS_OK;
6406 }
6407
6408 /****************************************************************
6409 ****************************************************************/
6410
6411 NTSTATUS _samr_Shutdown(pipes_struct *p,
6412                         struct samr_Shutdown *r)
6413 {
6414         p->rng_fault_state = true;
6415         return NT_STATUS_NOT_IMPLEMENTED;
6416 }
6417
6418 /****************************************************************
6419 ****************************************************************/
6420
6421 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6422                                           struct samr_SetMemberAttributesOfGroup *r)
6423 {
6424         p->rng_fault_state = true;
6425         return NT_STATUS_NOT_IMPLEMENTED;
6426 }
6427
6428 /****************************************************************
6429 ****************************************************************/
6430
6431 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6432                                           struct samr_TestPrivateFunctionsDomain *r)
6433 {
6434         return NT_STATUS_NOT_IMPLEMENTED;
6435 }
6436
6437 /****************************************************************
6438 ****************************************************************/
6439
6440 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6441                                         struct samr_TestPrivateFunctionsUser *r)
6442 {
6443         return NT_STATUS_NOT_IMPLEMENTED;
6444 }
6445
6446 /****************************************************************
6447 ****************************************************************/
6448
6449 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6450                                          struct samr_AddMultipleMembersToAlias *r)
6451 {
6452         p->rng_fault_state = true;
6453         return NT_STATUS_NOT_IMPLEMENTED;
6454 }
6455
6456 /****************************************************************
6457 ****************************************************************/
6458
6459 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6460                                               struct samr_RemoveMultipleMembersFromAlias *r)
6461 {
6462         p->rng_fault_state = true;
6463         return NT_STATUS_NOT_IMPLEMENTED;
6464 }
6465
6466 /****************************************************************
6467 ****************************************************************/
6468
6469 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6470                                      struct samr_SetBootKeyInformation *r)
6471 {
6472         p->rng_fault_state = true;
6473         return NT_STATUS_NOT_IMPLEMENTED;
6474 }
6475
6476 /****************************************************************
6477 ****************************************************************/
6478
6479 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6480                                      struct samr_GetBootKeyInformation *r)
6481 {
6482         p->rng_fault_state = true;
6483         return NT_STATUS_NOT_IMPLEMENTED;
6484 }
6485
6486 /****************************************************************
6487 ****************************************************************/
6488
6489 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6490                                struct samr_SetDsrmPassword *r)
6491 {
6492         p->rng_fault_state = true;
6493         return NT_STATUS_NOT_IMPLEMENTED;
6494 }
6495
6496 /****************************************************************
6497 ****************************************************************/
6498
6499 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6500                                 struct samr_ValidatePassword *r)
6501 {
6502         p->rng_fault_state = true;
6503         return NT_STATUS_NOT_IMPLEMENTED;
6504 }