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