source: trunk/samba/source/rpc_server/srv_samr_nt.c@ 32

Last change on this file since 32 was 32, checked in by Paul Smedley, 18 years ago

Update source to 3.0.25rc3 level

File size: 143.4 KB
Line 
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-2005,
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 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 SA_RIGHT_USER_CHANGE_PASSWORD | \
42 SA_RIGHT_USER_SET_LOC_COM )
43#define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
45
46#define DISP_INFO_CACHE_TIMEOUT 10
47
48typedef struct disp_info {
49 DOM_SID sid; /* identify which domain this is. */
50 BOOL builtin_domain; /* Quick flag to check if this is the builtin domain. */
51 struct pdb_search *users; /* querydispinfo 1 and 4 */
52 struct pdb_search *machines; /* querydispinfo 2 */
53 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
54 struct pdb_search *aliases; /* enumaliases */
55
56 uint16 enum_acb_mask;
57 struct pdb_search *enum_users; /* enumusers with a mask */
58
59
60 smb_event_id_t di_cache_timeout_event; /* cache idle timeout handler. */
61} DISP_INFO;
62
63/* We keep a static list of these by SID as modern clients close down
64 all resources between each request in a complete enumeration. */
65
66struct samr_info {
67 /* for use by the \PIPE\samr policy */
68 DOM_SID sid;
69 BOOL builtin_domain; /* Quick flag to check if this is the builtin domain. */
70 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
71 uint32 acc_granted;
72 DISP_INFO *disp_info;
73 TALLOC_CTX *mem_ctx;
74};
75
76static struct generic_mapping sam_generic_mapping = {
77 GENERIC_RIGHTS_SAM_READ,
78 GENERIC_RIGHTS_SAM_WRITE,
79 GENERIC_RIGHTS_SAM_EXECUTE,
80 GENERIC_RIGHTS_SAM_ALL_ACCESS};
81static struct generic_mapping dom_generic_mapping = {
82 GENERIC_RIGHTS_DOMAIN_READ,
83 GENERIC_RIGHTS_DOMAIN_WRITE,
84 GENERIC_RIGHTS_DOMAIN_EXECUTE,
85 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
86static struct generic_mapping usr_generic_mapping = {
87 GENERIC_RIGHTS_USER_READ,
88 GENERIC_RIGHTS_USER_WRITE,
89 GENERIC_RIGHTS_USER_EXECUTE,
90 GENERIC_RIGHTS_USER_ALL_ACCESS};
91static struct generic_mapping usr_nopwchange_generic_mapping = {
92 GENERIC_RIGHTS_USER_READ,
93 GENERIC_RIGHTS_USER_WRITE,
94 GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
95 GENERIC_RIGHTS_USER_ALL_ACCESS};
96static struct generic_mapping grp_generic_mapping = {
97 GENERIC_RIGHTS_GROUP_READ,
98 GENERIC_RIGHTS_GROUP_WRITE,
99 GENERIC_RIGHTS_GROUP_EXECUTE,
100 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
101static struct generic_mapping ali_generic_mapping = {
102 GENERIC_RIGHTS_ALIAS_READ,
103 GENERIC_RIGHTS_ALIAS_WRITE,
104 GENERIC_RIGHTS_ALIAS_EXECUTE,
105 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
106
107/*******************************************************************
108*******************************************************************/
109
110static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
111 struct generic_mapping *map,
112 DOM_SID *sid, uint32 sid_access )
113{
114 DOM_SID domadmin_sid;
115 SEC_ACE ace[5]; /* at most 5 entries */
116 SEC_ACCESS mask;
117 size_t i = 0;
118
119 SEC_ACL *psa = NULL;
120
121 /* basic access for Everyone */
122
123 init_sec_access(&mask, map->generic_execute | map->generic_read );
124 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
125
126 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
127
128 init_sec_access(&mask, map->generic_all);
129
130 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
131 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
132
133 /* Add Full Access for Domain Admins if we are a DC */
134
135 if ( IS_DC ) {
136 sid_copy( &domadmin_sid, get_global_sam_sid() );
137 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
138 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
139 }
140
141 /* if we have a sid, give it some special access */
142
143 if ( sid ) {
144 init_sec_access( &mask, sid_access );
145 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
146 }
147
148 /* create the security descriptor */
149
150 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
151 return NT_STATUS_NO_MEMORY;
152
153 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
154 return NT_STATUS_NO_MEMORY;
155
156 return NT_STATUS_OK;
157}
158
159/*******************************************************************
160 Checks if access to an object should be granted, and returns that
161 level of access for further checks.
162********************************************************************/
163
164static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
165 SE_PRIV *rights, uint32 rights_mask,
166 uint32 des_access, uint32 *acc_granted,
167 const char *debug )
168{
169 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
170 uint32 saved_mask = 0;
171
172 /* check privileges; certain SAM access bits should be overridden
173 by privileges (mostly having to do with creating/modifying/deleting
174 users and groups) */
175
176 if ( rights && user_has_any_privilege( token, rights ) ) {
177
178 saved_mask = (des_access & rights_mask);
179 des_access &= ~saved_mask;
180
181 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
182 rights_mask));
183 }
184
185
186 /* check the security descriptor first */
187
188 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
189 goto done;
190
191 /* give root a free pass */
192
193 if ( geteuid() == sec_initial_uid() ) {
194
195 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
196 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
197
198 *acc_granted = des_access;
199
200 status = NT_STATUS_OK;
201 goto done;
202 }
203
204
205done:
206 /* add in any bits saved during the privilege check (only
207 matters is status is ok) */
208
209 *acc_granted |= rights_mask;
210
211 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
212 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
213 des_access, *acc_granted));
214
215 return status;
216}
217
218/*******************************************************************
219 Checks if access to a function can be granted
220********************************************************************/
221
222static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
223{
224 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
225 debug, acc_granted, acc_required));
226
227 /* check the security descriptor first */
228
229 if ( (acc_granted&acc_required) == acc_required )
230 return NT_STATUS_OK;
231
232 /* give root a free pass */
233
234 if (geteuid() == sec_initial_uid()) {
235
236 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
237 debug, acc_granted, acc_required));
238 DEBUGADD(4,("but overwritten by euid == 0\n"));
239
240 return NT_STATUS_OK;
241 }
242
243 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
244 debug, acc_granted, acc_required));
245
246 return NT_STATUS_ACCESS_DENIED;
247}
248
249/*******************************************************************
250 Fetch or create a dispinfo struct.
251********************************************************************/
252
253static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
254{
255 /*
256 * We do a static cache for DISP_INFO's here. Explanation can be found
257 * in Jeremy's checkin message to r11793:
258 *
259 * Fix the SAMR cache so it works across completely insane
260 * client behaviour (ie.:
261 * open pipe/open SAMR handle/enumerate 0 - 1024
262 * close SAMR handle, close pipe.
263 * open pipe/open SAMR handle/enumerate 1024 - 2048...
264 * close SAMR handle, close pipe.
265 * And on ad-nausium. Amazing.... probably object-oriented
266 * client side programming in action yet again.
267 * This change should *massively* improve performance when
268 * enumerating users from an LDAP database.
269 * Jeremy.
270 *
271 * "Our" and the builtin domain are the only ones where we ever
272 * enumerate stuff, so just cache 2 entries.
273 */
274
275 static struct disp_info builtin_dispinfo;
276 static struct disp_info domain_dispinfo;
277
278 /* There are two cases to consider here:
279 1) The SID is a domain SID and we look for an equality match, or
280 2) This is an account SID and so we return the DISP_INFO* for our
281 domain */
282
283 if (psid == NULL) {
284 return NULL;
285 }
286
287 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
288 /*
289 * Necessary only once, but it does not really hurt.
290 */
291 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
292
293 return &builtin_dispinfo;
294 }
295
296 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
297 /*
298 * Necessary only once, but it does not really hurt.
299 */
300 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
301
302 return &domain_dispinfo;
303 }
304
305 return NULL;
306}
307
308/*******************************************************************
309 Create a samr_info struct.
310********************************************************************/
311
312static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
313{
314 struct samr_info *info;
315 fstring sid_str;
316 TALLOC_CTX *mem_ctx;
317
318 if (psid) {
319 sid_to_string(sid_str, psid);
320 } else {
321 fstrcpy(sid_str,"(NULL)");
322 }
323
324 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
325
326 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
327 return NULL;
328
329 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
330 if (psid) {
331 sid_copy( &info->sid, psid);
332 info->builtin_domain = sid_check_is_builtin(psid);
333 } else {
334 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
335 info->builtin_domain = False;
336 }
337 info->mem_ctx = mem_ctx;
338
339 info->disp_info = get_samr_dispinfo_by_sid(psid);
340
341 return info;
342}
343
344/*******************************************************************
345 Function to free the per SID data.
346 ********************************************************************/
347
348static void free_samr_cache(DISP_INFO *disp_info, const char *sid_str)
349{
350 DEBUG(10,("free_samr_cache: deleting cache for SID %s\n", sid_str));
351
352 /* We need to become root here because the paged search might have to
353 * tell the LDAP server we're not interested in the rest anymore. */
354
355 become_root();
356
357 if (disp_info->users) {
358 DEBUG(10,("free_samr_cache: deleting users cache\n"));
359 pdb_search_destroy(disp_info->users);
360 disp_info->users = NULL;
361 }
362 if (disp_info->machines) {
363 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
364 pdb_search_destroy(disp_info->machines);
365 disp_info->machines = NULL;
366 }
367 if (disp_info->groups) {
368 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
369 pdb_search_destroy(disp_info->groups);
370 disp_info->groups = NULL;
371 }
372 if (disp_info->aliases) {
373 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
374 pdb_search_destroy(disp_info->aliases);
375 disp_info->aliases = NULL;
376 }
377 if (disp_info->enum_users) {
378 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
379 pdb_search_destroy(disp_info->enum_users);
380 disp_info->enum_users = NULL;
381 }
382 disp_info->enum_acb_mask = 0;
383
384 unbecome_root();
385}
386
387/*******************************************************************
388 Function to free the per handle data.
389 ********************************************************************/
390
391static void free_samr_info(void *ptr)
392{
393 struct samr_info *info=(struct samr_info *) ptr;
394
395 /* Only free the dispinfo cache if no one bothered to set up
396 a timeout. */
397
398 if (info->disp_info && info->disp_info->di_cache_timeout_event == (smb_event_id_t)0) {
399 fstring sid_str;
400 sid_to_string(sid_str, &info->disp_info->sid);
401 free_samr_cache(info->disp_info, sid_str);
402 }
403
404 talloc_destroy(info->mem_ctx);
405}
406
407/*******************************************************************
408 Idle event handler. Throw away the disp info cache.
409 ********************************************************************/
410
411static void disp_info_cache_idle_timeout_handler(void **private_data,
412 time_t *ev_interval,
413 time_t ev_now)
414{
415 fstring sid_str;
416 DISP_INFO *disp_info = (DISP_INFO *)(*private_data);
417
418 sid_to_string(sid_str, &disp_info->sid);
419
420 free_samr_cache(disp_info, sid_str);
421
422 /* Remove the event. */
423 smb_unregister_idle_event(disp_info->di_cache_timeout_event);
424 disp_info->di_cache_timeout_event = (smb_event_id_t)0;
425
426 DEBUG(10,("disp_info_cache_idle_timeout_handler: caching timed out for SID %s at %u\n",
427 sid_str, (unsigned int)ev_now));
428}
429
430/*******************************************************************
431 Setup cache removal idle event handler.
432 ********************************************************************/
433
434static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
435{
436 fstring sid_str;
437
438 sid_to_string(sid_str, &disp_info->sid);
439
440 /* Remove any pending timeout and update. */
441
442 if (disp_info->di_cache_timeout_event) {
443 smb_unregister_idle_event(disp_info->di_cache_timeout_event);
444 disp_info->di_cache_timeout_event = (smb_event_id_t)0;
445 }
446
447 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for SID %s for %u seconds\n",
448 sid_str, (unsigned int)secs_fromnow ));
449
450 disp_info->di_cache_timeout_event =
451 smb_register_idle_event(disp_info_cache_idle_timeout_handler,
452 disp_info,
453 secs_fromnow);
454}
455
456/*******************************************************************
457 Force flush any cache. We do this on any samr_set_xxx call.
458 We must also remove the timeout handler.
459 ********************************************************************/
460
461static void force_flush_samr_cache(DISP_INFO *disp_info)
462{
463 if (disp_info) {
464 fstring sid_str;
465
466 sid_to_string(sid_str, &disp_info->sid);
467 if (disp_info->di_cache_timeout_event) {
468 smb_unregister_idle_event(disp_info->di_cache_timeout_event);
469 disp_info->di_cache_timeout_event = (smb_event_id_t)0;
470 DEBUG(10,("force_flush_samr_cache: clearing idle event for SID %s\n",
471 sid_str));
472 }
473 free_samr_cache(disp_info, sid_str);
474 }
475}
476
477/*******************************************************************
478 Ensure password info is never given out. Paranioa... JRA.
479 ********************************************************************/
480
481static void samr_clear_sam_passwd(struct samu *sam_pass)
482{
483
484 if (!sam_pass)
485 return;
486
487 /* These now zero out the old password */
488
489 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
490 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
491}
492
493static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
494{
495 struct samr_displayentry *entry;
496
497 if (info->builtin_domain) {
498 /* No users in builtin. */
499 return 0;
500 }
501
502 if (info->users == NULL) {
503 info->users = pdb_search_users(acct_flags);
504 if (info->users == NULL) {
505 return 0;
506 }
507 }
508 /* Fetch the last possible entry, thus trigger an enumeration */
509 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
510
511 /* Ensure we cache this enumeration. */
512 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
513
514 return info->users->num_entries;
515}
516
517static uint32 count_sam_groups(struct disp_info *info)
518{
519 struct samr_displayentry *entry;
520
521 if (info->builtin_domain) {
522 /* No groups in builtin. */
523 return 0;
524 }
525
526 if (info->groups == NULL) {
527 info->groups = pdb_search_groups();
528 if (info->groups == NULL) {
529 return 0;
530 }
531 }
532 /* Fetch the last possible entry, thus trigger an enumeration */
533 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
534
535 /* Ensure we cache this enumeration. */
536 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
537
538 return info->groups->num_entries;
539}
540
541static uint32 count_sam_aliases(struct disp_info *info)
542{
543 struct samr_displayentry *entry;
544
545 if (info->aliases == NULL) {
546 info->aliases = pdb_search_aliases(&info->sid);
547 if (info->aliases == NULL) {
548 return 0;
549 }
550 }
551 /* Fetch the last possible entry, thus trigger an enumeration */
552 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
553
554 /* Ensure we cache this enumeration. */
555 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
556
557 return info->aliases->num_entries;
558}
559
560/*******************************************************************
561 _samr_close_hnd
562 ********************************************************************/
563
564NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
565{
566 r_u->status = NT_STATUS_OK;
567
568 /* close the policy handle */
569 if (!close_policy_hnd(p, &q_u->pol))
570 return NT_STATUS_OBJECT_NAME_INVALID;
571
572 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
573
574 return r_u->status;
575}
576
577/*******************************************************************
578 samr_reply_open_domain
579 ********************************************************************/
580
581NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
582{
583 struct samr_info *info;
584 SEC_DESC *psd = NULL;
585 uint32 acc_granted;
586 uint32 des_access = q_u->flags;
587 NTSTATUS status;
588 size_t sd_size;
589 SE_PRIV se_rights;
590
591 r_u->status = NT_STATUS_OK;
592
593 /* find the connection policy handle. */
594
595 if ( !find_policy_by_hnd(p, &q_u->pol, (void**)(void *)&info) )
596 return NT_STATUS_INVALID_HANDLE;
597
598 status = access_check_samr_function( info->acc_granted,
599 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_open_domain" );
600
601 if ( !NT_STATUS_IS_OK(status) )
602 return status;
603
604 /*check if access can be granted as requested by client. */
605
606 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
607 se_map_generic( &des_access, &dom_generic_mapping );
608
609 se_priv_copy( &se_rights, &se_machine_account );
610 se_priv_add( &se_rights, &se_add_users );
611
612 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
613 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
614 &acc_granted, "_samr_open_domain" );
615
616 if ( !NT_STATUS_IS_OK(status) )
617 return status;
618
619 if (!sid_check_is_domain(&q_u->dom_sid.sid) &&
620 !sid_check_is_builtin(&q_u->dom_sid.sid)) {
621 return NT_STATUS_NO_SUCH_DOMAIN;
622 }
623
624 /* associate the domain SID with the (unique) handle. */
625 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
626 return NT_STATUS_NO_MEMORY;
627 info->acc_granted = acc_granted;
628
629 /* get a (unique) handle. open a policy on it. */
630 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
631 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
632
633 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
634
635 return r_u->status;
636}
637
638/*******************************************************************
639 _samr_get_usrdom_pwinfo
640 ********************************************************************/
641
642NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
643{
644 struct samr_info *info = NULL;
645
646 r_u->status = NT_STATUS_OK;
647
648 /* find the policy handle. open a policy on it. */
649 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)(void *)&info))
650 return NT_STATUS_INVALID_HANDLE;
651
652 if (!sid_check_is_in_our_domain(&info->sid))
653 return NT_STATUS_OBJECT_TYPE_MISMATCH;
654
655 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
656
657 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
658
659 /*
660 * NT sometimes return NT_STATUS_ACCESS_DENIED
661 * I don't know yet why.
662 */
663
664 return r_u->status;
665}
666
667/*******************************************************************
668********************************************************************/
669
670static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
671 DOM_SID *sid, uint32 *acc_granted,
672 DISP_INFO **ppdisp_info)
673{
674 struct samr_info *info = NULL;
675
676 /* find the policy handle. open a policy on it. */
677 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
678 return False;
679
680 if (!info)
681 return False;
682
683 *sid = info->sid;
684 *acc_granted = info->acc_granted;
685 if (ppdisp_info) {
686 *ppdisp_info = info->disp_info;
687 }
688
689 return True;
690}
691
692/*******************************************************************
693 _samr_set_sec_obj
694 ********************************************************************/
695
696NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
697{
698 DOM_SID pol_sid;
699 uint32 acc_granted, i;
700 SEC_ACL *dacl;
701 BOOL ret;
702 struct samu *sampass=NULL;
703 NTSTATUS status;
704
705 r_u->status = NT_STATUS_OK;
706
707 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL))
708 return NT_STATUS_INVALID_HANDLE;
709
710 if (!(sampass = samu_new( p->mem_ctx))) {
711 DEBUG(0,("No memory!\n"));
712 return NT_STATUS_NO_MEMORY;
713 }
714
715 /* get the user record */
716 become_root();
717 ret = pdb_getsampwsid(sampass, &pol_sid);
718 unbecome_root();
719
720 if (!ret) {
721 DEBUG(4, ("User %s not found\n", sid_string_static(&pol_sid)));
722 TALLOC_FREE(sampass);
723 return NT_STATUS_INVALID_HANDLE;
724 }
725
726 dacl = q_u->buf->sec->dacl;
727 for (i=0; i < dacl->num_aces; i++) {
728 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
729 ret = pdb_set_pass_can_change(sampass,
730 (dacl->aces[i].access_mask &
731 SA_RIGHT_USER_CHANGE_PASSWORD) ?
732 True: False);
733 break;
734 }
735 }
736
737 if (!ret) {
738 TALLOC_FREE(sampass);
739 return NT_STATUS_ACCESS_DENIED;
740 }
741
742 status = access_check_samr_function(acc_granted, SA_RIGHT_USER_SET_ATTRIBUTES, "_samr_set_sec_obj");
743 if (NT_STATUS_IS_OK(status)) {
744 become_root();
745 status = pdb_update_sam_account(sampass);
746 unbecome_root();
747 }
748
749 TALLOC_FREE(sampass);
750
751 return status;
752}
753
754/*******************************************************************
755 build correct perms based on policies and password times for _samr_query_sec_obj
756*******************************************************************/
757static BOOL check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
758{
759 struct samu *sampass=NULL;
760 BOOL ret;
761
762 if ( !(sampass = samu_new( mem_ctx )) ) {
763 DEBUG(0,("No memory!\n"));
764 return False;
765 }
766
767 become_root();
768 ret = pdb_getsampwsid(sampass, user_sid);
769 unbecome_root();
770
771 if (ret == False) {
772 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
773 TALLOC_FREE(sampass);
774 return False;
775 }
776
777 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
778
779 if (pdb_get_pass_can_change(sampass)) {
780 TALLOC_FREE(sampass);
781 return True;
782 }
783 TALLOC_FREE(sampass);
784 return False;
785}
786
787
788/*******************************************************************
789 _samr_query_sec_obj
790 ********************************************************************/
791
792NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
793{
794 DOM_SID pol_sid;
795 fstring str_sid;
796 SEC_DESC * psd = NULL;
797 uint32 acc_granted;
798 size_t sd_size;
799
800 r_u->status = NT_STATUS_OK;
801
802 /* Get the SID. */
803 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted, NULL))
804 return NT_STATUS_INVALID_HANDLE;
805
806 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
807
808 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
809
810 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
811 if (pol_sid.sid_rev_num == 0) {
812 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
813 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
814 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
815 /* check if it is our domain SID */
816 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
817 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
818 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
819 /* check if it is the Builtin Domain */
820 /* TODO: Builtin probably needs a different SD with restricted write access*/
821 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
822 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
823 } else if (sid_check_is_in_our_domain(&pol_sid) ||
824 sid_check_is_in_builtin(&pol_sid)) {
825 /* TODO: different SDs have to be generated for aliases groups and users.
826 Currently all three get a default user SD */
827 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
828 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
829 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
830 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
831 } else {
832 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
833 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
834 }
835 } else {
836 return NT_STATUS_OBJECT_TYPE_MISMATCH;
837 }
838
839 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
840 return NT_STATUS_NO_MEMORY;
841
842 if (NT_STATUS_IS_OK(r_u->status))
843 r_u->ptr = 1;
844
845 return r_u->status;
846}
847
848/*******************************************************************
849makes a SAM_ENTRY / UNISTR2* structure from a user list.
850********************************************************************/
851
852static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp,
853 UNISTR2 **uni_name_pp,
854 uint32 num_entries, uint32 start_idx,
855 struct samr_displayentry *entries)
856{
857 uint32 i;
858 SAM_ENTRY *sam;
859 UNISTR2 *uni_name;
860
861 *sam_pp = NULL;
862 *uni_name_pp = NULL;
863
864 if (num_entries == 0)
865 return NT_STATUS_OK;
866
867 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries);
868
869 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_entries);
870
871 if (sam == NULL || uni_name == NULL) {
872 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
873 return NT_STATUS_NO_MEMORY;
874 }
875
876 for (i = 0; i < num_entries; i++) {
877 UNISTR2 uni_temp_name;
878 /*
879 * usrmgr expects a non-NULL terminated string with
880 * trust relationships
881 */
882 if (entries[i].acct_flags & ACB_DOMTRUST) {
883 init_unistr2(&uni_temp_name, entries[i].account_name,
884 UNI_FLAGS_NONE);
885 } else {
886 init_unistr2(&uni_temp_name, entries[i].account_name,
887 UNI_STR_TERMINATE);
888 }
889
890 init_sam_entry(&sam[i], &uni_temp_name, entries[i].rid);
891 copy_unistr2(&uni_name[i], &uni_temp_name);
892 }
893
894 *sam_pp = sam;
895 *uni_name_pp = uni_name;
896 return NT_STATUS_OK;
897}
898
899/*******************************************************************
900 samr_reply_enum_dom_users
901 ********************************************************************/
902
903NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
904 SAMR_R_ENUM_DOM_USERS *r_u)
905{
906 struct samr_info *info = NULL;
907 int num_account;
908 uint32 enum_context=q_u->start_idx;
909 enum remote_arch_types ra_type = get_remote_arch();
910 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
911 uint32 max_entries = max_sam_entries;
912 struct samr_displayentry *entries = NULL;
913
914 r_u->status = NT_STATUS_OK;
915
916 /* find the policy handle. open a policy on it. */
917 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
918 return NT_STATUS_INVALID_HANDLE;
919
920 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
921 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
922 "_samr_enum_dom_users"))) {
923 return r_u->status;
924 }
925
926 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
927
928 if (info->builtin_domain) {
929 /* No users in builtin. */
930 init_samr_r_enum_dom_users(r_u, q_u->start_idx, 0);
931 DEBUG(5,("_samr_enum_dom_users: No users in BUILTIN\n"));
932 return r_u->status;
933 }
934
935 become_root();
936
937 /* AS ROOT !!!! */
938
939 if ((info->disp_info->enum_users != NULL) &&
940 (info->disp_info->enum_acb_mask != q_u->acb_mask)) {
941 pdb_search_destroy(info->disp_info->enum_users);
942 info->disp_info->enum_users = NULL;
943 }
944
945 if (info->disp_info->enum_users == NULL) {
946 info->disp_info->enum_users = pdb_search_users(q_u->acb_mask);
947 info->disp_info->enum_acb_mask = q_u->acb_mask;
948 }
949
950 if (info->disp_info->enum_users == NULL) {
951 /* END AS ROOT !!!! */
952 unbecome_root();
953 return NT_STATUS_ACCESS_DENIED;
954 }
955
956 num_account = pdb_search_entries(info->disp_info->enum_users,
957 enum_context, max_entries,
958 &entries);
959
960 /* END AS ROOT !!!! */
961
962 unbecome_root();
963
964 if (num_account == 0) {
965 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over "
966 "total entries\n"));
967 return NT_STATUS_OK;
968 }
969
970 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam,
971 &r_u->uni_acct_name,
972 num_account, enum_context,
973 entries);
974
975 if (!NT_STATUS_IS_OK(r_u->status))
976 return r_u->status;
977
978 if (max_entries <= num_account) {
979 r_u->status = STATUS_MORE_ENTRIES;
980 } else {
981 r_u->status = NT_STATUS_OK;
982 }
983
984 /* Ensure we cache this enumeration. */
985 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
986
987 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
988
989 init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_account,
990 num_account);
991
992 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
993
994 return r_u->status;
995}
996
997/*******************************************************************
998makes a SAM_ENTRY / UNISTR2* structure from a group list.
999********************************************************************/
1000
1001static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp,
1002 UNISTR2 **uni_name_pp,
1003 uint32 num_sam_entries,
1004 struct samr_displayentry *entries)
1005{
1006 uint32 i;
1007 SAM_ENTRY *sam;
1008 UNISTR2 *uni_name;
1009
1010 *sam_pp = NULL;
1011 *uni_name_pp = NULL;
1012
1013 if (num_sam_entries == 0)
1014 return;
1015
1016 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
1017 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
1018
1019 if (sam == NULL || uni_name == NULL) {
1020 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
1021 return;
1022 }
1023
1024 for (i = 0; i < num_sam_entries; i++) {
1025 /*
1026 * JRA. I think this should include the null. TNG does not.
1027 */
1028 init_unistr2(&uni_name[i], entries[i].account_name,
1029 UNI_STR_TERMINATE);
1030 init_sam_entry(&sam[i], &uni_name[i], entries[i].rid);
1031 }
1032
1033 *sam_pp = sam;
1034 *uni_name_pp = uni_name;
1035}
1036
1037/*******************************************************************
1038 samr_reply_enum_dom_groups
1039 ********************************************************************/
1040
1041NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1042{
1043 struct samr_info *info = NULL;
1044 struct samr_displayentry *groups;
1045 uint32 num_groups;
1046
1047 r_u->status = NT_STATUS_OK;
1048
1049 /* find the policy handle. open a policy on it. */
1050 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1051 return NT_STATUS_INVALID_HANDLE;
1052
1053 r_u->status = access_check_samr_function(info->acc_granted,
1054 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1055 "_samr_enum_dom_groups");
1056 if (!NT_STATUS_IS_OK(r_u->status))
1057 return r_u->status;
1058
1059 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1060
1061 if (info->builtin_domain) {
1062 /* No groups in builtin. */
1063 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, 0);
1064 DEBUG(5,("_samr_enum_dom_users: No groups in BUILTIN\n"));
1065 return r_u->status;
1066 }
1067
1068 /* the domain group array is being allocated in the function below */
1069
1070 become_root();
1071
1072 if (info->disp_info->groups == NULL) {
1073 info->disp_info->groups = pdb_search_groups();
1074
1075 if (info->disp_info->groups == NULL) {
1076 unbecome_root();
1077 return NT_STATUS_ACCESS_DENIED;
1078 }
1079 }
1080
1081 num_groups = pdb_search_entries(info->disp_info->groups, q_u->start_idx,
1082 MAX_SAM_ENTRIES, &groups);
1083 unbecome_root();
1084
1085 /* Ensure we cache this enumeration. */
1086 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1087
1088 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name,
1089 num_groups, groups);
1090
1091 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_groups);
1092
1093 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1094
1095 return r_u->status;
1096}
1097
1098/*******************************************************************
1099 samr_reply_enum_dom_aliases
1100 ********************************************************************/
1101
1102NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1103{
1104 struct samr_info *info;
1105 struct samr_displayentry *aliases;
1106 uint32 num_aliases = 0;
1107
1108 /* find the policy handle. open a policy on it. */
1109 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1110 return NT_STATUS_INVALID_HANDLE;
1111
1112 r_u->status = access_check_samr_function(info->acc_granted,
1113 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1114 "_samr_enum_dom_aliases");
1115 if (!NT_STATUS_IS_OK(r_u->status))
1116 return r_u->status;
1117
1118 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n",
1119 sid_string_static(&info->sid)));
1120
1121 become_root();
1122
1123 if (info->disp_info->aliases == NULL) {
1124 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1125 if (info->disp_info->aliases == NULL) {
1126 unbecome_root();
1127 return NT_STATUS_ACCESS_DENIED;
1128 }
1129 }
1130
1131 num_aliases = pdb_search_entries(info->disp_info->aliases, q_u->start_idx,
1132 MAX_SAM_ENTRIES, &aliases);
1133 unbecome_root();
1134
1135 /* Ensure we cache this enumeration. */
1136 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1137
1138 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name,
1139 num_aliases, aliases);
1140
1141 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_aliases,
1142 num_aliases);
1143
1144 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1145
1146 return r_u->status;
1147}
1148
1149/*******************************************************************
1150 samr_reply_query_dispinfo
1151 ********************************************************************/
1152
1153NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1154 SAMR_R_QUERY_DISPINFO *r_u)
1155{
1156 struct samr_info *info = NULL;
1157 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1158
1159 uint32 max_entries=q_u->max_entries;
1160 uint32 enum_context=q_u->start_idx;
1161 uint32 max_size=q_u->max_size;
1162
1163 SAM_DISPINFO_CTR *ctr;
1164 uint32 temp_size=0, total_data_size=0;
1165 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1166 uint32 num_account = 0;
1167 enum remote_arch_types ra_type = get_remote_arch();
1168 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1169 struct samr_displayentry *entries = NULL;
1170
1171 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1172 r_u->status = NT_STATUS_UNSUCCESSFUL;
1173
1174 /* find the policy handle. open a policy on it. */
1175 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info))
1176 return NT_STATUS_INVALID_HANDLE;
1177
1178 /*
1179 * calculate how many entries we will return.
1180 * based on
1181 * - the number of entries the client asked
1182 * - our limit on that
1183 * - the starting point (enumeration context)
1184 * - the buffer size the client will accept
1185 */
1186
1187 /*
1188 * We are a lot more like W2K. Instead of reading the SAM
1189 * each time to find the records we need to send back,
1190 * we read it once and link that copy to the sam handle.
1191 * For large user list (over the MAX_SAM_ENTRIES)
1192 * it's a definitive win.
1193 * second point to notice: between enumerations
1194 * our sam is now the same as it's a snapshoot.
1195 * third point: got rid of the static SAM_USER_21 struct
1196 * no more intermediate.
1197 * con: it uses much more memory, as a full copy is stored
1198 * in memory.
1199 *
1200 * If you want to change it, think twice and think
1201 * of the second point , that's really important.
1202 *
1203 * JFM, 12/20/2001
1204 */
1205
1206 if ((q_u->switch_level < 1) || (q_u->switch_level > 5)) {
1207 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n",
1208 (unsigned int)q_u->switch_level ));
1209 return NT_STATUS_INVALID_INFO_CLASS;
1210 }
1211
1212 /* first limit the number of entries we will return */
1213 if(max_entries > max_sam_entries) {
1214 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d "
1215 "entries, limiting to %d\n", max_entries,
1216 max_sam_entries));
1217 max_entries = max_sam_entries;
1218 }
1219
1220 /* calculate the size and limit on the number of entries we will
1221 * return */
1222
1223 temp_size=max_entries*struct_size;
1224
1225 if (temp_size>max_size) {
1226 max_entries=MIN((max_size/struct_size),max_entries);;
1227 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to "
1228 "only %d entries\n", max_entries));
1229 }
1230
1231 if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
1232 return NT_STATUS_NO_MEMORY;
1233
1234 ZERO_STRUCTP(ctr);
1235
1236 become_root();
1237
1238 /* THe following done as ROOT. Don't return without unbecome_root(). */
1239
1240 switch (q_u->switch_level) {
1241 case 0x1:
1242 case 0x4:
1243 if (info->disp_info->users == NULL) {
1244 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1245 if (info->disp_info->users == NULL) {
1246 unbecome_root();
1247 return NT_STATUS_ACCESS_DENIED;
1248 }
1249 DEBUG(10,("samr_reply_query_dispinfo: starting user enumeration at index %u\n",
1250 (unsigned int)enum_context ));
1251 } else {
1252 DEBUG(10,("samr_reply_query_dispinfo: using cached user enumeration at index %u\n",
1253 (unsigned int)enum_context ));
1254 }
1255
1256 num_account = pdb_search_entries(info->disp_info->users,
1257 enum_context, max_entries,
1258 &entries);
1259 break;
1260 case 0x2:
1261 if (info->disp_info->machines == NULL) {
1262 info->disp_info->machines =
1263 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1264 if (info->disp_info->machines == NULL) {
1265 unbecome_root();
1266 return NT_STATUS_ACCESS_DENIED;
1267 }
1268 DEBUG(10,("samr_reply_query_dispinfo: starting machine enumeration at index %u\n",
1269 (unsigned int)enum_context ));
1270 } else {
1271 DEBUG(10,("samr_reply_query_dispinfo: using cached machine enumeration at index %u\n",
1272 (unsigned int)enum_context ));
1273 }
1274
1275 num_account = pdb_search_entries(info->disp_info->machines,
1276 enum_context, max_entries,
1277 &entries);
1278 break;
1279 case 0x3:
1280 case 0x5:
1281 if (info->disp_info->groups == NULL) {
1282 info->disp_info->groups = pdb_search_groups();
1283 if (info->disp_info->groups == NULL) {
1284 unbecome_root();
1285 return NT_STATUS_ACCESS_DENIED;
1286 }
1287 DEBUG(10,("samr_reply_query_dispinfo: starting group enumeration at index %u\n",
1288 (unsigned int)enum_context ));
1289 } else {
1290 DEBUG(10,("samr_reply_query_dispinfo: using cached group enumeration at index %u\n",
1291 (unsigned int)enum_context ));
1292 }
1293
1294 num_account = pdb_search_entries(info->disp_info->groups,
1295 enum_context, max_entries,
1296 &entries);
1297 break;
1298 default:
1299 unbecome_root();
1300 smb_panic("info class changed");
1301 break;
1302 }
1303 unbecome_root();
1304
1305 /* Now create reply structure */
1306 switch (q_u->switch_level) {
1307 case 0x1:
1308 disp_ret = init_sam_dispinfo_1(p->mem_ctx, &ctr->sam.info1,
1309 num_account, enum_context,
1310 entries);
1311 break;
1312 case 0x2:
1313 disp_ret = init_sam_dispinfo_2(p->mem_ctx, &ctr->sam.info2,
1314 num_account, enum_context,
1315 entries);
1316 break;
1317 case 0x3:
1318 disp_ret = init_sam_dispinfo_3(p->mem_ctx, &ctr->sam.info3,
1319 num_account, enum_context,
1320 entries);
1321 break;
1322 case 0x4:
1323 disp_ret = init_sam_dispinfo_4(p->mem_ctx, &ctr->sam.info4,
1324 num_account, enum_context,
1325 entries);
1326 break;
1327 case 0x5:
1328 disp_ret = init_sam_dispinfo_5(p->mem_ctx, &ctr->sam.info5,
1329 num_account, enum_context,
1330 entries);
1331 break;
1332 default:
1333 smb_panic("info class changed");
1334 break;
1335 }
1336
1337 if (!NT_STATUS_IS_OK(disp_ret))
1338 return disp_ret;
1339
1340 /* calculate the total size */
1341 total_data_size=num_account*struct_size;
1342
1343 if (num_account) {
1344 r_u->status = STATUS_MORE_ENTRIES;
1345 } else {
1346 r_u->status = NT_STATUS_OK;
1347 }
1348
1349 /* Ensure we cache this enumeration. */
1350 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1351
1352 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1353
1354 init_samr_r_query_dispinfo(r_u, num_account, total_data_size,
1355 temp_size, q_u->switch_level, ctr,
1356 r_u->status);
1357
1358 return r_u->status;
1359
1360}
1361
1362/*******************************************************************
1363 samr_reply_query_aliasinfo
1364 ********************************************************************/
1365
1366NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1367{
1368 DOM_SID sid;
1369 struct acct_info info;
1370 uint32 acc_granted;
1371 BOOL ret;
1372
1373 r_u->status = NT_STATUS_OK;
1374
1375 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1376
1377 /* find the policy handle. open a policy on it. */
1378 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted, NULL))
1379 return NT_STATUS_INVALID_HANDLE;
1380 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1381 return r_u->status;
1382 }
1383
1384 become_root();
1385 ret = pdb_get_aliasinfo(&sid, &info);
1386 unbecome_root();
1387
1388 if ( !ret )
1389 return NT_STATUS_NO_SUCH_ALIAS;
1390
1391 if ( !(r_u->ctr = TALLOC_ZERO_P( p->mem_ctx, ALIAS_INFO_CTR )) )
1392 return NT_STATUS_NO_MEMORY;
1393
1394
1395 switch (q_u->level ) {
1396 case 1:
1397 r_u->ctr->level = 1;
1398 init_samr_alias_info1(&r_u->ctr->alias.info1, info.acct_name, 1, info.acct_desc);
1399 break;
1400 case 3:
1401 r_u->ctr->level = 3;
1402 init_samr_alias_info3(&r_u->ctr->alias.info3, info.acct_desc);
1403 break;
1404 default:
1405 return NT_STATUS_INVALID_INFO_CLASS;
1406 }
1407
1408 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1409
1410 return r_u->status;
1411}
1412
1413#if 0
1414/*******************************************************************
1415 samr_reply_lookup_ids
1416 ********************************************************************/
1417
1418 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1419{
1420 uint32 rid[MAX_SAM_ENTRIES];
1421 int num_rids = q_u->num_sids1;
1422
1423 r_u->status = NT_STATUS_OK;
1424
1425 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1426
1427 if (num_rids > MAX_SAM_ENTRIES) {
1428 num_rids = MAX_SAM_ENTRIES;
1429 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1430 }
1431
1432#if 0
1433 int i;
1434 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1435
1436 for (i = 0; i < num_rids && status == 0; i++)
1437 {
1438 struct sam_passwd *sam_pass;
1439 fstring user_name;
1440
1441
1442 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1443 q_u->uni_user_name[i].uni_str_len));
1444
1445 /* find the user account */
1446 become_root();
1447 sam_pass = get_smb21pwd_entry(user_name, 0);
1448 unbecome_root();
1449
1450 if (sam_pass == NULL)
1451 {
1452 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1453 rid[i] = 0;
1454 }
1455 else
1456 {
1457 rid[i] = sam_pass->user_rid;
1458 }
1459 }
1460#endif
1461
1462 num_rids = 1;
1463 rid[0] = BUILTIN_ALIAS_RID_USERS;
1464
1465 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1466
1467 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1468
1469 return r_u->status;
1470}
1471#endif
1472
1473/*******************************************************************
1474 _samr_lookup_names
1475 ********************************************************************/
1476
1477NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1478{
1479 uint32 rid[MAX_SAM_ENTRIES];
1480 enum lsa_SidType type[MAX_SAM_ENTRIES];
1481 int i;
1482 int num_rids = q_u->num_names2;
1483 DOM_SID pol_sid;
1484 fstring sid_str;
1485 uint32 acc_granted;
1486
1487 r_u->status = NT_STATUS_OK;
1488
1489 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1490
1491 ZERO_ARRAY(rid);
1492 ZERO_ARRAY(type);
1493
1494 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL)) {
1495 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1496 return r_u->status;
1497 }
1498
1499 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1500 return r_u->status;
1501 }
1502
1503 if (num_rids > MAX_SAM_ENTRIES) {
1504 num_rids = MAX_SAM_ENTRIES;
1505 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1506 }
1507
1508 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1509
1510 for (i = 0; i < num_rids; i++) {
1511 fstring name;
1512 int ret;
1513
1514 r_u->status = NT_STATUS_NONE_MAPPED;
1515 type[i] = SID_NAME_UNKNOWN;
1516
1517 rid [i] = 0xffffffff;
1518
1519 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1520
1521 if (ret <= 0) {
1522 continue;
1523 }
1524
1525 if (sid_check_is_builtin(&pol_sid)) {
1526 if (lookup_builtin_name(name, &rid[i])) {
1527 type[i] = SID_NAME_ALIAS;
1528 }
1529 } else {
1530 lookup_global_sam_name(name, 0, &rid[i], &type[i]);
1531 }
1532
1533 if (type[i] != SID_NAME_UNKNOWN) {
1534 r_u->status = NT_STATUS_OK;
1535 }
1536 }
1537
1538 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, type, r_u->status);
1539
1540 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1541
1542 return r_u->status;
1543}
1544
1545/*******************************************************************
1546 _samr_chgpasswd_user
1547 ********************************************************************/
1548
1549NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1550{
1551 fstring user_name;
1552 fstring wks;
1553
1554 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1555
1556 r_u->status = NT_STATUS_OK;
1557
1558 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1559 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1560
1561 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1562
1563 /*
1564 * Pass the user through the NT -> unix user mapping
1565 * function.
1566 */
1567
1568 (void)map_username(user_name);
1569
1570 /*
1571 * UNIX username case mangling not required, pass_oem_change
1572 * is case insensitive.
1573 */
1574
1575 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1576 q_u->nt_newpass.pass, q_u->nt_oldhash.hash, NULL);
1577
1578 init_samr_r_chgpasswd_user(r_u, r_u->status);
1579
1580 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1581
1582 return r_u->status;
1583}
1584
1585/*******************************************************************
1586 _samr_chgpasswd_user3
1587 ********************************************************************/
1588
1589NTSTATUS _samr_chgpasswd_user3(pipes_struct *p, SAMR_Q_CHGPASSWD_USER3 *q_u, SAMR_R_CHGPASSWD_USER3 *r_u)
1590{
1591 fstring user_name;
1592 fstring wks;
1593 uint32 reject_reason;
1594 SAM_UNK_INFO_1 *info = NULL;
1595 SAMR_CHANGE_REJECT *reject = NULL;
1596
1597 DEBUG(5,("_samr_chgpasswd_user3: %d\n", __LINE__));
1598
1599 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1600 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1601
1602 DEBUG(5,("_samr_chgpasswd_user3: user: %s wks: %s\n", user_name, wks));
1603
1604 /*
1605 * Pass the user through the NT -> unix user mapping
1606 * function.
1607 */
1608
1609 (void)map_username(user_name);
1610
1611 /*
1612 * UNIX username case mangling not required, pass_oem_change
1613 * is case insensitive.
1614 */
1615
1616 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1617 q_u->nt_newpass.pass, q_u->nt_oldhash.hash, &reject_reason);
1618
1619 if (NT_STATUS_EQUAL(r_u->status, NT_STATUS_PASSWORD_RESTRICTION) ||
1620 NT_STATUS_EQUAL(r_u->status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1621
1622 uint32 min_pass_len,pass_hist,password_properties;
1623 time_t u_expire, u_min_age;
1624 NTTIME nt_expire, nt_min_age;
1625 uint32 account_policy_temp;
1626
1627 if ((info = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_INFO_1)) == NULL) {
1628 return NT_STATUS_NO_MEMORY;
1629 }
1630
1631 if ((reject = TALLOC_ZERO_P(p->mem_ctx, SAMR_CHANGE_REJECT)) == NULL) {
1632 return NT_STATUS_NO_MEMORY;
1633 }
1634
1635 ZERO_STRUCTP(info);
1636 ZERO_STRUCTP(reject);
1637
1638 become_root();
1639
1640 /* AS ROOT !!! */
1641
1642 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1643 min_pass_len = account_policy_temp;
1644
1645 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1646 pass_hist = account_policy_temp;
1647
1648 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1649 password_properties = account_policy_temp;
1650
1651 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1652 u_expire = account_policy_temp;
1653
1654 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1655 u_min_age = account_policy_temp;
1656
1657 /* !AS ROOT */
1658
1659 unbecome_root();
1660
1661 unix_to_nt_time_abs(&nt_expire, u_expire);
1662 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1663
1664 init_unk_info1(info, (uint16)min_pass_len, (uint16)pass_hist,
1665 password_properties, nt_expire, nt_min_age);
1666
1667 reject->reject_reason = reject_reason;
1668 }
1669
1670 init_samr_r_chgpasswd_user3(r_u, r_u->status, reject, info);
1671
1672 DEBUG(5,("_samr_chgpasswd_user3: %d\n", __LINE__));
1673
1674 return r_u->status;
1675}
1676
1677/*******************************************************************
1678makes a SAMR_R_LOOKUP_RIDS structure.
1679********************************************************************/
1680
1681static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1682 const char **names, UNIHDR **pp_hdr_name,
1683 UNISTR2 **pp_uni_name)
1684{
1685 uint32 i;
1686 UNIHDR *hdr_name=NULL;
1687 UNISTR2 *uni_name=NULL;
1688
1689 *pp_uni_name = NULL;
1690 *pp_hdr_name = NULL;
1691
1692 if (num_names != 0) {
1693 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1694 if (hdr_name == NULL)
1695 return False;
1696
1697 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1698 if (uni_name == NULL)
1699 return False;
1700 }
1701
1702 for (i = 0; i < num_names; i++) {
1703 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
1704 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1705 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1706 }
1707
1708 *pp_uni_name = uni_name;
1709 *pp_hdr_name = hdr_name;
1710
1711 return True;
1712}
1713
1714/*******************************************************************
1715 _samr_lookup_rids
1716 ********************************************************************/
1717
1718NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1719{
1720 const char **names;
1721 enum lsa_SidType *attrs = NULL;
1722 uint32 *wire_attrs = NULL;
1723 UNIHDR *hdr_name = NULL;
1724 UNISTR2 *uni_name = NULL;
1725 DOM_SID pol_sid;
1726 int num_rids = q_u->num_rids1;
1727 uint32 acc_granted;
1728 int i;
1729
1730 r_u->status = NT_STATUS_OK;
1731
1732 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1733
1734 /* find the policy handle. open a policy on it. */
1735 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL))
1736 return NT_STATUS_INVALID_HANDLE;
1737
1738 if (num_rids > 1000) {
1739 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
1740 "to samba4 idl this is not possible\n", num_rids));
1741 return NT_STATUS_UNSUCCESSFUL;
1742 }
1743
1744 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
1745 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
1746 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
1747
1748 if ((num_rids != 0) && ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL)))
1749 return NT_STATUS_NO_MEMORY;
1750
1751 become_root(); /* lookup_sid can require root privs */
1752 r_u->status = pdb_lookup_rids(&pol_sid, num_rids, q_u->rid,
1753 names, attrs);
1754 unbecome_root();
1755
1756 if ( NT_STATUS_EQUAL(r_u->status, NT_STATUS_NONE_MAPPED) && (num_rids == 0) ) {
1757 r_u->status = NT_STATUS_OK;
1758 }
1759
1760 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
1761 &hdr_name, &uni_name))
1762 return NT_STATUS_NO_MEMORY;
1763
1764 /* Convert from enum lsa_SidType to uint32 for wire format. */
1765 for (i = 0; i < num_rids; i++) {
1766 wire_attrs[i] = (uint32)attrs[i];
1767 }
1768
1769 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, wire_attrs);
1770
1771 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1772
1773 return r_u->status;
1774}
1775
1776/*******************************************************************
1777 _samr_open_user. Safe - gives out no passwd info.
1778 ********************************************************************/
1779
1780NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1781{
1782 struct samu *sampass=NULL;
1783 DOM_SID sid;
1784 POLICY_HND domain_pol = q_u->domain_pol;
1785 POLICY_HND *user_pol = &r_u->user_pol;
1786 struct samr_info *info = NULL;
1787 SEC_DESC *psd = NULL;
1788 uint32 acc_granted;
1789 uint32 des_access = q_u->access_mask;
1790 size_t sd_size;
1791 BOOL ret;
1792 NTSTATUS nt_status;
1793 SE_PRIV se_rights;
1794
1795 r_u->status = NT_STATUS_OK;
1796
1797 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1798
1799 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
1800 return NT_STATUS_INVALID_HANDLE;
1801
1802 nt_status = access_check_samr_function( acc_granted,
1803 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user" );
1804
1805 if ( !NT_STATUS_IS_OK(nt_status) )
1806 return nt_status;
1807
1808 if ( !(sampass = samu_new( p->mem_ctx )) ) {
1809 return NT_STATUS_NO_MEMORY;
1810 }
1811
1812 /* append the user's RID to it */
1813
1814 if (!sid_append_rid(&sid, q_u->user_rid))
1815 return NT_STATUS_NO_SUCH_USER;
1816
1817 /* check if access can be granted as requested by client. */
1818
1819 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
1820 se_map_generic(&des_access, &usr_generic_mapping);
1821
1822 se_priv_copy( &se_rights, &se_machine_account );
1823 se_priv_add( &se_rights, &se_add_users );
1824
1825 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
1826 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
1827 &acc_granted, "_samr_open_user");
1828
1829 if ( !NT_STATUS_IS_OK(nt_status) )
1830 return nt_status;
1831
1832 become_root();
1833 ret=pdb_getsampwsid(sampass, &sid);
1834 unbecome_root();
1835
1836 /* check that the SID exists in our domain. */
1837 if (ret == False) {
1838 return NT_STATUS_NO_SUCH_USER;
1839 }
1840
1841 TALLOC_FREE(sampass);
1842
1843 /* associate the user's SID and access bits with the new handle. */
1844 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1845 return NT_STATUS_NO_MEMORY;
1846 info->acc_granted = acc_granted;
1847
1848 /* get a (unique) handle. open a policy on it. */
1849 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1850 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1851
1852 return r_u->status;
1853}
1854
1855/*************************************************************************
1856 get_user_info_7. Safe. Only gives out account_name.
1857 *************************************************************************/
1858
1859static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, SAM_USER_INFO_7 *id7, DOM_SID *user_sid)
1860{
1861 struct samu *smbpass=NULL;
1862 BOOL ret;
1863
1864 if ( !(smbpass = samu_new( mem_ctx )) ) {
1865 return NT_STATUS_NO_MEMORY;
1866 }
1867
1868 become_root();
1869 ret = pdb_getsampwsid(smbpass, user_sid);
1870 unbecome_root();
1871
1872 if ( !ret ) {
1873 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1874 return NT_STATUS_NO_SUCH_USER;
1875 }
1876
1877 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1878
1879 ZERO_STRUCTP(id7);
1880 init_sam_user_info7(id7, pdb_get_username(smbpass) );
1881
1882 TALLOC_FREE(smbpass);
1883
1884 return NT_STATUS_OK;
1885}
1886
1887/*************************************************************************
1888 get_user_info_9. Only gives out primary group SID.
1889 *************************************************************************/
1890static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx, SAM_USER_INFO_9 * id9, DOM_SID *user_sid)
1891{
1892 struct samu *smbpass=NULL;
1893 BOOL ret;
1894
1895 if ( !(smbpass = samu_new( mem_ctx )) ) {
1896 return NT_STATUS_NO_MEMORY;
1897 }
1898
1899 become_root();
1900 ret = pdb_getsampwsid(smbpass, user_sid);
1901 unbecome_root();
1902
1903 if (ret==False) {
1904 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1905 return NT_STATUS_NO_SUCH_USER;
1906 }
1907
1908 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1909
1910 ZERO_STRUCTP(id9);
1911 init_sam_user_info9(id9, pdb_get_group_rid(smbpass) );
1912
1913 TALLOC_FREE(smbpass);
1914
1915 return NT_STATUS_OK;
1916}
1917
1918/*************************************************************************
1919 get_user_info_16. Safe. Only gives out acb bits.
1920 *************************************************************************/
1921
1922static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx, SAM_USER_INFO_16 *id16, DOM_SID *user_sid)
1923{
1924 struct samu *smbpass=NULL;
1925 BOOL ret;
1926
1927 if ( !(smbpass = samu_new( mem_ctx )) ) {
1928 return NT_STATUS_NO_MEMORY;
1929 }
1930
1931 become_root();
1932 ret = pdb_getsampwsid(smbpass, user_sid);
1933 unbecome_root();
1934
1935 if (ret==False) {
1936 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1937 return NT_STATUS_NO_SUCH_USER;
1938 }
1939
1940 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1941
1942 ZERO_STRUCTP(id16);
1943 init_sam_user_info16(id16, pdb_get_acct_ctrl(smbpass) );
1944
1945 TALLOC_FREE(smbpass);
1946
1947 return NT_STATUS_OK;
1948}
1949
1950/*************************************************************************
1951 get_user_info_18. OK - this is the killer as it gives out password info.
1952 Ensure that this is only allowed on an encrypted connection with a root
1953 user. JRA.
1954 *************************************************************************/
1955
1956static NTSTATUS get_user_info_18(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_18 * id18, DOM_SID *user_sid)
1957{
1958 struct samu *smbpass=NULL;
1959 BOOL ret;
1960
1961 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
1962 return NT_STATUS_ACCESS_DENIED;
1963 }
1964
1965 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
1966 return NT_STATUS_ACCESS_DENIED;
1967 }
1968
1969 /*
1970 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1971 */
1972
1973 if ( !(smbpass = samu_new( mem_ctx )) ) {
1974 return NT_STATUS_NO_MEMORY;
1975 }
1976
1977 ret = pdb_getsampwsid(smbpass, user_sid);
1978
1979 if (ret == False) {
1980 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1981 TALLOC_FREE(smbpass);
1982 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1983 }
1984
1985 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1986
1987 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1988 TALLOC_FREE(smbpass);
1989 return NT_STATUS_ACCOUNT_DISABLED;
1990 }
1991
1992 ZERO_STRUCTP(id18);
1993 init_sam_user_info18(id18, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1994
1995 TALLOC_FREE(smbpass);
1996
1997 return NT_STATUS_OK;
1998}
1999
2000/*************************************************************************
2001 get_user_info_20
2002 *************************************************************************/
2003
2004static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
2005{
2006 struct samu *sampass=NULL;
2007 BOOL ret;
2008
2009 if ( !(sampass = samu_new( mem_ctx )) ) {
2010 return NT_STATUS_NO_MEMORY;
2011 }
2012
2013 become_root();
2014 ret = pdb_getsampwsid(sampass, user_sid);
2015 unbecome_root();
2016
2017 if (ret == False) {
2018 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
2019 return NT_STATUS_NO_SUCH_USER;
2020 }
2021
2022 samr_clear_sam_passwd(sampass);
2023
2024 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
2025
2026 ZERO_STRUCTP(id20);
2027 init_sam_user_info20A(id20, sampass);
2028
2029 TALLOC_FREE(sampass);
2030
2031 return NT_STATUS_OK;
2032}
2033
2034/*************************************************************************
2035 get_user_info_21
2036 *************************************************************************/
2037
2038static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
2039 DOM_SID *user_sid, DOM_SID *domain_sid)
2040{
2041 struct samu *sampass=NULL;
2042 BOOL ret;
2043 NTSTATUS nt_status;
2044
2045 if ( !(sampass = samu_new( mem_ctx )) ) {
2046 return NT_STATUS_NO_MEMORY;
2047 }
2048
2049 become_root();
2050 ret = pdb_getsampwsid(sampass, user_sid);
2051 unbecome_root();
2052
2053 if (ret == False) {
2054 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
2055 return NT_STATUS_NO_SUCH_USER;
2056 }
2057
2058 samr_clear_sam_passwd(sampass);
2059
2060 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
2061
2062 ZERO_STRUCTP(id21);
2063 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
2064
2065 TALLOC_FREE(sampass);
2066
2067 return nt_status;
2068}
2069
2070/*******************************************************************
2071 _samr_query_userinfo
2072 ********************************************************************/
2073
2074NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
2075{
2076 SAM_USERINFO_CTR *ctr;
2077 struct samr_info *info = NULL;
2078 DOM_SID domain_sid;
2079 uint32 rid;
2080
2081 r_u->status=NT_STATUS_OK;
2082
2083 /* search for the handle */
2084 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
2085 return NT_STATUS_INVALID_HANDLE;
2086
2087 domain_sid = info->sid;
2088
2089 sid_split_rid(&domain_sid, &rid);
2090
2091 if (!sid_check_is_in_our_domain(&info->sid))
2092 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2093
2094 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
2095
2096 ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
2097 if (!ctr)
2098 return NT_STATUS_NO_MEMORY;
2099
2100 ZERO_STRUCTP(ctr);
2101
2102 /* ok! user info levels (lots: see MSDEV help), off we go... */
2103 ctr->switch_value = q_u->switch_value;
2104
2105 DEBUG(5,("_samr_query_userinfo: user info level: %d\n", q_u->switch_value));
2106
2107 switch (q_u->switch_value) {
2108 case 7:
2109 ctr->info.id7 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_7);
2110 if (ctr->info.id7 == NULL)
2111 return NT_STATUS_NO_MEMORY;
2112
2113 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_7(p->mem_ctx, ctr->info.id7, &info->sid)))
2114 return r_u->status;
2115 break;
2116 case 9:
2117 ctr->info.id9 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_9);
2118 if (ctr->info.id9 == NULL)
2119 return NT_STATUS_NO_MEMORY;
2120
2121 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_9(p->mem_ctx, ctr->info.id9, &info->sid)))
2122 return r_u->status;
2123 break;
2124 case 16:
2125 ctr->info.id16 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_16);
2126 if (ctr->info.id16 == NULL)
2127 return NT_STATUS_NO_MEMORY;
2128
2129 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_16(p->mem_ctx, ctr->info.id16, &info->sid)))
2130 return r_u->status;
2131 break;
2132
2133 case 18:
2134 ctr->info.id18 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_18);
2135 if (ctr->info.id18 == NULL)
2136 return NT_STATUS_NO_MEMORY;
2137
2138 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_18(p, p->mem_ctx, ctr->info.id18, &info->sid)))
2139 return r_u->status;
2140 break;
2141
2142 case 20:
2143 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
2144 if (ctr->info.id20 == NULL)
2145 return NT_STATUS_NO_MEMORY;
2146 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
2147 return r_u->status;
2148 break;
2149
2150 case 21:
2151 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
2152 if (ctr->info.id21 == NULL)
2153 return NT_STATUS_NO_MEMORY;
2154 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
2155 &info->sid, &domain_sid)))
2156 return r_u->status;
2157 break;
2158
2159 default:
2160 return NT_STATUS_INVALID_INFO_CLASS;
2161 }
2162
2163 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
2164
2165 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
2166
2167 return r_u->status;
2168}
2169
2170/*******************************************************************
2171 samr_reply_query_usergroups
2172 ********************************************************************/
2173
2174NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
2175{
2176 struct samu *sam_pass=NULL;
2177 DOM_SID sid;
2178 DOM_SID *sids;
2179 DOM_GID dom_gid;
2180 DOM_GID *gids = NULL;
2181 uint32 primary_group_rid;
2182 size_t num_groups = 0;
2183 gid_t *unix_gids;
2184 size_t i, num_gids;
2185 uint32 acc_granted;
2186 BOOL ret;
2187 NTSTATUS result;
2188 BOOL success = False;
2189
2190 /*
2191 * from the SID in the request:
2192 * we should send back the list of DOMAIN GROUPS
2193 * the user is a member of
2194 *
2195 * and only the DOMAIN GROUPS
2196 * no ALIASES !!! neither aliases of the domain
2197 * nor aliases of the builtin SID
2198 *
2199 * JFM, 12/2/2001
2200 */
2201
2202 r_u->status = NT_STATUS_OK;
2203
2204 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2205
2206 /* find the policy handle. open a policy on it. */
2207 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted, NULL))
2208 return NT_STATUS_INVALID_HANDLE;
2209
2210 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2211 return r_u->status;
2212 }
2213
2214 if (!sid_check_is_in_our_domain(&sid))
2215 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2216
2217 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2218 return NT_STATUS_NO_MEMORY;
2219 }
2220
2221 become_root();
2222 ret = pdb_getsampwsid(sam_pass, &sid);
2223 unbecome_root();
2224
2225 if (!ret) {
2226 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2227 sid_string_static(&sid)));
2228 return NT_STATUS_NO_SUCH_USER;
2229 }
2230
2231 sids = NULL;
2232
2233 /* make both calls inside the root block */
2234 become_root();
2235 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2236 &sids, &unix_gids, &num_groups);
2237 if ( NT_STATUS_IS_OK(result) ) {
2238 success = sid_peek_check_rid(get_global_sam_sid(),
2239 pdb_get_group_sid(sam_pass),
2240 &primary_group_rid);
2241 }
2242 unbecome_root();
2243
2244 if (!NT_STATUS_IS_OK(result)) {
2245 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2246 sid_string_static(&sid)));
2247 return result;
2248 }
2249
2250 if ( !success ) {
2251 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2252 sid_string_static(pdb_get_group_sid(sam_pass)),
2253 pdb_get_username(sam_pass)));
2254 TALLOC_FREE(sam_pass);
2255 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2256 }
2257
2258 gids = NULL;
2259 num_gids = 0;
2260
2261 dom_gid.attr = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2262 SE_GROUP_ENABLED);
2263 dom_gid.g_rid = primary_group_rid;
2264 ADD_TO_ARRAY(p->mem_ctx, DOM_GID, dom_gid, &gids, &num_gids);
2265
2266 for (i=0; i<num_groups; i++) {
2267
2268 if (!sid_peek_check_rid(get_global_sam_sid(),
2269 &(sids[i]), &dom_gid.g_rid)) {
2270 DEBUG(10, ("Found sid %s not in our domain\n",
2271 sid_string_static(&sids[i])));
2272 continue;
2273 }
2274
2275 if (dom_gid.g_rid == primary_group_rid) {
2276 /* We added the primary group directly from the
2277 * sam_account. The other SIDs are unique from
2278 * enum_group_memberships */
2279 continue;
2280 }
2281
2282 ADD_TO_ARRAY(p->mem_ctx, DOM_GID, dom_gid, &gids, &num_gids);
2283 }
2284
2285 /* construct the response. lkclXXXX: gids are not copied! */
2286 init_samr_r_query_usergroups(r_u, num_gids, gids, r_u->status);
2287
2288 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2289
2290 return r_u->status;
2291}
2292
2293/*******************************************************************
2294 _samr_query_domain_info
2295 ********************************************************************/
2296
2297NTSTATUS _samr_query_domain_info(pipes_struct *p,
2298 SAMR_Q_QUERY_DOMAIN_INFO *q_u,
2299 SAMR_R_QUERY_DOMAIN_INFO *r_u)
2300{
2301 struct samr_info *info = NULL;
2302 SAM_UNK_CTR *ctr;
2303 uint32 min_pass_len,pass_hist,password_properties;
2304 time_t u_expire, u_min_age;
2305 NTTIME nt_expire, nt_min_age;
2306
2307 time_t u_lock_duration, u_reset_time;
2308 NTTIME nt_lock_duration, nt_reset_time;
2309 uint32 lockout;
2310 time_t u_logout;
2311 NTTIME nt_logout;
2312
2313 uint32 account_policy_temp;
2314
2315 time_t seq_num;
2316 uint32 server_role;
2317
2318 uint32 num_users=0, num_groups=0, num_aliases=0;
2319
2320 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL) {
2321 return NT_STATUS_NO_MEMORY;
2322 }
2323
2324 ZERO_STRUCTP(ctr);
2325
2326 r_u->status = NT_STATUS_OK;
2327
2328 DEBUG(5,("_samr_query_domain_info: %d\n", __LINE__));
2329
2330 /* find the policy handle. open a policy on it. */
2331 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info)) {
2332 return NT_STATUS_INVALID_HANDLE;
2333 }
2334
2335 switch (q_u->switch_value) {
2336 case 0x01:
2337
2338 become_root();
2339
2340 /* AS ROOT !!! */
2341
2342 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2343 min_pass_len = account_policy_temp;
2344
2345 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2346 pass_hist = account_policy_temp;
2347
2348 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2349 password_properties = account_policy_temp;
2350
2351 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2352 u_expire = account_policy_temp;
2353
2354 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2355 u_min_age = account_policy_temp;
2356
2357 /* !AS ROOT */
2358
2359 unbecome_root();
2360
2361 unix_to_nt_time_abs(&nt_expire, u_expire);
2362 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2363
2364 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2365 password_properties, nt_expire, nt_min_age);
2366 break;
2367 case 0x02:
2368
2369 become_root();
2370
2371 /* AS ROOT !!! */
2372
2373 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2374 num_groups = count_sam_groups(info->disp_info);
2375 num_aliases = count_sam_aliases(info->disp_info);
2376
2377 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2378 u_logout = account_policy_temp;
2379
2380 unix_to_nt_time_abs(&nt_logout, u_logout);
2381
2382 if (!pdb_get_seq_num(&seq_num))
2383 seq_num = time(NULL);
2384
2385 /* !AS ROOT */
2386
2387 unbecome_root();
2388
2389 server_role = ROLE_DOMAIN_PDC;
2390 if (lp_server_role() == ROLE_DOMAIN_BDC)
2391 server_role = ROLE_DOMAIN_BDC;
2392
2393 init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), seq_num,
2394 num_users, num_groups, num_aliases, nt_logout, server_role);
2395 break;
2396 case 0x03:
2397
2398 become_root();
2399
2400 /* AS ROOT !!! */
2401
2402 {
2403 uint32 ul;
2404 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2405 u_logout = (time_t)ul;
2406 }
2407
2408 /* !AS ROOT */
2409
2410 unbecome_root();
2411
2412 unix_to_nt_time_abs(&nt_logout, u_logout);
2413
2414 init_unk_info3(&ctr->info.inf3, nt_logout);
2415 break;
2416 case 0x04:
2417 init_unk_info4(&ctr->info.inf4, lp_serverstring());
2418 break;
2419 case 0x05:
2420 init_unk_info5(&ctr->info.inf5, get_global_sam_name());
2421 break;
2422 case 0x06:
2423 /* NT returns its own name when a PDC. win2k and later
2424 * only the name of the PDC if itself is a BDC (samba4
2425 * idl) */
2426 init_unk_info6(&ctr->info.inf6, global_myname());
2427 break;
2428 case 0x07:
2429 server_role = ROLE_DOMAIN_PDC;
2430 if (lp_server_role() == ROLE_DOMAIN_BDC)
2431 server_role = ROLE_DOMAIN_BDC;
2432
2433 init_unk_info7(&ctr->info.inf7, server_role);
2434 break;
2435 case 0x08:
2436
2437 become_root();
2438
2439 /* AS ROOT !!! */
2440
2441 if (!pdb_get_seq_num(&seq_num)) {
2442 seq_num = time(NULL);
2443 }
2444
2445 /* !AS ROOT */
2446
2447 unbecome_root();
2448
2449 init_unk_info8(&ctr->info.inf8, (uint32) seq_num);
2450 break;
2451 case 0x0c:
2452
2453 become_root();
2454
2455 /* AS ROOT !!! */
2456
2457 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2458 u_lock_duration = account_policy_temp;
2459 if (u_lock_duration != -1) {
2460 u_lock_duration *= 60;
2461 }
2462
2463 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2464 u_reset_time = account_policy_temp * 60;
2465
2466 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2467 lockout = account_policy_temp;
2468
2469 /* !AS ROOT */
2470
2471 unbecome_root();
2472
2473 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2474 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2475
2476 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2477 break;
2478 default:
2479 return NT_STATUS_INVALID_INFO_CLASS;
2480 }
2481
2482
2483 init_samr_r_query_domain_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2484
2485 DEBUG(5,("_samr_query_domain_info: %d\n", __LINE__));
2486
2487 return r_u->status;
2488}
2489
2490/* W2k3 seems to use the same check for all 3 objects that can be created via
2491 * SAMR, if you try to create for example "Dialup" as an alias it says
2492 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
2493 * database. */
2494
2495static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
2496{
2497 enum lsa_SidType type;
2498 BOOL result;
2499
2500 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
2501
2502 become_root();
2503 /* Lookup in our local databases (only LOOKUP_NAME_ISOLATED set)
2504 * whether the name already exists */
2505 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_ISOLATED,
2506 NULL, NULL, NULL, &type);
2507 unbecome_root();
2508
2509 if (!result) {
2510 DEBUG(10, ("%s does not exist, can create it\n", new_name));
2511 return NT_STATUS_OK;
2512 }
2513
2514 DEBUG(5, ("trying to create %s, exists as %s\n",
2515 new_name, sid_type_lookup(type)));
2516
2517 if (type == SID_NAME_DOM_GRP) {
2518 return NT_STATUS_GROUP_EXISTS;
2519 }
2520 if (type == SID_NAME_ALIAS) {
2521 return NT_STATUS_ALIAS_EXISTS;
2522 }
2523
2524 /* Yes, the default is NT_STATUS_USER_EXISTS */
2525 return NT_STATUS_USER_EXISTS;
2526}
2527
2528/*******************************************************************
2529 _samr_create_user
2530 Create an account, can be either a normal user or a machine.
2531 This funcion will need to be updated for bdc/domain trusts.
2532 ********************************************************************/
2533
2534NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
2535 SAMR_R_CREATE_USER *r_u)
2536{
2537 char *account;
2538 DOM_SID sid;
2539 POLICY_HND dom_pol = q_u->domain_pol;
2540 uint16 acb_info = q_u->acb_info;
2541 POLICY_HND *user_pol = &r_u->user_pol;
2542 struct samr_info *info = NULL;
2543 NTSTATUS nt_status;
2544 uint32 acc_granted;
2545 SEC_DESC *psd;
2546 size_t sd_size;
2547 /* check this, when giving away 'add computer to domain' privs */
2548 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2549 BOOL can_add_account = False;
2550 SE_PRIV se_rights;
2551 DISP_INFO *disp_info = NULL;
2552
2553 /* Get the domain SID stored in the domain policy */
2554 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
2555 &disp_info))
2556 return NT_STATUS_INVALID_HANDLE;
2557
2558 nt_status = access_check_samr_function(acc_granted,
2559 SA_RIGHT_DOMAIN_CREATE_USER,
2560 "_samr_create_user");
2561 if (!NT_STATUS_IS_OK(nt_status)) {
2562 return nt_status;
2563 }
2564
2565 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
2566 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2567 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2568 this parameter is not an account type */
2569 return NT_STATUS_INVALID_PARAMETER;
2570 }
2571
2572 account = rpcstr_pull_unistr2_talloc(p->mem_ctx, &q_u->uni_name);
2573 if (account == NULL) {
2574 return NT_STATUS_NO_MEMORY;
2575 }
2576
2577 nt_status = can_create(p->mem_ctx, account);
2578 if (!NT_STATUS_IS_OK(nt_status)) {
2579 return nt_status;
2580 }
2581
2582 /* determine which user right we need to check based on the acb_info */
2583
2584 if ( acb_info & ACB_WSTRUST )
2585 {
2586 se_priv_copy( &se_rights, &se_machine_account );
2587 can_add_account = user_has_privileges(
2588 p->pipe_user.nt_user_token, &se_rights );
2589 }
2590 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
2591 account for domain trusts and changes the ACB flags later */
2592 else if ( acb_info & ACB_NORMAL &&
2593 (account[strlen(account)-1] != '$') )
2594 {
2595 se_priv_copy( &se_rights, &se_add_users );
2596 can_add_account = user_has_privileges(
2597 p->pipe_user.nt_user_token, &se_rights );
2598 }
2599 else /* implicit assumption of a BDC or domain trust account here
2600 * (we already check the flags earlier) */
2601 {
2602 if ( lp_enable_privileges() ) {
2603 /* only Domain Admins can add a BDC or domain trust */
2604 se_priv_copy( &se_rights, &se_priv_none );
2605 can_add_account = nt_token_check_domain_rid(
2606 p->pipe_user.nt_user_token,
2607 DOMAIN_GROUP_RID_ADMINS );
2608 }
2609 }
2610
2611 DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2612 uidtoname(p->pipe_user.ut.uid),
2613 can_add_account ? "True":"False" ));
2614
2615 /********** BEGIN Admin BLOCK **********/
2616
2617 if ( can_add_account )
2618 become_root();
2619
2620 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
2621 &r_u->user_rid);
2622
2623 if ( can_add_account )
2624 unbecome_root();
2625
2626 /********** END Admin BLOCK **********/
2627
2628 /* now check for failure */
2629
2630 if ( !NT_STATUS_IS_OK(nt_status) )
2631 return nt_status;
2632
2633 /* Get the user's SID */
2634
2635 sid_compose(&sid, get_global_sam_sid(), r_u->user_rid);
2636
2637 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
2638 &sid, SAMR_USR_RIGHTS_WRITE_PW);
2639 se_map_generic(&des_access, &usr_generic_mapping);
2640
2641 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2642 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2643 &acc_granted, "_samr_create_user");
2644
2645 if ( !NT_STATUS_IS_OK(nt_status) ) {
2646 return nt_status;
2647 }
2648
2649 /* associate the user's SID with the new handle. */
2650 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2651 return NT_STATUS_NO_MEMORY;
2652 }
2653
2654 ZERO_STRUCTP(info);
2655 info->sid = sid;
2656 info->acc_granted = acc_granted;
2657
2658 /* get a (unique) handle. open a policy on it. */
2659 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2660 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2661 }
2662
2663 /* After a "set" ensure we have no cached display info. */
2664 force_flush_samr_cache(info->disp_info);
2665
2666 r_u->access_granted = acc_granted;
2667
2668 return NT_STATUS_OK;
2669}
2670
2671/*******************************************************************
2672 samr_reply_connect_anon
2673 ********************************************************************/
2674
2675NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2676{
2677 struct samr_info *info = NULL;
2678 uint32 des_access = q_u->access_mask;
2679
2680 /* Access check */
2681
2682 if (!pipe_access_check(p)) {
2683 DEBUG(3, ("access denied to samr_connect_anon\n"));
2684 r_u->status = NT_STATUS_ACCESS_DENIED;
2685 return r_u->status;
2686 }
2687
2688 /* set up the SAMR connect_anon response */
2689
2690 r_u->status = NT_STATUS_OK;
2691
2692 /* associate the user's SID with the new handle. */
2693 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2694 return NT_STATUS_NO_MEMORY;
2695
2696 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2697 was observed from a win98 client trying to enumerate users (when configured
2698 user level access control on shares) --jerry */
2699
2700 if (des_access == MAXIMUM_ALLOWED_ACCESS) {
2701 /* Map to max possible knowing we're filtered below. */
2702 des_access = GENERIC_ALL_ACCESS;
2703 }
2704
2705 se_map_generic( &des_access, &sam_generic_mapping );
2706 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2707
2708 info->status = q_u->unknown_0;
2709
2710 /* get a (unique) handle. open a policy on it. */
2711 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2712 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2713
2714 return r_u->status;
2715}
2716
2717/*******************************************************************
2718 samr_reply_connect
2719 ********************************************************************/
2720
2721NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2722{
2723 struct samr_info *info = NULL;
2724 SEC_DESC *psd = NULL;
2725 uint32 acc_granted;
2726 uint32 des_access = q_u->access_mask;
2727 NTSTATUS nt_status;
2728 size_t sd_size;
2729
2730
2731 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2732
2733 /* Access check */
2734
2735 if (!pipe_access_check(p)) {
2736 DEBUG(3, ("access denied to samr_connect\n"));
2737 r_u->status = NT_STATUS_ACCESS_DENIED;
2738 return r_u->status;
2739 }
2740
2741 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2742 se_map_generic(&des_access, &sam_generic_mapping);
2743
2744 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2745 NULL, 0, des_access, &acc_granted, "_samr_connect");
2746
2747 if ( !NT_STATUS_IS_OK(nt_status) )
2748 return nt_status;
2749
2750 r_u->status = NT_STATUS_OK;
2751
2752 /* associate the user's SID and access granted with the new handle. */
2753 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2754 return NT_STATUS_NO_MEMORY;
2755
2756 info->acc_granted = acc_granted;
2757 info->status = q_u->access_mask;
2758
2759 /* get a (unique) handle. open a policy on it. */
2760 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2761 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2762
2763 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2764
2765 return r_u->status;
2766}
2767
2768/*******************************************************************
2769 samr_connect4
2770 ********************************************************************/
2771
2772NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2773{
2774 struct samr_info *info = NULL;
2775 SEC_DESC *psd = NULL;
2776 uint32 acc_granted;
2777 uint32 des_access = q_u->access_mask;
2778 NTSTATUS nt_status;
2779 size_t sd_size;
2780
2781
2782 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2783
2784 /* Access check */
2785
2786 if (!pipe_access_check(p)) {
2787 DEBUG(3, ("access denied to samr_connect4\n"));
2788 r_u->status = NT_STATUS_ACCESS_DENIED;
2789 return r_u->status;
2790 }
2791
2792 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2793 se_map_generic(&des_access, &sam_generic_mapping);
2794
2795 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2796 NULL, 0, des_access, &acc_granted, "_samr_connect4");
2797
2798 if ( !NT_STATUS_IS_OK(nt_status) )
2799 return nt_status;
2800
2801 r_u->status = NT_STATUS_OK;
2802
2803 /* associate the user's SID and access granted with the new handle. */
2804 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2805 return NT_STATUS_NO_MEMORY;
2806
2807 info->acc_granted = acc_granted;
2808 info->status = q_u->access_mask;
2809
2810 /* get a (unique) handle. open a policy on it. */
2811 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2812 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2813
2814 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2815
2816 return r_u->status;
2817}
2818
2819/*******************************************************************
2820 samr_connect5
2821 ********************************************************************/
2822
2823NTSTATUS _samr_connect5(pipes_struct *p, SAMR_Q_CONNECT5 *q_u, SAMR_R_CONNECT5 *r_u)
2824{
2825 struct samr_info *info = NULL;
2826 SEC_DESC *psd = NULL;
2827 uint32 acc_granted;
2828 uint32 des_access = q_u->access_mask;
2829 NTSTATUS nt_status;
2830 POLICY_HND pol;
2831 size_t sd_size;
2832
2833
2834 DEBUG(5,("_samr_connect5: %d\n", __LINE__));
2835
2836 ZERO_STRUCTP(r_u);
2837
2838 /* Access check */
2839
2840 if (!pipe_access_check(p)) {
2841 DEBUG(3, ("access denied to samr_connect5\n"));
2842 r_u->status = NT_STATUS_ACCESS_DENIED;
2843 return r_u->status;
2844 }
2845
2846 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2847 se_map_generic(&des_access, &sam_generic_mapping);
2848
2849 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2850 NULL, 0, des_access, &acc_granted, "_samr_connect5");
2851
2852 if ( !NT_STATUS_IS_OK(nt_status) )
2853 return nt_status;
2854
2855 /* associate the user's SID and access granted with the new handle. */
2856 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2857 return NT_STATUS_NO_MEMORY;
2858
2859 info->acc_granted = acc_granted;
2860 info->status = q_u->access_mask;
2861
2862 /* get a (unique) handle. open a policy on it. */
2863 if (!create_policy_hnd(p, &pol, free_samr_info, (void *)info))
2864 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2865
2866 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2867
2868 init_samr_r_connect5(r_u, &pol, NT_STATUS_OK);
2869
2870 return r_u->status;
2871}
2872
2873/**********************************************************************
2874 api_samr_lookup_domain
2875 **********************************************************************/
2876
2877NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2878{
2879 struct samr_info *info;
2880 fstring domain_name;
2881 DOM_SID sid;
2882
2883 r_u->status = NT_STATUS_OK;
2884
2885 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)(void *)&info))
2886 return NT_STATUS_INVALID_HANDLE;
2887
2888 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
2889 Reverted that change so we will work with RAS servers again */
2890
2891 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2892 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain")))
2893 {
2894 return r_u->status;
2895 }
2896
2897 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2898
2899 ZERO_STRUCT(sid);
2900
2901 if (strequal(domain_name, builtin_domain_name())) {
2902 sid_copy(&sid, &global_sid_Builtin);
2903 } else {
2904 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2905 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2906 }
2907 }
2908
2909 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2910
2911 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2912
2913 return r_u->status;
2914}
2915
2916/******************************************************************
2917makes a SAMR_R_ENUM_DOMAINS structure.
2918********************************************************************/
2919
2920static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2921 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2922{
2923 uint32 i;
2924 SAM_ENTRY *sam;
2925 UNISTR2 *uni_name;
2926
2927 DEBUG(5, ("make_enum_domains\n"));
2928
2929 *pp_sam = NULL;
2930 *pp_uni_name = NULL;
2931
2932 if (num_sam_entries == 0)
2933 return True;
2934
2935 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2936 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2937
2938 if (sam == NULL || uni_name == NULL)
2939 return False;
2940
2941 for (i = 0; i < num_sam_entries; i++) {
2942 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2943 init_sam_entry(&sam[i], &uni_name[i], 0);
2944 }
2945
2946 *pp_sam = sam;
2947 *pp_uni_name = uni_name;
2948
2949 return True;
2950}
2951
2952/**********************************************************************
2953 api_samr_enum_domains
2954 **********************************************************************/
2955
2956NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2957{
2958 struct samr_info *info;
2959 uint32 num_entries = 2;
2960 fstring dom[2];
2961 const char *name;
2962
2963 r_u->status = NT_STATUS_OK;
2964
2965 if (!find_policy_by_hnd(p, &q_u->pol, (void**)(void *)&info))
2966 return NT_STATUS_INVALID_HANDLE;
2967
2968 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2969 return r_u->status;
2970 }
2971
2972 name = get_global_sam_name();
2973
2974 fstrcpy(dom[0],name);
2975 strupper_m(dom[0]);
2976 fstrcpy(dom[1],"Builtin");
2977
2978 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2979 return NT_STATUS_NO_MEMORY;
2980
2981 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2982
2983 return r_u->status;
2984}
2985
2986/*******************************************************************
2987 api_samr_open_alias
2988 ********************************************************************/
2989
2990NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2991{
2992 DOM_SID sid;
2993 POLICY_HND domain_pol = q_u->dom_pol;
2994 uint32 alias_rid = q_u->rid_alias;
2995 POLICY_HND *alias_pol = &r_u->pol;
2996 struct samr_info *info = NULL;
2997 SEC_DESC *psd = NULL;
2998 uint32 acc_granted;
2999 uint32 des_access = q_u->access_mask;
3000 size_t sd_size;
3001 NTSTATUS status;
3002 SE_PRIV se_rights;
3003
3004 r_u->status = NT_STATUS_OK;
3005
3006 /* find the domain policy and get the SID / access bits stored in the domain policy */
3007
3008 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3009 return NT_STATUS_INVALID_HANDLE;
3010
3011 status = access_check_samr_function(acc_granted,
3012 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias");
3013
3014 if ( !NT_STATUS_IS_OK(status) )
3015 return status;
3016
3017 /* append the alias' RID to it */
3018
3019 if (!sid_append_rid(&sid, alias_rid))
3020 return NT_STATUS_NO_SUCH_ALIAS;
3021
3022 /*check if access can be granted as requested by client. */
3023
3024 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3025 se_map_generic(&des_access,&ali_generic_mapping);
3026
3027 se_priv_copy( &se_rights, &se_add_users );
3028
3029
3030 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3031 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3032 &acc_granted, "_samr_open_alias");
3033
3034 if ( !NT_STATUS_IS_OK(status) )
3035 return status;
3036
3037 {
3038 /* Check we actually have the requested alias */
3039 enum lsa_SidType type;
3040 BOOL result;
3041 gid_t gid;
3042
3043 become_root();
3044 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3045 unbecome_root();
3046
3047 if (!result || (type != SID_NAME_ALIAS)) {
3048 return NT_STATUS_NO_SUCH_ALIAS;
3049 }
3050
3051 /* make sure there is a mapping */
3052
3053 if ( !sid_to_gid( &sid, &gid ) ) {
3054 return NT_STATUS_NO_SUCH_ALIAS;
3055 }
3056
3057 }
3058
3059 /* associate the alias SID with the new handle. */
3060 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3061 return NT_STATUS_NO_MEMORY;
3062
3063 info->acc_granted = acc_granted;
3064
3065 /* get a (unique) handle. open a policy on it. */
3066 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3067 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3068
3069 return r_u->status;
3070}
3071
3072/*******************************************************************
3073 set_user_info_7
3074 ********************************************************************/
3075static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3076 const SAM_USER_INFO_7 *id7, struct samu *pwd)
3077{
3078 fstring new_name;
3079 NTSTATUS rc;
3080
3081 if (id7 == NULL) {
3082 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3083 TALLOC_FREE(pwd);
3084 return NT_STATUS_ACCESS_DENIED;
3085 }
3086
3087 if(!rpcstr_pull(new_name, id7->uni_name.buffer, sizeof(new_name), id7->uni_name.uni_str_len*2, 0)) {
3088 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3089 TALLOC_FREE(pwd);
3090 return NT_STATUS_ACCESS_DENIED;
3091 }
3092
3093 /* check to see if the new username already exists. Note: we can't
3094 reliably lock all backends, so there is potentially the
3095 possibility that a user can be created in between this check and
3096 the rename. The rename should fail, but may not get the
3097 exact same failure status code. I think this is small enough
3098 of a window for this type of operation and the results are
3099 simply that the rename fails with a slightly different status
3100 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3101
3102 rc = can_create(mem_ctx, new_name);
3103 if (!NT_STATUS_IS_OK(rc)) {
3104 return rc;
3105 }
3106
3107 rc = pdb_rename_sam_account(pwd, new_name);
3108
3109 TALLOC_FREE(pwd);
3110 return rc;
3111}
3112
3113/*******************************************************************
3114 set_user_info_16
3115 ********************************************************************/
3116
3117static BOOL set_user_info_16(const SAM_USER_INFO_16 *id16, struct samu *pwd)
3118{
3119 if (id16 == NULL) {
3120 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3121 TALLOC_FREE(pwd);
3122 return False;
3123 }
3124
3125 /* FIX ME: check if the value is really changed --metze */
3126 if (!pdb_set_acct_ctrl(pwd, id16->acb_info, PDB_CHANGED)) {
3127 TALLOC_FREE(pwd);
3128 return False;
3129 }
3130
3131 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3132 TALLOC_FREE(pwd);
3133 return False;
3134 }
3135
3136 TALLOC_FREE(pwd);
3137
3138 return True;
3139}
3140
3141/*******************************************************************
3142 set_user_info_18
3143 ********************************************************************/
3144
3145static BOOL set_user_info_18(SAM_USER_INFO_18 *id18, struct samu *pwd)
3146{
3147
3148 if (id18 == NULL) {
3149 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3150 TALLOC_FREE(pwd);
3151 return False;
3152 }
3153
3154 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd, PDB_CHANGED)) {
3155 TALLOC_FREE(pwd);
3156 return False;
3157 }
3158 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd, PDB_CHANGED)) {
3159 TALLOC_FREE(pwd);
3160 return False;
3161 }
3162 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3163 TALLOC_FREE(pwd);
3164 return False;
3165 }
3166
3167 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3168 TALLOC_FREE(pwd);
3169 return False;
3170 }
3171
3172 TALLOC_FREE(pwd);
3173 return True;
3174}
3175
3176/*******************************************************************
3177 set_user_info_20
3178 ********************************************************************/
3179
3180static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, struct samu *pwd)
3181{
3182 if (id20 == NULL) {
3183 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3184 return False;
3185 }
3186
3187 copy_id20_to_sam_passwd(pwd, id20);
3188
3189 /* write the change out */
3190 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3191 TALLOC_FREE(pwd);
3192 return False;
3193 }
3194
3195 TALLOC_FREE(pwd);
3196
3197 return True;
3198}
3199/*******************************************************************
3200 set_user_info_21
3201 ********************************************************************/
3202
3203static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
3204 struct samu *pwd)
3205{
3206 fstring new_name;
3207 NTSTATUS status;
3208
3209 if (id21 == NULL) {
3210 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3211 return NT_STATUS_INVALID_PARAMETER;
3212 }
3213
3214 /* we need to separately check for an account rename first */
3215
3216 if (rpcstr_pull(new_name, id21->uni_user_name.buffer,
3217 sizeof(new_name), id21->uni_user_name.uni_str_len*2, 0)
3218 && (!strequal(new_name, pdb_get_username(pwd))))
3219 {
3220
3221 /* check to see if the new username already exists. Note: we can't
3222 reliably lock all backends, so there is potentially the
3223 possibility that a user can be created in between this check and
3224 the rename. The rename should fail, but may not get the
3225 exact same failure status code. I think this is small enough
3226 of a window for this type of operation and the results are
3227 simply that the rename fails with a slightly different status
3228 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3229
3230 status = can_create(mem_ctx, new_name);
3231 if (!NT_STATUS_IS_OK(status)) {
3232 return status;
3233 }
3234
3235 status = pdb_rename_sam_account(pwd, new_name);
3236
3237 if (!NT_STATUS_IS_OK(status)) {
3238 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3239 nt_errstr(status)));
3240 TALLOC_FREE(pwd);
3241 return status;
3242 }
3243
3244 /* set the new username so that later
3245 functions can work on the new account */
3246 pdb_set_username(pwd, new_name, PDB_SET);
3247 }
3248
3249 copy_id21_to_sam_passwd(pwd, id21);
3250
3251 /*
3252 * The funny part about the previous two calls is
3253 * that pwd still has the password hashes from the
3254 * passdb entry. These have not been updated from
3255 * id21. I don't know if they need to be set. --jerry
3256 */
3257
3258 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3259 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3260 if ( !NT_STATUS_IS_OK(status) ) {
3261 return status;
3262 }
3263 }
3264
3265 /* Don't worry about writing out the user account since the
3266 primary group SID is generated solely from the user's Unix
3267 primary group. */
3268
3269 /* write the change out */
3270 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3271 TALLOC_FREE(pwd);
3272 return status;
3273 }
3274
3275 TALLOC_FREE(pwd);
3276
3277 return NT_STATUS_OK;
3278}
3279
3280/*******************************************************************
3281 set_user_info_23
3282 ********************************************************************/
3283
3284static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23,
3285 struct samu *pwd)
3286{
3287 pstring plaintext_buf;
3288 uint32 len;
3289 uint16 acct_ctrl;
3290 NTSTATUS status;
3291
3292 if (id23 == NULL) {
3293 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3294 return NT_STATUS_INVALID_PARAMETER;
3295 }
3296
3297 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3298 pdb_get_username(pwd)));
3299
3300 acct_ctrl = pdb_get_acct_ctrl(pwd);
3301
3302 if (!decode_pw_buffer(id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
3303 TALLOC_FREE(pwd);
3304 return NT_STATUS_INVALID_PARAMETER;
3305 }
3306
3307 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3308 TALLOC_FREE(pwd);
3309 return NT_STATUS_ACCESS_DENIED;
3310 }
3311
3312 copy_id23_to_sam_passwd(pwd, id23);
3313
3314 /* if it's a trust account, don't update /etc/passwd */
3315 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3316 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3317 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3318 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3319 } else {
3320 /* update the UNIX password */
3321 if (lp_unix_password_sync() ) {
3322 struct passwd *passwd;
3323 if (pdb_get_username(pwd) == NULL) {
3324 DEBUG(1, ("chgpasswd: User without name???\n"));
3325 TALLOC_FREE(pwd);
3326 return NT_STATUS_ACCESS_DENIED;
3327 }
3328
3329 if ((passwd = Get_Pwnam(pdb_get_username(pwd))) == NULL) {
3330 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3331 }
3332
3333 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3334 TALLOC_FREE(pwd);
3335 return NT_STATUS_ACCESS_DENIED;
3336 }
3337 }
3338 }
3339
3340 ZERO_STRUCT(plaintext_buf);
3341
3342 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3343 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3344 pwd)))) {
3345 TALLOC_FREE(pwd);
3346 return status;
3347 }
3348
3349 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3350 TALLOC_FREE(pwd);
3351 return status;
3352 }
3353
3354 TALLOC_FREE(pwd);
3355
3356 return NT_STATUS_OK;
3357}
3358
3359/*******************************************************************
3360 set_user_info_pw
3361 ********************************************************************/
3362
3363static BOOL set_user_info_pw(uint8 *pass, struct samu *pwd)
3364{
3365 uint32 len;
3366 pstring plaintext_buf;
3367 uint32 acct_ctrl;
3368
3369 DEBUG(5, ("Attempting administrator password change for user %s\n",
3370 pdb_get_username(pwd)));
3371
3372 acct_ctrl = pdb_get_acct_ctrl(pwd);
3373
3374 ZERO_STRUCT(plaintext_buf);
3375
3376 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
3377 TALLOC_FREE(pwd);
3378 return False;
3379 }
3380
3381 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3382 TALLOC_FREE(pwd);
3383 return False;
3384 }
3385
3386 /* if it's a trust account, don't update /etc/passwd */
3387 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3388 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3389 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3390 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3391 } else {
3392 /* update the UNIX password */
3393 if (lp_unix_password_sync()) {
3394 struct passwd *passwd;
3395
3396 if (pdb_get_username(pwd) == NULL) {
3397 DEBUG(1, ("chgpasswd: User without name???\n"));
3398 TALLOC_FREE(pwd);
3399 return False;
3400 }
3401
3402 if ((passwd = Get_Pwnam(pdb_get_username(pwd))) == NULL) {
3403 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3404 }
3405
3406 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3407 TALLOC_FREE(pwd);
3408 return False;
3409 }
3410 }
3411 }
3412
3413 ZERO_STRUCT(plaintext_buf);
3414
3415 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3416
3417 /* update the SAMBA password */
3418 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3419 TALLOC_FREE(pwd);
3420 return False;
3421 }
3422
3423 TALLOC_FREE(pwd);
3424
3425 return True;
3426}
3427
3428/*******************************************************************
3429 set_user_info_25
3430 ********************************************************************/
3431
3432static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx, SAM_USER_INFO_25 *id25,
3433 struct samu *pwd)
3434{
3435 NTSTATUS status;
3436
3437 if (id25 == NULL) {
3438 DEBUG(5, ("set_user_info_25: NULL id25\n"));
3439 return NT_STATUS_INVALID_PARAMETER;
3440 }
3441
3442 copy_id25_to_sam_passwd(pwd, id25);
3443
3444 /* write the change out */
3445 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3446 TALLOC_FREE(pwd);
3447 return status;
3448 }
3449
3450 /*
3451 * We need to "pdb_update_sam_account" before the unix primary group
3452 * is set, because the idealx scripts would also change the
3453 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
3454 * the delete explicit / add explicit, which would then fail to find
3455 * the previous primaryGroupSid value.
3456 */
3457
3458 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3459 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3460 if ( !NT_STATUS_IS_OK(status) ) {
3461 return status;
3462 }
3463 }
3464
3465 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
3466 * hereafter! */
3467
3468 return NT_STATUS_OK;
3469}
3470
3471/*******************************************************************
3472 samr_reply_set_userinfo
3473 ********************************************************************/
3474
3475NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3476{
3477 struct samu *pwd = NULL;
3478 DOM_SID sid;
3479 POLICY_HND *pol = &q_u->pol;
3480 uint16 switch_value = q_u->switch_value;
3481 SAM_USERINFO_CTR *ctr = q_u->ctr;
3482 uint32 acc_granted;
3483 uint32 acc_required;
3484 BOOL ret;
3485 BOOL has_enough_rights = False;
3486 uint32 acb_info;
3487 DISP_INFO *disp_info = NULL;
3488
3489 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3490
3491 r_u->status = NT_STATUS_OK;
3492
3493 /* find the policy handle. open a policy on it. */
3494 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info))
3495 return NT_STATUS_INVALID_HANDLE;
3496
3497 /* This is tricky. A WinXP domain join sets
3498 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
3499 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
3500 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
3501 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
3502 we'll use the set from the WinXP join as the basis. */
3503
3504 switch (switch_value) {
3505 case 18:
3506 case 24:
3507 case 25:
3508 case 26:
3509 acc_required = SA_RIGHT_USER_SET_PASSWORD;
3510 break;
3511 default:
3512 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3513 break;
3514 }
3515
3516 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3517 return r_u->status;
3518 }
3519
3520 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3521
3522 if (ctr == NULL) {
3523 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3524 return NT_STATUS_INVALID_INFO_CLASS;
3525 }
3526
3527 if ( !(pwd = samu_new( NULL )) ) {
3528 return NT_STATUS_NO_MEMORY;
3529 }
3530
3531 become_root();
3532 ret = pdb_getsampwsid(pwd, &sid);
3533 unbecome_root();
3534
3535 if ( !ret ) {
3536 TALLOC_FREE(pwd);
3537 return NT_STATUS_NO_SUCH_USER;
3538 }
3539
3540 /* deal with machine password changes differently from userinfo changes */
3541 /* check to see if we have the sufficient rights */
3542
3543 acb_info = pdb_get_acct_ctrl(pwd);
3544 if ( acb_info & ACB_WSTRUST )
3545 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3546 else if ( acb_info & ACB_NORMAL )
3547 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3548 else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3549 if ( lp_enable_privileges() )
3550 has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3551 }
3552
3553 DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3554 uidtoname(p->pipe_user.ut.uid),
3555 has_enough_rights ? "" : " not"));
3556
3557 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3558
3559 if ( has_enough_rights )
3560 become_root();
3561
3562 /* ok! user info levels (lots: see MSDEV help), off we go... */
3563
3564 switch (switch_value) {
3565 case 18:
3566 if (!set_user_info_18(ctr->info.id18, pwd))
3567 r_u->status = NT_STATUS_ACCESS_DENIED;
3568 break;
3569
3570 case 24:
3571 if (!p->session_key.length) {
3572 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3573 }
3574 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3575
3576 dump_data(100, (char *)ctr->info.id24->pass, 516);
3577
3578 if (!set_user_info_pw(ctr->info.id24->pass, pwd))
3579 r_u->status = NT_STATUS_ACCESS_DENIED;
3580 break;
3581
3582 case 25:
3583 if (!p->session_key.length) {
3584 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3585 }
3586 encode_or_decode_arc4_passwd_buffer(ctr->info.id25->pass, &p->session_key);
3587
3588 dump_data(100, (char *)ctr->info.id25->pass, 532);
3589
3590 r_u->status = set_user_info_25(p->mem_ctx,
3591 ctr->info.id25, pwd);
3592 if (!NT_STATUS_IS_OK(r_u->status)) {
3593 goto done;
3594 }
3595 if (!set_user_info_pw(ctr->info.id25->pass, pwd))
3596 r_u->status = NT_STATUS_ACCESS_DENIED;
3597 break;
3598
3599 case 26:
3600 if (!p->session_key.length) {
3601 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3602 }
3603 encode_or_decode_arc4_passwd_buffer(ctr->info.id26->pass, &p->session_key);
3604
3605 dump_data(100, (char *)ctr->info.id26->pass, 516);
3606
3607 if (!set_user_info_pw(ctr->info.id26->pass, pwd))
3608 r_u->status = NT_STATUS_ACCESS_DENIED;
3609 break;
3610
3611 case 23:
3612 if (!p->session_key.length) {
3613 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3614 }
3615 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3616
3617 dump_data(100, (char *)ctr->info.id23->pass, 516);
3618
3619 r_u->status = set_user_info_23(p->mem_ctx,
3620 ctr->info.id23, pwd);
3621 break;
3622
3623 default:
3624 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3625 }
3626
3627 done:
3628
3629 if ( has_enough_rights )
3630 unbecome_root();
3631
3632 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3633
3634 if (NT_STATUS_IS_OK(r_u->status)) {
3635 force_flush_samr_cache(disp_info);
3636 }
3637
3638 return r_u->status;
3639}
3640
3641/*******************************************************************
3642 samr_reply_set_userinfo2
3643 ********************************************************************/
3644
3645NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3646{
3647 struct samu *pwd = NULL;
3648 DOM_SID sid;
3649 SAM_USERINFO_CTR *ctr = q_u->ctr;
3650 POLICY_HND *pol = &q_u->pol;
3651 uint16 switch_value = q_u->switch_value;
3652 uint32 acc_granted;
3653 uint32 acc_required;
3654 BOOL ret;
3655 BOOL has_enough_rights = False;
3656 uint32 acb_info;
3657 DISP_INFO *disp_info = NULL;
3658
3659 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3660
3661 r_u->status = NT_STATUS_OK;
3662
3663 /* find the policy handle. open a policy on it. */
3664 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info))
3665 return NT_STATUS_INVALID_HANDLE;
3666
3667
3668#if 0 /* this really should be applied on a per info level basis --jerry */
3669
3670 /* observed when joining XP client to Samba domain */
3671 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3672#else
3673 acc_required = SA_RIGHT_USER_SET_ATTRIBUTES;
3674#endif
3675
3676 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3677 return r_u->status;
3678 }
3679
3680 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3681
3682 if (ctr == NULL) {
3683 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3684 return NT_STATUS_INVALID_INFO_CLASS;
3685 }
3686
3687 switch_value=ctr->switch_value;
3688
3689 if ( !(pwd = samu_new( NULL )) ) {
3690 return NT_STATUS_NO_MEMORY;
3691 }
3692
3693 become_root();
3694 ret = pdb_getsampwsid(pwd, &sid);
3695 unbecome_root();
3696
3697 if ( !ret ) {
3698 TALLOC_FREE(pwd);
3699 return NT_STATUS_NO_SUCH_USER;
3700 }
3701
3702 acb_info = pdb_get_acct_ctrl(pwd);
3703 if ( acb_info & ACB_WSTRUST )
3704 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3705 else if ( acb_info & ACB_NORMAL )
3706 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3707 else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3708 if ( lp_enable_privileges() )
3709 has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3710 }
3711
3712 DEBUG(5, ("_samr_set_userinfo2: %s does%s possess sufficient rights\n",
3713 uidtoname(p->pipe_user.ut.uid),
3714 has_enough_rights ? "" : " not"));
3715
3716 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3717
3718 if ( has_enough_rights )
3719 become_root();
3720
3721 /* ok! user info levels (lots: see MSDEV help), off we go... */
3722
3723 switch (switch_value) {
3724 case 7:
3725 r_u->status = set_user_info_7(p->mem_ctx,
3726 ctr->info.id7, pwd);
3727 break;
3728 case 16:
3729 if (!set_user_info_16(ctr->info.id16, pwd))
3730 r_u->status = NT_STATUS_ACCESS_DENIED;
3731 break;
3732 case 18:
3733 /* Used by AS/U JRA. */
3734 if (!set_user_info_18(ctr->info.id18, pwd))
3735 r_u->status = NT_STATUS_ACCESS_DENIED;
3736 break;
3737 case 20:
3738 if (!set_user_info_20(ctr->info.id20, pwd))
3739 r_u->status = NT_STATUS_ACCESS_DENIED;
3740 break;
3741 case 21:
3742 r_u->status = set_user_info_21(p->mem_ctx,
3743 ctr->info.id21, pwd);
3744 break;
3745 case 23:
3746 if (!p->session_key.length) {
3747 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3748 }
3749 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3750
3751 dump_data(100, (char *)ctr->info.id23->pass, 516);
3752
3753 r_u->status = set_user_info_23(p->mem_ctx,
3754 ctr->info.id23, pwd);
3755 break;
3756 case 26:
3757 if (!p->session_key.length) {
3758 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3759 }
3760 encode_or_decode_arc4_passwd_buffer(ctr->info.id26->pass, &p->session_key);
3761
3762 dump_data(100, (char *)ctr->info.id26->pass, 516);
3763
3764 if (!set_user_info_pw(ctr->info.id26->pass, pwd))
3765 r_u->status = NT_STATUS_ACCESS_DENIED;
3766 break;
3767 default:
3768 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3769 }
3770
3771 if ( has_enough_rights )
3772 unbecome_root();
3773
3774 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3775
3776 if (NT_STATUS_IS_OK(r_u->status)) {
3777 force_flush_samr_cache(disp_info);
3778 }
3779
3780 return r_u->status;
3781}
3782
3783/*********************************************************************
3784 _samr_query_aliasmem
3785*********************************************************************/
3786
3787NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3788{
3789 size_t num_alias_rids;
3790 uint32 *alias_rids;
3791 struct samr_info *info = NULL;
3792 size_t i;
3793
3794 NTSTATUS ntstatus1;
3795 NTSTATUS ntstatus2;
3796
3797 DOM_SID *members;
3798
3799 r_u->status = NT_STATUS_OK;
3800
3801 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3802
3803 /* find the policy handle. open a policy on it. */
3804 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
3805 return NT_STATUS_INVALID_HANDLE;
3806
3807 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3808 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3809
3810 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3811 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3812 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3813 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3814 }
3815 }
3816
3817 if (!sid_check_is_domain(&info->sid) &&
3818 !sid_check_is_builtin(&info->sid))
3819 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3820
3821 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3822
3823 if (members == NULL)
3824 return NT_STATUS_NO_MEMORY;
3825
3826 for (i=0; i<q_u->num_sids1; i++)
3827 sid_copy(&members[i], &q_u->sid[i].sid);
3828
3829 alias_rids = NULL;
3830 num_alias_rids = 0;
3831
3832 become_root();
3833 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
3834 q_u->num_sids1,
3835 &alias_rids, &num_alias_rids);
3836 unbecome_root();
3837
3838 if (!NT_STATUS_IS_OK(ntstatus1)) {
3839 return ntstatus1;
3840 }
3841
3842 init_samr_r_query_useraliases(r_u, num_alias_rids, alias_rids,
3843 NT_STATUS_OK);
3844 return NT_STATUS_OK;
3845}
3846
3847/*********************************************************************
3848 _samr_query_aliasmem
3849*********************************************************************/
3850
3851NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3852{
3853 NTSTATUS status;
3854 size_t i;
3855 size_t num_sids = 0;
3856 DOM_SID2 *sid;
3857 DOM_SID *sids=NULL;
3858
3859 DOM_SID alias_sid;
3860
3861 uint32 acc_granted;
3862
3863 /* find the policy handle. open a policy on it. */
3864 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted, NULL))
3865 return NT_STATUS_INVALID_HANDLE;
3866
3867 if (!NT_STATUS_IS_OK(r_u->status =
3868 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3869 return r_u->status;
3870 }
3871
3872 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3873
3874 become_root();
3875 status = pdb_enum_aliasmem(&alias_sid, &sids, &num_sids);
3876 unbecome_root();
3877
3878 if (!NT_STATUS_IS_OK(status)) {
3879 return status;
3880 }
3881
3882 sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);
3883 if (num_sids!=0 && sid == NULL) {
3884 SAFE_FREE(sids);
3885 return NT_STATUS_NO_MEMORY;
3886 }
3887
3888 for (i = 0; i < num_sids; i++) {
3889 init_dom_sid2(&sid[i], &sids[i]);
3890 }
3891
3892 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3893
3894 TALLOC_FREE(sids);
3895
3896 return NT_STATUS_OK;
3897}
3898
3899/*********************************************************************
3900 _samr_query_groupmem
3901*********************************************************************/
3902
3903NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3904{
3905 DOM_SID group_sid;
3906 fstring group_sid_str;
3907 size_t i, num_members;
3908
3909 uint32 *rid=NULL;
3910 uint32 *attr=NULL;
3911
3912 uint32 acc_granted;
3913
3914 NTSTATUS result;
3915
3916 /* find the policy handle. open a policy on it. */
3917 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted, NULL))
3918 return NT_STATUS_INVALID_HANDLE;
3919
3920 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3921 return r_u->status;
3922 }
3923
3924 sid_to_string(group_sid_str, &group_sid);
3925 DEBUG(10, ("sid is %s\n", group_sid_str));
3926
3927 if (!sid_check_is_in_our_domain(&group_sid)) {
3928 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3929 return NT_STATUS_NO_SUCH_GROUP;
3930 }
3931
3932 DEBUG(10, ("lookup on Domain SID\n"));
3933
3934 become_root();
3935 result = pdb_enum_group_members(p->mem_ctx, &group_sid,
3936 &rid, &num_members);
3937 unbecome_root();
3938
3939 if (!NT_STATUS_IS_OK(result))
3940 return result;
3941
3942 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
3943
3944 if ((num_members!=0) && (attr==NULL))
3945 return NT_STATUS_NO_MEMORY;
3946
3947 for (i=0; i<num_members; i++)
3948 attr[i] = SID_NAME_USER;
3949
3950 init_samr_r_query_groupmem(r_u, num_members, rid, attr, NT_STATUS_OK);
3951
3952 return NT_STATUS_OK;
3953}
3954
3955/*********************************************************************
3956 _samr_add_aliasmem
3957*********************************************************************/
3958
3959NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3960{
3961 DOM_SID alias_sid;
3962 uint32 acc_granted;
3963 SE_PRIV se_rights;
3964 BOOL can_add_accounts;
3965 NTSTATUS ret;
3966 DISP_INFO *disp_info = NULL;
3967
3968 /* Find the policy handle. Open a policy on it. */
3969 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted, &disp_info))
3970 return NT_STATUS_INVALID_HANDLE;
3971
3972 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3973 return r_u->status;
3974 }
3975
3976 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3977
3978 se_priv_copy( &se_rights, &se_add_users );
3979 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3980
3981 /******** BEGIN SeAddUsers BLOCK *********/
3982
3983 if ( can_add_accounts )
3984 become_root();
3985
3986 ret = pdb_add_aliasmem(&alias_sid, &q_u->sid.sid);
3987
3988 if ( can_add_accounts )
3989 unbecome_root();
3990
3991 /******** END SeAddUsers BLOCK *********/
3992
3993 if (NT_STATUS_IS_OK(ret)) {
3994 force_flush_samr_cache(disp_info);
3995 }
3996
3997 return ret;
3998}
3999
4000/*********************************************************************
4001 _samr_del_aliasmem
4002*********************************************************************/
4003
4004NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
4005{
4006 DOM_SID alias_sid;
4007 uint32 acc_granted;
4008 SE_PRIV se_rights;
4009 BOOL can_add_accounts;
4010 NTSTATUS ret;
4011 DISP_INFO *disp_info = NULL;
4012
4013 /* Find the policy handle. Open a policy on it. */
4014 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted, &disp_info))
4015 return NT_STATUS_INVALID_HANDLE;
4016
4017 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
4018 return r_u->status;
4019 }
4020
4021 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4022 sid_string_static(&alias_sid)));
4023
4024 se_priv_copy( &se_rights, &se_add_users );
4025 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4026
4027 /******** BEGIN SeAddUsers BLOCK *********/
4028
4029 if ( can_add_accounts )
4030 become_root();
4031
4032 ret = pdb_del_aliasmem(&alias_sid, &q_u->sid.sid);
4033
4034 if ( can_add_accounts )
4035 unbecome_root();
4036
4037 /******** END SeAddUsers BLOCK *********/
4038
4039 if (NT_STATUS_IS_OK(ret)) {
4040 force_flush_samr_cache(disp_info);
4041 }
4042
4043 return ret;
4044}
4045
4046/*********************************************************************
4047 _samr_add_groupmem
4048*********************************************************************/
4049
4050NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
4051{
4052 DOM_SID group_sid;
4053 uint32 group_rid;
4054 uint32 acc_granted;
4055 SE_PRIV se_rights;
4056 BOOL can_add_accounts;
4057 DISP_INFO *disp_info = NULL;
4058
4059 /* Find the policy handle. Open a policy on it. */
4060 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted, &disp_info))
4061 return NT_STATUS_INVALID_HANDLE;
4062
4063 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
4064 return r_u->status;
4065 }
4066
4067 DEBUG(10, ("sid is %s\n", sid_string_static(&group_sid)));
4068
4069 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4070 &group_rid)) {
4071 return NT_STATUS_INVALID_HANDLE;
4072 }
4073
4074 se_priv_copy( &se_rights, &se_add_users );
4075 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4076
4077 /******** BEGIN SeAddUsers BLOCK *********/
4078
4079 if ( can_add_accounts )
4080 become_root();
4081
4082 r_u->status = pdb_add_groupmem(p->mem_ctx, group_rid, q_u->rid);
4083
4084 if ( can_add_accounts )
4085 unbecome_root();
4086
4087 /******** END SeAddUsers BLOCK *********/
4088
4089 force_flush_samr_cache(disp_info);
4090
4091 return r_u->status;
4092}
4093
4094/*********************************************************************
4095 _samr_del_groupmem
4096*********************************************************************/
4097
4098NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
4099{
4100 DOM_SID group_sid;
4101 uint32 group_rid;
4102 uint32 acc_granted;
4103 SE_PRIV se_rights;
4104 BOOL can_add_accounts;
4105 DISP_INFO *disp_info = NULL;
4106
4107 /*
4108 * delete the group member named q_u->rid
4109 * who is a member of the sid associated with the handle
4110 * the rid is a user's rid as the group is a domain group.
4111 */
4112
4113 /* Find the policy handle. Open a policy on it. */
4114 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted, &disp_info))
4115 return NT_STATUS_INVALID_HANDLE;
4116
4117 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
4118 return r_u->status;
4119 }
4120
4121 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4122 &group_rid)) {
4123 return NT_STATUS_INVALID_HANDLE;
4124 }
4125
4126 se_priv_copy( &se_rights, &se_add_users );
4127 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4128
4129 /******** BEGIN SeAddUsers BLOCK *********/
4130
4131 if ( can_add_accounts )
4132 become_root();
4133
4134 r_u->status = pdb_del_groupmem(p->mem_ctx, group_rid, q_u->rid);
4135
4136 if ( can_add_accounts )
4137 unbecome_root();
4138
4139 /******** END SeAddUsers BLOCK *********/
4140
4141 force_flush_samr_cache(disp_info);
4142
4143 return r_u->status;
4144}
4145
4146/*********************************************************************
4147 _samr_delete_dom_user
4148*********************************************************************/
4149
4150NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
4151{
4152 DOM_SID user_sid;
4153 struct samu *sam_pass=NULL;
4154 uint32 acc_granted;
4155 BOOL can_add_accounts;
4156 uint32 acb_info;
4157 DISP_INFO *disp_info = NULL;
4158 BOOL ret;
4159
4160 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
4161
4162 /* Find the policy handle. Open a policy on it. */
4163 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted, &disp_info))
4164 return NT_STATUS_INVALID_HANDLE;
4165
4166 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
4167 return r_u->status;
4168 }
4169
4170 if (!sid_check_is_in_our_domain(&user_sid))
4171 return NT_STATUS_CANNOT_DELETE;
4172
4173 /* check if the user exists before trying to delete */
4174 if ( !(sam_pass = samu_new( NULL )) ) {
4175 return NT_STATUS_NO_MEMORY;
4176 }
4177
4178 become_root();
4179 ret = pdb_getsampwsid(sam_pass, &user_sid);
4180 unbecome_root();
4181
4182 if( !ret ) {
4183 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
4184 sid_string_static(&user_sid)));
4185 TALLOC_FREE(sam_pass);
4186 return NT_STATUS_NO_SUCH_USER;
4187 }
4188
4189 acb_info = pdb_get_acct_ctrl(sam_pass);
4190
4191 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4192 if ( acb_info & ACB_WSTRUST ) {
4193 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4194 } else {
4195 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4196 }
4197
4198 /******** BEGIN SeAddUsers BLOCK *********/
4199
4200 if ( can_add_accounts )
4201 become_root();
4202
4203 r_u->status = pdb_delete_user(p->mem_ctx, sam_pass);
4204
4205 if ( can_add_accounts )
4206 unbecome_root();
4207
4208 /******** END SeAddUsers BLOCK *********/
4209
4210 if ( !NT_STATUS_IS_OK(r_u->status) ) {
4211 DEBUG(5,("_samr_delete_dom_user: Failed to delete entry for "
4212 "user %s: %s.\n", pdb_get_username(sam_pass),
4213 nt_errstr(r_u->status)));
4214 TALLOC_FREE(sam_pass);
4215 return r_u->status;
4216 }
4217
4218
4219 TALLOC_FREE(sam_pass);
4220
4221 if (!close_policy_hnd(p, &q_u->user_pol))
4222 return NT_STATUS_OBJECT_NAME_INVALID;
4223
4224 force_flush_samr_cache(disp_info);
4225
4226 return NT_STATUS_OK;
4227}
4228
4229/*********************************************************************
4230 _samr_delete_dom_group
4231*********************************************************************/
4232
4233NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
4234{
4235 DOM_SID group_sid;
4236 uint32 group_rid;
4237 uint32 acc_granted;
4238 SE_PRIV se_rights;
4239 BOOL can_add_accounts;
4240 DISP_INFO *disp_info = NULL;
4241
4242 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
4243
4244 /* Find the policy handle. Open a policy on it. */
4245 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted, &disp_info))
4246 return NT_STATUS_INVALID_HANDLE;
4247
4248 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
4249 return r_u->status;
4250 }
4251
4252 DEBUG(10, ("sid is %s\n", sid_string_static(&group_sid)));
4253
4254 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4255 &group_rid)) {
4256 return NT_STATUS_NO_SUCH_GROUP;
4257 }
4258
4259 se_priv_copy( &se_rights, &se_add_users );
4260 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4261
4262 /******** BEGIN SeAddUsers BLOCK *********/
4263
4264 if ( can_add_accounts )
4265 become_root();
4266
4267 r_u->status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4268
4269 if ( can_add_accounts )
4270 unbecome_root();
4271
4272 /******** END SeAddUsers BLOCK *********/
4273
4274 if ( !NT_STATUS_IS_OK(r_u->status) ) {
4275 DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping "
4276 "entry for group %s: %s\n",
4277 sid_string_static(&group_sid),
4278 nt_errstr(r_u->status)));
4279 return r_u->status;
4280 }
4281
4282 if (!close_policy_hnd(p, &q_u->group_pol))
4283 return NT_STATUS_OBJECT_NAME_INVALID;
4284
4285 force_flush_samr_cache(disp_info);
4286
4287 return NT_STATUS_OK;
4288}
4289
4290/*********************************************************************
4291 _samr_delete_dom_alias
4292*********************************************************************/
4293
4294NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
4295{
4296 DOM_SID alias_sid;
4297 uint32 acc_granted;
4298 SE_PRIV se_rights;
4299 BOOL can_add_accounts;
4300 BOOL ret;
4301 DISP_INFO *disp_info = NULL;
4302
4303 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
4304
4305 /* Find the policy handle. Open a policy on it. */
4306 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted, &disp_info))
4307 return NT_STATUS_INVALID_HANDLE;
4308
4309 /* copy the handle to the outgoing reply */
4310
4311 memcpy( &r_u->pol, &q_u->alias_pol, sizeof(r_u->pol) );
4312
4313 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
4314 return r_u->status;
4315 }
4316
4317 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
4318
4319 /* Don't let Windows delete builtin groups */
4320
4321 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4322 return NT_STATUS_SPECIAL_ACCOUNT;
4323 }
4324
4325 if (!sid_check_is_in_our_domain(&alias_sid))
4326 return NT_STATUS_NO_SUCH_ALIAS;
4327
4328 DEBUG(10, ("lookup on Local SID\n"));
4329
4330 se_priv_copy( &se_rights, &se_add_users );
4331 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4332
4333 /******** BEGIN SeAddUsers BLOCK *********/
4334
4335 if ( can_add_accounts )
4336 become_root();
4337
4338 /* Have passdb delete the alias */
4339 ret = pdb_delete_alias(&alias_sid);
4340
4341 if ( can_add_accounts )
4342 unbecome_root();
4343
4344 /******** END SeAddUsers BLOCK *********/
4345
4346 if ( !ret )
4347 return NT_STATUS_ACCESS_DENIED;
4348
4349 if (!close_policy_hnd(p, &q_u->alias_pol))
4350 return NT_STATUS_OBJECT_NAME_INVALID;
4351
4352 force_flush_samr_cache(disp_info);
4353
4354 return NT_STATUS_OK;
4355}
4356
4357/*********************************************************************
4358 _samr_create_dom_group
4359*********************************************************************/
4360
4361NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
4362{
4363 DOM_SID dom_sid;
4364 DOM_SID info_sid;
4365 const char *name;
4366 struct samr_info *info;
4367 uint32 acc_granted;
4368 SE_PRIV se_rights;
4369 BOOL can_add_accounts;
4370 DISP_INFO *disp_info = NULL;
4371
4372 /* Find the policy handle. Open a policy on it. */
4373 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted, &disp_info))
4374 return NT_STATUS_INVALID_HANDLE;
4375
4376 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
4377 return r_u->status;
4378 }
4379
4380 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4381 return NT_STATUS_ACCESS_DENIED;
4382
4383 name = rpcstr_pull_unistr2_talloc(p->mem_ctx, &q_u->uni_acct_desc);
4384 if (name == NULL) {
4385 return NT_STATUS_NO_MEMORY;
4386 }
4387
4388 r_u->status = can_create(p->mem_ctx, name);
4389 if (!NT_STATUS_IS_OK(r_u->status)) {
4390 return r_u->status;
4391 }
4392
4393 se_priv_copy( &se_rights, &se_add_users );
4394 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4395
4396 /******** BEGIN SeAddUsers BLOCK *********/
4397
4398 if ( can_add_accounts )
4399 become_root();
4400
4401 /* check that we successfully create the UNIX group */
4402
4403 r_u->status = pdb_create_dom_group(p->mem_ctx, name, &r_u->rid);
4404
4405 if ( can_add_accounts )
4406 unbecome_root();
4407
4408 /******** END SeAddUsers BLOCK *********/
4409
4410 /* check if we should bail out here */
4411
4412 if ( !NT_STATUS_IS_OK(r_u->status) )
4413 return r_u->status;
4414
4415 sid_compose(&info_sid, get_global_sam_sid(), r_u->rid);
4416
4417 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4418 return NT_STATUS_NO_MEMORY;
4419
4420 /* they created it; let the user do what he wants with it */
4421
4422 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
4423
4424 /* get a (unique) handle. open a policy on it. */
4425 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4426 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4427
4428 force_flush_samr_cache(disp_info);
4429
4430 return NT_STATUS_OK;
4431}
4432
4433/*********************************************************************
4434 _samr_create_dom_alias
4435*********************************************************************/
4436
4437NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4438{
4439 DOM_SID dom_sid;
4440 DOM_SID info_sid;
4441 fstring name;
4442 struct samr_info *info;
4443 uint32 acc_granted;
4444 gid_t gid;
4445 NTSTATUS result;
4446 SE_PRIV se_rights;
4447 BOOL can_add_accounts;
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, &q_u->dom_pol, &dom_sid, &acc_granted, &disp_info))
4452 return NT_STATUS_INVALID_HANDLE;
4453
4454 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4455 return r_u->status;
4456 }
4457
4458 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4459 return NT_STATUS_ACCESS_DENIED;
4460
4461 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4462
4463 se_priv_copy( &se_rights, &se_add_users );
4464 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4465
4466 result = can_create(p->mem_ctx, name);
4467 if (!NT_STATUS_IS_OK(result)) {
4468 return result;
4469 }
4470
4471 /******** BEGIN SeAddUsers BLOCK *********/
4472
4473 if ( can_add_accounts )
4474 become_root();
4475
4476 /* Have passdb create the alias */
4477 result = pdb_create_alias(name, &r_u->rid);
4478
4479 if ( can_add_accounts )
4480 unbecome_root();
4481
4482 /******** END SeAddUsers BLOCK *********/
4483
4484 if (!NT_STATUS_IS_OK(result)) {
4485 DEBUG(10, ("pdb_create_alias failed: %s\n",
4486 nt_errstr(result)));
4487 return result;
4488 }
4489
4490 sid_copy(&info_sid, get_global_sam_sid());
4491 sid_append_rid(&info_sid, r_u->rid);
4492
4493 if (!sid_to_gid(&info_sid, &gid)) {
4494 DEBUG(10, ("Could not find alias just created\n"));
4495 return NT_STATUS_ACCESS_DENIED;
4496 }
4497
4498 /* check if the group has been successfully created */
4499 if ( getgrgid(gid) == NULL ) {
4500 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
4501 gid));
4502 return NT_STATUS_ACCESS_DENIED;
4503 }
4504
4505 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4506 return NT_STATUS_NO_MEMORY;
4507
4508 /* they created it; let the user do what he wants with it */
4509
4510 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
4511
4512 /* get a (unique) handle. open a policy on it. */
4513 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4514 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4515
4516 force_flush_samr_cache(disp_info);
4517
4518 return NT_STATUS_OK;
4519}
4520
4521/*********************************************************************
4522 _samr_query_groupinfo
4523
4524sends the name/comment pair of a domain group
4525level 1 send also the number of users of that group
4526*********************************************************************/
4527
4528NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4529{
4530 DOM_SID group_sid;
4531 GROUP_MAP map;
4532 GROUP_INFO_CTR *ctr;
4533 uint32 acc_granted;
4534 BOOL ret;
4535
4536 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted, NULL))
4537 return NT_STATUS_INVALID_HANDLE;
4538
4539 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4540 return r_u->status;
4541 }
4542
4543 become_root();
4544 ret = get_domain_group_from_sid(group_sid, &map);
4545 unbecome_root();
4546 if (!ret)
4547 return NT_STATUS_INVALID_HANDLE;
4548
4549 ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
4550 if (ctr==NULL)
4551 return NT_STATUS_NO_MEMORY;
4552
4553 switch (q_u->switch_level) {
4554 case 1: {
4555 uint32 *members;
4556 size_t num_members;
4557
4558 ctr->switch_value1 = 1;
4559
4560 become_root();
4561 r_u->status = pdb_enum_group_members(
4562 p->mem_ctx, &group_sid, &members, &num_members);
4563 unbecome_root();
4564
4565 if (!NT_STATUS_IS_OK(r_u->status)) {
4566 return r_u->status;
4567 }
4568
4569 init_samr_group_info1(&ctr->group.info1, map.nt_name,
4570 map.comment, num_members);
4571 break;
4572 }
4573 case 2:
4574 ctr->switch_value1 = 2;
4575 init_samr_group_info2(&ctr->group.info2, map.nt_name);
4576 break;
4577 case 3:
4578 ctr->switch_value1 = 3;
4579 init_samr_group_info3(&ctr->group.info3);
4580 break;
4581 case 4:
4582 ctr->switch_value1 = 4;
4583 init_samr_group_info4(&ctr->group.info4, map.comment);
4584 break;
4585 case 5: {
4586 /*
4587 uint32 *members;
4588 size_t num_members;
4589 */
4590
4591 ctr->switch_value1 = 5;
4592
4593 /*
4594 become_root();
4595 r_u->status = pdb_enum_group_members(
4596 p->mem_ctx, &group_sid, &members, &num_members);
4597 unbecome_root();
4598
4599 if (!NT_STATUS_IS_OK(r_u->status)) {
4600 return r_u->status;
4601 }
4602 */
4603 init_samr_group_info5(&ctr->group.info5, map.nt_name,
4604 map.comment, 0 /* num_members */); /* in w2k3 this is always 0 */
4605 break;
4606 }
4607 default:
4608 return NT_STATUS_INVALID_INFO_CLASS;
4609 }
4610
4611 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4612
4613 return NT_STATUS_OK;
4614}
4615
4616/*********************************************************************
4617 _samr_set_groupinfo
4618
4619 update a domain group's comment.
4620*********************************************************************/
4621
4622NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4623{
4624 DOM_SID group_sid;
4625 GROUP_MAP map;
4626 GROUP_INFO_CTR *ctr;
4627 uint32 acc_granted;
4628 NTSTATUS ret;
4629 BOOL result;
4630 BOOL can_mod_accounts;
4631 DISP_INFO *disp_info = NULL;
4632
4633 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted, &disp_info))
4634 return NT_STATUS_INVALID_HANDLE;
4635
4636 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4637 return r_u->status;
4638 }
4639
4640 become_root();
4641 result = get_domain_group_from_sid(group_sid, &map);
4642 unbecome_root();
4643 if (!result)
4644 return NT_STATUS_NO_SUCH_GROUP;
4645
4646 ctr=q_u->ctr;
4647
4648 switch (ctr->switch_value1) {
4649 case 1:
4650 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4651 break;
4652 case 4:
4653 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4654 break;
4655 default:
4656 return NT_STATUS_INVALID_INFO_CLASS;
4657 }
4658
4659 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4660
4661 /******** BEGIN SeAddUsers BLOCK *********/
4662
4663 if ( can_mod_accounts )
4664 become_root();
4665
4666 ret = pdb_update_group_mapping_entry(&map);
4667
4668 if ( can_mod_accounts )
4669 unbecome_root();
4670
4671 /******** End SeAddUsers BLOCK *********/
4672
4673 if (NT_STATUS_IS_OK(ret)) {
4674 force_flush_samr_cache(disp_info);
4675 }
4676
4677 return ret;
4678}
4679
4680/*********************************************************************
4681 _samr_set_aliasinfo
4682
4683 update an alias's comment.
4684*********************************************************************/
4685
4686NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4687{
4688 DOM_SID group_sid;
4689 struct acct_info info;
4690 ALIAS_INFO_CTR *ctr;
4691 uint32 acc_granted;
4692 BOOL ret;
4693 BOOL can_mod_accounts;
4694 DISP_INFO *disp_info = NULL;
4695
4696 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted, &disp_info))
4697 return NT_STATUS_INVALID_HANDLE;
4698
4699 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4700 return r_u->status;
4701 }
4702
4703 ctr=&q_u->ctr;
4704
4705 /* get the current group information */
4706
4707 become_root();
4708 ret = pdb_get_aliasinfo( &group_sid, &info );
4709 unbecome_root();
4710
4711 if ( !ret ) {
4712 return NT_STATUS_NO_SUCH_ALIAS;
4713 }
4714
4715 switch (ctr->level) {
4716 case 2:
4717 {
4718 fstring group_name, acct_name;
4719 NTSTATUS status;
4720
4721 /* We currently do not support renaming groups in the
4722 the BUILTIN domain. Refer to util_builtin.c to understand
4723 why. The eventually needs to be fixed to be like Windows
4724 where you can rename builtin groups, just not delete them */
4725
4726 if ( sid_check_is_in_builtin( &group_sid ) ) {
4727 return NT_STATUS_SPECIAL_ACCOUNT;
4728 }
4729
4730 /* There has to be a valid name (and it has to be different) */
4731
4732 if ( !ctr->alias.info2.name.string )
4733 return NT_STATUS_INVALID_PARAMETER;
4734
4735 unistr2_to_ascii( acct_name, ctr->alias.info2.name.string,
4736 sizeof(acct_name)-1 );
4737
4738 /* If the name is the same just reply "ok". Yes this
4739 doesn't allow you to change the case of a group name. */
4740
4741 if ( strequal( acct_name, info.acct_name ) )
4742 return NT_STATUS_OK;
4743
4744 fstrcpy( info.acct_name, acct_name );
4745
4746 /* make sure the name doesn't already exist as a user
4747 or local group */
4748
4749 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
4750 status = can_create( p->mem_ctx, group_name );
4751 if ( !NT_STATUS_IS_OK( status ) )
4752 return status;
4753 break;
4754 }
4755 case 3:
4756 if ( ctr->alias.info3.description.string ) {
4757 unistr2_to_ascii( info.acct_desc,
4758 ctr->alias.info3.description.string,
4759 sizeof(info.acct_desc)-1 );
4760 }
4761 else
4762 fstrcpy( info.acct_desc, "" );
4763 break;
4764 default:
4765 return NT_STATUS_INVALID_INFO_CLASS;
4766 }
4767
4768 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4769
4770 /******** BEGIN SeAddUsers BLOCK *********/
4771
4772 if ( can_mod_accounts )
4773 become_root();
4774
4775 ret = pdb_set_aliasinfo( &group_sid, &info );
4776
4777 if ( can_mod_accounts )
4778 unbecome_root();
4779
4780 /******** End SeAddUsers BLOCK *********/
4781
4782 if (ret) {
4783 force_flush_samr_cache(disp_info);
4784 }
4785
4786 return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
4787}
4788
4789/*********************************************************************
4790 _samr_get_dom_pwinfo
4791*********************************************************************/
4792
4793NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4794{
4795 /* Perform access check. Since this rpc does not require a
4796 policy handle it will not be caught by the access checks on
4797 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4798
4799 if (!pipe_access_check(p)) {
4800 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4801 r_u->status = NT_STATUS_ACCESS_DENIED;
4802 return r_u->status;
4803 }
4804
4805 /* Actually, returning zeros here works quite well :-). */
4806
4807 return NT_STATUS_OK;
4808}
4809
4810/*********************************************************************
4811 _samr_open_group
4812*********************************************************************/
4813
4814NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4815{
4816 DOM_SID sid;
4817 DOM_SID info_sid;
4818 GROUP_MAP map;
4819 struct samr_info *info;
4820 SEC_DESC *psd = NULL;
4821 uint32 acc_granted;
4822 uint32 des_access = q_u->access_mask;
4823 size_t sd_size;
4824 NTSTATUS status;
4825 fstring sid_string;
4826 BOOL ret;
4827 SE_PRIV se_rights;
4828
4829 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted, NULL))
4830 return NT_STATUS_INVALID_HANDLE;
4831
4832 status = access_check_samr_function(acc_granted,
4833 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group");
4834
4835 if ( !NT_STATUS_IS_OK(status) )
4836 return status;
4837
4838 /*check if access can be granted as requested by client. */
4839 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
4840 se_map_generic(&des_access,&grp_generic_mapping);
4841
4842 se_priv_copy( &se_rights, &se_add_users );
4843
4844 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
4845 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
4846 &acc_granted, "_samr_open_group");
4847
4848 if ( !NT_STATUS_IS_OK(status) )
4849 return status;
4850
4851 /* this should not be hard-coded like this */
4852
4853 if (!sid_equal(&sid, get_global_sam_sid()))
4854 return NT_STATUS_ACCESS_DENIED;
4855
4856 sid_copy(&info_sid, get_global_sam_sid());
4857 sid_append_rid(&info_sid, q_u->rid_group);
4858 sid_to_string(sid_string, &info_sid);
4859
4860 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4861 return NT_STATUS_NO_MEMORY;
4862
4863 info->acc_granted = acc_granted;
4864
4865 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4866
4867 /* check if that group really exists */
4868 become_root();
4869 ret = get_domain_group_from_sid(info->sid, &map);
4870 unbecome_root();
4871 if (!ret)
4872 return NT_STATUS_NO_SUCH_GROUP;
4873
4874 /* get a (unique) handle. open a policy on it. */
4875 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4876 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4877
4878 return NT_STATUS_OK;
4879}
4880
4881/*********************************************************************
4882 _samr_remove_sid_foreign_domain
4883*********************************************************************/
4884
4885NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4886 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4887 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4888{
4889 DOM_SID delete_sid, domain_sid;
4890 uint32 acc_granted;
4891 NTSTATUS result;
4892 DISP_INFO *disp_info = NULL;
4893
4894 sid_copy( &delete_sid, &q_u->sid.sid );
4895
4896 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4897 sid_string_static(&delete_sid)));
4898
4899 /* Find the policy handle. Open a policy on it. */
4900
4901 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &domain_sid,
4902 &acc_granted, &disp_info))
4903 return NT_STATUS_INVALID_HANDLE;
4904
4905 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4906 "_samr_remove_sid_foreign_domain");
4907
4908 if (!NT_STATUS_IS_OK(result))
4909 return result;
4910
4911 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4912 sid_string_static(&domain_sid)));
4913
4914 /* we can only delete a user from a group since we don't have
4915 nested groups anyways. So in the latter case, just say OK */
4916
4917 /* TODO: The above comment nowadays is bogus. Since we have nested
4918 * groups now, and aliases members are never reported out of the unix
4919 * group membership, the "just say OK" makes this call a no-op. For
4920 * us. This needs fixing however. */
4921
4922 /* I've only ever seen this in the wild when deleting a user from
4923 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
4924 * is the user about to be deleted. I very much suspect this is the
4925 * only application of this call. To verify this, let people report
4926 * other cases. */
4927
4928 if (!sid_check_is_builtin(&domain_sid)) {
4929 DEBUG(1,("_samr_remove_sid_foreign_domain: domain_sid = %s, "
4930 "global_sam_sid() = %s\n",
4931 sid_string_static(&domain_sid),
4932 sid_string_static(get_global_sam_sid())));
4933 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
4934 return NT_STATUS_OK;
4935 }
4936
4937 force_flush_samr_cache(disp_info);
4938
4939 result = NT_STATUS_OK;
4940
4941 return result;
4942}
4943
4944/*******************************************************************
4945 _samr_query_domain_info2
4946 ********************************************************************/
4947
4948NTSTATUS _samr_query_domain_info2(pipes_struct *p,
4949 SAMR_Q_QUERY_DOMAIN_INFO2 *q_u,
4950 SAMR_R_QUERY_DOMAIN_INFO2 *r_u)
4951{
4952 SAMR_Q_QUERY_DOMAIN_INFO q;
4953 SAMR_R_QUERY_DOMAIN_INFO r;
4954
4955 ZERO_STRUCT(q);
4956 ZERO_STRUCT(r);
4957
4958 DEBUG(5,("_samr_query_domain_info2: %d\n", __LINE__));
4959
4960 q.domain_pol = q_u->domain_pol;
4961 q.switch_value = q_u->switch_value;
4962
4963 r_u->status = _samr_query_domain_info(p, &q, &r);
4964
4965 r_u->ptr_0 = r.ptr_0;
4966 r_u->switch_value = r.switch_value;
4967 r_u->ctr = r.ctr;
4968
4969 return r_u->status;
4970}
4971
4972/*******************************************************************
4973 _samr_set_dom_info
4974 ********************************************************************/
4975
4976NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4977{
4978 time_t u_expire, u_min_age;
4979 time_t u_logout;
4980 time_t u_lock_duration, u_reset_time;
4981
4982 r_u->status = NT_STATUS_OK;
4983
4984 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4985
4986 /* find the policy handle. open a policy on it. */
4987 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4988 return NT_STATUS_INVALID_HANDLE;
4989
4990 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4991
4992 switch (q_u->switch_value) {
4993 case 0x01:
4994 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4995 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4996
4997 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4998 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4999 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.password_properties);
5000 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5001 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5002 break;
5003 case 0x02:
5004 break;
5005 case 0x03:
5006 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
5007 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5008 break;
5009 case 0x05:
5010 break;
5011 case 0x06:
5012 break;
5013 case 0x07:
5014 break;
5015 case 0x0c:
5016 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
5017 if (u_lock_duration != -1)
5018 u_lock_duration /= 60;
5019
5020 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
5021
5022 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5023 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5024 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
5025 break;
5026 default:
5027 return NT_STATUS_INVALID_INFO_CLASS;
5028 }
5029
5030 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
5031
5032 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
5033
5034 return r_u->status;
5035}
Note: See TracBrowser for help on using the repository browser.