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