2
* Unix SMB/CIFS implementation.
3
* RPC Pipe client / server routines
4
* Copyright (C) Andrew Tridgell 1992-1997,
5
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6
* Copyright (C) Paul Ashton 1997,
7
* Copyright (C) Marc Jacobsen 1999,
8
* Copyright (C) Jeremy Allison 2001-2008,
9
* Copyright (C) Jean François Micouleau 1998-2001,
10
* Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11
* Copyright (C) Gerald (Jerry) Carter 2003-2004,
12
* Copyright (C) Simo Sorce 2003.
13
* Copyright (C) Volker Lendecke 2005.
14
* Copyright (C) Guenther Deschner 2008.
16
* This program is free software; you can redistribute it and/or modify
17
* it under the terms of the GNU General Public License as published by
18
* the Free Software Foundation; either version 3 of the License, or
19
* (at your option) any later version.
21
* This program is distributed in the hope that it will be useful,
22
* but WITHOUT ANY WARRANTY; without even the implied warranty of
23
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
* GNU General Public License for more details.
26
* You should have received a copy of the GNU General Public License
27
* along with this program; if not, see <http://www.gnu.org/licenses/>.
31
* This is the implementation of the SAMR code.
35
#include "system/passwd.h"
36
#include "../libcli/auth/libcli_auth.h"
38
#include "../librpc/gen_ndr/srv_samr.h"
39
#include "rpc_server/samr/srv_samr_util.h"
40
#include "../lib/crypto/arcfour.h"
42
#include "rpc_client/init_lsa.h"
43
#include "../libcli/security/security.h"
46
#include "rpc_server/srv_access_check.h"
49
#define DBGC_CLASS DBGC_RPC_SRV
51
#define SAMR_USR_RIGHTS_WRITE_PW \
52
( READ_CONTROL_ACCESS | \
53
SAMR_USER_ACCESS_CHANGE_PASSWORD | \
54
SAMR_USER_ACCESS_SET_LOC_COM)
55
#define SAMR_USR_RIGHTS_CANT_WRITE_PW \
56
( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
58
#define DISP_INFO_CACHE_TIMEOUT 10
60
#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
61
#define MAX_SAM_ENTRIES_W95 50
63
struct samr_connect_info {
67
struct samr_domain_info {
69
struct disp_info *disp_info;
72
struct samr_user_info {
76
struct samr_group_info {
80
struct samr_alias_info {
84
typedef struct disp_info {
85
struct dom_sid sid; /* identify which domain this is. */
86
struct pdb_search *users; /* querydispinfo 1 and 4 */
87
struct pdb_search *machines; /* querydispinfo 2 */
88
struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
89
struct pdb_search *aliases; /* enumaliases */
91
uint32_t enum_acb_mask;
92
struct pdb_search *enum_users; /* enumusers with a mask */
94
struct timed_event *cache_timeout_event; /* cache idle timeout
98
static const struct generic_mapping sam_generic_mapping = {
99
GENERIC_RIGHTS_SAM_READ,
100
GENERIC_RIGHTS_SAM_WRITE,
101
GENERIC_RIGHTS_SAM_EXECUTE,
102
GENERIC_RIGHTS_SAM_ALL_ACCESS};
103
static const struct generic_mapping dom_generic_mapping = {
104
GENERIC_RIGHTS_DOMAIN_READ,
105
GENERIC_RIGHTS_DOMAIN_WRITE,
106
GENERIC_RIGHTS_DOMAIN_EXECUTE,
107
GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
108
static const struct generic_mapping usr_generic_mapping = {
109
GENERIC_RIGHTS_USER_READ,
110
GENERIC_RIGHTS_USER_WRITE,
111
GENERIC_RIGHTS_USER_EXECUTE,
112
GENERIC_RIGHTS_USER_ALL_ACCESS};
113
static const struct generic_mapping usr_nopwchange_generic_mapping = {
114
GENERIC_RIGHTS_USER_READ,
115
GENERIC_RIGHTS_USER_WRITE,
116
GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
117
GENERIC_RIGHTS_USER_ALL_ACCESS};
118
static const struct generic_mapping grp_generic_mapping = {
119
GENERIC_RIGHTS_GROUP_READ,
120
GENERIC_RIGHTS_GROUP_WRITE,
121
GENERIC_RIGHTS_GROUP_EXECUTE,
122
GENERIC_RIGHTS_GROUP_ALL_ACCESS};
123
static const struct generic_mapping ali_generic_mapping = {
124
GENERIC_RIGHTS_ALIAS_READ,
125
GENERIC_RIGHTS_ALIAS_WRITE,
126
GENERIC_RIGHTS_ALIAS_EXECUTE,
127
GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
129
/*******************************************************************
130
*******************************************************************/
132
static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
133
const struct generic_mapping *map,
134
struct dom_sid *sid, uint32 sid_access )
136
struct dom_sid domadmin_sid;
137
struct security_ace ace[5]; /* at most 5 entries */
140
struct security_acl *psa = NULL;
142
/* basic access for Everyone */
144
init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
145
map->generic_execute | map->generic_read, 0);
147
/* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
149
init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
150
SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
151
init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
152
SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
154
/* Add Full Access for Domain Admins if we are a DC */
157
sid_compose(&domadmin_sid, get_global_sam_sid(),
159
init_sec_ace(&ace[i++], &domadmin_sid,
160
SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
163
/* if we have a sid, give it some special access */
166
init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
169
/* create the security descriptor */
171
if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
172
return NT_STATUS_NO_MEMORY;
174
if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
175
SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
176
psa, sd_size)) == NULL)
177
return NT_STATUS_NO_MEMORY;
182
/*******************************************************************
183
Fetch or create a dispinfo struct.
184
********************************************************************/
186
static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
189
* We do a static cache for DISP_INFO's here. Explanation can be found
190
* in Jeremy's checkin message to r11793:
192
* Fix the SAMR cache so it works across completely insane
193
* client behaviour (ie.:
194
* open pipe/open SAMR handle/enumerate 0 - 1024
195
* close SAMR handle, close pipe.
196
* open pipe/open SAMR handle/enumerate 1024 - 2048...
197
* close SAMR handle, close pipe.
198
* And on ad-nausium. Amazing.... probably object-oriented
199
* client side programming in action yet again.
200
* This change should *massively* improve performance when
201
* enumerating users from an LDAP database.
204
* "Our" and the builtin domain are the only ones where we ever
205
* enumerate stuff, so just cache 2 entries.
208
static struct disp_info *builtin_dispinfo;
209
static struct disp_info *domain_dispinfo;
211
/* There are two cases to consider here:
212
1) The SID is a domain SID and we look for an equality match, or
213
2) This is an account SID and so we return the DISP_INFO* for our
220
if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
222
* Necessary only once, but it does not really hurt.
224
if (builtin_dispinfo == NULL) {
225
builtin_dispinfo = talloc_zero(NULL, struct disp_info);
226
if (builtin_dispinfo == NULL) {
230
sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
232
return builtin_dispinfo;
235
if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
237
* Necessary only once, but it does not really hurt.
239
if (domain_dispinfo == NULL) {
240
domain_dispinfo = talloc_zero(NULL, struct disp_info);
241
if (domain_dispinfo == NULL) {
245
sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
247
return domain_dispinfo;
253
/*******************************************************************
254
Function to free the per SID data.
255
********************************************************************/
257
static void free_samr_cache(DISP_INFO *disp_info)
259
DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
260
sid_string_dbg(&disp_info->sid)));
262
/* We need to become root here because the paged search might have to
263
* tell the LDAP server we're not interested in the rest anymore. */
267
TALLOC_FREE(disp_info->users);
268
TALLOC_FREE(disp_info->machines);
269
TALLOC_FREE(disp_info->groups);
270
TALLOC_FREE(disp_info->aliases);
271
TALLOC_FREE(disp_info->enum_users);
276
/*******************************************************************
277
Idle event handler. Throw away the disp info cache.
278
********************************************************************/
280
static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
281
struct timed_event *te,
285
DISP_INFO *disp_info = (DISP_INFO *)private_data;
287
TALLOC_FREE(disp_info->cache_timeout_event);
289
DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
291
free_samr_cache(disp_info);
294
/*******************************************************************
295
Setup cache removal idle event handler.
296
********************************************************************/
298
static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
300
/* Remove any pending timeout and update. */
302
TALLOC_FREE(disp_info->cache_timeout_event);
304
DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
305
"SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
306
(unsigned int)secs_fromnow ));
308
disp_info->cache_timeout_event = event_add_timed(
309
server_event_context(), NULL,
310
timeval_current_ofs(secs_fromnow, 0),
311
disp_info_cache_idle_timeout_handler, (void *)disp_info);
314
/*******************************************************************
315
Force flush any cache. We do this on any samr_set_xxx call.
316
We must also remove the timeout handler.
317
********************************************************************/
319
static void force_flush_samr_cache(const struct dom_sid *sid)
321
struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
323
if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
327
DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
328
TALLOC_FREE(disp_info->cache_timeout_event);
329
free_samr_cache(disp_info);
332
/*******************************************************************
333
Ensure password info is never given out. Paranioa... JRA.
334
********************************************************************/
336
static void samr_clear_sam_passwd(struct samu *sam_pass)
342
/* These now zero out the old password */
344
pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
345
pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
348
static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
350
struct samr_displayentry *entry;
352
if (sid_check_is_builtin(&info->sid)) {
353
/* No users in builtin. */
357
if (info->users == NULL) {
358
info->users = pdb_search_users(info, acct_flags);
359
if (info->users == NULL) {
363
/* Fetch the last possible entry, thus trigger an enumeration */
364
pdb_search_entries(info->users, 0xffffffff, 1, &entry);
366
/* Ensure we cache this enumeration. */
367
set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
369
return info->users->num_entries;
372
static uint32 count_sam_groups(struct disp_info *info)
374
struct samr_displayentry *entry;
376
if (sid_check_is_builtin(&info->sid)) {
377
/* No groups in builtin. */
381
if (info->groups == NULL) {
382
info->groups = pdb_search_groups(info);
383
if (info->groups == NULL) {
387
/* Fetch the last possible entry, thus trigger an enumeration */
388
pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
390
/* Ensure we cache this enumeration. */
391
set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
393
return info->groups->num_entries;
396
static uint32 count_sam_aliases(struct disp_info *info)
398
struct samr_displayentry *entry;
400
if (info->aliases == NULL) {
401
info->aliases = pdb_search_aliases(info, &info->sid);
402
if (info->aliases == NULL) {
406
/* Fetch the last possible entry, thus trigger an enumeration */
407
pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
409
/* Ensure we cache this enumeration. */
410
set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
412
return info->aliases->num_entries;
415
/*******************************************************************
417
********************************************************************/
419
NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
421
if (!close_policy_hnd(p, r->in.handle)) {
422
return NT_STATUS_INVALID_HANDLE;
425
ZERO_STRUCTP(r->out.handle);
430
/*******************************************************************
432
********************************************************************/
434
NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
435
struct samr_OpenDomain *r)
437
struct samr_connect_info *cinfo;
438
struct samr_domain_info *dinfo;
439
struct security_descriptor *psd = NULL;
441
uint32 des_access = r->in.access_mask;
444
uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
446
/* find the connection policy handle. */
448
cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
449
struct samr_connect_info, &status);
450
if (!NT_STATUS_IS_OK(status)) {
454
/*check if access can be granted as requested by client. */
455
map_max_allowed_access(p->session_info->security_token,
456
&p->session_info->utok,
459
make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
460
se_map_generic( &des_access, &dom_generic_mapping );
463
* Users with SeAddUser get the ability to manipulate groups
466
if (security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS)) {
467
extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
468
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
469
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
470
SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
471
SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
475
* Users with SeMachineAccount or SeAddUser get additional
476
* SAMR_DOMAIN_ACCESS_CREATE_USER access.
479
status = access_check_object( psd, p->session_info->security_token,
480
SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
481
extra_access, des_access,
482
&acc_granted, "_samr_OpenDomain" );
484
if ( !NT_STATUS_IS_OK(status) )
487
if (!sid_check_is_domain(r->in.sid) &&
488
!sid_check_is_builtin(r->in.sid)) {
489
return NT_STATUS_NO_SUCH_DOMAIN;
492
dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
493
struct samr_domain_info, &status);
494
if (!NT_STATUS_IS_OK(status)) {
497
dinfo->sid = *r->in.sid;
498
dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
500
DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
505
/*******************************************************************
507
********************************************************************/
509
NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
510
struct samr_GetUserPwInfo *r)
512
struct samr_user_info *uinfo;
513
enum lsa_SidType sid_type;
514
uint32_t min_password_length = 0;
515
uint32_t password_properties = 0;
519
DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
521
uinfo = policy_handle_find(p, r->in.user_handle,
522
SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
523
struct samr_user_info, &status);
524
if (!NT_STATUS_IS_OK(status)) {
528
if (!sid_check_is_in_our_domain(&uinfo->sid)) {
529
return NT_STATUS_OBJECT_TYPE_MISMATCH;
533
ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
536
return NT_STATUS_NO_SUCH_USER;
542
pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
543
&min_password_length);
544
pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
545
&password_properties);
548
if (lp_check_password_script() && *lp_check_password_script()) {
549
password_properties |= DOMAIN_PASSWORD_COMPLEX;
557
r->out.info->min_password_length = min_password_length;
558
r->out.info->password_properties = password_properties;
560
DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
565
/*******************************************************************
567
********************************************************************/
569
NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
570
struct samr_SetSecurity *r)
572
struct samr_user_info *uinfo;
574
struct security_acl *dacl;
576
struct samu *sampass=NULL;
579
uinfo = policy_handle_find(p, r->in.handle,
580
SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
581
struct samr_user_info, &status);
582
if (!NT_STATUS_IS_OK(status)) {
586
if (!(sampass = samu_new( p->mem_ctx))) {
587
DEBUG(0,("No memory!\n"));
588
return NT_STATUS_NO_MEMORY;
591
/* get the user record */
593
ret = pdb_getsampwsid(sampass, &uinfo->sid);
597
DEBUG(4, ("User %s not found\n",
598
sid_string_dbg(&uinfo->sid)));
599
TALLOC_FREE(sampass);
600
return NT_STATUS_INVALID_HANDLE;
603
dacl = r->in.sdbuf->sd->dacl;
604
for (i=0; i < dacl->num_aces; i++) {
605
if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
606
ret = pdb_set_pass_can_change(sampass,
607
(dacl->aces[i].access_mask &
608
SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
615
TALLOC_FREE(sampass);
616
return NT_STATUS_ACCESS_DENIED;
620
status = pdb_update_sam_account(sampass);
623
TALLOC_FREE(sampass);
628
/*******************************************************************
629
build correct perms based on policies and password times for _samr_query_sec_obj
630
*******************************************************************/
631
static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
633
struct samu *sampass=NULL;
636
if ( !(sampass = samu_new( mem_ctx )) ) {
637
DEBUG(0,("No memory!\n"));
642
ret = pdb_getsampwsid(sampass, user_sid);
646
DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
647
TALLOC_FREE(sampass);
651
DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
653
if (pdb_get_pass_can_change(sampass)) {
654
TALLOC_FREE(sampass);
657
TALLOC_FREE(sampass);
662
/*******************************************************************
664
********************************************************************/
666
NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
667
struct samr_QuerySecurity *r)
669
struct samr_connect_info *cinfo;
670
struct samr_domain_info *dinfo;
671
struct samr_user_info *uinfo;
672
struct samr_group_info *ginfo;
673
struct samr_alias_info *ainfo;
675
struct security_descriptor * psd = NULL;
678
cinfo = policy_handle_find(p, r->in.handle,
679
SEC_STD_READ_CONTROL, NULL,
680
struct samr_connect_info, &status);
681
if (NT_STATUS_IS_OK(status)) {
682
DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
683
status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
684
&sam_generic_mapping, NULL, 0);
688
dinfo = policy_handle_find(p, r->in.handle,
689
SEC_STD_READ_CONTROL, NULL,
690
struct samr_domain_info, &status);
691
if (NT_STATUS_IS_OK(status)) {
692
DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
693
"with SID: %s\n", sid_string_dbg(&dinfo->sid)));
695
* TODO: Builtin probably needs a different SD with restricted
698
status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
699
&dom_generic_mapping, NULL, 0);
703
uinfo = policy_handle_find(p, r->in.handle,
704
SEC_STD_READ_CONTROL, NULL,
705
struct samr_user_info, &status);
706
if (NT_STATUS_IS_OK(status)) {
707
DEBUG(10,("_samr_QuerySecurity: querying security on user "
708
"Object with SID: %s\n",
709
sid_string_dbg(&uinfo->sid)));
710
if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
711
status = make_samr_object_sd(
712
p->mem_ctx, &psd, &sd_size,
713
&usr_generic_mapping,
714
&uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
716
status = make_samr_object_sd(
717
p->mem_ctx, &psd, &sd_size,
718
&usr_nopwchange_generic_mapping,
719
&uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
724
ginfo = policy_handle_find(p, r->in.handle,
725
SEC_STD_READ_CONTROL, NULL,
726
struct samr_group_info, &status);
727
if (NT_STATUS_IS_OK(status)) {
729
* TODO: different SDs have to be generated for aliases groups
730
* and users. Currently all three get a default user SD
732
DEBUG(10,("_samr_QuerySecurity: querying security on group "
733
"Object with SID: %s\n",
734
sid_string_dbg(&ginfo->sid)));
735
status = make_samr_object_sd(
736
p->mem_ctx, &psd, &sd_size,
737
&usr_nopwchange_generic_mapping,
738
&ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
742
ainfo = policy_handle_find(p, r->in.handle,
743
SEC_STD_READ_CONTROL, NULL,
744
struct samr_alias_info, &status);
745
if (NT_STATUS_IS_OK(status)) {
747
* TODO: different SDs have to be generated for aliases groups
748
* and users. Currently all three get a default user SD
750
DEBUG(10,("_samr_QuerySecurity: querying security on alias "
751
"Object with SID: %s\n",
752
sid_string_dbg(&ainfo->sid)));
753
status = make_samr_object_sd(
754
p->mem_ctx, &psd, &sd_size,
755
&usr_nopwchange_generic_mapping,
756
&ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
760
return NT_STATUS_OBJECT_TYPE_MISMATCH;
762
if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
763
return NT_STATUS_NO_MEMORY;
768
/*******************************************************************
769
makes a SAM_ENTRY / UNISTR2* structure from a user list.
770
********************************************************************/
772
static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
773
struct samr_SamEntry **sam_pp,
774
uint32_t num_entries,
776
struct samr_displayentry *entries)
779
struct samr_SamEntry *sam;
783
if (num_entries == 0) {
787
sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
789
DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
790
return NT_STATUS_NO_MEMORY;
793
for (i = 0; i < num_entries; i++) {
796
* usrmgr expects a non-NULL terminated string with
797
* trust relationships
799
if (entries[i].acct_flags & ACB_DOMTRUST) {
800
init_unistr2(&uni_temp_name, entries[i].account_name,
803
init_unistr2(&uni_temp_name, entries[i].account_name,
807
init_lsa_String(&sam[i].name, entries[i].account_name);
808
sam[i].idx = entries[i].rid;
816
#define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
818
/*******************************************************************
819
_samr_EnumDomainUsers
820
********************************************************************/
822
NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
823
struct samr_EnumDomainUsers *r)
826
struct samr_domain_info *dinfo;
828
uint32 enum_context = *r->in.resume_handle;
829
enum remote_arch_types ra_type = get_remote_arch();
830
int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
831
uint32 max_entries = max_sam_entries;
832
struct samr_displayentry *entries = NULL;
833
struct samr_SamArray *samr_array = NULL;
834
struct samr_SamEntry *samr_entries = NULL;
836
DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
838
dinfo = policy_handle_find(p, r->in.domain_handle,
839
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
840
struct samr_domain_info, &status);
841
if (!NT_STATUS_IS_OK(status)) {
845
samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
847
return NT_STATUS_NO_MEMORY;
849
*r->out.sam = samr_array;
851
if (sid_check_is_builtin(&dinfo->sid)) {
852
/* No users in builtin. */
853
*r->out.resume_handle = *r->in.resume_handle;
854
DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
862
if ((dinfo->disp_info->enum_users != NULL) &&
863
(dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
864
TALLOC_FREE(dinfo->disp_info->enum_users);
867
if (dinfo->disp_info->enum_users == NULL) {
868
dinfo->disp_info->enum_users = pdb_search_users(
869
dinfo->disp_info, r->in.acct_flags);
870
dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
873
if (dinfo->disp_info->enum_users == NULL) {
874
/* END AS ROOT !!!! */
876
return NT_STATUS_ACCESS_DENIED;
879
num_account = pdb_search_entries(dinfo->disp_info->enum_users,
880
enum_context, max_entries,
883
/* END AS ROOT !!!! */
887
if (num_account == 0) {
888
DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
890
*r->out.resume_handle = *r->in.resume_handle;
894
status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
895
num_account, enum_context,
897
if (!NT_STATUS_IS_OK(status)) {
901
if (max_entries <= num_account) {
902
status = STATUS_MORE_ENTRIES;
904
status = NT_STATUS_OK;
907
/* Ensure we cache this enumeration. */
908
set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
910
DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
912
samr_array->count = num_account;
913
samr_array->entries = samr_entries;
915
*r->out.resume_handle = *r->in.resume_handle + num_account;
916
*r->out.num_entries = num_account;
918
DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
923
/*******************************************************************
924
makes a SAM_ENTRY / UNISTR2* structure from a group list.
925
********************************************************************/
927
static void make_group_sam_entry_list(TALLOC_CTX *ctx,
928
struct samr_SamEntry **sam_pp,
929
uint32_t num_sam_entries,
930
struct samr_displayentry *entries)
932
struct samr_SamEntry *sam;
937
if (num_sam_entries == 0) {
941
sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
946
for (i = 0; i < num_sam_entries; i++) {
948
* JRA. I think this should include the null. TNG does not.
950
init_lsa_String(&sam[i].name, entries[i].account_name);
951
sam[i].idx = entries[i].rid;
957
/*******************************************************************
958
_samr_EnumDomainGroups
959
********************************************************************/
961
NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
962
struct samr_EnumDomainGroups *r)
965
struct samr_domain_info *dinfo;
966
struct samr_displayentry *groups;
968
struct samr_SamArray *samr_array = NULL;
969
struct samr_SamEntry *samr_entries = NULL;
971
dinfo = policy_handle_find(p, r->in.domain_handle,
972
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
973
struct samr_domain_info, &status);
974
if (!NT_STATUS_IS_OK(status)) {
978
DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
980
samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
982
return NT_STATUS_NO_MEMORY;
984
*r->out.sam = samr_array;
986
if (sid_check_is_builtin(&dinfo->sid)) {
987
/* No groups in builtin. */
988
*r->out.resume_handle = *r->in.resume_handle;
989
DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
993
/* the domain group array is being allocated in the function below */
997
if (dinfo->disp_info->groups == NULL) {
998
dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1000
if (dinfo->disp_info->groups == NULL) {
1002
return NT_STATUS_ACCESS_DENIED;
1006
num_groups = pdb_search_entries(dinfo->disp_info->groups,
1007
*r->in.resume_handle,
1008
MAX_SAM_ENTRIES, &groups);
1011
/* Ensure we cache this enumeration. */
1012
set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1014
make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1015
num_groups, groups);
1017
if (MAX_SAM_ENTRIES <= num_groups) {
1018
status = STATUS_MORE_ENTRIES;
1020
status = NT_STATUS_OK;
1023
samr_array->count = num_groups;
1024
samr_array->entries = samr_entries;
1026
*r->out.num_entries = num_groups;
1027
*r->out.resume_handle = num_groups + *r->in.resume_handle;
1029
DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1034
/*******************************************************************
1035
_samr_EnumDomainAliases
1036
********************************************************************/
1038
NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1039
struct samr_EnumDomainAliases *r)
1042
struct samr_domain_info *dinfo;
1043
struct samr_displayentry *aliases;
1044
uint32 num_aliases = 0;
1045
struct samr_SamArray *samr_array = NULL;
1046
struct samr_SamEntry *samr_entries = NULL;
1048
dinfo = policy_handle_find(p, r->in.domain_handle,
1049
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1050
struct samr_domain_info, &status);
1051
if (!NT_STATUS_IS_OK(status)) {
1055
DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1056
sid_string_dbg(&dinfo->sid)));
1058
samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1060
return NT_STATUS_NO_MEMORY;
1065
if (dinfo->disp_info->aliases == NULL) {
1066
dinfo->disp_info->aliases = pdb_search_aliases(
1067
dinfo->disp_info, &dinfo->sid);
1068
if (dinfo->disp_info->aliases == NULL) {
1070
return NT_STATUS_ACCESS_DENIED;
1074
num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1075
*r->in.resume_handle,
1076
MAX_SAM_ENTRIES, &aliases);
1079
/* Ensure we cache this enumeration. */
1080
set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1082
make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1083
num_aliases, aliases);
1085
DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1087
if (MAX_SAM_ENTRIES <= num_aliases) {
1088
status = STATUS_MORE_ENTRIES;
1090
status = NT_STATUS_OK;
1093
samr_array->count = num_aliases;
1094
samr_array->entries = samr_entries;
1096
*r->out.sam = samr_array;
1097
*r->out.num_entries = num_aliases;
1098
*r->out.resume_handle = num_aliases + *r->in.resume_handle;
1103
/*******************************************************************
1104
inits a samr_DispInfoGeneral structure.
1105
********************************************************************/
1107
static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1108
struct samr_DispInfoGeneral *r,
1109
uint32_t num_entries,
1111
struct samr_displayentry *entries)
1115
DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1117
if (num_entries == 0) {
1118
return NT_STATUS_OK;
1121
r->count = num_entries;
1123
r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1125
return NT_STATUS_NO_MEMORY;
1128
for (i = 0; i < num_entries ; i++) {
1130
init_lsa_String(&r->entries[i].account_name,
1131
entries[i].account_name);
1133
init_lsa_String(&r->entries[i].description,
1134
entries[i].description);
1136
init_lsa_String(&r->entries[i].full_name,
1137
entries[i].fullname);
1139
r->entries[i].rid = entries[i].rid;
1140
r->entries[i].acct_flags = entries[i].acct_flags;
1141
r->entries[i].idx = start_idx+i+1;
1144
return NT_STATUS_OK;
1147
/*******************************************************************
1148
inits a samr_DispInfoFull structure.
1149
********************************************************************/
1151
static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1152
struct samr_DispInfoFull *r,
1153
uint32_t num_entries,
1155
struct samr_displayentry *entries)
1159
DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1161
if (num_entries == 0) {
1162
return NT_STATUS_OK;
1165
r->count = num_entries;
1167
r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1169
return NT_STATUS_NO_MEMORY;
1172
for (i = 0; i < num_entries ; i++) {
1174
init_lsa_String(&r->entries[i].account_name,
1175
entries[i].account_name);
1177
init_lsa_String(&r->entries[i].description,
1178
entries[i].description);
1180
r->entries[i].rid = entries[i].rid;
1181
r->entries[i].acct_flags = entries[i].acct_flags;
1182
r->entries[i].idx = start_idx+i+1;
1185
return NT_STATUS_OK;
1188
/*******************************************************************
1189
inits a samr_DispInfoFullGroups structure.
1190
********************************************************************/
1192
static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1193
struct samr_DispInfoFullGroups *r,
1194
uint32_t num_entries,
1196
struct samr_displayentry *entries)
1200
DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1202
if (num_entries == 0) {
1203
return NT_STATUS_OK;
1206
r->count = num_entries;
1208
r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1210
return NT_STATUS_NO_MEMORY;
1213
for (i = 0; i < num_entries ; i++) {
1215
init_lsa_String(&r->entries[i].account_name,
1216
entries[i].account_name);
1218
init_lsa_String(&r->entries[i].description,
1219
entries[i].description);
1221
r->entries[i].rid = entries[i].rid;
1222
r->entries[i].acct_flags = entries[i].acct_flags;
1223
r->entries[i].idx = start_idx+i+1;
1226
return NT_STATUS_OK;
1229
/*******************************************************************
1230
inits a samr_DispInfoAscii structure.
1231
********************************************************************/
1233
static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1234
struct samr_DispInfoAscii *r,
1235
uint32_t num_entries,
1237
struct samr_displayentry *entries)
1241
DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1243
if (num_entries == 0) {
1244
return NT_STATUS_OK;
1247
r->count = num_entries;
1249
r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1251
return NT_STATUS_NO_MEMORY;
1254
for (i = 0; i < num_entries ; i++) {
1256
init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1257
entries[i].account_name);
1259
r->entries[i].idx = start_idx+i+1;
1262
return NT_STATUS_OK;
1265
/*******************************************************************
1266
inits a samr_DispInfoAscii structure.
1267
********************************************************************/
1269
static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1270
struct samr_DispInfoAscii *r,
1271
uint32_t num_entries,
1273
struct samr_displayentry *entries)
1277
DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1279
if (num_entries == 0) {
1280
return NT_STATUS_OK;
1283
r->count = num_entries;
1285
r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1287
return NT_STATUS_NO_MEMORY;
1290
for (i = 0; i < num_entries ; i++) {
1292
init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1293
entries[i].account_name);
1295
r->entries[i].idx = start_idx+i+1;
1298
return NT_STATUS_OK;
1301
/*******************************************************************
1302
_samr_QueryDisplayInfo
1303
********************************************************************/
1305
NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1306
struct samr_QueryDisplayInfo *r)
1309
struct samr_domain_info *dinfo;
1310
uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1312
uint32 max_entries = r->in.max_entries;
1314
union samr_DispInfo *disp_info = r->out.info;
1317
NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1318
uint32 num_account = 0;
1319
enum remote_arch_types ra_type = get_remote_arch();
1320
int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1321
struct samr_displayentry *entries = NULL;
1323
DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1325
dinfo = policy_handle_find(p, r->in.domain_handle,
1326
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1327
struct samr_domain_info, &status);
1328
if (!NT_STATUS_IS_OK(status)) {
1332
if (sid_check_is_builtin(&dinfo->sid)) {
1333
DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1334
return NT_STATUS_OK;
1338
* calculate how many entries we will return.
1340
* - the number of entries the client asked
1341
* - our limit on that
1342
* - the starting point (enumeration context)
1343
* - the buffer size the client will accept
1347
* We are a lot more like W2K. Instead of reading the SAM
1348
* each time to find the records we need to send back,
1349
* we read it once and link that copy to the sam handle.
1350
* For large user list (over the MAX_SAM_ENTRIES)
1351
* it's a definitive win.
1352
* second point to notice: between enumerations
1353
* our sam is now the same as it's a snapshoot.
1354
* third point: got rid of the static SAM_USER_21 struct
1355
* no more intermediate.
1356
* con: it uses much more memory, as a full copy is stored
1359
* If you want to change it, think twice and think
1360
* of the second point , that's really important.
1365
if ((r->in.level < 1) || (r->in.level > 5)) {
1366
DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1367
(unsigned int)r->in.level ));
1368
return NT_STATUS_INVALID_INFO_CLASS;
1371
/* first limit the number of entries we will return */
1372
if (r->in.max_entries > max_sam_entries) {
1373
DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1374
"entries, limiting to %d\n", r->in.max_entries,
1376
max_entries = max_sam_entries;
1379
/* calculate the size and limit on the number of entries we will
1382
temp_size=max_entries*struct_size;
1384
if (temp_size > r->in.buf_size) {
1385
max_entries = MIN((r->in.buf_size / struct_size),max_entries);
1386
DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1387
"only %d entries\n", max_entries));
1392
/* THe following done as ROOT. Don't return without unbecome_root(). */
1394
switch (r->in.level) {
1397
if (dinfo->disp_info->users == NULL) {
1398
dinfo->disp_info->users = pdb_search_users(
1399
dinfo->disp_info, ACB_NORMAL);
1400
if (dinfo->disp_info->users == NULL) {
1402
return NT_STATUS_ACCESS_DENIED;
1404
DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1405
(unsigned int)r->in.start_idx));
1407
DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1408
(unsigned int)r->in.start_idx));
1411
num_account = pdb_search_entries(dinfo->disp_info->users,
1412
r->in.start_idx, max_entries,
1416
if (dinfo->disp_info->machines == NULL) {
1417
dinfo->disp_info->machines = pdb_search_users(
1418
dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1419
if (dinfo->disp_info->machines == NULL) {
1421
return NT_STATUS_ACCESS_DENIED;
1423
DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1424
(unsigned int)r->in.start_idx));
1426
DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1427
(unsigned int)r->in.start_idx));
1430
num_account = pdb_search_entries(dinfo->disp_info->machines,
1431
r->in.start_idx, max_entries,
1436
if (dinfo->disp_info->groups == NULL) {
1437
dinfo->disp_info->groups = pdb_search_groups(
1439
if (dinfo->disp_info->groups == NULL) {
1441
return NT_STATUS_ACCESS_DENIED;
1443
DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1444
(unsigned int)r->in.start_idx));
1446
DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1447
(unsigned int)r->in.start_idx));
1450
num_account = pdb_search_entries(dinfo->disp_info->groups,
1451
r->in.start_idx, max_entries,
1456
smb_panic("info class changed");
1462
/* Now create reply structure */
1463
switch (r->in.level) {
1465
disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1466
num_account, r->in.start_idx,
1470
disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1471
num_account, r->in.start_idx,
1475
disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1476
num_account, r->in.start_idx,
1480
disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1481
num_account, r->in.start_idx,
1485
disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1486
num_account, r->in.start_idx,
1490
smb_panic("info class changed");
1494
if (!NT_STATUS_IS_OK(disp_ret))
1497
if (max_entries <= num_account) {
1498
status = STATUS_MORE_ENTRIES;
1500
status = NT_STATUS_OK;
1503
/* Ensure we cache this enumeration. */
1504
set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1506
DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1508
*r->out.total_size = num_account * struct_size;
1509
*r->out.returned_size = num_account ? temp_size : 0;
1514
/****************************************************************
1515
_samr_QueryDisplayInfo2
1516
****************************************************************/
1518
NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1519
struct samr_QueryDisplayInfo2 *r)
1521
struct samr_QueryDisplayInfo q;
1523
q.in.domain_handle = r->in.domain_handle;
1524
q.in.level = r->in.level;
1525
q.in.start_idx = r->in.start_idx;
1526
q.in.max_entries = r->in.max_entries;
1527
q.in.buf_size = r->in.buf_size;
1529
q.out.total_size = r->out.total_size;
1530
q.out.returned_size = r->out.returned_size;
1531
q.out.info = r->out.info;
1533
return _samr_QueryDisplayInfo(p, &q);
1536
/****************************************************************
1537
_samr_QueryDisplayInfo3
1538
****************************************************************/
1540
NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1541
struct samr_QueryDisplayInfo3 *r)
1543
struct samr_QueryDisplayInfo q;
1545
q.in.domain_handle = r->in.domain_handle;
1546
q.in.level = r->in.level;
1547
q.in.start_idx = r->in.start_idx;
1548
q.in.max_entries = r->in.max_entries;
1549
q.in.buf_size = r->in.buf_size;
1551
q.out.total_size = r->out.total_size;
1552
q.out.returned_size = r->out.returned_size;
1553
q.out.info = r->out.info;
1555
return _samr_QueryDisplayInfo(p, &q);
1558
/*******************************************************************
1559
_samr_QueryAliasInfo
1560
********************************************************************/
1562
NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1563
struct samr_QueryAliasInfo *r)
1565
struct samr_alias_info *ainfo;
1566
struct acct_info info;
1568
union samr_AliasInfo *alias_info = NULL;
1569
const char *alias_name = NULL;
1570
const char *alias_description = NULL;
1572
DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1574
ainfo = policy_handle_find(p, r->in.alias_handle,
1575
SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1576
struct samr_alias_info, &status);
1577
if (!NT_STATUS_IS_OK(status)) {
1581
alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1583
return NT_STATUS_NO_MEMORY;
1587
status = pdb_get_aliasinfo(&ainfo->sid, &info);
1590
if ( !NT_STATUS_IS_OK(status))
1593
/* FIXME: info contains fstrings */
1594
alias_name = talloc_strdup(r, info.acct_name);
1595
alias_description = talloc_strdup(r, info.acct_desc);
1597
switch (r->in.level) {
1599
alias_info->all.name.string = alias_name;
1600
alias_info->all.num_members = 1; /* ??? */
1601
alias_info->all.description.string = alias_description;
1604
alias_info->name.string = alias_name;
1606
case ALIASINFODESCRIPTION:
1607
alias_info->description.string = alias_description;
1610
return NT_STATUS_INVALID_INFO_CLASS;
1613
*r->out.info = alias_info;
1615
DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1617
return NT_STATUS_OK;
1620
/*******************************************************************
1622
********************************************************************/
1624
NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1625
struct samr_LookupNames *r)
1627
struct samr_domain_info *dinfo;
1630
enum lsa_SidType *type;
1632
int num_rids = r->in.num_names;
1633
struct samr_Ids rids, types;
1634
uint32_t num_mapped = 0;
1636
DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1638
dinfo = policy_handle_find(p, r->in.domain_handle,
1639
0 /* Don't know the acc_bits yet */, NULL,
1640
struct samr_domain_info, &status);
1641
if (!NT_STATUS_IS_OK(status)) {
1645
if (num_rids > MAX_SAM_ENTRIES) {
1646
num_rids = MAX_SAM_ENTRIES;
1647
DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1650
rid = talloc_array(p->mem_ctx, uint32, num_rids);
1651
NT_STATUS_HAVE_NO_MEMORY(rid);
1653
type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1654
NT_STATUS_HAVE_NO_MEMORY(type);
1656
DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1657
sid_string_dbg(&dinfo->sid)));
1659
for (i = 0; i < num_rids; i++) {
1661
status = NT_STATUS_NONE_MAPPED;
1662
type[i] = SID_NAME_UNKNOWN;
1664
rid[i] = 0xffffffff;
1666
if (sid_check_is_builtin(&dinfo->sid)) {
1667
if (lookup_builtin_name(r->in.names[i].string,
1670
type[i] = SID_NAME_ALIAS;
1673
lookup_global_sam_name(r->in.names[i].string, 0,
1677
if (type[i] != SID_NAME_UNKNOWN) {
1682
if (num_mapped == num_rids) {
1683
status = NT_STATUS_OK;
1684
} else if (num_mapped == 0) {
1685
status = NT_STATUS_NONE_MAPPED;
1687
status = STATUS_SOME_UNMAPPED;
1690
rids.count = num_rids;
1693
types.count = num_rids;
1694
types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1695
NT_STATUS_HAVE_NO_MEMORY(type);
1696
for (i = 0; i < num_rids; i++) {
1697
types.ids[i] = (type[i] & 0xffffffff);
1700
*r->out.rids = rids;
1701
*r->out.types = types;
1703
DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1708
/****************************************************************
1709
_samr_ChangePasswordUser
1710
****************************************************************/
1712
NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1713
struct samr_ChangePasswordUser *r)
1717
struct samr_user_info *uinfo;
1719
struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1720
struct samr_Password lm_pwd, nt_pwd;
1722
uinfo = policy_handle_find(p, r->in.user_handle,
1723
SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1724
struct samr_user_info, &status);
1725
if (!NT_STATUS_IS_OK(status)) {
1729
DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1730
sid_string_dbg(&uinfo->sid)));
1732
if (!(pwd = samu_new(NULL))) {
1733
return NT_STATUS_NO_MEMORY;
1737
ret = pdb_getsampwsid(pwd, &uinfo->sid);
1742
return NT_STATUS_WRONG_PASSWORD;
1746
const uint8_t *lm_pass, *nt_pass;
1748
lm_pass = pdb_get_lanman_passwd(pwd);
1749
nt_pass = pdb_get_nt_passwd(pwd);
1751
if (!lm_pass || !nt_pass) {
1752
status = NT_STATUS_WRONG_PASSWORD;
1756
memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1757
memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1760
/* basic sanity checking on parameters. Do this before any database ops */
1761
if (!r->in.lm_present || !r->in.nt_present ||
1762
!r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1763
!r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1764
/* we should really handle a change with lm not
1766
status = NT_STATUS_INVALID_PARAMETER_MIX;
1770
/* decrypt and check the new lm hash */
1771
D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1772
D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1773
if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1774
status = NT_STATUS_WRONG_PASSWORD;
1778
/* decrypt and check the new nt hash */
1779
D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1780
D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1781
if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1782
status = NT_STATUS_WRONG_PASSWORD;
1786
/* The NT Cross is not required by Win2k3 R2, but if present
1787
check the nt cross hash */
1788
if (r->in.cross1_present && r->in.nt_cross) {
1789
D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1790
if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1791
status = NT_STATUS_WRONG_PASSWORD;
1796
/* The LM Cross is not required by Win2k3 R2, but if present
1797
check the lm cross hash */
1798
if (r->in.cross2_present && r->in.lm_cross) {
1799
D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1800
if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1801
status = NT_STATUS_WRONG_PASSWORD;
1806
if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1807
!pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1808
status = NT_STATUS_ACCESS_DENIED;
1812
status = pdb_update_sam_account(pwd);
1819
/*******************************************************************
1820
_samr_ChangePasswordUser2
1821
********************************************************************/
1823
NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1824
struct samr_ChangePasswordUser2 *r)
1827
char *user_name = NULL;
1830
DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1832
if (!r->in.account->string) {
1833
return NT_STATUS_INVALID_PARAMETER;
1835
fstrcpy(wks, r->in.server->string);
1837
DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1840
* Pass the user through the NT -> unix user mapping
1844
(void)map_username(talloc_tos(), r->in.account->string, &user_name);
1846
return NT_STATUS_NO_MEMORY;
1850
* UNIX username case mangling not required, pass_oem_change
1851
* is case insensitive.
1854
status = pass_oem_change(user_name,
1856
r->in.lm_password->data,
1857
r->in.lm_verifier->hash,
1858
r->in.nt_password->data,
1859
r->in.nt_verifier->hash,
1862
DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1864
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1865
return NT_STATUS_WRONG_PASSWORD;
1871
/****************************************************************
1872
_samr_OemChangePasswordUser2
1873
****************************************************************/
1875
NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1876
struct samr_OemChangePasswordUser2 *r)
1879
char *user_name = NULL;
1880
const char *wks = NULL;
1882
DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1884
if (!r->in.account->string) {
1885
return NT_STATUS_INVALID_PARAMETER;
1887
if (r->in.server && r->in.server->string) {
1888
wks = r->in.server->string;
1891
DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1894
* Pass the user through the NT -> unix user mapping
1898
(void)map_username(talloc_tos(), r->in.account->string, &user_name);
1900
return NT_STATUS_NO_MEMORY;
1904
* UNIX username case mangling not required, pass_oem_change
1905
* is case insensitive.
1908
if (!r->in.hash || !r->in.password) {
1909
return NT_STATUS_INVALID_PARAMETER;
1912
status = pass_oem_change(user_name,
1914
r->in.password->data,
1920
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1921
return NT_STATUS_WRONG_PASSWORD;
1924
DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1929
/*******************************************************************
1930
_samr_ChangePasswordUser3
1931
********************************************************************/
1933
NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
1934
struct samr_ChangePasswordUser3 *r)
1937
char *user_name = NULL;
1938
const char *wks = NULL;
1939
enum samPwdChangeReason reject_reason;
1940
struct samr_DomInfo1 *dominfo = NULL;
1941
struct userPwdChangeFailureInformation *reject = NULL;
1944
DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1946
if (!r->in.account->string) {
1947
return NT_STATUS_INVALID_PARAMETER;
1949
if (r->in.server && r->in.server->string) {
1950
wks = r->in.server->string;
1953
DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1956
* Pass the user through the NT -> unix user mapping
1960
(void)map_username(talloc_tos(), r->in.account->string, &user_name);
1962
return NT_STATUS_NO_MEMORY;
1966
* UNIX username case mangling not required, pass_oem_change
1967
* is case insensitive.
1970
status = pass_oem_change(user_name,
1972
r->in.lm_password->data,
1973
r->in.lm_verifier->hash,
1974
r->in.nt_password->data,
1975
r->in.nt_verifier->hash,
1977
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1978
return NT_STATUS_WRONG_PASSWORD;
1981
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1982
NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1984
time_t u_expire, u_min_age;
1985
uint32 account_policy_temp;
1987
dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1989
return NT_STATUS_NO_MEMORY;
1992
reject = TALLOC_ZERO_P(p->mem_ctx,
1993
struct userPwdChangeFailureInformation);
1995
return NT_STATUS_NO_MEMORY;
2002
pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2003
dominfo->min_password_length = tmp;
2005
pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2006
dominfo->password_history_length = tmp;
2008
pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2009
&dominfo->password_properties);
2011
pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2012
u_expire = account_policy_temp;
2014
pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2015
u_min_age = account_policy_temp;
2021
unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2022
unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2024
if (lp_check_password_script() && *lp_check_password_script()) {
2025
dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2028
reject->extendedFailureReason = reject_reason;
2030
*r->out.dominfo = dominfo;
2031
*r->out.reject = reject;
2034
DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2039
/*******************************************************************
2040
makes a SAMR_R_LOOKUP_RIDS structure.
2041
********************************************************************/
2043
static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2045
struct lsa_String **lsa_name_array_p)
2047
struct lsa_String *lsa_name_array = NULL;
2050
*lsa_name_array_p = NULL;
2052
if (num_names != 0) {
2053
lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2054
if (!lsa_name_array) {
2059
for (i = 0; i < num_names; i++) {
2060
DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2061
init_lsa_String(&lsa_name_array[i], names[i]);
2064
*lsa_name_array_p = lsa_name_array;
2069
/*******************************************************************
2071
********************************************************************/
2073
NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2074
struct samr_LookupRids *r)
2076
struct samr_domain_info *dinfo;
2079
enum lsa_SidType *attrs = NULL;
2080
uint32 *wire_attrs = NULL;
2081
int num_rids = (int)r->in.num_rids;
2083
struct lsa_Strings names_array;
2084
struct samr_Ids types_array;
2085
struct lsa_String *lsa_names = NULL;
2087
DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2089
dinfo = policy_handle_find(p, r->in.domain_handle,
2090
0 /* Don't know the acc_bits yet */, NULL,
2091
struct samr_domain_info, &status);
2092
if (!NT_STATUS_IS_OK(status)) {
2096
if (num_rids > 1000) {
2097
DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2098
"to samba4 idl this is not possible\n", num_rids));
2099
return NT_STATUS_UNSUCCESSFUL;
2103
names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2104
attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2105
wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2107
if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2108
return NT_STATUS_NO_MEMORY;
2115
become_root(); /* lookup_sid can require root privs */
2116
status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2120
if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2121
status = NT_STATUS_OK;
2124
if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2126
return NT_STATUS_NO_MEMORY;
2129
/* Convert from enum lsa_SidType to uint32 for wire format. */
2130
for (i = 0; i < num_rids; i++) {
2131
wire_attrs[i] = (uint32)attrs[i];
2134
names_array.count = num_rids;
2135
names_array.names = lsa_names;
2137
types_array.count = num_rids;
2138
types_array.ids = wire_attrs;
2140
*r->out.names = names_array;
2141
*r->out.types = types_array;
2143
DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2148
/*******************************************************************
2150
********************************************************************/
2152
NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2153
struct samr_OpenUser *r)
2155
struct samu *sampass=NULL;
2157
struct samr_domain_info *dinfo;
2158
struct samr_user_info *uinfo;
2159
struct security_descriptor *psd = NULL;
2161
uint32 des_access = r->in.access_mask;
2162
uint32_t extra_access = 0;
2167
/* These two privileges, if != SEC_PRIV_INVALID, indicate
2168
* privileges that the user must have to complete this
2169
* operation in defience of the fixed ACL */
2170
enum sec_privilege needed_priv_1, needed_priv_2;
2173
dinfo = policy_handle_find(p, r->in.domain_handle,
2174
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2175
struct samr_domain_info, &status);
2176
if (!NT_STATUS_IS_OK(status)) {
2180
if ( !(sampass = samu_new( p->mem_ctx )) ) {
2181
return NT_STATUS_NO_MEMORY;
2184
/* append the user's RID to it */
2186
if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2187
return NT_STATUS_NO_SUCH_USER;
2189
/* check if access can be granted as requested by client. */
2190
map_max_allowed_access(p->session_info->security_token,
2191
&p->session_info->utok,
2194
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2195
se_map_generic(&des_access, &usr_generic_mapping);
2198
* Get the sampass first as we need to check privileges
2199
* based on what kind of user object this is.
2200
* But don't reveal info too early if it didn't exist.
2204
ret=pdb_getsampwsid(sampass, &sid);
2207
needed_priv_1 = SEC_PRIV_INVALID;
2208
needed_priv_2 = SEC_PRIV_INVALID;
2210
* We do the override access checks on *open*, not at
2214
uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2216
if (acb_info & ACB_WSTRUST) {
2218
* SeMachineAccount is needed to add
2219
* GENERIC_RIGHTS_USER_WRITE to a machine
2222
needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2224
if (acb_info & ACB_NORMAL) {
2226
* SeAddUsers is needed to add
2227
* GENERIC_RIGHTS_USER_WRITE to a normal
2230
needed_priv_1 = SEC_PRIV_ADD_USERS;
2233
* Cheat - we have not set a specific privilege for
2234
* server (BDC) or domain trust account, so allow
2235
* GENERIC_RIGHTS_USER_WRITE if pipe user is in
2236
* DOMAIN_RID_ADMINS.
2238
if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2239
if (lp_enable_privileges() && nt_token_check_domain_rid(p->session_info->security_token,
2240
DOMAIN_RID_ADMINS)) {
2241
des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2242
extra_access = GENERIC_RIGHTS_USER_WRITE;
2243
DEBUG(4,("_samr_OpenUser: Allowing "
2244
"GENERIC_RIGHTS_USER_WRITE for "
2250
TALLOC_FREE(sampass);
2252
nt_status = access_check_object(psd, p->session_info->security_token,
2253
needed_priv_1, needed_priv_2,
2254
GENERIC_RIGHTS_USER_WRITE, des_access,
2255
&acc_granted, "_samr_OpenUser");
2257
if ( !NT_STATUS_IS_OK(nt_status) )
2260
/* check that the SID exists in our domain. */
2262
return NT_STATUS_NO_SUCH_USER;
2265
/* If we did the rid admins hack above, allow access. */
2266
acc_granted |= extra_access;
2268
uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2269
struct samr_user_info, &nt_status);
2270
if (!NT_STATUS_IS_OK(nt_status)) {
2275
return NT_STATUS_OK;
2278
/*************************************************************************
2279
*************************************************************************/
2281
static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2283
struct lsa_BinaryString **_r)
2285
struct lsa_BinaryString *r;
2288
return NT_STATUS_INVALID_PARAMETER;
2291
r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2293
return NT_STATUS_NO_MEMORY;
2296
r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2298
return NT_STATUS_NO_MEMORY;
2300
memcpy(r->array, blob->data, blob->length);
2301
r->size = blob->length;
2302
r->length = blob->length;
2305
return NT_STATUS_NO_MEMORY;
2310
return NT_STATUS_OK;
2313
/*************************************************************************
2314
*************************************************************************/
2316
static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2319
struct samr_LogonHours hours;
2320
const int units_per_week = 168;
2323
hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2328
hours.units_per_week = units_per_week;
2329
memset(hours.bits, 0xFF, units_per_week);
2331
if (pdb_get_hours(pw)) {
2332
memcpy(hours.bits, pdb_get_hours(pw),
2333
MIN(pdb_get_hours_len(pw), units_per_week));
2339
/*************************************************************************
2341
*************************************************************************/
2343
static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2344
struct samr_UserInfo1 *r,
2346
struct dom_sid *domain_sid)
2348
const struct dom_sid *sid_group;
2349
uint32_t primary_gid;
2352
sid_group = pdb_get_group_sid(pw);
2355
if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2356
DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2357
"which conflicts with the domain sid %s. Failing operation.\n",
2358
pdb_get_username(pw), sid_string_dbg(sid_group),
2359
sid_string_dbg(domain_sid)));
2360
return NT_STATUS_UNSUCCESSFUL;
2363
r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2364
r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2365
r->primary_gid = primary_gid;
2366
r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2367
r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2369
return NT_STATUS_OK;
2372
/*************************************************************************
2374
*************************************************************************/
2376
static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2377
struct samr_UserInfo2 *r,
2380
r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2381
r->reserved.string = NULL;
2382
r->country_code = pdb_get_country_code(pw);
2383
r->code_page = pdb_get_code_page(pw);
2385
return NT_STATUS_OK;
2388
/*************************************************************************
2390
*************************************************************************/
2392
static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2393
struct samr_UserInfo3 *r,
2395
struct dom_sid *domain_sid)
2397
const struct dom_sid *sid_user, *sid_group;
2398
uint32_t rid, primary_gid;
2400
sid_user = pdb_get_user_sid(pw);
2402
if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2403
DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2404
"the domain sid %s. Failing operation.\n",
2405
pdb_get_username(pw), sid_string_dbg(sid_user),
2406
sid_string_dbg(domain_sid)));
2407
return NT_STATUS_UNSUCCESSFUL;
2411
sid_group = pdb_get_group_sid(pw);
2414
if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2415
DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2416
"which conflicts with the domain sid %s. Failing operation.\n",
2417
pdb_get_username(pw), sid_string_dbg(sid_group),
2418
sid_string_dbg(domain_sid)));
2419
return NT_STATUS_UNSUCCESSFUL;
2422
unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2423
unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2424
unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2425
unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2426
unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2428
r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2429
r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2430
r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2431
r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2432
r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2433
r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2434
r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2436
r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2438
r->primary_gid = primary_gid;
2439
r->acct_flags = pdb_get_acct_ctrl(pw);
2440
r->bad_password_count = pdb_get_bad_password_count(pw);
2441
r->logon_count = pdb_get_logon_count(pw);
2443
return NT_STATUS_OK;
2446
/*************************************************************************
2448
*************************************************************************/
2450
static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2451
struct samr_UserInfo4 *r,
2454
r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2456
return NT_STATUS_OK;
2459
/*************************************************************************
2461
*************************************************************************/
2463
static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2464
struct samr_UserInfo5 *r,
2466
struct dom_sid *domain_sid)
2468
const struct dom_sid *sid_user, *sid_group;
2469
uint32_t rid, primary_gid;
2471
sid_user = pdb_get_user_sid(pw);
2473
if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2474
DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2475
"the domain sid %s. Failing operation.\n",
2476
pdb_get_username(pw), sid_string_dbg(sid_user),
2477
sid_string_dbg(domain_sid)));
2478
return NT_STATUS_UNSUCCESSFUL;
2482
sid_group = pdb_get_group_sid(pw);
2485
if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2486
DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2487
"which conflicts with the domain sid %s. Failing operation.\n",
2488
pdb_get_username(pw), sid_string_dbg(sid_group),
2489
sid_string_dbg(domain_sid)));
2490
return NT_STATUS_UNSUCCESSFUL;
2493
unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2494
unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2495
unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2496
unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2498
r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2499
r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2500
r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2501
r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2502
r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2503
r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2504
r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2505
r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2507
r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2509
r->primary_gid = primary_gid;
2510
r->acct_flags = pdb_get_acct_ctrl(pw);
2511
r->bad_password_count = pdb_get_bad_password_count(pw);
2512
r->logon_count = pdb_get_logon_count(pw);
2514
return NT_STATUS_OK;
2517
/*************************************************************************
2519
*************************************************************************/
2521
static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2522
struct samr_UserInfo6 *r,
2525
r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2526
r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2528
return NT_STATUS_OK;
2531
/*************************************************************************
2532
get_user_info_7. Safe. Only gives out account_name.
2533
*************************************************************************/
2535
static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2536
struct samr_UserInfo7 *r,
2537
struct samu *smbpass)
2539
r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2540
if (!r->account_name.string) {
2541
return NT_STATUS_NO_MEMORY;
2544
return NT_STATUS_OK;
2547
/*************************************************************************
2549
*************************************************************************/
2551
static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2552
struct samr_UserInfo8 *r,
2555
r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2557
return NT_STATUS_OK;
2560
/*************************************************************************
2561
get_user_info_9. Only gives out primary group SID.
2562
*************************************************************************/
2564
static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2565
struct samr_UserInfo9 *r,
2566
struct samu *smbpass)
2568
r->primary_gid = pdb_get_group_rid(smbpass);
2570
return NT_STATUS_OK;
2573
/*************************************************************************
2575
*************************************************************************/
2577
static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2578
struct samr_UserInfo10 *r,
2581
r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2582
r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2584
return NT_STATUS_OK;
2587
/*************************************************************************
2589
*************************************************************************/
2591
static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2592
struct samr_UserInfo11 *r,
2595
r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2597
return NT_STATUS_OK;
2600
/*************************************************************************
2602
*************************************************************************/
2604
static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2605
struct samr_UserInfo12 *r,
2608
r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2610
return NT_STATUS_OK;
2613
/*************************************************************************
2615
*************************************************************************/
2617
static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2618
struct samr_UserInfo13 *r,
2621
r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2623
return NT_STATUS_OK;
2626
/*************************************************************************
2628
*************************************************************************/
2630
static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2631
struct samr_UserInfo14 *r,
2634
r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2636
return NT_STATUS_OK;
2639
/*************************************************************************
2640
get_user_info_16. Safe. Only gives out acb bits.
2641
*************************************************************************/
2643
static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2644
struct samr_UserInfo16 *r,
2645
struct samu *smbpass)
2647
r->acct_flags = pdb_get_acct_ctrl(smbpass);
2649
return NT_STATUS_OK;
2652
/*************************************************************************
2654
*************************************************************************/
2656
static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2657
struct samr_UserInfo17 *r,
2660
unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2662
return NT_STATUS_OK;
2665
/*************************************************************************
2666
get_user_info_18. OK - this is the killer as it gives out password info.
2667
Ensure that this is only allowed on an encrypted connection with a root
2669
*************************************************************************/
2671
static NTSTATUS get_user_info_18(struct pipes_struct *p,
2672
TALLOC_CTX *mem_ctx,
2673
struct samr_UserInfo18 *r,
2674
struct dom_sid *user_sid)
2676
struct samu *smbpass=NULL;
2678
const uint8_t *nt_pass = NULL;
2679
const uint8_t *lm_pass = NULL;
2683
if (p->session_info->system) {
2687
if ((p->auth.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) ||
2688
(p->auth.auth_type != DCERPC_AUTH_TYPE_KRB5) ||
2689
(p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO)) {
2690
return NT_STATUS_ACCESS_DENIED;
2693
if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2694
return NT_STATUS_ACCESS_DENIED;
2699
* Do *NOT* do become_root()/unbecome_root() here ! JRA.
2702
if ( !(smbpass = samu_new( mem_ctx )) ) {
2703
return NT_STATUS_NO_MEMORY;
2706
ret = pdb_getsampwsid(smbpass, user_sid);
2709
DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2710
TALLOC_FREE(smbpass);
2711
return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2714
DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2716
if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2717
TALLOC_FREE(smbpass);
2718
return NT_STATUS_ACCOUNT_DISABLED;
2721
lm_pass = pdb_get_lanman_passwd(smbpass);
2722
if (lm_pass != NULL) {
2723
memcpy(r->lm_pwd.hash, lm_pass, 16);
2724
r->lm_pwd_active = true;
2727
nt_pass = pdb_get_nt_passwd(smbpass);
2728
if (nt_pass != NULL) {
2729
memcpy(r->nt_pwd.hash, nt_pass, 16);
2730
r->nt_pwd_active = true;
2732
r->password_expired = 0; /* FIXME */
2734
TALLOC_FREE(smbpass);
2736
return NT_STATUS_OK;
2739
/*************************************************************************
2741
*************************************************************************/
2743
static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2744
struct samr_UserInfo20 *r,
2745
struct samu *sampass)
2747
const char *munged_dial = NULL;
2750
struct lsa_BinaryString *parameters = NULL;
2754
munged_dial = pdb_get_munged_dial(sampass);
2756
DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2757
munged_dial, (int)strlen(munged_dial)));
2760
blob = base64_decode_data_blob(munged_dial);
2762
blob = data_blob_string_const_null("");
2765
status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2766
data_blob_free(&blob);
2767
if (!NT_STATUS_IS_OK(status)) {
2771
r->parameters = *parameters;
2773
return NT_STATUS_OK;
2777
/*************************************************************************
2779
*************************************************************************/
2781
static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2782
struct samr_UserInfo21 *r,
2784
struct dom_sid *domain_sid,
2785
uint32_t acc_granted)
2788
const struct dom_sid *sid_user, *sid_group;
2789
uint32_t rid, primary_gid;
2790
NTTIME force_password_change;
2791
time_t must_change_time;
2792
struct lsa_BinaryString *parameters = NULL;
2793
const char *munged_dial = NULL;
2798
sid_user = pdb_get_user_sid(pw);
2800
if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2801
DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2802
"the domain sid %s. Failing operation.\n",
2803
pdb_get_username(pw), sid_string_dbg(sid_user),
2804
sid_string_dbg(domain_sid)));
2805
return NT_STATUS_UNSUCCESSFUL;
2809
sid_group = pdb_get_group_sid(pw);
2812
if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2813
DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2814
"which conflicts with the domain sid %s. Failing operation.\n",
2815
pdb_get_username(pw), sid_string_dbg(sid_group),
2816
sid_string_dbg(domain_sid)));
2817
return NT_STATUS_UNSUCCESSFUL;
2820
unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2821
unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2822
unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2823
unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2824
unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2826
must_change_time = pdb_get_pass_must_change_time(pw);
2827
if (must_change_time == get_time_t_max()) {
2828
unix_to_nt_time_abs(&force_password_change, must_change_time);
2830
unix_to_nt_time(&force_password_change, must_change_time);
2833
munged_dial = pdb_get_munged_dial(pw);
2835
blob = base64_decode_data_blob(munged_dial);
2837
blob = data_blob_string_const_null("");
2840
status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2841
data_blob_free(&blob);
2842
if (!NT_STATUS_IS_OK(status)) {
2846
r->force_password_change = force_password_change;
2848
r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2849
r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2850
r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2851
r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2852
r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2853
r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2854
r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2855
r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2856
r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2858
r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2859
r->parameters = *parameters;
2861
r->primary_gid = primary_gid;
2862
r->acct_flags = pdb_get_acct_ctrl(pw);
2863
r->bad_password_count = pdb_get_bad_password_count(pw);
2864
r->logon_count = pdb_get_logon_count(pw);
2865
r->fields_present = pdb_build_fields_present(pw);
2866
r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2867
PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2868
r->country_code = pdb_get_country_code(pw);
2869
r->code_page = pdb_get_code_page(pw);
2870
r->lm_password_set = 0;
2871
r->nt_password_set = 0;
2876
Look at a user on a real NT4 PDC with usrmgr, press
2877
'ok'. Then you will see that fields_present is set to
2878
0x08f827fa. Look at the user immediately after that again,
2879
and you will see that 0x00fffff is returned. This solves
2880
the problem that you get access denied after having looked
2888
return NT_STATUS_OK;
2891
/*******************************************************************
2893
********************************************************************/
2895
NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
2896
struct samr_QueryUserInfo *r)
2899
union samr_UserInfo *user_info = NULL;
2900
struct samr_user_info *uinfo;
2901
struct dom_sid domain_sid;
2904
struct samu *pwd = NULL;
2905
uint32_t acc_required, acc_granted;
2907
switch (r->in.level) {
2908
case 1: /* UserGeneralInformation */
2909
/* USER_READ_GENERAL */
2910
acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2912
case 2: /* UserPreferencesInformation */
2913
/* USER_READ_PREFERENCES | USER_READ_GENERAL */
2914
acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2915
SAMR_USER_ACCESS_GET_NAME_ETC;
2917
case 3: /* UserLogonInformation */
2918
/* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2919
acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2920
SAMR_USER_ACCESS_GET_LOCALE |
2921
SAMR_USER_ACCESS_GET_LOGONINFO |
2922
SAMR_USER_ACCESS_GET_ATTRIBUTES;
2924
case 4: /* UserLogonHoursInformation */
2925
/* USER_READ_LOGON */
2926
acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2928
case 5: /* UserAccountInformation */
2929
/* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2930
acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2931
SAMR_USER_ACCESS_GET_LOCALE |
2932
SAMR_USER_ACCESS_GET_LOGONINFO |
2933
SAMR_USER_ACCESS_GET_ATTRIBUTES;
2935
case 6: /* UserNameInformation */
2936
case 7: /* UserAccountNameInformation */
2937
case 8: /* UserFullNameInformation */
2938
case 9: /* UserPrimaryGroupInformation */
2939
case 13: /* UserAdminCommentInformation */
2940
/* USER_READ_GENERAL */
2941
acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2943
case 10: /* UserHomeInformation */
2944
case 11: /* UserScriptInformation */
2945
case 12: /* UserProfileInformation */
2946
case 14: /* UserWorkStationsInformation */
2947
/* USER_READ_LOGON */
2948
acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2950
case 16: /* UserControlInformation */
2951
case 17: /* UserExpiresInformation */
2952
case 20: /* UserParametersInformation */
2953
/* USER_READ_ACCOUNT */
2954
acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2956
case 21: /* UserAllInformation */
2958
acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2960
case 18: /* UserInternal1Information */
2962
acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2964
case 23: /* UserInternal4Information */
2965
case 24: /* UserInternal4InformationNew */
2966
case 25: /* UserInternal4InformationNew */
2967
case 26: /* UserInternal5InformationNew */
2969
return NT_STATUS_INVALID_INFO_CLASS;
2973
uinfo = policy_handle_find(p, r->in.user_handle,
2974
acc_required, &acc_granted,
2975
struct samr_user_info, &status);
2976
if (!NT_STATUS_IS_OK(status)) {
2980
domain_sid = uinfo->sid;
2982
sid_split_rid(&domain_sid, &rid);
2984
if (!sid_check_is_in_our_domain(&uinfo->sid))
2985
return NT_STATUS_OBJECT_TYPE_MISMATCH;
2987
DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2988
sid_string_dbg(&uinfo->sid)));
2990
user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2992
return NT_STATUS_NO_MEMORY;
2995
DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2997
if (!(pwd = samu_new(p->mem_ctx))) {
2998
return NT_STATUS_NO_MEMORY;
3002
ret = pdb_getsampwsid(pwd, &uinfo->sid);
3006
DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3008
return NT_STATUS_NO_SUCH_USER;
3011
DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3013
samr_clear_sam_passwd(pwd);
3015
switch (r->in.level) {
3017
status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3020
status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3023
status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3026
status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3029
status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3032
status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3035
status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3038
status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3041
status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3044
status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3047
status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3050
status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3053
status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3056
status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3059
status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3062
status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3065
/* level 18 is special */
3066
status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3070
status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3073
status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3076
status = NT_STATUS_INVALID_INFO_CLASS;
3080
if (!NT_STATUS_IS_OK(status)) {
3084
*r->out.info = user_info;
3089
DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3094
/****************************************************************
3095
****************************************************************/
3097
NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3098
struct samr_QueryUserInfo2 *r)
3100
struct samr_QueryUserInfo u;
3102
u.in.user_handle = r->in.user_handle;
3103
u.in.level = r->in.level;
3104
u.out.info = r->out.info;
3106
return _samr_QueryUserInfo(p, &u);
3109
/*******************************************************************
3110
_samr_GetGroupsForUser
3111
********************************************************************/
3113
NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3114
struct samr_GetGroupsForUser *r)
3116
struct samr_user_info *uinfo;
3117
struct samu *sam_pass=NULL;
3118
struct dom_sid *sids;
3119
struct samr_RidWithAttribute dom_gid;
3120
struct samr_RidWithAttribute *gids = NULL;
3121
uint32 primary_group_rid;
3122
uint32_t num_groups = 0;
3124
uint32_t i, num_gids;
3127
bool success = False;
3129
struct samr_RidWithAttributeArray *rids = NULL;
3132
* from the SID in the request:
3133
* we should send back the list of DOMAIN GROUPS
3134
* the user is a member of
3136
* and only the DOMAIN GROUPS
3137
* no ALIASES !!! neither aliases of the domain
3138
* nor aliases of the builtin SID
3143
DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3145
uinfo = policy_handle_find(p, r->in.user_handle,
3146
SAMR_USER_ACCESS_GET_GROUPS, NULL,
3147
struct samr_user_info, &result);
3148
if (!NT_STATUS_IS_OK(result)) {
3152
rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3154
return NT_STATUS_NO_MEMORY;
3157
if (!sid_check_is_in_our_domain(&uinfo->sid))
3158
return NT_STATUS_OBJECT_TYPE_MISMATCH;
3160
if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3161
return NT_STATUS_NO_MEMORY;
3165
ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3169
DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3170
sid_string_dbg(&uinfo->sid)));
3171
return NT_STATUS_NO_SUCH_USER;
3176
/* make both calls inside the root block */
3178
result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3179
&sids, &unix_gids, &num_groups);
3180
if ( NT_STATUS_IS_OK(result) ) {
3181
success = sid_peek_check_rid(get_global_sam_sid(),
3182
pdb_get_group_sid(sam_pass),
3183
&primary_group_rid);
3187
if (!NT_STATUS_IS_OK(result)) {
3188
DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3189
sid_string_dbg(&uinfo->sid)));
3194
DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3195
sid_string_dbg(pdb_get_group_sid(sam_pass)),
3196
pdb_get_username(sam_pass)));
3197
TALLOC_FREE(sam_pass);
3198
return NT_STATUS_INTERNAL_DB_CORRUPTION;
3204
dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3206
dom_gid.rid = primary_group_rid;
3207
ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3209
for (i=0; i<num_groups; i++) {
3211
if (!sid_peek_check_rid(get_global_sam_sid(),
3212
&(sids[i]), &dom_gid.rid)) {
3213
DEBUG(10, ("Found sid %s not in our domain\n",
3214
sid_string_dbg(&sids[i])));
3218
if (dom_gid.rid == primary_group_rid) {
3219
/* We added the primary group directly from the
3220
* sam_account. The other SIDs are unique from
3221
* enum_group_memberships */
3225
ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3228
rids->count = num_gids;
3231
*r->out.rids = rids;
3233
DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3238
/*******************************************************************
3239
********************************************************************/
3241
static uint32_t samr_get_server_role(void)
3243
uint32_t role = ROLE_DOMAIN_PDC;
3245
if (lp_server_role() == ROLE_DOMAIN_BDC) {
3246
role = ROLE_DOMAIN_BDC;
3252
/*******************************************************************
3253
********************************************************************/
3255
static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3256
struct samr_DomInfo1 *r)
3258
uint32_t account_policy_temp;
3259
time_t u_expire, u_min_age;
3265
pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3266
r->min_password_length = account_policy_temp;
3268
pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3269
r->password_history_length = account_policy_temp;
3271
pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3272
&r->password_properties);
3274
pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3275
u_expire = account_policy_temp;
3277
pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3278
u_min_age = account_policy_temp;
3284
unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3285
unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3287
if (lp_check_password_script() && *lp_check_password_script()) {
3288
r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3291
return NT_STATUS_OK;
3294
/*******************************************************************
3295
********************************************************************/
3297
static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3298
struct samr_DomGeneralInformation *r,
3299
struct samr_domain_info *dinfo)
3308
r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3309
r->num_groups = count_sam_groups(dinfo->disp_info);
3310
r->num_aliases = count_sam_aliases(dinfo->disp_info);
3312
pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3314
unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3316
if (!pdb_get_seq_num(&seq_num)) {
3317
seq_num = time(NULL);
3324
r->oem_information.string = lp_serverstring();
3325
r->domain_name.string = lp_workgroup();
3326
r->primary.string = global_myname();
3327
r->sequence_num = seq_num;
3328
r->domain_server_state = DOMAIN_SERVER_ENABLED;
3329
r->role = (enum samr_Role) samr_get_server_role();
3332
return NT_STATUS_OK;
3335
/*******************************************************************
3336
********************************************************************/
3338
static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3339
struct samr_DomInfo3 *r)
3349
pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3350
u_logout = (time_t)ul;
3357
unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3359
return NT_STATUS_OK;
3362
/*******************************************************************
3363
********************************************************************/
3365
static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3366
struct samr_DomOEMInformation *r)
3368
r->oem_information.string = lp_serverstring();
3370
return NT_STATUS_OK;
3373
/*******************************************************************
3374
********************************************************************/
3376
static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3377
struct samr_DomInfo5 *r)
3379
r->domain_name.string = get_global_sam_name();
3381
return NT_STATUS_OK;
3384
/*******************************************************************
3385
********************************************************************/
3387
static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3388
struct samr_DomInfo6 *r)
3390
/* NT returns its own name when a PDC. win2k and later
3391
* only the name of the PDC if itself is a BDC (samba4
3393
r->primary.string = global_myname();
3395
return NT_STATUS_OK;
3398
/*******************************************************************
3399
********************************************************************/
3401
static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3402
struct samr_DomInfo7 *r)
3404
r->role = (enum samr_Role) samr_get_server_role();
3406
return NT_STATUS_OK;
3409
/*******************************************************************
3410
********************************************************************/
3412
static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3413
struct samr_DomInfo8 *r)
3421
if (!pdb_get_seq_num(&seq_num)) {
3422
seq_num = time(NULL);
3429
r->sequence_num = seq_num;
3430
r->domain_create_time = 0;
3432
return NT_STATUS_OK;
3435
/*******************************************************************
3436
********************************************************************/
3438
static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3439
struct samr_DomInfo9 *r)
3441
r->domain_server_state = DOMAIN_SERVER_ENABLED;
3443
return NT_STATUS_OK;
3446
/*******************************************************************
3447
********************************************************************/
3449
static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3450
struct samr_DomGeneralInformation2 *r,
3451
struct samr_domain_info *dinfo)
3454
uint32_t account_policy_temp;
3455
time_t u_lock_duration, u_reset_time;
3457
status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3458
if (!NT_STATUS_IS_OK(status)) {
3466
pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3467
u_lock_duration = account_policy_temp;
3468
if (u_lock_duration != -1) {
3469
u_lock_duration *= 60;
3472
pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3473
u_reset_time = account_policy_temp * 60;
3475
pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3476
r->lockout_threshold = account_policy_temp;
3482
unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3483
unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3485
return NT_STATUS_OK;
3488
/*******************************************************************
3489
********************************************************************/
3491
static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3492
struct samr_DomInfo12 *r)
3494
uint32_t account_policy_temp;
3495
time_t u_lock_duration, u_reset_time;
3501
pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3502
u_lock_duration = account_policy_temp;
3503
if (u_lock_duration != -1) {
3504
u_lock_duration *= 60;
3507
pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3508
u_reset_time = account_policy_temp * 60;
3510
pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3511
r->lockout_threshold = account_policy_temp;
3517
unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3518
unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3520
return NT_STATUS_OK;
3523
/*******************************************************************
3524
********************************************************************/
3526
static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3527
struct samr_DomInfo13 *r)
3535
if (!pdb_get_seq_num(&seq_num)) {
3536
seq_num = time(NULL);
3543
r->sequence_num = seq_num;
3544
r->domain_create_time = 0;
3545
r->modified_count_at_last_promotion = 0;
3547
return NT_STATUS_OK;
3550
/*******************************************************************
3551
_samr_QueryDomainInfo
3552
********************************************************************/
3554
NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3555
struct samr_QueryDomainInfo *r)
3557
NTSTATUS status = NT_STATUS_OK;
3558
struct samr_domain_info *dinfo;
3559
union samr_DomainInfo *dom_info;
3561
uint32_t acc_required;
3563
DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3565
switch (r->in.level) {
3566
case 1: /* DomainPasswordInformation */
3567
case 12: /* DomainLockoutInformation */
3568
/* DOMAIN_READ_PASSWORD_PARAMETERS */
3569
acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3571
case 11: /* DomainGeneralInformation2 */
3572
/* DOMAIN_READ_PASSWORD_PARAMETERS |
3573
* DOMAIN_READ_OTHER_PARAMETERS */
3574
acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3575
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3577
case 2: /* DomainGeneralInformation */
3578
case 3: /* DomainLogoffInformation */
3579
case 4: /* DomainOemInformation */
3580
case 5: /* DomainReplicationInformation */
3581
case 6: /* DomainReplicationInformation */
3582
case 7: /* DomainServerRoleInformation */
3583
case 8: /* DomainModifiedInformation */
3584
case 9: /* DomainStateInformation */
3585
case 10: /* DomainUasInformation */
3586
case 13: /* DomainModifiedInformation2 */
3587
/* DOMAIN_READ_OTHER_PARAMETERS */
3588
acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3591
return NT_STATUS_INVALID_INFO_CLASS;
3594
dinfo = policy_handle_find(p, r->in.domain_handle,
3596
struct samr_domain_info, &status);
3597
if (!NT_STATUS_IS_OK(status)) {
3601
dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3603
return NT_STATUS_NO_MEMORY;
3606
switch (r->in.level) {
3608
status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3611
status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3614
status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3617
status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3620
status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3623
status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3626
status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3629
status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3632
status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3635
status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3638
status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3641
status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3644
return NT_STATUS_INVALID_INFO_CLASS;
3647
if (!NT_STATUS_IS_OK(status)) {
3651
*r->out.info = dom_info;
3653
DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3658
/* W2k3 seems to use the same check for all 3 objects that can be created via
3659
* SAMR, if you try to create for example "Dialup" as an alias it says
3660
* "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3663
static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3665
enum lsa_SidType type;
3668
DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3671
/* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3672
* whether the name already exists */
3673
result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3674
NULL, NULL, NULL, &type);
3678
DEBUG(10, ("%s does not exist, can create it\n", new_name));
3679
return NT_STATUS_OK;
3682
DEBUG(5, ("trying to create %s, exists as %s\n",
3683
new_name, sid_type_lookup(type)));
3685
if (type == SID_NAME_DOM_GRP) {
3686
return NT_STATUS_GROUP_EXISTS;
3688
if (type == SID_NAME_ALIAS) {
3689
return NT_STATUS_ALIAS_EXISTS;
3692
/* Yes, the default is NT_STATUS_USER_EXISTS */
3693
return NT_STATUS_USER_EXISTS;
3696
/*******************************************************************
3698
********************************************************************/
3700
NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3701
struct samr_CreateUser2 *r)
3703
const char *account = NULL;
3705
uint32_t acb_info = r->in.acct_flags;
3706
struct samr_domain_info *dinfo;
3707
struct samr_user_info *uinfo;
3710
struct security_descriptor *psd;
3712
/* check this, when giving away 'add computer to domain' privs */
3713
uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3714
bool can_add_account = False;
3716
/* Which privilege is needed to override the ACL? */
3717
enum sec_privilege needed_priv = SEC_PRIV_INVALID;
3719
dinfo = policy_handle_find(p, r->in.domain_handle,
3720
SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3721
struct samr_domain_info, &nt_status);
3722
if (!NT_STATUS_IS_OK(nt_status)) {
3726
if (sid_check_is_builtin(&dinfo->sid)) {
3727
DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3728
return NT_STATUS_ACCESS_DENIED;
3731
if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3732
acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3733
/* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3734
this parameter is not an account type */
3735
return NT_STATUS_INVALID_PARAMETER;
3738
account = r->in.account_name->string;
3739
if (account == NULL) {
3740
return NT_STATUS_NO_MEMORY;
3743
nt_status = can_create(p->mem_ctx, account);
3744
if (!NT_STATUS_IS_OK(nt_status)) {
3748
/* determine which user right we need to check based on the acb_info */
3750
if (geteuid() == sec_initial_uid()) {
3751
can_add_account = true;
3752
} else if (acb_info & ACB_WSTRUST) {
3753
needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
3754
can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_MACHINE_ACCOUNT);
3755
} else if (acb_info & ACB_NORMAL &&
3756
(account[strlen(account)-1] != '$')) {
3757
/* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3758
account for domain trusts and changes the ACB flags later */
3759
needed_priv = SEC_PRIV_ADD_USERS;
3760
can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS);
3761
} else if (lp_enable_privileges()) {
3762
/* implicit assumption of a BDC or domain trust account here
3763
* (we already check the flags earlier) */
3764
/* only Domain Admins can add a BDC or domain trust */
3765
can_add_account = nt_token_check_domain_rid(
3766
p->session_info->security_token,
3767
DOMAIN_RID_ADMINS );
3770
DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3771
uidtoname(p->session_info->utok.uid),
3772
can_add_account ? "True":"False" ));
3774
if (!can_add_account) {
3775
return NT_STATUS_ACCESS_DENIED;
3778
/********** BEGIN Admin BLOCK **********/
3781
nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3785
/********** END Admin BLOCK **********/
3787
/* now check for failure */
3789
if ( !NT_STATUS_IS_OK(nt_status) )
3792
/* Get the user's SID */
3794
sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3796
map_max_allowed_access(p->session_info->security_token,
3797
&p->session_info->utok,
3800
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3801
&sid, SAMR_USR_RIGHTS_WRITE_PW);
3802
se_map_generic(&des_access, &usr_generic_mapping);
3805
* JRA - TESTME. We just created this user so we
3806
* had rights to create them. Do we need to check
3807
* any further access on this object ? Can't we
3808
* just assume we have all the rights we need ?
3811
nt_status = access_check_object(psd, p->session_info->security_token,
3812
needed_priv, SEC_PRIV_INVALID,
3813
GENERIC_RIGHTS_USER_WRITE, des_access,
3814
&acc_granted, "_samr_CreateUser2");
3816
if ( !NT_STATUS_IS_OK(nt_status) ) {
3820
uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3821
struct samr_user_info, &nt_status);
3822
if (!NT_STATUS_IS_OK(nt_status)) {
3827
/* After a "set" ensure we have no cached display info. */
3828
force_flush_samr_cache(&sid);
3830
*r->out.access_granted = acc_granted;
3832
return NT_STATUS_OK;
3835
/****************************************************************
3836
****************************************************************/
3838
NTSTATUS _samr_CreateUser(struct pipes_struct *p,
3839
struct samr_CreateUser *r)
3841
struct samr_CreateUser2 c;
3842
uint32_t access_granted;
3844
c.in.domain_handle = r->in.domain_handle;
3845
c.in.account_name = r->in.account_name;
3846
c.in.acct_flags = ACB_NORMAL;
3847
c.in.access_mask = r->in.access_mask;
3848
c.out.user_handle = r->out.user_handle;
3849
c.out.access_granted = &access_granted;
3850
c.out.rid = r->out.rid;
3852
return _samr_CreateUser2(p, &c);
3855
/*******************************************************************
3857
********************************************************************/
3859
NTSTATUS _samr_Connect(struct pipes_struct *p,
3860
struct samr_Connect *r)
3862
struct samr_connect_info *info;
3863
uint32_t acc_granted;
3864
struct policy_handle hnd;
3865
uint32 des_access = r->in.access_mask;
3870
if (!pipe_access_check(p)) {
3871
DEBUG(3, ("access denied to _samr_Connect\n"));
3872
return NT_STATUS_ACCESS_DENIED;
3875
/* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3876
was observed from a win98 client trying to enumerate users (when configured
3877
user level access control on shares) --jerry */
3879
map_max_allowed_access(p->session_info->security_token,
3880
&p->session_info->utok,
3883
se_map_generic( &des_access, &sam_generic_mapping );
3885
acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3886
|SAMR_ACCESS_LOOKUP_DOMAIN);
3888
/* set up the SAMR connect_anon response */
3890
info = policy_handle_create(p, &hnd, acc_granted,
3891
struct samr_connect_info,
3893
if (!NT_STATUS_IS_OK(status)) {
3897
*r->out.connect_handle = hnd;
3898
return NT_STATUS_OK;
3901
/*******************************************************************
3903
********************************************************************/
3905
NTSTATUS _samr_Connect2(struct pipes_struct *p,
3906
struct samr_Connect2 *r)
3908
struct samr_connect_info *info = NULL;
3909
struct policy_handle hnd;
3910
struct security_descriptor *psd = NULL;
3912
uint32 des_access = r->in.access_mask;
3915
const char *fn = "_samr_Connect2";
3918
case NDR_SAMR_CONNECT2:
3919
fn = "_samr_Connect2";
3921
case NDR_SAMR_CONNECT3:
3922
fn = "_samr_Connect3";
3924
case NDR_SAMR_CONNECT4:
3925
fn = "_samr_Connect4";
3927
case NDR_SAMR_CONNECT5:
3928
fn = "_samr_Connect5";
3932
DEBUG(5,("%s: %d\n", fn, __LINE__));
3936
if (!pipe_access_check(p)) {
3937
DEBUG(3, ("access denied to %s\n", fn));
3938
return NT_STATUS_ACCESS_DENIED;
3941
map_max_allowed_access(p->session_info->security_token,
3942
&p->session_info->utok,
3945
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3946
se_map_generic(&des_access, &sam_generic_mapping);
3948
nt_status = access_check_object(psd, p->session_info->security_token,
3949
SEC_PRIV_INVALID, SEC_PRIV_INVALID,
3950
0, des_access, &acc_granted, fn);
3952
if ( !NT_STATUS_IS_OK(nt_status) )
3955
info = policy_handle_create(p, &hnd, acc_granted,
3956
struct samr_connect_info, &nt_status);
3957
if (!NT_STATUS_IS_OK(nt_status)) {
3961
DEBUG(5,("%s: %d\n", fn, __LINE__));
3963
*r->out.connect_handle = hnd;
3964
return NT_STATUS_OK;
3967
/****************************************************************
3969
****************************************************************/
3971
NTSTATUS _samr_Connect3(struct pipes_struct *p,
3972
struct samr_Connect3 *r)
3974
struct samr_Connect2 c;
3976
c.in.system_name = r->in.system_name;
3977
c.in.access_mask = r->in.access_mask;
3978
c.out.connect_handle = r->out.connect_handle;
3980
return _samr_Connect2(p, &c);
3983
/*******************************************************************
3985
********************************************************************/
3987
NTSTATUS _samr_Connect4(struct pipes_struct *p,
3988
struct samr_Connect4 *r)
3990
struct samr_Connect2 c;
3992
c.in.system_name = r->in.system_name;
3993
c.in.access_mask = r->in.access_mask;
3994
c.out.connect_handle = r->out.connect_handle;
3996
return _samr_Connect2(p, &c);
3999
/*******************************************************************
4001
********************************************************************/
4003
NTSTATUS _samr_Connect5(struct pipes_struct *p,
4004
struct samr_Connect5 *r)
4007
struct samr_Connect2 c;
4008
struct samr_ConnectInfo1 info1;
4010
info1.client_version = SAMR_CONNECT_AFTER_W2K;
4013
c.in.system_name = r->in.system_name;
4014
c.in.access_mask = r->in.access_mask;
4015
c.out.connect_handle = r->out.connect_handle;
4017
*r->out.level_out = 1;
4019
status = _samr_Connect2(p, &c);
4020
if (!NT_STATUS_IS_OK(status)) {
4024
r->out.info_out->info1 = info1;
4026
return NT_STATUS_OK;
4029
/**********************************************************************
4031
**********************************************************************/
4033
NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
4034
struct samr_LookupDomain *r)
4037
struct samr_connect_info *info;
4038
const char *domain_name;
4039
struct dom_sid *sid = NULL;
4041
/* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4042
Reverted that change so we will work with RAS servers again */
4044
info = policy_handle_find(p, r->in.connect_handle,
4045
SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4046
struct samr_connect_info,
4048
if (!NT_STATUS_IS_OK(status)) {
4052
domain_name = r->in.domain_name->string;
4054
return NT_STATUS_INVALID_PARAMETER;
4057
sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
4059
return NT_STATUS_NO_MEMORY;
4062
if (strequal(domain_name, builtin_domain_name())) {
4063
sid_copy(sid, &global_sid_Builtin);
4065
if (!secrets_fetch_domain_sid(domain_name, sid)) {
4066
status = NT_STATUS_NO_SUCH_DOMAIN;
4070
DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4071
sid_string_dbg(sid)));
4078
/**********************************************************************
4080
**********************************************************************/
4082
NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4083
struct samr_EnumDomains *r)
4086
struct samr_connect_info *info;
4087
uint32_t num_entries = 2;
4088
struct samr_SamEntry *entry_array = NULL;
4089
struct samr_SamArray *sam;
4091
info = policy_handle_find(p, r->in.connect_handle,
4092
SAMR_ACCESS_ENUM_DOMAINS, NULL,
4093
struct samr_connect_info, &status);
4094
if (!NT_STATUS_IS_OK(status)) {
4098
sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4100
return NT_STATUS_NO_MEMORY;
4103
entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4104
struct samr_SamEntry,
4107
return NT_STATUS_NO_MEMORY;
4110
entry_array[0].idx = 0;
4111
init_lsa_String(&entry_array[0].name, get_global_sam_name());
4113
entry_array[1].idx = 1;
4114
init_lsa_String(&entry_array[1].name, "Builtin");
4116
sam->count = num_entries;
4117
sam->entries = entry_array;
4120
*r->out.num_entries = num_entries;
4125
/*******************************************************************
4127
********************************************************************/
4129
NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4130
struct samr_OpenAlias *r)
4133
uint32 alias_rid = r->in.rid;
4134
struct samr_alias_info *ainfo;
4135
struct samr_domain_info *dinfo;
4136
struct security_descriptor *psd = NULL;
4138
uint32 des_access = r->in.access_mask;
4142
dinfo = policy_handle_find(p, r->in.domain_handle,
4143
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4144
struct samr_domain_info, &status);
4145
if (!NT_STATUS_IS_OK(status)) {
4149
/* append the alias' RID to it */
4151
if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4152
return NT_STATUS_NO_SUCH_ALIAS;
4154
/*check if access can be granted as requested by client. */
4156
map_max_allowed_access(p->session_info->security_token,
4157
&p->session_info->utok,
4160
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4161
se_map_generic(&des_access,&ali_generic_mapping);
4163
status = access_check_object(psd, p->session_info->security_token,
4164
SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
4165
GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4166
des_access, &acc_granted, "_samr_OpenAlias");
4168
if ( !NT_STATUS_IS_OK(status) )
4172
/* Check we actually have the requested alias */
4173
enum lsa_SidType type;
4178
result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4181
if (!result || (type != SID_NAME_ALIAS)) {
4182
return NT_STATUS_NO_SUCH_ALIAS;
4185
/* make sure there is a mapping */
4187
if ( !sid_to_gid( &sid, &gid ) ) {
4188
return NT_STATUS_NO_SUCH_ALIAS;
4193
ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4194
struct samr_alias_info, &status);
4195
if (!NT_STATUS_IS_OK(status)) {
4200
return NT_STATUS_OK;
4203
/*******************************************************************
4205
********************************************************************/
4207
static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4208
struct samr_UserInfo2 *id2,
4212
DEBUG(5,("set_user_info_2: NULL id2\n"));
4213
return NT_STATUS_ACCESS_DENIED;
4216
copy_id2_to_sam_passwd(pwd, id2);
4218
return pdb_update_sam_account(pwd);
4221
/*******************************************************************
4223
********************************************************************/
4225
static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4226
struct samr_UserInfo4 *id4,
4230
DEBUG(5,("set_user_info_2: NULL id4\n"));
4231
return NT_STATUS_ACCESS_DENIED;
4234
copy_id4_to_sam_passwd(pwd, id4);
4236
return pdb_update_sam_account(pwd);
4239
/*******************************************************************
4241
********************************************************************/
4243
static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4244
struct samr_UserInfo6 *id6,
4248
DEBUG(5,("set_user_info_6: NULL id6\n"));
4249
return NT_STATUS_ACCESS_DENIED;
4252
copy_id6_to_sam_passwd(pwd, id6);
4254
return pdb_update_sam_account(pwd);
4257
/*******************************************************************
4259
********************************************************************/
4261
static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4262
struct samr_UserInfo7 *id7,
4268
DEBUG(5, ("set_user_info_7: NULL id7\n"));
4269
return NT_STATUS_ACCESS_DENIED;
4272
if (!id7->account_name.string) {
4273
DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4274
return NT_STATUS_ACCESS_DENIED;
4277
/* check to see if the new username already exists. Note: we can't
4278
reliably lock all backends, so there is potentially the
4279
possibility that a user can be created in between this check and
4280
the rename. The rename should fail, but may not get the
4281
exact same failure status code. I think this is small enough
4282
of a window for this type of operation and the results are
4283
simply that the rename fails with a slightly different status
4284
code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4286
rc = can_create(mem_ctx, id7->account_name.string);
4288
/* when there is nothing to change, we're done here */
4289
if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4290
strequal(id7->account_name.string, pdb_get_username(pwd))) {
4291
return NT_STATUS_OK;
4293
if (!NT_STATUS_IS_OK(rc)) {
4297
rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4302
/*******************************************************************
4304
********************************************************************/
4306
static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4307
struct samr_UserInfo8 *id8,
4311
DEBUG(5,("set_user_info_8: NULL id8\n"));
4312
return NT_STATUS_ACCESS_DENIED;
4315
copy_id8_to_sam_passwd(pwd, id8);
4317
return pdb_update_sam_account(pwd);
4320
/*******************************************************************
4322
********************************************************************/
4324
static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4325
struct samr_UserInfo10 *id10,
4329
DEBUG(5,("set_user_info_8: NULL id10\n"));
4330
return NT_STATUS_ACCESS_DENIED;
4333
copy_id10_to_sam_passwd(pwd, id10);
4335
return pdb_update_sam_account(pwd);
4338
/*******************************************************************
4340
********************************************************************/
4342
static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4343
struct samr_UserInfo11 *id11,
4347
DEBUG(5,("set_user_info_11: NULL id11\n"));
4348
return NT_STATUS_ACCESS_DENIED;
4351
copy_id11_to_sam_passwd(pwd, id11);
4353
return pdb_update_sam_account(pwd);
4356
/*******************************************************************
4358
********************************************************************/
4360
static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4361
struct samr_UserInfo12 *id12,
4365
DEBUG(5,("set_user_info_12: NULL id12\n"));
4366
return NT_STATUS_ACCESS_DENIED;
4369
copy_id12_to_sam_passwd(pwd, id12);
4371
return pdb_update_sam_account(pwd);
4374
/*******************************************************************
4376
********************************************************************/
4378
static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4379
struct samr_UserInfo13 *id13,
4383
DEBUG(5,("set_user_info_13: NULL id13\n"));
4384
return NT_STATUS_ACCESS_DENIED;
4387
copy_id13_to_sam_passwd(pwd, id13);
4389
return pdb_update_sam_account(pwd);
4392
/*******************************************************************
4394
********************************************************************/
4396
static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4397
struct samr_UserInfo14 *id14,
4401
DEBUG(5,("set_user_info_14: NULL id14\n"));
4402
return NT_STATUS_ACCESS_DENIED;
4405
copy_id14_to_sam_passwd(pwd, id14);
4407
return pdb_update_sam_account(pwd);
4410
/*******************************************************************
4412
********************************************************************/
4414
static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4415
struct samr_UserInfo16 *id16,
4419
DEBUG(5,("set_user_info_16: NULL id16\n"));
4420
return NT_STATUS_ACCESS_DENIED;
4423
copy_id16_to_sam_passwd(pwd, id16);
4425
return pdb_update_sam_account(pwd);
4428
/*******************************************************************
4430
********************************************************************/
4432
static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4433
struct samr_UserInfo17 *id17,
4437
DEBUG(5,("set_user_info_17: NULL id17\n"));
4438
return NT_STATUS_ACCESS_DENIED;
4441
copy_id17_to_sam_passwd(pwd, id17);
4443
return pdb_update_sam_account(pwd);
4446
/*******************************************************************
4448
********************************************************************/
4450
static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4451
TALLOC_CTX *mem_ctx,
4452
DATA_BLOB *session_key,
4456
DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4457
return NT_STATUS_INVALID_PARAMETER;
4460
if (id18->nt_pwd_active || id18->lm_pwd_active) {
4461
if (!session_key->length) {
4462
return NT_STATUS_NO_USER_SESSION_KEY;
4466
if (id18->nt_pwd_active) {
4470
in = data_blob_const(id18->nt_pwd.hash, 16);
4471
out = data_blob_talloc_zero(mem_ctx, 16);
4473
sess_crypt_blob(&out, &in, session_key, false);
4475
if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4476
return NT_STATUS_ACCESS_DENIED;
4479
pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4482
if (id18->lm_pwd_active) {
4486
in = data_blob_const(id18->lm_pwd.hash, 16);
4487
out = data_blob_talloc_zero(mem_ctx, 16);
4489
sess_crypt_blob(&out, &in, session_key, false);
4491
if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4492
return NT_STATUS_ACCESS_DENIED;
4495
pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4498
copy_id18_to_sam_passwd(pwd, id18);
4500
return pdb_update_sam_account(pwd);
4503
/*******************************************************************
4505
********************************************************************/
4507
static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4508
struct samr_UserInfo20 *id20,
4512
DEBUG(5,("set_user_info_20: NULL id20\n"));
4513
return NT_STATUS_ACCESS_DENIED;
4516
copy_id20_to_sam_passwd(pwd, id20);
4518
return pdb_update_sam_account(pwd);
4521
/*******************************************************************
4523
********************************************************************/
4525
static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4526
TALLOC_CTX *mem_ctx,
4527
DATA_BLOB *session_key,
4533
DEBUG(5, ("set_user_info_21: NULL id21\n"));
4534
return NT_STATUS_INVALID_PARAMETER;
4537
if (id21->fields_present == 0) {
4538
return NT_STATUS_INVALID_PARAMETER;
4541
if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4542
return NT_STATUS_ACCESS_DENIED;
4545
if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4546
if (id21->nt_password_set) {
4549
if ((id21->nt_owf_password.length != 16) ||
4550
(id21->nt_owf_password.size != 16)) {
4551
return NT_STATUS_INVALID_PARAMETER;
4554
if (!session_key->length) {
4555
return NT_STATUS_NO_USER_SESSION_KEY;
4558
in = data_blob_const(id21->nt_owf_password.array, 16);
4559
out = data_blob_talloc_zero(mem_ctx, 16);
4561
sess_crypt_blob(&out, &in, session_key, false);
4563
pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4564
pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4568
if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4569
if (id21->lm_password_set) {
4572
if ((id21->lm_owf_password.length != 16) ||
4573
(id21->lm_owf_password.size != 16)) {
4574
return NT_STATUS_INVALID_PARAMETER;
4577
if (!session_key->length) {
4578
return NT_STATUS_NO_USER_SESSION_KEY;
4581
in = data_blob_const(id21->lm_owf_password.array, 16);
4582
out = data_blob_talloc_zero(mem_ctx, 16);
4584
sess_crypt_blob(&out, &in, session_key, false);
4586
pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4587
pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4591
/* we need to separately check for an account rename first */
4593
if (id21->account_name.string &&
4594
(!strequal(id21->account_name.string, pdb_get_username(pwd))))
4597
/* check to see if the new username already exists. Note: we can't
4598
reliably lock all backends, so there is potentially the
4599
possibility that a user can be created in between this check and
4600
the rename. The rename should fail, but may not get the
4601
exact same failure status code. I think this is small enough
4602
of a window for this type of operation and the results are
4603
simply that the rename fails with a slightly different status
4604
code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4606
status = can_create(mem_ctx, id21->account_name.string);
4607
if (!NT_STATUS_IS_OK(status)) {
4611
status = pdb_rename_sam_account(pwd, id21->account_name.string);
4613
if (!NT_STATUS_IS_OK(status)) {
4614
DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4615
nt_errstr(status)));
4619
/* set the new username so that later
4620
functions can work on the new account */
4621
pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4624
copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4627
* The funny part about the previous two calls is
4628
* that pwd still has the password hashes from the
4629
* passdb entry. These have not been updated from
4630
* id21. I don't know if they need to be set. --jerry
4633
if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4634
status = pdb_set_unix_primary_group(mem_ctx, pwd);
4635
if ( !NT_STATUS_IS_OK(status) ) {
4640
/* Don't worry about writing out the user account since the
4641
primary group SID is generated solely from the user's Unix
4644
/* write the change out */
4645
if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4649
return NT_STATUS_OK;
4652
/*******************************************************************
4654
********************************************************************/
4656
static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4657
struct samr_UserInfo23 *id23,
4661
char *plaintext_buf = NULL;
4667
DEBUG(5, ("set_user_info_23: NULL id23\n"));
4668
return NT_STATUS_INVALID_PARAMETER;
4671
if (id23->info.fields_present == 0) {
4672
return NT_STATUS_INVALID_PARAMETER;
4675
if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4676
return NT_STATUS_ACCESS_DENIED;
4679
if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4680
(id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4682
DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4683
pdb_get_username(pwd)));
4685
if (!decode_pw_buffer(mem_ctx,
4686
id23->password.data,
4690
return NT_STATUS_WRONG_PASSWORD;
4693
if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4694
return NT_STATUS_ACCESS_DENIED;
4698
copy_id23_to_sam_passwd(pwd, id23);
4700
acct_ctrl = pdb_get_acct_ctrl(pwd);
4702
/* if it's a trust account, don't update /etc/passwd */
4703
if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4704
( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4705
( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4706
DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4707
} else if (plaintext_buf) {
4708
/* update the UNIX password */
4709
if (lp_unix_password_sync() ) {
4710
struct passwd *passwd;
4711
if (pdb_get_username(pwd) == NULL) {
4712
DEBUG(1, ("chgpasswd: User without name???\n"));
4713
return NT_STATUS_ACCESS_DENIED;
4716
passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4717
if (passwd == NULL) {
4718
DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4721
if(!chgpasswd(pdb_get_username(pwd), rhost,
4722
passwd, "", plaintext_buf, True)) {
4723
return NT_STATUS_ACCESS_DENIED;
4725
TALLOC_FREE(passwd);
4729
if (plaintext_buf) {
4730
memset(plaintext_buf, '\0', strlen(plaintext_buf));
4733
if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4734
(!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4739
if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4743
return NT_STATUS_OK;
4746
/*******************************************************************
4748
********************************************************************/
4750
static bool set_user_info_pw(uint8 *pass, const char *rhost, struct samu *pwd)
4753
char *plaintext_buf = NULL;
4756
DEBUG(5, ("Attempting administrator password change for user %s\n",
4757
pdb_get_username(pwd)));
4759
acct_ctrl = pdb_get_acct_ctrl(pwd);
4761
if (!decode_pw_buffer(talloc_tos(),
4769
if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4773
/* if it's a trust account, don't update /etc/passwd */
4774
if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4775
( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4776
( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4777
DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4779
/* update the UNIX password */
4780
if (lp_unix_password_sync()) {
4781
struct passwd *passwd;
4783
if (pdb_get_username(pwd) == NULL) {
4784
DEBUG(1, ("chgpasswd: User without name???\n"));
4788
passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4789
if (passwd == NULL) {
4790
DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4793
if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
4794
"", plaintext_buf, True)) {
4797
TALLOC_FREE(passwd);
4801
memset(plaintext_buf, '\0', strlen(plaintext_buf));
4803
DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4808
/*******************************************************************
4810
********************************************************************/
4812
static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4814
struct samr_UserInfo24 *id24,
4820
DEBUG(5, ("set_user_info_24: NULL id24\n"));
4821
return NT_STATUS_INVALID_PARAMETER;
4824
if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
4825
return NT_STATUS_WRONG_PASSWORD;
4828
copy_id24_to_sam_passwd(pwd, id24);
4830
status = pdb_update_sam_account(pwd);
4831
if (!NT_STATUS_IS_OK(status)) {
4835
return NT_STATUS_OK;
4838
/*******************************************************************
4840
********************************************************************/
4842
static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4844
struct samr_UserInfo25 *id25,
4850
DEBUG(5, ("set_user_info_25: NULL id25\n"));
4851
return NT_STATUS_INVALID_PARAMETER;
4854
if (id25->info.fields_present == 0) {
4855
return NT_STATUS_INVALID_PARAMETER;
4858
if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4859
return NT_STATUS_ACCESS_DENIED;
4862
if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4863
(id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4865
if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
4866
return NT_STATUS_WRONG_PASSWORD;
4870
copy_id25_to_sam_passwd(pwd, id25);
4872
/* write the change out */
4873
if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4878
* We need to "pdb_update_sam_account" before the unix primary group
4879
* is set, because the idealx scripts would also change the
4880
* sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4881
* the delete explicit / add explicit, which would then fail to find
4882
* the previous primaryGroupSid value.
4885
if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4886
status = pdb_set_unix_primary_group(mem_ctx, pwd);
4887
if ( !NT_STATUS_IS_OK(status) ) {
4892
return NT_STATUS_OK;
4895
/*******************************************************************
4897
********************************************************************/
4899
static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4901
struct samr_UserInfo26 *id26,
4907
DEBUG(5, ("set_user_info_26: NULL id26\n"));
4908
return NT_STATUS_INVALID_PARAMETER;
4911
if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
4912
return NT_STATUS_WRONG_PASSWORD;
4915
copy_id26_to_sam_passwd(pwd, id26);
4917
status = pdb_update_sam_account(pwd);
4918
if (!NT_STATUS_IS_OK(status)) {
4922
return NT_STATUS_OK;
4925
/*************************************************************
4926
**************************************************************/
4928
static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4930
uint32_t acc_required = 0;
4932
/* USER_ALL_USERNAME */
4933
if (fields & SAMR_FIELD_ACCOUNT_NAME)
4934
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4935
/* USER_ALL_FULLNAME */
4936
if (fields & SAMR_FIELD_FULL_NAME)
4937
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4938
/* USER_ALL_PRIMARYGROUPID */
4939
if (fields & SAMR_FIELD_PRIMARY_GID)
4940
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4941
/* USER_ALL_HOMEDIRECTORY */
4942
if (fields & SAMR_FIELD_HOME_DIRECTORY)
4943
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4944
/* USER_ALL_HOMEDIRECTORYDRIVE */
4945
if (fields & SAMR_FIELD_HOME_DRIVE)
4946
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4947
/* USER_ALL_SCRIPTPATH */
4948
if (fields & SAMR_FIELD_LOGON_SCRIPT)
4949
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4950
/* USER_ALL_PROFILEPATH */
4951
if (fields & SAMR_FIELD_PROFILE_PATH)
4952
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4953
/* USER_ALL_ADMINCOMMENT */
4954
if (fields & SAMR_FIELD_COMMENT)
4955
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4956
/* USER_ALL_WORKSTATIONS */
4957
if (fields & SAMR_FIELD_WORKSTATIONS)
4958
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4959
/* USER_ALL_LOGONHOURS */
4960
if (fields & SAMR_FIELD_LOGON_HOURS)
4961
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4962
/* USER_ALL_ACCOUNTEXPIRES */
4963
if (fields & SAMR_FIELD_ACCT_EXPIRY)
4964
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4965
/* USER_ALL_USERACCOUNTCONTROL */
4966
if (fields & SAMR_FIELD_ACCT_FLAGS)
4967
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4968
/* USER_ALL_PARAMETERS */
4969
if (fields & SAMR_FIELD_PARAMETERS)
4970
acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4971
/* USER_ALL_USERCOMMENT */
4972
if (fields & SAMR_FIELD_COMMENT)
4973
acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4974
/* USER_ALL_COUNTRYCODE */
4975
if (fields & SAMR_FIELD_COUNTRY_CODE)
4976
acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4977
/* USER_ALL_CODEPAGE */
4978
if (fields & SAMR_FIELD_CODE_PAGE)
4979
acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4980
/* USER_ALL_NTPASSWORDPRESENT */
4981
if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
4982
acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4983
/* USER_ALL_LMPASSWORDPRESENT */
4984
if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
4985
acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4986
/* USER_ALL_PASSWORDEXPIRED */
4987
if (fields & SAMR_FIELD_EXPIRED_FLAG)
4988
acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4990
return acc_required;
4993
/*******************************************************************
4995
********************************************************************/
4997
NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
4998
struct samr_SetUserInfo *r)
5000
struct samr_user_info *uinfo;
5002
struct samu *pwd = NULL;
5003
union samr_UserInfo *info = r->in.info;
5004
uint32_t acc_required = 0;
5005
uint32_t fields = 0;
5008
DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
5010
/* This is tricky. A WinXP domain join sets
5011
(SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5012
The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
5013
standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5014
This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
5015
we'll use the set from the WinXP join as the basis. */
5017
switch (r->in.level) {
5018
case 2: /* UserPreferencesInformation */
5019
/* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5020
acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5022
case 4: /* UserLogonHoursInformation */
5023
case 6: /* UserNameInformation */
5024
case 7: /* UserAccountNameInformation */
5025
case 8: /* UserFullNameInformation */
5026
case 9: /* UserPrimaryGroupInformation */
5027
case 10: /* UserHomeInformation */
5028
case 11: /* UserScriptInformation */
5029
case 12: /* UserProfileInformation */
5030
case 13: /* UserAdminCommentInformation */
5031
case 14: /* UserWorkStationsInformation */
5032
case 16: /* UserControlInformation */
5033
case 17: /* UserExpiresInformation */
5034
case 20: /* UserParametersInformation */
5035
/* USER_WRITE_ACCOUNT */
5036
acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5038
case 18: /* UserInternal1Information */
5039
/* FIXME: gd, this is a guess */
5040
acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5042
case 21: /* UserAllInformation */
5043
fields = info->info21.fields_present;
5044
acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5046
case 23: /* UserInternal4Information */
5047
fields = info->info23.info.fields_present;
5048
acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5050
case 25: /* UserInternal4InformationNew */
5051
fields = info->info25.info.fields_present;
5052
acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5054
case 24: /* UserInternal5Information */
5055
case 26: /* UserInternal5InformationNew */
5056
acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5059
return NT_STATUS_INVALID_INFO_CLASS;
5062
uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5063
struct samr_user_info, &status);
5064
if (!NT_STATUS_IS_OK(status)) {
5068
DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5069
sid_string_dbg(&uinfo->sid), r->in.level));
5072
DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5073
return NT_STATUS_INVALID_INFO_CLASS;
5076
if (!(pwd = samu_new(NULL))) {
5077
return NT_STATUS_NO_MEMORY;
5081
ret = pdb_getsampwsid(pwd, &uinfo->sid);
5086
return NT_STATUS_NO_SUCH_USER;
5089
/* ================ BEGIN Privilege BLOCK ================ */
5093
/* ok! user info levels (lots: see MSDEV help), off we go... */
5095
switch (r->in.level) {
5098
status = set_user_info_2(p->mem_ctx,
5103
status = set_user_info_4(p->mem_ctx,
5108
status = set_user_info_6(p->mem_ctx,
5113
status = set_user_info_7(p->mem_ctx,
5118
status = set_user_info_8(p->mem_ctx,
5123
status = set_user_info_10(p->mem_ctx,
5124
&info->info10, pwd);
5128
status = set_user_info_11(p->mem_ctx,
5129
&info->info11, pwd);
5133
status = set_user_info_12(p->mem_ctx,
5134
&info->info12, pwd);
5138
status = set_user_info_13(p->mem_ctx,
5139
&info->info13, pwd);
5143
status = set_user_info_14(p->mem_ctx,
5144
&info->info14, pwd);
5148
status = set_user_info_16(p->mem_ctx,
5149
&info->info16, pwd);
5153
status = set_user_info_17(p->mem_ctx,
5154
&info->info17, pwd);
5158
/* Used by AS/U JRA. */
5159
status = set_user_info_18(&info->info18,
5161
&p->session_info->user_session_key,
5166
status = set_user_info_20(p->mem_ctx,
5167
&info->info20, pwd);
5171
status = set_user_info_21(&info->info21,
5173
&p->session_info->user_session_key,
5178
if (!p->session_info->user_session_key.length) {
5179
status = NT_STATUS_NO_USER_SESSION_KEY;
5181
arcfour_crypt_blob(info->info23.password.data, 516,
5182
&p->session_info->user_session_key);
5184
dump_data(100, info->info23.password.data, 516);
5186
status = set_user_info_23(p->mem_ctx,
5193
if (!p->session_info->user_session_key.length) {
5194
status = NT_STATUS_NO_USER_SESSION_KEY;
5196
arcfour_crypt_blob(info->info24.password.data,
5198
&p->session_info->user_session_key);
5200
dump_data(100, info->info24.password.data, 516);
5202
status = set_user_info_24(p->mem_ctx,
5204
&info->info24, pwd);
5208
if (!p->session_info->user_session_key.length) {
5209
status = NT_STATUS_NO_USER_SESSION_KEY;
5211
encode_or_decode_arc4_passwd_buffer(
5212
info->info25.password.data,
5213
&p->session_info->user_session_key);
5215
dump_data(100, info->info25.password.data, 532);
5217
status = set_user_info_25(p->mem_ctx,
5219
&info->info25, pwd);
5223
if (!p->session_info->user_session_key.length) {
5224
status = NT_STATUS_NO_USER_SESSION_KEY;
5226
encode_or_decode_arc4_passwd_buffer(
5227
info->info26.password.data,
5228
&p->session_info->user_session_key);
5230
dump_data(100, info->info26.password.data, 516);
5232
status = set_user_info_26(p->mem_ctx,
5234
&info->info26, pwd);
5238
status = NT_STATUS_INVALID_INFO_CLASS;
5245
/* ================ END Privilege BLOCK ================ */
5247
if (NT_STATUS_IS_OK(status)) {
5248
force_flush_samr_cache(&uinfo->sid);
5254
/*******************************************************************
5256
********************************************************************/
5258
NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
5259
struct samr_SetUserInfo2 *r)
5261
struct samr_SetUserInfo q;
5263
q.in.user_handle = r->in.user_handle;
5264
q.in.level = r->in.level;
5265
q.in.info = r->in.info;
5267
return _samr_SetUserInfo(p, &q);
5270
/*********************************************************************
5271
_samr_GetAliasMembership
5272
*********************************************************************/
5274
NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
5275
struct samr_GetAliasMembership *r)
5277
size_t num_alias_rids;
5279
struct samr_domain_info *dinfo;
5284
struct dom_sid *members;
5286
DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5288
dinfo = policy_handle_find(p, r->in.domain_handle,
5289
SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5290
| SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5291
struct samr_domain_info, &status);
5292
if (!NT_STATUS_IS_OK(status)) {
5296
if (!sid_check_is_domain(&dinfo->sid) &&
5297
!sid_check_is_builtin(&dinfo->sid))
5298
return NT_STATUS_OBJECT_TYPE_MISMATCH;
5300
if (r->in.sids->num_sids) {
5301
members = TALLOC_ARRAY(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
5303
if (members == NULL)
5304
return NT_STATUS_NO_MEMORY;
5309
for (i=0; i<r->in.sids->num_sids; i++)
5310
sid_copy(&members[i], r->in.sids->sids[i].sid);
5316
status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5317
r->in.sids->num_sids,
5318
&alias_rids, &num_alias_rids);
5321
if (!NT_STATUS_IS_OK(status)) {
5325
r->out.rids->count = num_alias_rids;
5326
r->out.rids->ids = alias_rids;
5328
if (r->out.rids->ids == NULL) {
5329
/* Windows domain clients don't accept a NULL ptr here */
5330
r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5332
if (r->out.rids->ids == NULL) {
5333
return NT_STATUS_NO_MEMORY;
5336
return NT_STATUS_OK;
5339
/*********************************************************************
5340
_samr_GetMembersInAlias
5341
*********************************************************************/
5343
NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
5344
struct samr_GetMembersInAlias *r)
5346
struct samr_alias_info *ainfo;
5349
size_t num_sids = 0;
5350
struct lsa_SidPtr *sids = NULL;
5351
struct dom_sid *pdb_sids = NULL;
5353
ainfo = policy_handle_find(p, r->in.alias_handle,
5354
SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5355
struct samr_alias_info, &status);
5356
if (!NT_STATUS_IS_OK(status)) {
5360
DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5363
status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5367
if (!NT_STATUS_IS_OK(status)) {
5372
sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5374
TALLOC_FREE(pdb_sids);
5375
return NT_STATUS_NO_MEMORY;
5379
for (i = 0; i < num_sids; i++) {
5380
sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
5382
TALLOC_FREE(pdb_sids);
5383
return NT_STATUS_NO_MEMORY;
5387
r->out.sids->num_sids = num_sids;
5388
r->out.sids->sids = sids;
5390
TALLOC_FREE(pdb_sids);
5392
return NT_STATUS_OK;
5395
/*********************************************************************
5396
_samr_QueryGroupMember
5397
*********************************************************************/
5399
NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
5400
struct samr_QueryGroupMember *r)
5402
struct samr_group_info *ginfo;
5403
size_t i, num_members;
5409
struct samr_RidAttrArray *rids = NULL;
5411
ginfo = policy_handle_find(p, r->in.group_handle,
5412
SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5413
struct samr_group_info, &status);
5414
if (!NT_STATUS_IS_OK(status)) {
5418
rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidAttrArray);
5420
return NT_STATUS_NO_MEMORY;
5423
DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5425
if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5426
DEBUG(3, ("sid %s is not in our domain\n",
5427
sid_string_dbg(&ginfo->sid)));
5428
return NT_STATUS_NO_SUCH_GROUP;
5431
DEBUG(10, ("lookup on Domain SID\n"));
5434
status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5435
&rid, &num_members);
5438
if (!NT_STATUS_IS_OK(status))
5442
attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5444
return NT_STATUS_NO_MEMORY;
5450
for (i=0; i<num_members; i++) {
5451
attr[i] = SE_GROUP_MANDATORY |
5452
SE_GROUP_ENABLED_BY_DEFAULT |
5456
rids->count = num_members;
5457
rids->attributes = attr;
5460
*r->out.rids = rids;
5462
return NT_STATUS_OK;
5465
/*********************************************************************
5466
_samr_AddAliasMember
5467
*********************************************************************/
5469
NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
5470
struct samr_AddAliasMember *r)
5472
struct samr_alias_info *ainfo;
5475
ainfo = policy_handle_find(p, r->in.alias_handle,
5476
SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5477
struct samr_alias_info, &status);
5478
if (!NT_STATUS_IS_OK(status)) {
5482
DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5484
/******** BEGIN SeAddUsers BLOCK *********/
5487
status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5490
/******** END SeAddUsers BLOCK *********/
5492
if (NT_STATUS_IS_OK(status)) {
5493
force_flush_samr_cache(&ainfo->sid);
5499
/*********************************************************************
5500
_samr_DeleteAliasMember
5501
*********************************************************************/
5503
NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
5504
struct samr_DeleteAliasMember *r)
5506
struct samr_alias_info *ainfo;
5509
ainfo = policy_handle_find(p, r->in.alias_handle,
5510
SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5511
struct samr_alias_info, &status);
5512
if (!NT_STATUS_IS_OK(status)) {
5516
DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5517
sid_string_dbg(&ainfo->sid)));
5519
/******** BEGIN SeAddUsers BLOCK *********/
5522
status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5525
/******** END SeAddUsers BLOCK *********/
5527
if (NT_STATUS_IS_OK(status)) {
5528
force_flush_samr_cache(&ainfo->sid);
5534
/*********************************************************************
5535
_samr_AddGroupMember
5536
*********************************************************************/
5538
NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
5539
struct samr_AddGroupMember *r)
5541
struct samr_group_info *ginfo;
5545
ginfo = policy_handle_find(p, r->in.group_handle,
5546
SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5547
struct samr_group_info, &status);
5548
if (!NT_STATUS_IS_OK(status)) {
5552
DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5554
if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5556
return NT_STATUS_INVALID_HANDLE;
5559
/******** BEGIN SeAddUsers BLOCK *********/
5562
status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5565
/******** END SeAddUsers BLOCK *********/
5567
force_flush_samr_cache(&ginfo->sid);
5572
/*********************************************************************
5573
_samr_DeleteGroupMember
5574
*********************************************************************/
5576
NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
5577
struct samr_DeleteGroupMember *r)
5580
struct samr_group_info *ginfo;
5585
* delete the group member named r->in.rid
5586
* who is a member of the sid associated with the handle
5587
* the rid is a user's rid as the group is a domain group.
5590
ginfo = policy_handle_find(p, r->in.group_handle,
5591
SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5592
struct samr_group_info, &status);
5593
if (!NT_STATUS_IS_OK(status)) {
5597
if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5599
return NT_STATUS_INVALID_HANDLE;
5602
/******** BEGIN SeAddUsers BLOCK *********/
5605
status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5608
/******** END SeAddUsers BLOCK *********/
5610
force_flush_samr_cache(&ginfo->sid);
5615
/*********************************************************************
5617
*********************************************************************/
5619
NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
5620
struct samr_DeleteUser *r)
5622
struct samr_user_info *uinfo;
5624
struct samu *sam_pass=NULL;
5627
DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5629
uinfo = policy_handle_find(p, r->in.user_handle,
5630
SEC_STD_DELETE, NULL,
5631
struct samr_user_info, &status);
5632
if (!NT_STATUS_IS_OK(status)) {
5636
if (!sid_check_is_in_our_domain(&uinfo->sid))
5637
return NT_STATUS_CANNOT_DELETE;
5639
/* check if the user exists before trying to delete */
5640
if ( !(sam_pass = samu_new( NULL )) ) {
5641
return NT_STATUS_NO_MEMORY;
5645
ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5649
DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5650
sid_string_dbg(&uinfo->sid)));
5651
TALLOC_FREE(sam_pass);
5652
return NT_STATUS_NO_SUCH_USER;
5655
/******** BEGIN SeAddUsers BLOCK *********/
5658
status = pdb_delete_user(p->mem_ctx, sam_pass);
5661
/******** END SeAddUsers BLOCK *********/
5663
if ( !NT_STATUS_IS_OK(status) ) {
5664
DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5665
"user %s: %s.\n", pdb_get_username(sam_pass),
5666
nt_errstr(status)));
5667
TALLOC_FREE(sam_pass);
5672
TALLOC_FREE(sam_pass);
5674
force_flush_samr_cache(&uinfo->sid);
5676
if (!close_policy_hnd(p, r->in.user_handle))
5677
return NT_STATUS_OBJECT_NAME_INVALID;
5679
ZERO_STRUCTP(r->out.user_handle);
5681
return NT_STATUS_OK;
5684
/*********************************************************************
5685
_samr_DeleteDomainGroup
5686
*********************************************************************/
5688
NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
5689
struct samr_DeleteDomainGroup *r)
5691
struct samr_group_info *ginfo;
5695
DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5697
ginfo = policy_handle_find(p, r->in.group_handle,
5698
SEC_STD_DELETE, NULL,
5699
struct samr_group_info, &status);
5700
if (!NT_STATUS_IS_OK(status)) {
5704
DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5706
if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5708
return NT_STATUS_NO_SUCH_GROUP;
5711
/******** BEGIN SeAddUsers BLOCK *********/
5714
status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5717
/******** END SeAddUsers BLOCK *********/
5719
if ( !NT_STATUS_IS_OK(status) ) {
5720
DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5721
"entry for group %s: %s\n",
5722
sid_string_dbg(&ginfo->sid),
5723
nt_errstr(status)));
5727
force_flush_samr_cache(&ginfo->sid);
5729
if (!close_policy_hnd(p, r->in.group_handle))
5730
return NT_STATUS_OBJECT_NAME_INVALID;
5732
return NT_STATUS_OK;
5735
/*********************************************************************
5736
_samr_DeleteDomAlias
5737
*********************************************************************/
5739
NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
5740
struct samr_DeleteDomAlias *r)
5742
struct samr_alias_info *ainfo;
5745
DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5747
ainfo = policy_handle_find(p, r->in.alias_handle,
5748
SEC_STD_DELETE, NULL,
5749
struct samr_alias_info, &status);
5750
if (!NT_STATUS_IS_OK(status)) {
5754
DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5756
/* Don't let Windows delete builtin groups */
5758
if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5759
return NT_STATUS_SPECIAL_ACCOUNT;
5762
if (!sid_check_is_in_our_domain(&ainfo->sid))
5763
return NT_STATUS_NO_SUCH_ALIAS;
5765
DEBUG(10, ("lookup on Local SID\n"));
5767
/******** BEGIN SeAddUsers BLOCK *********/
5770
/* Have passdb delete the alias */
5771
status = pdb_delete_alias(&ainfo->sid);
5774
/******** END SeAddUsers BLOCK *********/
5776
if ( !NT_STATUS_IS_OK(status))
5779
force_flush_samr_cache(&ainfo->sid);
5781
if (!close_policy_hnd(p, r->in.alias_handle))
5782
return NT_STATUS_OBJECT_NAME_INVALID;
5784
return NT_STATUS_OK;
5787
/*********************************************************************
5788
_samr_CreateDomainGroup
5789
*********************************************************************/
5791
NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
5792
struct samr_CreateDomainGroup *r)
5797
struct samr_domain_info *dinfo;
5798
struct samr_group_info *ginfo;
5800
dinfo = policy_handle_find(p, r->in.domain_handle,
5801
SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5802
struct samr_domain_info, &status);
5803
if (!NT_STATUS_IS_OK(status)) {
5807
if (!sid_check_is_domain(&dinfo->sid)) {
5808
return NT_STATUS_ACCESS_DENIED;
5811
name = r->in.name->string;
5813
return NT_STATUS_NO_MEMORY;
5816
status = can_create(p->mem_ctx, name);
5817
if (!NT_STATUS_IS_OK(status)) {
5821
/******** BEGIN SeAddUsers BLOCK *********/
5824
/* check that we successfully create the UNIX group */
5825
status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5828
/******** END SeAddUsers BLOCK *********/
5830
/* check if we should bail out here */
5832
if ( !NT_STATUS_IS_OK(status) )
5835
ginfo = policy_handle_create(p, r->out.group_handle,
5836
GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5837
struct samr_group_info, &status);
5838
if (!NT_STATUS_IS_OK(status)) {
5841
sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5843
force_flush_samr_cache(&dinfo->sid);
5845
return NT_STATUS_OK;
5848
/*********************************************************************
5849
_samr_CreateDomAlias
5850
*********************************************************************/
5852
NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
5853
struct samr_CreateDomAlias *r)
5855
struct dom_sid info_sid;
5856
const char *name = NULL;
5857
struct samr_domain_info *dinfo;
5858
struct samr_alias_info *ainfo;
5862
dinfo = policy_handle_find(p, r->in.domain_handle,
5863
SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5864
struct samr_domain_info, &result);
5865
if (!NT_STATUS_IS_OK(result)) {
5869
if (!sid_check_is_domain(&dinfo->sid)) {
5870
return NT_STATUS_ACCESS_DENIED;
5873
name = r->in.alias_name->string;
5875
result = can_create(p->mem_ctx, name);
5876
if (!NT_STATUS_IS_OK(result)) {
5880
/******** BEGIN SeAddUsers BLOCK *********/
5883
/* Have passdb create the alias */
5884
result = pdb_create_alias(name, r->out.rid);
5887
/******** END SeAddUsers BLOCK *********/
5889
if (!NT_STATUS_IS_OK(result)) {
5890
DEBUG(10, ("pdb_create_alias failed: %s\n",
5891
nt_errstr(result)));
5895
sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5897
if (!sid_to_gid(&info_sid, &gid)) {
5898
DEBUG(10, ("Could not find alias just created\n"));
5899
return NT_STATUS_ACCESS_DENIED;
5902
/* check if the group has been successfully created */
5903
if ( getgrgid(gid) == NULL ) {
5904
DEBUG(1, ("getgrgid(%u) of just created alias failed\n",
5905
(unsigned int)gid));
5906
return NT_STATUS_ACCESS_DENIED;
5909
ainfo = policy_handle_create(p, r->out.alias_handle,
5910
GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5911
struct samr_alias_info, &result);
5912
if (!NT_STATUS_IS_OK(result)) {
5915
ainfo->sid = info_sid;
5917
force_flush_samr_cache(&info_sid);
5919
return NT_STATUS_OK;
5922
/*********************************************************************
5923
_samr_QueryGroupInfo
5924
*********************************************************************/
5926
NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
5927
struct samr_QueryGroupInfo *r)
5929
struct samr_group_info *ginfo;
5932
union samr_GroupInfo *info = NULL;
5934
uint32_t attributes = SE_GROUP_MANDATORY |
5935
SE_GROUP_ENABLED_BY_DEFAULT |
5937
const char *group_name = NULL;
5938
const char *group_description = NULL;
5940
ginfo = policy_handle_find(p, r->in.group_handle,
5941
SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5942
struct samr_group_info, &status);
5943
if (!NT_STATUS_IS_OK(status)) {
5948
ret = get_domain_group_from_sid(ginfo->sid, &map);
5951
return NT_STATUS_INVALID_HANDLE;
5953
/* FIXME: map contains fstrings */
5954
group_name = talloc_strdup(r, map.nt_name);
5955
group_description = talloc_strdup(r, map.comment);
5957
info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5959
return NT_STATUS_NO_MEMORY;
5962
switch (r->in.level) {
5968
status = pdb_enum_group_members(
5969
p->mem_ctx, &ginfo->sid, &members,
5973
if (!NT_STATUS_IS_OK(status)) {
5977
info->all.name.string = group_name;
5978
info->all.attributes = attributes;
5979
info->all.num_members = num_members;
5980
info->all.description.string = group_description;
5984
info->name.string = group_name;
5987
info->attributes.attributes = attributes;
5990
info->description.string = group_description;
6000
status = pdb_enum_group_members(
6001
p->mem_ctx, &ginfo->sid, &members,
6005
if (!NT_STATUS_IS_OK(status)) {
6009
info->all2.name.string = group_name;
6010
info->all2.attributes = attributes;
6011
info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
6012
info->all2.description.string = group_description;
6017
return NT_STATUS_INVALID_INFO_CLASS;
6020
*r->out.info = info;
6022
return NT_STATUS_OK;
6025
/*********************************************************************
6027
*********************************************************************/
6029
NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
6030
struct samr_SetGroupInfo *r)
6032
struct samr_group_info *ginfo;
6037
ginfo = policy_handle_find(p, r->in.group_handle,
6038
SAMR_GROUP_ACCESS_SET_INFO, NULL,
6039
struct samr_group_info, &status);
6040
if (!NT_STATUS_IS_OK(status)) {
6045
ret = get_domain_group_from_sid(ginfo->sid, &map);
6048
return NT_STATUS_NO_SUCH_GROUP;
6050
switch (r->in.level) {
6052
fstrcpy(map.nt_name, r->in.info->name.string);
6057
fstrcpy(map.comment, r->in.info->description.string);
6060
return NT_STATUS_INVALID_INFO_CLASS;
6063
/******** BEGIN SeAddUsers BLOCK *********/
6066
status = pdb_update_group_mapping_entry(&map);
6069
/******** End SeAddUsers BLOCK *********/
6071
if (NT_STATUS_IS_OK(status)) {
6072
force_flush_samr_cache(&ginfo->sid);
6078
/*********************************************************************
6080
*********************************************************************/
6082
NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
6083
struct samr_SetAliasInfo *r)
6085
struct samr_alias_info *ainfo;
6086
struct acct_info info;
6089
ainfo = policy_handle_find(p, r->in.alias_handle,
6090
SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6091
struct samr_alias_info, &status);
6092
if (!NT_STATUS_IS_OK(status)) {
6096
/* get the current group information */
6099
status = pdb_get_aliasinfo( &ainfo->sid, &info );
6102
if ( !NT_STATUS_IS_OK(status))
6105
switch (r->in.level) {
6110
/* We currently do not support renaming groups in the
6111
the BUILTIN domain. Refer to util_builtin.c to understand
6112
why. The eventually needs to be fixed to be like Windows
6113
where you can rename builtin groups, just not delete them */
6115
if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6116
return NT_STATUS_SPECIAL_ACCOUNT;
6119
/* There has to be a valid name (and it has to be different) */
6121
if ( !r->in.info->name.string )
6122
return NT_STATUS_INVALID_PARAMETER;
6124
/* If the name is the same just reply "ok". Yes this
6125
doesn't allow you to change the case of a group name. */
6127
if ( strequal( r->in.info->name.string, info.acct_name ) )
6128
return NT_STATUS_OK;
6130
fstrcpy( info.acct_name, r->in.info->name.string);
6132
/* make sure the name doesn't already exist as a user
6135
fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6136
status = can_create( p->mem_ctx, group_name );
6137
if ( !NT_STATUS_IS_OK( status ) )
6141
case ALIASINFODESCRIPTION:
6142
if (r->in.info->description.string) {
6143
fstrcpy(info.acct_desc,
6144
r->in.info->description.string);
6146
fstrcpy( info.acct_desc, "" );
6150
return NT_STATUS_INVALID_INFO_CLASS;
6153
/******** BEGIN SeAddUsers BLOCK *********/
6156
status = pdb_set_aliasinfo( &ainfo->sid, &info );
6159
/******** End SeAddUsers BLOCK *********/
6161
if (NT_STATUS_IS_OK(status))
6162
force_flush_samr_cache(&ainfo->sid);
6167
/****************************************************************
6169
****************************************************************/
6171
NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
6172
struct samr_GetDomPwInfo *r)
6174
uint32_t min_password_length = 0;
6175
uint32_t password_properties = 0;
6177
/* Perform access check. Since this rpc does not require a
6178
policy handle it will not be caught by the access checks on
6179
SAMR_CONNECT or SAMR_CONNECT_ANON. */
6181
if (!pipe_access_check(p)) {
6182
DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6183
return NT_STATUS_ACCESS_DENIED;
6187
pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6188
&min_password_length);
6189
pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6190
&password_properties);
6193
if (lp_check_password_script() && *lp_check_password_script()) {
6194
password_properties |= DOMAIN_PASSWORD_COMPLEX;
6197
r->out.info->min_password_length = min_password_length;
6198
r->out.info->password_properties = password_properties;
6200
return NT_STATUS_OK;
6203
/*********************************************************************
6205
*********************************************************************/
6207
NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
6208
struct samr_OpenGroup *r)
6211
struct dom_sid info_sid;
6213
struct samr_domain_info *dinfo;
6214
struct samr_group_info *ginfo;
6215
struct security_descriptor *psd = NULL;
6217
uint32 des_access = r->in.access_mask;
6222
dinfo = policy_handle_find(p, r->in.domain_handle,
6223
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6224
struct samr_domain_info, &status);
6225
if (!NT_STATUS_IS_OK(status)) {
6229
/*check if access can be granted as requested by client. */
6230
map_max_allowed_access(p->session_info->security_token,
6231
&p->session_info->utok,
6234
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6235
se_map_generic(&des_access,&grp_generic_mapping);
6237
status = access_check_object(psd, p->session_info->security_token,
6238
SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6239
des_access, &acc_granted, "_samr_OpenGroup");
6241
if ( !NT_STATUS_IS_OK(status) )
6244
/* this should not be hard-coded like this */
6246
if (!sid_check_is_domain(&dinfo->sid)) {
6247
return NT_STATUS_ACCESS_DENIED;
6250
sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6252
DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6253
sid_string_dbg(&info_sid)));
6255
/* check if that group really exists */
6257
ret = get_domain_group_from_sid(info_sid, &map);
6260
return NT_STATUS_NO_SUCH_GROUP;
6262
ginfo = policy_handle_create(p, r->out.group_handle,
6264
struct samr_group_info, &status);
6265
if (!NT_STATUS_IS_OK(status)) {
6268
ginfo->sid = info_sid;
6270
return NT_STATUS_OK;
6273
/*********************************************************************
6274
_samr_RemoveMemberFromForeignDomain
6275
*********************************************************************/
6277
NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
6278
struct samr_RemoveMemberFromForeignDomain *r)
6280
struct samr_domain_info *dinfo;
6283
DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6284
sid_string_dbg(r->in.sid)));
6286
/* Find the policy handle. Open a policy on it. */
6288
dinfo = policy_handle_find(p, r->in.domain_handle,
6289
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6290
struct samr_domain_info, &result);
6291
if (!NT_STATUS_IS_OK(result)) {
6295
DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6296
sid_string_dbg(&dinfo->sid)));
6298
/* we can only delete a user from a group since we don't have
6299
nested groups anyways. So in the latter case, just say OK */
6301
/* TODO: The above comment nowadays is bogus. Since we have nested
6302
* groups now, and aliases members are never reported out of the unix
6303
* group membership, the "just say OK" makes this call a no-op. For
6304
* us. This needs fixing however. */
6306
/* I've only ever seen this in the wild when deleting a user from
6307
* usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6308
* is the user about to be deleted. I very much suspect this is the
6309
* only application of this call. To verify this, let people report
6312
if (!sid_check_is_builtin(&dinfo->sid)) {
6313
DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6314
"global_sam_sid() = %s\n",
6315
sid_string_dbg(&dinfo->sid),
6316
sid_string_dbg(get_global_sam_sid())));
6317
DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6318
return NT_STATUS_OK;
6321
force_flush_samr_cache(&dinfo->sid);
6323
result = NT_STATUS_OK;
6328
/*******************************************************************
6329
_samr_QueryDomainInfo2
6330
********************************************************************/
6332
NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
6333
struct samr_QueryDomainInfo2 *r)
6335
struct samr_QueryDomainInfo q;
6337
q.in.domain_handle = r->in.domain_handle;
6338
q.in.level = r->in.level;
6340
q.out.info = r->out.info;
6342
return _samr_QueryDomainInfo(p, &q);
6345
/*******************************************************************
6346
********************************************************************/
6348
static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6349
struct samr_DomInfo1 *r)
6351
time_t u_expire, u_min_age;
6353
u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6354
u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6356
pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6357
(uint32_t)r->min_password_length);
6358
pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6359
(uint32_t)r->password_history_length);
6360
pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6361
(uint32_t)r->password_properties);
6362
pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6363
pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6365
return NT_STATUS_OK;
6368
/*******************************************************************
6369
********************************************************************/
6371
static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6372
struct samr_DomInfo3 *r)
6376
u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6378
pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6380
return NT_STATUS_OK;
6383
/*******************************************************************
6384
********************************************************************/
6386
static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6387
struct samr_DomInfo12 *r)
6389
time_t u_lock_duration, u_reset_time;
6391
u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6392
if (u_lock_duration != -1) {
6393
u_lock_duration /= 60;
6396
u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6398
pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6399
pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6400
pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6401
(uint32_t)r->lockout_threshold);
6403
return NT_STATUS_OK;
6406
/*******************************************************************
6408
********************************************************************/
6410
NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
6411
struct samr_SetDomainInfo *r)
6413
struct samr_domain_info *dinfo;
6415
uint32_t acc_required = 0;
6417
DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6419
switch (r->in.level) {
6420
case 1: /* DomainPasswordInformation */
6421
case 12: /* DomainLockoutInformation */
6422
/* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6423
acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6425
case 3: /* DomainLogoffInformation */
6426
case 4: /* DomainOemInformation */
6427
/* DOMAIN_WRITE_OTHER_PARAMETERS */
6428
acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6430
case 6: /* DomainReplicationInformation */
6431
case 9: /* DomainStateInformation */
6432
case 7: /* DomainServerRoleInformation */
6433
/* DOMAIN_ADMINISTER_SERVER */
6434
acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6437
return NT_STATUS_INVALID_INFO_CLASS;
6440
dinfo = policy_handle_find(p, r->in.domain_handle,
6442
struct samr_domain_info, &status);
6443
if (!NT_STATUS_IS_OK(status)) {
6447
DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6449
switch (r->in.level) {
6451
status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6454
status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6465
status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6468
return NT_STATUS_INVALID_INFO_CLASS;
6471
if (!NT_STATUS_IS_OK(status)) {
6475
DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6477
return NT_STATUS_OK;
6480
/****************************************************************
6481
_samr_GetDisplayEnumerationIndex
6482
****************************************************************/
6484
NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
6485
struct samr_GetDisplayEnumerationIndex *r)
6487
struct samr_domain_info *dinfo;
6488
uint32_t max_entries = (uint32_t) -1;
6489
uint32_t enum_context = 0;
6491
uint32_t num_account = 0;
6492
struct samr_displayentry *entries = NULL;
6495
DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6497
dinfo = policy_handle_find(p, r->in.domain_handle,
6498
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6499
struct samr_domain_info, &status);
6500
if (!NT_STATUS_IS_OK(status)) {
6504
if ((r->in.level < 1) || (r->in.level > 3)) {
6505
DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6506
"Unknown info level (%u)\n",
6508
return NT_STATUS_INVALID_INFO_CLASS;
6513
/* The following done as ROOT. Don't return without unbecome_root(). */
6515
switch (r->in.level) {
6517
if (dinfo->disp_info->users == NULL) {
6518
dinfo->disp_info->users = pdb_search_users(
6519
dinfo->disp_info, ACB_NORMAL);
6520
if (dinfo->disp_info->users == NULL) {
6522
return NT_STATUS_ACCESS_DENIED;
6524
DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6525
"starting user enumeration at index %u\n",
6526
(unsigned int)enum_context));
6528
DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6529
"using cached user enumeration at index %u\n",
6530
(unsigned int)enum_context));
6532
num_account = pdb_search_entries(dinfo->disp_info->users,
6533
enum_context, max_entries,
6537
if (dinfo->disp_info->machines == NULL) {
6538
dinfo->disp_info->machines = pdb_search_users(
6539
dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6540
if (dinfo->disp_info->machines == NULL) {
6542
return NT_STATUS_ACCESS_DENIED;
6544
DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6545
"starting machine enumeration at index %u\n",
6546
(unsigned int)enum_context));
6548
DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6549
"using cached machine enumeration at index %u\n",
6550
(unsigned int)enum_context));
6552
num_account = pdb_search_entries(dinfo->disp_info->machines,
6553
enum_context, max_entries,
6557
if (dinfo->disp_info->groups == NULL) {
6558
dinfo->disp_info->groups = pdb_search_groups(
6560
if (dinfo->disp_info->groups == NULL) {
6562
return NT_STATUS_ACCESS_DENIED;
6564
DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6565
"starting group enumeration at index %u\n",
6566
(unsigned int)enum_context));
6568
DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6569
"using cached group enumeration at index %u\n",
6570
(unsigned int)enum_context));
6572
num_account = pdb_search_entries(dinfo->disp_info->groups,
6573
enum_context, max_entries,
6578
smb_panic("info class changed");
6584
/* Ensure we cache this enumeration. */
6585
set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6587
DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6588
r->in.name->string));
6590
for (i=0; i<num_account; i++) {
6591
if (strequal(entries[i].account_name, r->in.name->string)) {
6592
DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6593
"found %s at idx %d\n",
6594
r->in.name->string, i));
6596
return NT_STATUS_OK;
6600
/* assuming account_name lives at the very end */
6601
*r->out.idx = num_account;
6603
return NT_STATUS_NO_MORE_ENTRIES;
6606
/****************************************************************
6607
_samr_GetDisplayEnumerationIndex2
6608
****************************************************************/
6610
NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
6611
struct samr_GetDisplayEnumerationIndex2 *r)
6613
struct samr_GetDisplayEnumerationIndex q;
6615
q.in.domain_handle = r->in.domain_handle;
6616
q.in.level = r->in.level;
6617
q.in.name = r->in.name;
6619
q.out.idx = r->out.idx;
6621
return _samr_GetDisplayEnumerationIndex(p, &q);
6624
/****************************************************************
6626
****************************************************************/
6628
NTSTATUS _samr_RidToSid(struct pipes_struct *p,
6629
struct samr_RidToSid *r)
6631
struct samr_domain_info *dinfo;
6635
dinfo = policy_handle_find(p, r->in.domain_handle,
6637
struct samr_domain_info, &status);
6638
if (!NT_STATUS_IS_OK(status)) {
6642
if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6643
return NT_STATUS_NO_MEMORY;
6646
*r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
6648
return NT_STATUS_NO_MEMORY;
6651
return NT_STATUS_OK;
6654
/****************************************************************
6655
****************************************************************/
6657
static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
6658
const struct samr_PwInfo *dom_pw_info,
6659
const struct samr_ValidatePasswordReq2 *req,
6660
struct samr_ValidatePasswordRepCtr *rep)
6664
if (req->password.string == NULL) {
6665
return SAMR_VALIDATION_STATUS_SUCCESS;
6667
if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6668
ZERO_STRUCT(rep->info);
6669
return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6671
if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6672
status = check_password_complexity(req->account.string,
6673
req->password.string,
6675
if (!NT_STATUS_IS_OK(status)) {
6676
ZERO_STRUCT(rep->info);
6677
return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6681
return SAMR_VALIDATION_STATUS_SUCCESS;
6684
/****************************************************************
6685
****************************************************************/
6687
static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
6688
const struct samr_PwInfo *dom_pw_info,
6689
const struct samr_ValidatePasswordReq3 *req,
6690
struct samr_ValidatePasswordRepCtr *rep)
6694
if (req->password.string == NULL) {
6695
return SAMR_VALIDATION_STATUS_SUCCESS;
6697
if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6698
ZERO_STRUCT(rep->info);
6699
return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6701
if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6702
status = check_password_complexity(req->account.string,
6703
req->password.string,
6705
if (!NT_STATUS_IS_OK(status)) {
6706
ZERO_STRUCT(rep->info);
6707
return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6711
return SAMR_VALIDATION_STATUS_SUCCESS;
6714
/****************************************************************
6715
_samr_ValidatePassword
6716
****************************************************************/
6718
NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
6719
struct samr_ValidatePassword *r)
6721
union samr_ValidatePasswordRep *rep;
6723
struct samr_GetDomPwInfo pw;
6724
struct samr_PwInfo dom_pw_info;
6726
if (r->in.level < 1 || r->in.level > 3) {
6727
return NT_STATUS_INVALID_INFO_CLASS;
6730
pw.in.domain_name = NULL;
6731
pw.out.info = &dom_pw_info;
6733
status = _samr_GetDomPwInfo(p, &pw);
6734
if (!NT_STATUS_IS_OK(status)) {
6738
rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
6740
return NT_STATUS_NO_MEMORY;
6743
switch (r->in.level) {
6745
status = NT_STATUS_NOT_SUPPORTED;
6748
rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
6754
rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
6760
status = NT_STATUS_INVALID_INFO_CLASS;
6764
if (!NT_STATUS_IS_OK(status)) {
6771
return NT_STATUS_OK;
6774
/****************************************************************
6775
****************************************************************/
6777
NTSTATUS _samr_Shutdown(struct pipes_struct *p,
6778
struct samr_Shutdown *r)
6780
p->rng_fault_state = true;
6781
return NT_STATUS_NOT_IMPLEMENTED;
6784
/****************************************************************
6785
****************************************************************/
6787
NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
6788
struct samr_SetMemberAttributesOfGroup *r)
6790
p->rng_fault_state = true;
6791
return NT_STATUS_NOT_IMPLEMENTED;
6794
/****************************************************************
6795
****************************************************************/
6797
NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
6798
struct samr_TestPrivateFunctionsDomain *r)
6800
return NT_STATUS_NOT_IMPLEMENTED;
6803
/****************************************************************
6804
****************************************************************/
6806
NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
6807
struct samr_TestPrivateFunctionsUser *r)
6809
return NT_STATUS_NOT_IMPLEMENTED;
6812
/****************************************************************
6813
****************************************************************/
6815
NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
6816
struct samr_AddMultipleMembersToAlias *r)
6818
p->rng_fault_state = true;
6819
return NT_STATUS_NOT_IMPLEMENTED;
6822
/****************************************************************
6823
****************************************************************/
6825
NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
6826
struct samr_RemoveMultipleMembersFromAlias *r)
6828
p->rng_fault_state = true;
6829
return NT_STATUS_NOT_IMPLEMENTED;
6832
/****************************************************************
6833
****************************************************************/
6835
NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
6836
struct samr_SetBootKeyInformation *r)
6838
p->rng_fault_state = true;
6839
return NT_STATUS_NOT_IMPLEMENTED;
6842
/****************************************************************
6843
****************************************************************/
6845
NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
6846
struct samr_GetBootKeyInformation *r)
6848
p->rng_fault_state = true;
6849
return NT_STATUS_NOT_IMPLEMENTED;
6852
/****************************************************************
6853
****************************************************************/
6855
NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
6856
struct samr_SetDsrmPassword *r)
6858
p->rng_fault_state = true;
6859
return NT_STATUS_NOT_IMPLEMENTED;