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