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-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Anthony Liguori 2002,
11 * Copyright (C) Jim McDonough 2002.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin
;
39 extern rid_name domain_group_rids
[];
40 extern rid_name domain_alias_rids
[];
41 extern rid_name builtin_alias_rids
[];
44 typedef struct _disp_info
{
46 uint32 num_user_account
;
47 DISP_USER_INFO
*disp_user_info
;
49 uint32 num_group_account
;
50 DISP_GROUP_INFO
*disp_group_info
;
54 /* for use by the \PIPE\samr policy */
56 uint32 status
; /* some sort of flag. best to record it. comes from opnum 0x39 */
65 struct generic_mapping sam_generic_mapping
= {GENERIC_RIGHTS_SAM_READ
, GENERIC_RIGHTS_SAM_WRITE
, GENERIC_RIGHTS_SAM_EXECUTE
, GENERIC_RIGHTS_SAM_ALL_ACCESS
};
66 struct generic_mapping dom_generic_mapping
= {GENERIC_RIGHTS_DOMAIN_READ
, GENERIC_RIGHTS_DOMAIN_WRITE
, GENERIC_RIGHTS_DOMAIN_EXECUTE
, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS
};
67 struct generic_mapping usr_generic_mapping
= {GENERIC_RIGHTS_USER_READ
, GENERIC_RIGHTS_USER_WRITE
, GENERIC_RIGHTS_USER_EXECUTE
, GENERIC_RIGHTS_USER_ALL_ACCESS
};
68 struct generic_mapping grp_generic_mapping
= {GENERIC_RIGHTS_GROUP_READ
, GENERIC_RIGHTS_GROUP_WRITE
, GENERIC_RIGHTS_GROUP_EXECUTE
, GENERIC_RIGHTS_GROUP_ALL_ACCESS
};
69 struct generic_mapping ali_generic_mapping
= {GENERIC_RIGHTS_ALIAS_READ
, GENERIC_RIGHTS_ALIAS_WRITE
, GENERIC_RIGHTS_ALIAS_EXECUTE
, GENERIC_RIGHTS_ALIAS_ALL_ACCESS
};
71 static NTSTATUS
samr_make_dom_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 NTSTATUS
access_check_samr_object(SEC_DESC
*psd
, NT_USER_TOKEN
*nt_user_token
, uint32 des_access
,
79 uint32
*acc_granted
, const char *debug
)
81 NTSTATUS status
= NT_STATUS_ACCESS_DENIED
;
83 if (!se_access_check(psd
, nt_user_token
, des_access
, acc_granted
, &status
)) {
84 *acc_granted
= des_access
;
85 if (geteuid() == sec_initial_uid()) {
86 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
88 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89 status
= NT_STATUS_OK
;
92 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
99 /*******************************************************************
100 Checks if access to a function can be granted
101 ********************************************************************/
103 NTSTATUS
access_check_samr_function(uint32 acc_granted
, uint32 acc_required
, const char *debug
)
105 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
106 debug
, acc_granted
, acc_required
));
107 if ((acc_granted
& acc_required
) != acc_required
) {
108 if (geteuid() == sec_initial_uid()) {
109 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
110 debug
, acc_granted
, acc_required
));
111 DEBUGADD(4,("but overwritten by euid == 0\n"));
114 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
115 debug
, acc_granted
, acc_required
));
116 return NT_STATUS_ACCESS_DENIED
;
122 /*******************************************************************
123 Create a samr_info struct.
124 ********************************************************************/
126 static struct samr_info
*get_samr_info_by_sid(DOM_SID
*psid
)
128 struct samr_info
*info
;
133 sid_to_string(sid_str
, psid
);
135 fstrcpy(sid_str
,"(NULL)");
138 mem_ctx
= talloc_init("samr_info for domain sid %s", sid_str
);
140 if ((info
= (struct samr_info
*)talloc(mem_ctx
, sizeof(struct samr_info
))) == NULL
)
144 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str
));
146 sid_copy( &info
->sid
, psid
);
148 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
150 info
->mem_ctx
= mem_ctx
;
155 /*******************************************************************
156 Function to free the per handle data.
157 ********************************************************************/
158 static void free_samr_users(struct samr_info
*info
)
162 if (info
->disp_info
.user_dbloaded
){
163 for (i
=0; i
<info
->disp_info
.num_user_account
; i
++) {
164 /* Not really a free, actually a 'clear' */
165 pdb_free_sam(&info
->disp_info
.disp_user_info
[i
].sam
);
168 info
->disp_info
.user_dbloaded
=False
;
169 info
->disp_info
.num_user_account
=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
176 static void free_samr_db(struct samr_info
*info
)
178 /* Groups are talloced */
180 free_samr_users(info
);
182 info
->disp_info
.group_dbloaded
=False
;
183 info
->disp_info
.num_group_account
=0;
187 static void free_samr_info(void *ptr
)
189 struct samr_info
*info
=(struct samr_info
*) ptr
;
192 talloc_destroy(info
->mem_ctx
);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT
*sam_pass
)
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
208 pdb_set_nt_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
212 static NTSTATUS
load_sampwd_entries(struct samr_info
*info
, uint16 acb_mask
, BOOL all_machines
)
214 SAM_ACCOUNT
*pwd
= NULL
;
215 DISP_USER_INFO
*pwd_array
= NULL
;
216 NTSTATUS nt_status
= NT_STATUS_OK
;
217 TALLOC_CTX
*mem_ctx
= info
->mem_ctx
;
219 DEBUG(10,("load_sampwd_entries\n"));
221 /* if the snapshoot is already loaded, return */
222 if ((info
->disp_info
.user_dbloaded
==True
)
223 && (info
->acb_mask
== acb_mask
)
224 && (info
->all_machines
== all_machines
)) {
225 DEBUG(10,("load_sampwd_entries: already in memory\n"));
229 free_samr_users(info
);
231 if (!pdb_setsampwent(False
)) {
232 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233 return NT_STATUS_ACCESS_DENIED
;
236 for (; (NT_STATUS_IS_OK(nt_status
= pdb_init_sam_talloc(mem_ctx
, &pwd
)))
237 && pdb_getsampwent(pwd
) == True
; pwd
=NULL
) {
240 if (!((pdb_get_acct_ctrl(pwd
) & ACB_WSTRUST
)
241 || (pdb_get_acct_ctrl(pwd
) & ACB_SVRTRUST
))) {
242 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd
), acb_mask
));
247 if (acb_mask
!= 0 && !(pdb_get_acct_ctrl(pwd
) & acb_mask
)) {
249 DEBUG(5,(" acb_mask %x reject\n", acb_mask
));
254 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255 if (info
->disp_info
.num_user_account
% MAX_SAM_ENTRIES
== 0) {
257 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258 pwd_array
=(DISP_USER_INFO
*)talloc_realloc(mem_ctx
, info
->disp_info
.disp_user_info
,
259 (info
->disp_info
.num_user_account
+MAX_SAM_ENTRIES
)*sizeof(DISP_USER_INFO
));
262 return NT_STATUS_NO_MEMORY
;
264 info
->disp_info
.disp_user_info
=pwd_array
;
267 /* link the SAM_ACCOUNT to the array */
268 info
->disp_info
.disp_user_info
[info
->disp_info
.num_user_account
].sam
=pwd
;
270 DEBUG(10,("load_sampwd_entries: entry: %d\n", info
->disp_info
.num_user_account
));
272 info
->disp_info
.num_user_account
++;
277 /* the snapshoot is in memory, we're ready to enumerate fast */
279 info
->acb_mask
= acb_mask
;
280 info
->all_machines
= all_machines
;
281 info
->disp_info
.user_dbloaded
=True
;
283 DEBUG(10,("load_sampwd_entries: done\n"));
288 static NTSTATUS
load_group_domain_entries(struct samr_info
*info
, DOM_SID
*sid
)
291 DISP_GROUP_INFO
*grp_array
= NULL
;
292 uint32 group_entries
= 0;
294 TALLOC_CTX
*mem_ctx
= info
->mem_ctx
;
296 DEBUG(10,("load_group_domain_entries\n"));
298 /* if the snapshoot is already loaded, return */
299 if (info
->disp_info
.group_dbloaded
==True
) {
300 DEBUG(10,("load_group_domain_entries: already in memory\n"));
307 if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP
, &map
, (int *)&group_entries
, ENUM_ONLY_MAPPED
, MAPPING_WITHOUT_PRIV
)) {
308 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
309 return NT_STATUS_NO_MEMORY
;
314 info
->disp_info
.num_group_account
=group_entries
;
316 grp_array
=(DISP_GROUP_INFO
*)talloc(mem_ctx
, info
->disp_info
.num_group_account
*sizeof(DISP_GROUP_INFO
));
318 if (group_entries
!=0 && grp_array
==NULL
) {
319 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
321 return NT_STATUS_NO_MEMORY
;
324 info
->disp_info
.disp_group_info
=grp_array
;
326 for (i
=0; i
<group_entries
; i
++) {
328 grp_array
[i
].grp
=(DOMAIN_GRP
*)talloc(mem_ctx
, sizeof(DOMAIN_GRP
));
330 fstrcpy(grp_array
[i
].grp
->name
, map
[i
].nt_name
);
331 fstrcpy(grp_array
[i
].grp
->comment
, map
[i
].comment
);
332 sid_split_rid(&map
[i
].sid
, &grp_array
[i
].grp
->rid
);
333 grp_array
[i
].grp
->attr
=SID_NAME_DOM_GRP
;
338 /* the snapshoot is in memory, we're ready to enumerate fast */
340 info
->disp_info
.group_dbloaded
=True
;
342 DEBUG(10,("load_group_domain_entries: done\n"));
348 /*******************************************************************
350 ********************************************************************/
352 NTSTATUS
_samr_close_hnd(pipes_struct
*p
, SAMR_Q_CLOSE_HND
*q_u
, SAMR_R_CLOSE_HND
*r_u
)
354 r_u
->status
= NT_STATUS_OK
;
356 /* close the policy handle */
357 if (!close_policy_hnd(p
, &q_u
->pol
))
358 return NT_STATUS_OBJECT_NAME_INVALID
;
360 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__
));
365 /*******************************************************************
366 samr_reply_open_domain
367 ********************************************************************/
369 NTSTATUS
_samr_open_domain(pipes_struct
*p
, SAMR_Q_OPEN_DOMAIN
*q_u
, SAMR_R_OPEN_DOMAIN
*r_u
)
371 struct samr_info
*info
;
372 SEC_DESC
*psd
= NULL
;
374 uint32 des_access
= q_u
->flags
;
378 r_u
->status
= NT_STATUS_OK
;
380 /* find the connection policy handle. */
381 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void**)&info
))
382 return NT_STATUS_INVALID_HANDLE
;
384 if (!NT_STATUS_IS_OK(status
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_SAM_OPEN_DOMAIN
,"_samr_open_domain"))) {
388 /*check if access can be granted as requested by client. */
389 samr_make_dom_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
390 se_map_generic(&des_access
,&dom_generic_mapping
);
392 if (!NT_STATUS_IS_OK(status
=
393 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
394 des_access
, &acc_granted
, "_samr_open_domain"))) {
398 /* associate the domain SID with the (unique) handle. */
399 if ((info
= get_samr_info_by_sid(&q_u
->dom_sid
.sid
))==NULL
)
400 return NT_STATUS_NO_MEMORY
;
401 info
->acc_granted
= acc_granted
;
403 /* get a (unique) handle. open a policy on it. */
404 if (!create_policy_hnd(p
, &r_u
->domain_pol
, free_samr_info
, (void *)info
))
405 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
407 DEBUG(5,("samr_open_domain: %d\n", __LINE__
));
412 /*******************************************************************
413 _samr_get_usrdom_pwinfo
414 ********************************************************************/
416 NTSTATUS
_samr_get_usrdom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_USRDOM_PWINFO
*q_u
, SAMR_R_GET_USRDOM_PWINFO
*r_u
)
418 struct samr_info
*info
= NULL
;
420 r_u
->status
= NT_STATUS_OK
;
422 /* find the policy handle. open a policy on it. */
423 if (!find_policy_by_hnd(p
, &q_u
->user_pol
, (void **)&info
))
424 return NT_STATUS_INVALID_HANDLE
;
426 if (!sid_check_is_in_our_domain(&info
->sid
))
427 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
429 init_samr_r_get_usrdom_pwinfo(r_u
, NT_STATUS_OK
);
431 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__
));
434 * NT sometimes return NT_STATUS_ACCESS_DENIED
435 * I don't know yet why.
441 /*******************************************************************
443 ********************************************************************/
445 static NTSTATUS
samr_make_dom_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
)
447 extern DOM_SID global_sid_World
;
456 sid_copy(&adm_sid
, &global_sid_Builtin
);
457 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
459 sid_copy(&act_sid
, &global_sid_Builtin
);
460 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
462 /*basic access for every one*/
463 init_sec_access(&mask
, GENERIC_RIGHTS_DOMAIN_EXECUTE
| GENERIC_RIGHTS_DOMAIN_READ
);
464 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
466 /*full access for builtin aliases Administrators and Account Operators*/
467 init_sec_access(&mask
, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS
);
468 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
469 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
471 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
472 return NT_STATUS_NO_MEMORY
;
474 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
475 return NT_STATUS_NO_MEMORY
;
480 /*******************************************************************
482 ********************************************************************/
484 static NTSTATUS
samr_make_usr_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
, DOM_SID
*usr_sid
)
486 extern DOM_SID global_sid_World
;
495 sid_copy(&adm_sid
, &global_sid_Builtin
);
496 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
498 sid_copy(&act_sid
, &global_sid_Builtin
);
499 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
501 /*basic access for every one*/
502 init_sec_access(&mask
, GENERIC_RIGHTS_USER_EXECUTE
| GENERIC_RIGHTS_USER_READ
);
503 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
505 /*full access for builtin aliases Administrators and Account Operators*/
506 init_sec_access(&mask
, GENERIC_RIGHTS_USER_ALL_ACCESS
);
507 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
508 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
510 /*extended access for the user*/
511 init_sec_access(&mask
,READ_CONTROL_ACCESS
| SA_RIGHT_USER_CHANGE_PASSWORD
| SA_RIGHT_USER_SET_LOC_COM
);
512 init_sec_ace(&ace
[3], usr_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
514 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 4, ace
)) == NULL
)
515 return NT_STATUS_NO_MEMORY
;
517 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
518 return NT_STATUS_NO_MEMORY
;
523 /*******************************************************************
525 ********************************************************************/
527 static NTSTATUS
samr_make_grp_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
)
529 extern DOM_SID global_sid_World
;
538 sid_copy(&adm_sid
, &global_sid_Builtin
);
539 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
541 sid_copy(&act_sid
, &global_sid_Builtin
);
542 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
544 /*basic access for every one*/
545 init_sec_access(&mask
, GENERIC_RIGHTS_GROUP_EXECUTE
| GENERIC_RIGHTS_GROUP_READ
);
546 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
548 /*full access for builtin aliases Administrators and Account Operators*/
549 init_sec_access(&mask
, GENERIC_RIGHTS_GROUP_ALL_ACCESS
);
550 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
551 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
553 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
554 return NT_STATUS_NO_MEMORY
;
556 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
557 return NT_STATUS_NO_MEMORY
;
562 /*******************************************************************
564 ********************************************************************/
566 static NTSTATUS
samr_make_ali_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
)
568 extern DOM_SID global_sid_World
;
577 sid_copy(&adm_sid
, &global_sid_Builtin
);
578 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
580 sid_copy(&act_sid
, &global_sid_Builtin
);
581 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
583 /*basic access for every one*/
584 init_sec_access(&mask
, GENERIC_RIGHTS_ALIAS_EXECUTE
| GENERIC_RIGHTS_ALIAS_READ
);
585 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
587 /*full access for builtin aliases Administrators and Account Operators*/
588 init_sec_access(&mask
, GENERIC_RIGHTS_ALIAS_ALL_ACCESS
);
589 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
590 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
592 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
593 return NT_STATUS_NO_MEMORY
;
595 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
596 return NT_STATUS_NO_MEMORY
;
601 static BOOL
get_lsa_policy_samr_sid(pipes_struct
*p
, POLICY_HND
*pol
, DOM_SID
*sid
, uint32
*acc_granted
)
603 struct samr_info
*info
= NULL
;
605 /* find the policy handle. open a policy on it. */
606 if (!find_policy_by_hnd(p
, pol
, (void **)&info
))
613 *acc_granted
= info
->acc_granted
;
617 /*******************************************************************
619 ********************************************************************/
621 NTSTATUS
_samr_set_sec_obj(pipes_struct
*p
, SAMR_Q_SET_SEC_OBJ
*q_u
, SAMR_R_SET_SEC_OBJ
*r_u
)
623 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
624 return NT_STATUS_NOT_IMPLEMENTED
;
628 /*******************************************************************
630 ********************************************************************/
632 NTSTATUS
_samr_query_sec_obj(pipes_struct
*p
, SAMR_Q_QUERY_SEC_OBJ
*q_u
, SAMR_R_QUERY_SEC_OBJ
*r_u
)
636 SEC_DESC
* psd
= NULL
;
640 r_u
->status
= NT_STATUS_OK
;
643 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &pol_sid
, &acc_granted
))
644 return NT_STATUS_INVALID_HANDLE
;
648 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
650 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
652 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
653 if (pol_sid
.sid_rev_num
== 0)
655 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
656 r_u
->status
= samr_make_sam_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
658 else if (sid_equal(&pol_sid
,get_global_sam_sid())) /* check if it is our domain SID */
661 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
662 r_u
->status
= samr_make_dom_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
664 else if (sid_equal(&pol_sid
,&global_sid_Builtin
)) /* check if it is the Builtin Domain */
666 /* TODO: Builtin probably needs a different SD with restricted write access*/
667 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
668 r_u
->status
= samr_make_dom_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
670 else if (sid_check_is_in_our_domain(&pol_sid
) ||
671 sid_check_is_in_builtin(&pol_sid
))
673 /* TODO: different SDs have to be generated for aliases groups and users.
674 Currently all three get a default user SD */
675 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
676 r_u
->status
= samr_make_usr_obj_sd(p
->mem_ctx
, &psd
,&sd_size
, &pol_sid
);
678 else return NT_STATUS_OBJECT_TYPE_MISMATCH
;
680 if ((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
681 return NT_STATUS_NO_MEMORY
;
683 if (NT_STATUS_IS_OK(r_u
->status
))
689 /*******************************************************************
690 makes a SAM_ENTRY / UNISTR2* structure from a user list.
691 ********************************************************************/
693 static NTSTATUS
make_user_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
694 uint32 num_entries
, uint32 start_idx
, DISP_USER_INFO
*disp_user_info
,
700 SAM_ACCOUNT
*pwd
= NULL
;
701 UNISTR2 uni_temp_name
;
702 const char *temp_name
;
703 const DOM_SID
*user_sid
;
705 fstring user_sid_string
;
706 fstring domain_sid_string
;
711 if (num_entries
== 0)
714 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_entries
);
716 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_entries
);
718 if (sam
== NULL
|| uni_name
== NULL
) {
719 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
720 return NT_STATUS_NO_MEMORY
;
723 for (i
= 0; i
< num_entries
; i
++) {
724 pwd
= disp_user_info
[i
+start_idx
].sam
;
725 temp_name
= pdb_get_username(pwd
);
726 init_unistr2(&uni_temp_name
, temp_name
, strlen(temp_name
)+1);
727 user_sid
= pdb_get_user_sid(pwd
);
729 if (!sid_peek_check_rid(domain_sid
, user_sid
, &user_rid
)) {
730 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
731 "the domain sid %s. Failing operation.\n",
733 sid_to_string(user_sid_string
, user_sid
),
734 sid_to_string(domain_sid_string
, domain_sid
)));
735 return NT_STATUS_UNSUCCESSFUL
;
738 init_sam_entry(&sam
[i
], uni_temp_name
.uni_str_len
, user_rid
);
739 copy_unistr2(&uni_name
[i
], &uni_temp_name
);
743 *uni_name_pp
= uni_name
;
747 /*******************************************************************
748 samr_reply_enum_dom_users
749 ********************************************************************/
751 NTSTATUS
_samr_enum_dom_users(pipes_struct
*p
, SAMR_Q_ENUM_DOM_USERS
*q_u
,
752 SAMR_R_ENUM_DOM_USERS
*r_u
)
754 struct samr_info
*info
= NULL
;
755 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
757 uint32 enum_context
=q_u
->start_idx
;
758 uint32 max_size
=q_u
->max_size
;
760 enum remote_arch_types ra_type
= get_remote_arch();
761 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
762 uint32 max_entries
= max_sam_entries
;
765 r_u
->status
= NT_STATUS_OK
;
767 /* find the policy handle. open a policy on it. */
768 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
769 return NT_STATUS_INVALID_HANDLE
;
771 domain_sid
= info
->sid
;
773 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
,
774 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
,
775 "_samr_enum_dom_users"))) {
779 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
782 r_u
->status
=load_sampwd_entries(info
, q_u
->acb_mask
, False
);
785 if (!NT_STATUS_IS_OK(r_u
->status
))
788 num_account
= info
->disp_info
.num_user_account
;
790 if (enum_context
> num_account
) {
791 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
795 /* verify we won't overflow */
796 if (max_entries
> num_account
-enum_context
) {
797 max_entries
= num_account
-enum_context
;
798 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries
));
801 /* calculate the size and limit on the number of entries we will return */
802 temp_size
=max_entries
*struct_size
;
804 if (temp_size
>max_size
) {
805 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
806 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries
));
810 * Note from JRA. total_entries is not being used here. Currently if there is a
811 * large user base then it looks like NT will enumerate until get_sampwd_entries
812 * returns False due to num_entries being zero. This will cause an access denied
813 * return. I don't think this is right and needs further investigation. Note that
814 * this is also the same in the TNG code (I don't think that has been tested with
815 * a very large user list as MAX_SAM_ENTRIES is set to 600).
817 * I also think that one of the 'num_entries' return parameters is probably
818 * the "max entries" parameter - but in the TNG code they're all currently set to the same
819 * value (again I think this is wrong).
822 r_u
->status
= make_user_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_acct_name
,
823 max_entries
, enum_context
,
824 info
->disp_info
.disp_user_info
,
827 if (!NT_STATUS_IS_OK(r_u
->status
))
830 if (enum_context
+max_entries
< num_account
)
831 r_u
->status
= STATUS_MORE_ENTRIES
;
833 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__
));
835 init_samr_r_enum_dom_users(r_u
, q_u
->start_idx
+ max_entries
, max_entries
);
837 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
842 /*******************************************************************
843 makes a SAM_ENTRY / UNISTR2* structure from a group list.
844 ********************************************************************/
846 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
847 uint32 num_sam_entries
, DOMAIN_GRP
*grp
)
856 if (num_sam_entries
== 0)
859 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
861 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
863 if (sam
== NULL
|| uni_name
== NULL
) {
864 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
868 for (i
= 0; i
< num_sam_entries
; i
++) {
870 * JRA. I think this should include the null. TNG does not.
872 int len
= strlen(grp
[i
].name
)+1;
874 init_sam_entry(&sam
[i
], len
, grp
[i
].rid
);
875 init_unistr2(&uni_name
[i
], grp
[i
].name
, len
);
879 *uni_name_pp
= uni_name
;
882 /*******************************************************************
883 Get the group entries - similar to get_sampwd_entries().
884 ********************************************************************/
886 static NTSTATUS
get_group_alias_entries(TALLOC_CTX
*ctx
, DOMAIN_GRP
**d_grp
, DOM_SID
*sid
, uint32 start_idx
,
887 uint32
*p_num_entries
, uint32 max_entries
)
890 uint32 num_entries
= 0;
893 GROUP_MAP
*map
= NULL
;
895 sid_to_string(sid_str
, sid
);
896 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str
));
900 /* well-known aliases */
901 if (sid_equal(sid
, &global_sid_Builtin
) && !lp_hide_local_users()) {
903 pdb_enum_group_mapping(SID_NAME_WKN_GRP
, &map
, (int *)&num_entries
, ENUM_ONLY_MAPPED
, MAPPING_WITHOUT_PRIV
);
905 if (num_entries
!= 0) {
906 *d_grp
=(DOMAIN_GRP
*)talloc_zero(ctx
, num_entries
*sizeof(DOMAIN_GRP
));
908 return NT_STATUS_NO_MEMORY
;
910 for(i
=0; i
<num_entries
&& i
<max_entries
; i
++) {
911 fstrcpy((*d_grp
)[i
].name
, map
[i
+start_idx
].nt_name
);
912 sid_split_rid(&map
[i
+start_idx
].sid
, &(*d_grp
)[i
].rid
);
918 } else if (sid_equal(sid
, get_global_sam_sid()) && !lp_hide_local_users()) {
919 struct sys_grent
*glist
;
920 struct sys_grent
*grp
;
922 gid_t winbind_gid_low
, winbind_gid_high
;
923 BOOL winbind_groups_exist
= lp_idmap_gid(&winbind_gid_low
, &winbind_gid_high
);
926 /* we return the UNIX groups here. This seems to be the right */
927 /* thing to do, since NT member servers return their local */
928 /* groups in the same situation. */
930 /* use getgrent_list() to retrieve the list of groups to avoid
931 * problems with getgrent possible infinite loop by internal
932 * libc grent structures overwrites by called functions */
933 grp
= glist
= getgrent_list();
935 return NT_STATUS_NO_MEMORY
;
937 for (; (num_entries
< max_entries
) && (grp
!= NULL
); grp
= grp
->next
) {
940 if(!pdb_getgrgid(&smap
, grp
->gr_gid
, MAPPING_WITHOUT_PRIV
))
943 if (smap
.sid_name_use
!=SID_NAME_ALIAS
) {
947 sid_split_rid(&smap
.sid
, &trid
);
949 if (!sid_equal(sid
, &smap
.sid
))
952 /* Don't return winbind groups as they are not local! */
953 if (winbind_groups_exist
&& (grp
->gr_gid
>= winbind_gid_low
)&&(grp
->gr_gid
<= winbind_gid_high
)) {
954 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap
.nt_name
));
958 /* Don't return user private groups... */
960 if ((pw
= Get_Pwnam(smap
.nt_name
)) != 0) {
961 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap
.nt_name
));
965 for( i
= 0; i
< num_entries
; i
++)
966 if ( (*d_grp
)[i
].rid
== trid
)
969 if ( i
< num_entries
) {
970 continue; /* rid was there, dup! */
973 /* JRA - added this for large group db enumeration... */
976 /* skip the requested number of entries.
977 not very efficient, but hey...
983 *d_grp
=talloc_realloc(ctx
,*d_grp
, (num_entries
+1)*sizeof(DOMAIN_GRP
));
986 return NT_STATUS_NO_MEMORY
;
989 fstrcpy((*d_grp
)[num_entries
].name
, smap
.nt_name
);
990 (*d_grp
)[num_entries
].rid
= trid
;
992 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries
, trid
));
998 *p_num_entries
= num_entries
;
1000 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries
));
1002 if (num_entries
>= max_entries
)
1003 return STATUS_MORE_ENTRIES
;
1004 return NT_STATUS_OK
;
1007 /*******************************************************************
1008 Get the group entries - similar to get_sampwd_entries().
1009 ********************************************************************/
1011 static NTSTATUS
get_group_domain_entries(TALLOC_CTX
*ctx
, DOMAIN_GRP
**d_grp
, DOM_SID
*sid
, uint32 start_idx
,
1012 uint32
*p_num_entries
, uint32 max_entries
)
1014 GROUP_MAP
*map
=NULL
;
1016 uint32 group_entries
= 0;
1017 uint32 num_entries
= 0;
1021 pdb_enum_group_mapping(SID_NAME_DOM_GRP
, &map
, (int *)&group_entries
, ENUM_ONLY_MAPPED
, MAPPING_WITHOUT_PRIV
);
1023 num_entries
=group_entries
-start_idx
;
1025 /* limit the number of entries */
1026 if (num_entries
>max_entries
) {
1027 DEBUG(5,("Limiting to %d entries\n", max_entries
));
1028 num_entries
=max_entries
;
1031 *d_grp
=(DOMAIN_GRP
*)talloc_zero(ctx
, num_entries
*sizeof(DOMAIN_GRP
));
1032 if (num_entries
!=0 && *d_grp
==NULL
){
1034 return NT_STATUS_NO_MEMORY
;
1037 for (i
=0; i
<num_entries
; i
++) {
1038 fstrcpy((*d_grp
)[i
].name
, map
[i
+start_idx
].nt_name
);
1039 fstrcpy((*d_grp
)[i
].comment
, map
[i
+start_idx
].comment
);
1040 sid_split_rid(&map
[i
+start_idx
].sid
, &(*d_grp
)[i
].rid
);
1041 (*d_grp
)[i
].attr
=SID_NAME_DOM_GRP
;
1046 *p_num_entries
= num_entries
;
1048 return NT_STATUS_OK
;
1051 /*******************************************************************
1052 samr_reply_enum_dom_groups
1053 ********************************************************************/
1055 NTSTATUS
_samr_enum_dom_groups(pipes_struct
*p
, SAMR_Q_ENUM_DOM_GROUPS
*q_u
, SAMR_R_ENUM_DOM_GROUPS
*r_u
)
1057 DOMAIN_GRP
*grp
=NULL
;
1062 r_u
->status
= NT_STATUS_OK
;
1064 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
1065 return NT_STATUS_INVALID_HANDLE
;
1067 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
, "_samr_enum_dom_groups"))) {
1071 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__
));
1073 /* the domain group array is being allocated in the function below */
1074 if (!NT_STATUS_IS_OK(r_u
->status
= get_group_domain_entries(p
->mem_ctx
, &grp
, &sid
, q_u
->start_idx
, &num_entries
, MAX_SAM_ENTRIES
))) {
1078 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
1080 init_samr_r_enum_dom_groups(r_u
, q_u
->start_idx
, num_entries
);
1082 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__
));
1088 /*******************************************************************
1089 samr_reply_enum_dom_aliases
1090 ********************************************************************/
1092 NTSTATUS
_samr_enum_dom_aliases(pipes_struct
*p
, SAMR_Q_ENUM_DOM_ALIASES
*q_u
, SAMR_R_ENUM_DOM_ALIASES
*r_u
)
1094 DOMAIN_GRP
*grp
=NULL
;
1095 uint32 num_entries
= 0;
1101 r_u
->status
= NT_STATUS_OK
;
1103 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
1104 return NT_STATUS_INVALID_HANDLE
;
1106 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
, "_samr_enum_dom_aliases"))) {
1110 sid_to_string(sid_str
, &sid
);
1111 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str
));
1113 status
= get_group_alias_entries(p
->mem_ctx
, &grp
, &sid
, q_u
->start_idx
,
1114 &num_entries
, MAX_SAM_ENTRIES
);
1115 if (NT_STATUS_IS_ERR(status
)) return status
;
1117 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
1121 init_samr_r_enum_dom_aliases(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
1123 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__
));
1128 /*******************************************************************
1129 samr_reply_query_dispinfo
1130 ********************************************************************/
1131 NTSTATUS
_samr_query_dispinfo(pipes_struct
*p
, SAMR_Q_QUERY_DISPINFO
*q_u
,
1132 SAMR_R_QUERY_DISPINFO
*r_u
)
1134 struct samr_info
*info
= NULL
;
1135 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
1137 uint32 max_entries
=q_u
->max_entries
;
1138 uint32 enum_context
=q_u
->start_idx
;
1139 uint32 max_size
=q_u
->max_size
;
1141 SAM_DISPINFO_CTR
*ctr
;
1142 uint32 temp_size
=0, total_data_size
=0;
1144 uint32 num_account
= 0;
1145 enum remote_arch_types ra_type
= get_remote_arch();
1146 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
1149 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__
));
1150 r_u
->status
= NT_STATUS_OK
;
1152 /* find the policy handle. open a policy on it. */
1153 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
1154 return NT_STATUS_INVALID_HANDLE
;
1156 domain_sid
= info
->sid
;
1159 * calculate how many entries we will return.
1161 * - the number of entries the client asked
1162 * - our limit on that
1163 * - the starting point (enumeration context)
1164 * - the buffer size the client will accept
1168 * We are a lot more like W2K. Instead of reading the SAM
1169 * each time to find the records we need to send back,
1170 * we read it once and link that copy to the sam handle.
1171 * For large user list (over the MAX_SAM_ENTRIES)
1172 * it's a definitive win.
1173 * second point to notice: between enumerations
1174 * our sam is now the same as it's a snapshoot.
1175 * third point: got rid of the static SAM_USER_21 struct
1176 * no more intermediate.
1177 * con: it uses much more memory, as a full copy is stored
1180 * If you want to change it, think twice and think
1181 * of the second point , that's really important.
1186 /* Get what we need from the password database */
1187 switch (q_u
->switch_level
) {
1189 /* When playing with usrmgr, this is necessary
1190 if you want immediate refresh after editing
1191 a user. I would like to do this after the
1192 setuserinfo2, but we do not have access to
1193 the domain handle in that call, only to the
1194 user handle. Where else does this hurt?
1198 /* We cannot do this here - it kills performace. JRA. */
1199 free_samr_users(info
);
1204 /* Level 2 is for all machines, otherwise only 'normal' users */
1205 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
, q_u
->switch_level
==2);
1207 if (!NT_STATUS_IS_OK(r_u
->status
)) {
1208 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1211 num_account
= info
->disp_info
.num_user_account
;
1215 r_u
->status
= load_group_domain_entries(info
, &info
->sid
);
1216 if (!NT_STATUS_IS_OK(r_u
->status
))
1218 num_account
= info
->disp_info
.num_group_account
;
1221 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u
->switch_level
));
1222 return NT_STATUS_INVALID_INFO_CLASS
;
1225 /* first limit the number of entries we will return */
1226 if(max_entries
> max_sam_entries
) {
1227 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries
, max_sam_entries
));
1228 max_entries
= max_sam_entries
;
1231 if (enum_context
> num_account
) {
1232 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1233 return NT_STATUS_NO_MORE_ENTRIES
;
1236 /* verify we won't overflow */
1237 if (max_entries
> num_account
-enum_context
) {
1238 max_entries
= num_account
-enum_context
;
1239 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries
));
1242 /* calculate the size and limit on the number of entries we will return */
1243 temp_size
=max_entries
*struct_size
;
1245 if (temp_size
>max_size
) {
1246 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
1247 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries
));
1250 if (!(ctr
= (SAM_DISPINFO_CTR
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_DISPINFO_CTR
))))
1251 return NT_STATUS_NO_MEMORY
;
1255 /* Now create reply structure */
1256 switch (q_u
->switch_level
) {
1259 if (!(ctr
->sam
.info1
= (SAM_DISPINFO_1
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_1
))))
1260 return NT_STATUS_NO_MEMORY
;
1262 disp_ret
= init_sam_dispinfo_1(p
->mem_ctx
, ctr
->sam
.info1
, max_entries
, enum_context
,
1263 info
->disp_info
.disp_user_info
, &domain_sid
);
1264 if (!NT_STATUS_IS_OK(disp_ret
))
1269 if (!(ctr
->sam
.info2
= (SAM_DISPINFO_2
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_2
))))
1270 return NT_STATUS_NO_MEMORY
;
1272 disp_ret
= init_sam_dispinfo_2(p
->mem_ctx
, ctr
->sam
.info2
, max_entries
, enum_context
,
1273 info
->disp_info
.disp_user_info
, &domain_sid
);
1274 if (!NT_STATUS_IS_OK(disp_ret
))
1279 if (!(ctr
->sam
.info3
= (SAM_DISPINFO_3
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_3
))))
1280 return NT_STATUS_NO_MEMORY
;
1282 disp_ret
= init_sam_dispinfo_3(p
->mem_ctx
, ctr
->sam
.info3
, max_entries
, enum_context
, info
->disp_info
.disp_group_info
);
1283 if (!NT_STATUS_IS_OK(disp_ret
))
1288 if (!(ctr
->sam
.info4
= (SAM_DISPINFO_4
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_4
))))
1289 return NT_STATUS_NO_MEMORY
;
1291 disp_ret
= init_sam_dispinfo_4(p
->mem_ctx
, ctr
->sam
.info4
, max_entries
, enum_context
, info
->disp_info
.disp_user_info
);
1292 if (!NT_STATUS_IS_OK(disp_ret
))
1297 if (!(ctr
->sam
.info5
= (SAM_DISPINFO_5
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_5
))))
1298 return NT_STATUS_NO_MEMORY
;
1300 disp_ret
= init_sam_dispinfo_5(p
->mem_ctx
, ctr
->sam
.info5
, max_entries
, enum_context
, info
->disp_info
.disp_group_info
);
1301 if (!NT_STATUS_IS_OK(disp_ret
))
1306 ctr
->sam
.info
= NULL
;
1307 return NT_STATUS_INVALID_INFO_CLASS
;
1310 /* calculate the total size */
1311 total_data_size
=num_account
*struct_size
;
1313 if (enum_context
+max_entries
< num_account
)
1314 r_u
->status
= STATUS_MORE_ENTRIES
;
1316 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__
));
1318 init_samr_r_query_dispinfo(r_u
, max_entries
, total_data_size
, temp_size
, q_u
->switch_level
, ctr
, r_u
->status
);
1324 /*******************************************************************
1325 samr_reply_query_aliasinfo
1326 ********************************************************************/
1328 NTSTATUS
_samr_query_aliasinfo(pipes_struct
*p
, SAMR_Q_QUERY_ALIASINFO
*q_u
, SAMR_R_QUERY_ALIASINFO
*r_u
)
1334 r_u
->status
= NT_STATUS_OK
;
1336 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1338 /* find the policy handle. open a policy on it. */
1339 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
1340 return NT_STATUS_INVALID_HANDLE
;
1341 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_LOOKUP_INFO
, "_samr_query_aliasinfo"))) {
1345 if (!sid_check_is_in_our_domain(&sid
) &&
1346 !sid_check_is_in_builtin(&sid
))
1347 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1349 if (!pdb_getgrsid(&map
, sid
, MAPPING_WITHOUT_PRIV
))
1350 return NT_STATUS_NO_SUCH_ALIAS
;
1352 switch (q_u
->switch_level
) {
1355 r_u
->ctr
.switch_value1
= 1;
1356 init_samr_alias_info1(&r_u
->ctr
.alias
.info1
, map
.nt_name
, 1, map
.comment
);
1360 r_u
->ctr
.switch_value1
= 3;
1361 init_samr_alias_info3(&r_u
->ctr
.alias
.info3
, map
.comment
);
1364 return NT_STATUS_INVALID_INFO_CLASS
;
1367 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1373 /*******************************************************************
1374 samr_reply_lookup_ids
1375 ********************************************************************/
1377 uint32
_samr_lookup_ids(pipes_struct
*p
, SAMR_Q_LOOKUP_IDS
*q_u
, SAMR_R_LOOKUP_IDS
*r_u
)
1379 uint32 rid
[MAX_SAM_ENTRIES
];
1380 int num_rids
= q_u
->num_sids1
;
1382 r_u
->status
= NT_STATUS_OK
;
1384 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1386 if (num_rids
> MAX_SAM_ENTRIES
) {
1387 num_rids
= MAX_SAM_ENTRIES
;
1388 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids
));
1393 SMB_ASSERT_ARRAY(q_u
->uni_user_name
, num_rids
);
1395 for (i
= 0; i
< num_rids
&& status
== 0; i
++)
1397 struct sam_passwd
*sam_pass
;
1401 fstrcpy(user_name
, unistrn2(q_u
->uni_user_name
[i
].buffer
,
1402 q_u
->uni_user_name
[i
].uni_str_len
));
1404 /* find the user account */
1406 sam_pass
= get_smb21pwd_entry(user_name
, 0);
1409 if (sam_pass
== NULL
)
1411 status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1416 rid
[i
] = sam_pass
->user_rid
;
1422 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
1424 init_samr_r_lookup_ids(&r_u
, num_rids
, rid
, NT_STATUS_OK
);
1426 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1432 /*******************************************************************
1434 ********************************************************************/
1436 NTSTATUS
_samr_lookup_names(pipes_struct
*p
, SAMR_Q_LOOKUP_NAMES
*q_u
, SAMR_R_LOOKUP_NAMES
*r_u
)
1438 uint32 rid
[MAX_SAM_ENTRIES
];
1440 enum SID_NAME_USE type
[MAX_SAM_ENTRIES
];
1441 enum SID_NAME_USE local_type
;
1443 int num_rids
= q_u
->num_names2
;
1448 r_u
->status
= NT_STATUS_OK
;
1450 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1455 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
, &acc_granted
)) {
1456 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, 0, NULL
, NULL
, NT_STATUS_OBJECT_TYPE_MISMATCH
);
1460 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1464 if (num_rids
> MAX_SAM_ENTRIES
) {
1465 num_rids
= MAX_SAM_ENTRIES
;
1466 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids
));
1469 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str
, &pol_sid
)));
1471 become_root(); /* local_lookup_name can require root privs */
1473 for (i
= 0; i
< num_rids
; i
++) {
1477 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1479 rid
[i
] = 0xffffffff;
1480 type
[i
] = SID_NAME_UNKNOWN
;
1482 rpcstr_pull(name
, q_u
->uni_name
[i
].buffer
, sizeof(name
), q_u
->uni_name
[i
].uni_str_len
*2, 0);
1485 * we are only looking for a name
1486 * the SID we get back can be outside
1487 * the scope of the pol_sid
1489 * in clear: it prevents to reply to domain\group: yes
1490 * when only builtin\group exists.
1492 * a cleaner code is to add the sid of the domain we're looking in
1493 * to the local_lookup_name function.
1495 if(local_lookup_name(name
, &sid
, &local_type
)) {
1496 sid_split_rid(&sid
, &local_rid
);
1498 if (sid_equal(&sid
, &pol_sid
)) {
1501 r_u
->status
= NT_STATUS_OK
;
1508 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, num_rids
, rid
, (uint32
*)type
, r_u
->status
);
1510 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1515 /*******************************************************************
1516 _samr_chgpasswd_user
1517 ********************************************************************/
1519 NTSTATUS
_samr_chgpasswd_user(pipes_struct
*p
, SAMR_Q_CHGPASSWD_USER
*q_u
, SAMR_R_CHGPASSWD_USER
*r_u
)
1524 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1526 r_u
->status
= NT_STATUS_OK
;
1528 rpcstr_pull(user_name
, q_u
->uni_user_name
.buffer
, sizeof(user_name
), q_u
->uni_user_name
.uni_str_len
*2, 0);
1529 rpcstr_pull(wks
, q_u
->uni_dest_host
.buffer
, sizeof(wks
), q_u
->uni_dest_host
.uni_str_len
*2,0);
1531 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name
, wks
));
1534 * Pass the user through the NT -> unix user mapping
1538 (void)map_username(user_name
);
1541 * UNIX username case mangling not required, pass_oem_change
1542 * is case insensitive.
1545 r_u
->status
= pass_oem_change(user_name
, q_u
->lm_newpass
.pass
, q_u
->lm_oldhash
.hash
,
1546 q_u
->nt_newpass
.pass
, q_u
->nt_oldhash
.hash
);
1548 init_samr_r_chgpasswd_user(r_u
, r_u
->status
);
1550 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1555 /*******************************************************************
1556 makes a SAMR_R_LOOKUP_RIDS structure.
1557 ********************************************************************/
1559 static BOOL
make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
, fstring names
[],
1560 UNIHDR
**pp_hdr_name
, UNISTR2
**pp_uni_name
)
1563 UNIHDR
*hdr_name
=NULL
;
1564 UNISTR2
*uni_name
=NULL
;
1566 *pp_uni_name
= NULL
;
1567 *pp_hdr_name
= NULL
;
1569 if (num_names
!= 0) {
1570 hdr_name
= (UNIHDR
*)talloc_zero(ctx
, sizeof(UNIHDR
)*num_names
);
1571 if (hdr_name
== NULL
)
1574 uni_name
= (UNISTR2
*)talloc_zero(ctx
,sizeof(UNISTR2
)*num_names
);
1575 if (uni_name
== NULL
)
1579 for (i
= 0; i
< num_names
; i
++) {
1580 int len
= names
[i
] != NULL
? strlen(names
[i
]) : 0;
1581 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
]));
1582 init_uni_hdr(&hdr_name
[i
], len
);
1583 init_unistr2(&uni_name
[i
], names
[i
], len
);
1586 *pp_uni_name
= uni_name
;
1587 *pp_hdr_name
= hdr_name
;
1592 /*******************************************************************
1594 ********************************************************************/
1596 NTSTATUS
_samr_lookup_rids(pipes_struct
*p
, SAMR_Q_LOOKUP_RIDS
*q_u
, SAMR_R_LOOKUP_RIDS
*r_u
)
1598 fstring group_names
[MAX_SAM_ENTRIES
];
1599 uint32
*group_attrs
= NULL
;
1600 UNIHDR
*hdr_name
= NULL
;
1601 UNISTR2
*uni_name
= NULL
;
1603 int num_rids
= q_u
->num_rids1
;
1607 r_u
->status
= NT_STATUS_OK
;
1609 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1611 /* find the policy handle. open a policy on it. */
1612 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
, &acc_granted
))
1613 return NT_STATUS_INVALID_HANDLE
;
1615 if (num_rids
> MAX_SAM_ENTRIES
) {
1616 num_rids
= MAX_SAM_ENTRIES
;
1617 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids
));
1621 if ((group_attrs
= (uint32
*)talloc_zero(p
->mem_ctx
, num_rids
* sizeof(uint32
))) == NULL
)
1622 return NT_STATUS_NO_MEMORY
;
1625 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1627 become_root(); /* lookup_sid can require root privs */
1629 for (i
= 0; i
< num_rids
; i
++) {
1633 enum SID_NAME_USE type
;
1635 group_attrs
[i
] = SID_NAME_UNKNOWN
;
1636 *group_names
[i
] = '\0';
1638 if (sid_equal(&pol_sid
, get_global_sam_sid())) {
1639 sid_copy(&sid
, &pol_sid
);
1640 sid_append_rid(&sid
, q_u
->rid
[i
]);
1642 if (lookup_sid(&sid
, domname
, tmpname
, &type
)) {
1643 r_u
->status
= NT_STATUS_OK
;
1644 group_attrs
[i
] = (uint32
)type
;
1645 fstrcpy(group_names
[i
],tmpname
);
1646 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names
[i
], group_attrs
[i
]));
1653 if(!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, group_names
, &hdr_name
, &uni_name
))
1654 return NT_STATUS_NO_MEMORY
;
1656 init_samr_r_lookup_rids(r_u
, num_rids
, hdr_name
, uni_name
, group_attrs
);
1658 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1663 /*******************************************************************
1664 _api_samr_open_user. Safe - gives out no passwd info.
1665 ********************************************************************/
1667 NTSTATUS
_api_samr_open_user(pipes_struct
*p
, SAMR_Q_OPEN_USER
*q_u
, SAMR_R_OPEN_USER
*r_u
)
1669 SAM_ACCOUNT
*sampass
=NULL
;
1671 POLICY_HND domain_pol
= q_u
->domain_pol
;
1672 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1673 struct samr_info
*info
= NULL
;
1674 SEC_DESC
*psd
= NULL
;
1676 uint32 des_access
= q_u
->access_mask
;
1681 r_u
->status
= NT_STATUS_OK
;
1683 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1684 if (!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
, &acc_granted
))
1685 return NT_STATUS_INVALID_HANDLE
;
1687 if (!NT_STATUS_IS_OK(nt_status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_open_user"))) {
1691 nt_status
= pdb_init_sam_talloc(p
->mem_ctx
, &sampass
);
1692 if (!NT_STATUS_IS_OK(nt_status
)) {
1696 /* append the user's RID to it */
1697 if (!sid_append_rid(&sid
, q_u
->user_rid
))
1698 return NT_STATUS_NO_SUCH_USER
;
1700 /* check if access can be granted as requested by client. */
1701 samr_make_usr_obj_sd(p
->mem_ctx
, &psd
, &sd_size
, &sid
);
1702 se_map_generic(&des_access
, &usr_generic_mapping
);
1703 if (!NT_STATUS_IS_OK(nt_status
=
1704 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
1705 des_access
, &acc_granted
, "_samr_open_user"))) {
1710 ret
=pdb_getsampwsid(sampass
, &sid
);
1713 /* check that the SID exists in our domain. */
1715 return NT_STATUS_NO_SUCH_USER
;
1718 pdb_free_sam(&sampass
);
1720 /* associate the user's SID and access bits with the new handle. */
1721 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
)
1722 return NT_STATUS_NO_MEMORY
;
1723 info
->acc_granted
= acc_granted
;
1725 /* get a (unique) handle. open a policy on it. */
1726 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
))
1727 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1732 /*************************************************************************
1733 get_user_info_10. Safe. Only gives out acb bits.
1734 *************************************************************************/
1736 static NTSTATUS
get_user_info_10(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_10
*id10
, DOM_SID
*user_sid
)
1738 SAM_ACCOUNT
*smbpass
=NULL
;
1742 nt_status
= pdb_init_sam_talloc(mem_ctx
, &smbpass
);
1744 if (!NT_STATUS_IS_OK(nt_status
)) {
1749 ret
= pdb_getsampwsid(smbpass
, user_sid
);
1753 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1754 return NT_STATUS_NO_SUCH_USER
;
1757 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass
) ));
1760 init_sam_user_info10(id10
, pdb_get_acct_ctrl(smbpass
) );
1762 pdb_free_sam(&smbpass
);
1764 return NT_STATUS_OK
;
1767 /*************************************************************************
1768 get_user_info_12. OK - this is the killer as it gives out password info.
1769 Ensure that this is only allowed on an encrypted connection with a root
1771 *************************************************************************/
1773 static NTSTATUS
get_user_info_12(pipes_struct
*p
, TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_12
* id12
, DOM_SID
*user_sid
)
1775 SAM_ACCOUNT
*smbpass
=NULL
;
1779 if (!p
->ntlmssp_auth_validated
)
1780 return NT_STATUS_ACCESS_DENIED
;
1782 if (!(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SIGN
) || !(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SEAL
))
1783 return NT_STATUS_ACCESS_DENIED
;
1786 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1789 nt_status
= pdb_init_sam_talloc(mem_ctx
, &smbpass
);
1791 if (!NT_STATUS_IS_OK(nt_status
)) {
1795 ret
= pdb_getsampwsid(smbpass
, user_sid
);
1798 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid
)));
1799 pdb_free_sam(&smbpass
);
1800 return (geteuid() == (uid_t
)0) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
1803 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
1805 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
1806 pdb_free_sam(&smbpass
);
1807 return NT_STATUS_ACCOUNT_DISABLED
;
1811 init_sam_user_info12(id12
, pdb_get_lanman_passwd(smbpass
), pdb_get_nt_passwd(smbpass
));
1813 pdb_free_sam(&smbpass
);
1815 return NT_STATUS_OK
;
1818 /*************************************************************************
1820 *************************************************************************/
1822 static NTSTATUS
get_user_info_20(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_20
*id20
, DOM_SID
*user_sid
)
1824 SAM_ACCOUNT
*sampass
=NULL
;
1827 pdb_init_sam_talloc(mem_ctx
, &sampass
);
1830 ret
= pdb_getsampwsid(sampass
, user_sid
);
1834 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1835 return NT_STATUS_NO_SUCH_USER
;
1838 samr_clear_sam_passwd(sampass
);
1840 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1843 init_sam_user_info20A(id20
, sampass
);
1845 pdb_free_sam(&sampass
);
1847 return NT_STATUS_OK
;
1850 /*************************************************************************
1852 *************************************************************************/
1854 static NTSTATUS
get_user_info_21(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_21
*id21
,
1855 DOM_SID
*user_sid
, DOM_SID
*domain_sid
)
1857 SAM_ACCOUNT
*sampass
=NULL
;
1861 nt_status
= pdb_init_sam_talloc(mem_ctx
, &sampass
);
1862 if (!NT_STATUS_IS_OK(nt_status
)) {
1867 ret
= pdb_getsampwsid(sampass
, user_sid
);
1871 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1872 return NT_STATUS_NO_SUCH_USER
;
1875 samr_clear_sam_passwd(sampass
);
1877 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1880 nt_status
= init_sam_user_info21A(id21
, sampass
, domain_sid
);
1882 pdb_free_sam(&sampass
);
1884 return NT_STATUS_OK
;
1887 /*******************************************************************
1888 _samr_query_userinfo
1889 ********************************************************************/
1891 NTSTATUS
_samr_query_userinfo(pipes_struct
*p
, SAMR_Q_QUERY_USERINFO
*q_u
, SAMR_R_QUERY_USERINFO
*r_u
)
1893 SAM_USERINFO_CTR
*ctr
;
1894 struct samr_info
*info
= NULL
;
1898 r_u
->status
=NT_STATUS_OK
;
1900 /* search for the handle */
1901 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1902 return NT_STATUS_INVALID_HANDLE
;
1904 domain_sid
= info
->sid
;
1906 sid_split_rid(&domain_sid
, &rid
);
1908 if (!sid_check_is_in_our_domain(&info
->sid
))
1909 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1911 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info
->sid
)));
1913 ctr
= (SAM_USERINFO_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USERINFO_CTR
));
1915 return NT_STATUS_NO_MEMORY
;
1919 /* ok! user info levels (lots: see MSDEV help), off we go... */
1920 ctr
->switch_value
= q_u
->switch_value
;
1922 switch (q_u
->switch_value
) {
1924 ctr
->info
.id10
= (SAM_USER_INFO_10
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USER_INFO_10
));
1925 if (ctr
->info
.id10
== NULL
)
1926 return NT_STATUS_NO_MEMORY
;
1928 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_10(p
->mem_ctx
, ctr
->info
.id10
, &info
->sid
)))
1933 /* whoops - got this wrong. i think. or don't understand what's happening. */
1937 info
= (void *)&id11
;
1939 expire
.low
= 0xffffffff;
1940 expire
.high
= 0x7fffffff;
1942 ctr
->info
.id
= (SAM_USER_INFO_11
*)talloc_zero(p
->mem_ctx
,
1947 ZERO_STRUCTP(ctr
->info
.id11
);
1948 init_sam_user_info11(ctr
->info
.id11
, &expire
,
1949 "BROOKFIELDS$", /* name */
1950 0x03ef, /* user rid */
1951 0x201, /* group rid */
1952 0x0080); /* acb info */
1959 ctr
->info
.id12
= (SAM_USER_INFO_12
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USER_INFO_12
));
1960 if (ctr
->info
.id12
== NULL
)
1961 return NT_STATUS_NO_MEMORY
;
1963 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_12(p
, p
->mem_ctx
, ctr
->info
.id12
, &info
->sid
)))
1968 ctr
->info
.id20
= (SAM_USER_INFO_20
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_USER_INFO_20
));
1969 if (ctr
->info
.id20
== NULL
)
1970 return NT_STATUS_NO_MEMORY
;
1971 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_20(p
->mem_ctx
, ctr
->info
.id20
, &info
->sid
)))
1976 ctr
->info
.id21
= (SAM_USER_INFO_21
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_USER_INFO_21
));
1977 if (ctr
->info
.id21
== NULL
)
1978 return NT_STATUS_NO_MEMORY
;
1979 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_21(p
->mem_ctx
, ctr
->info
.id21
,
1980 &info
->sid
, &domain_sid
)))
1985 return NT_STATUS_INVALID_INFO_CLASS
;
1988 init_samr_r_query_userinfo(r_u
, ctr
, r_u
->status
);
1990 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__
));
1995 /*******************************************************************
1996 samr_reply_query_usergroups
1997 ********************************************************************/
1999 NTSTATUS
_samr_query_usergroups(pipes_struct
*p
, SAMR_Q_QUERY_USERGROUPS
*q_u
, SAMR_R_QUERY_USERGROUPS
*r_u
)
2001 SAM_ACCOUNT
*sam_pass
=NULL
;
2003 DOM_GID
*gids
= NULL
;
2009 * from the SID in the request:
2010 * we should send back the list of DOMAIN GROUPS
2011 * the user is a member of
2013 * and only the DOMAIN GROUPS
2014 * no ALIASES !!! neither aliases of the domain
2015 * nor aliases of the builtin SID
2020 r_u
->status
= NT_STATUS_OK
;
2022 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
2024 /* find the policy handle. open a policy on it. */
2025 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
2026 return NT_STATUS_INVALID_HANDLE
;
2028 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_USER_GET_GROUPS
, "_samr_query_usergroups"))) {
2032 if (!sid_check_is_in_our_domain(&sid
))
2033 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
2035 pdb_init_sam(&sam_pass
);
2038 ret
= pdb_getsampwsid(sam_pass
, &sid
);
2042 pdb_free_sam(&sam_pass
);
2043 return NT_STATUS_NO_SUCH_USER
;
2046 if(!get_domain_user_groups(p
->mem_ctx
, &num_groups
, &gids
, sam_pass
)) {
2047 pdb_free_sam(&sam_pass
);
2048 return NT_STATUS_NO_SUCH_GROUP
;
2051 /* construct the response. lkclXXXX: gids are not copied! */
2052 init_samr_r_query_usergroups(r_u
, num_groups
, gids
, r_u
->status
);
2054 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
2056 pdb_free_sam(&sam_pass
);
2061 /*******************************************************************
2062 _samr_query_dom_info
2063 ********************************************************************/
2065 NTSTATUS
_samr_query_dom_info(pipes_struct
*p
, SAMR_Q_QUERY_DOMAIN_INFO
*q_u
, SAMR_R_QUERY_DOMAIN_INFO
*r_u
)
2067 struct samr_info
*info
= NULL
;
2069 uint32 min_pass_len
,pass_hist
,flag
;
2070 time_t u_expire
, u_min_age
;
2071 NTTIME nt_expire
, nt_min_age
;
2073 time_t u_lock_duration
, u_reset_time
;
2074 NTTIME nt_lock_duration
, nt_reset_time
;
2080 uint32 account_policy_temp
;
2082 uint32 num_users
=0, num_groups
=0, num_aliases
=0;
2084 if ((ctr
= (SAM_UNK_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_UNK_CTR
))) == NULL
)
2085 return NT_STATUS_NO_MEMORY
;
2089 r_u
->status
= NT_STATUS_OK
;
2091 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
2093 /* find the policy handle. open a policy on it. */
2094 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
2095 return NT_STATUS_INVALID_HANDLE
;
2097 switch (q_u
->switch_value
) {
2100 account_policy_get(AP_MIN_PASSWORD_LEN
, &account_policy_temp
);
2101 min_pass_len
= account_policy_temp
;
2103 account_policy_get(AP_PASSWORD_HISTORY
, &account_policy_temp
);
2104 pass_hist
= account_policy_temp
;
2106 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS
, &account_policy_temp
);
2107 flag
= account_policy_temp
;
2109 account_policy_get(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
2110 u_expire
= account_policy_temp
;
2112 account_policy_get(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
2113 u_min_age
= account_policy_temp
;
2115 unix_to_nt_time_abs(&nt_expire
, u_expire
);
2116 unix_to_nt_time_abs(&nt_min_age
, u_min_age
);
2118 init_unk_info1(&ctr
->info
.inf1
, (uint16
)min_pass_len
, (uint16
)pass_hist
,
2119 flag
, nt_expire
, nt_min_age
);
2123 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
, False
);
2125 if (!NT_STATUS_IS_OK(r_u
->status
)) {
2126 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2129 num_users
=info
->disp_info
.num_user_account
;
2132 r_u
->status
=load_group_domain_entries(info
, get_global_sam_sid());
2133 if (!NT_STATUS_IS_OK(r_u
->status
)) {
2134 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2137 num_groups
=info
->disp_info
.num_group_account
;
2140 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2141 init_unk_info2(&ctr
->info
.inf2
, lp_workgroup(), global_myname(), (uint32
) time(NULL
),
2142 num_users
, num_groups
, num_aliases
);
2145 account_policy_get(AP_TIME_TO_LOGOUT
, (int *)&u_logout
);
2146 unix_to_nt_time_abs(&nt_logout
, u_logout
);
2148 init_unk_info3(&ctr
->info
.inf3
, nt_logout
);
2151 init_unk_info5(&ctr
->info
.inf5
, global_myname());
2154 init_unk_info6(&ctr
->info
.inf6
);
2157 init_unk_info7(&ctr
->info
.inf7
);
2160 account_policy_get(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
2161 u_lock_duration
= account_policy_temp
;
2163 account_policy_get(AP_RESET_COUNT_TIME
, &account_policy_temp
);
2164 u_reset_time
= account_policy_temp
;
2166 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
2167 lockout
= account_policy_temp
;
2169 unix_to_nt_time_abs(&nt_lock_duration
, u_lock_duration
);
2170 unix_to_nt_time_abs(&nt_reset_time
, u_reset_time
);
2172 init_unk_info12(&ctr
->info
.inf12
, nt_lock_duration
, nt_reset_time
, (uint16
)lockout
);
2175 return NT_STATUS_INVALID_INFO_CLASS
;
2178 init_samr_r_query_dom_info(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_OK
);
2180 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
2185 /*******************************************************************
2186 _api_samr_create_user
2187 Create an account, can be either a normal user or a machine.
2188 This funcion will need to be updated for bdc/domain trusts.
2189 ********************************************************************/
2191 NTSTATUS
_api_samr_create_user(pipes_struct
*p
, SAMR_Q_CREATE_USER
*q_u
, SAMR_R_CREATE_USER
*r_u
)
2193 SAM_ACCOUNT
*sam_pass
=NULL
;
2197 POLICY_HND dom_pol
= q_u
->domain_pol
;
2198 UNISTR2 user_account
= q_u
->uni_name
;
2199 uint16 acb_info
= q_u
->acb_info
;
2200 POLICY_HND
*user_pol
= &r_u
->user_pol
;
2201 struct samr_info
*info
= NULL
;
2208 uint32 des_access
= GENERIC_RIGHTS_USER_ALL_ACCESS
;
2210 /* Get the domain SID stored in the domain policy */
2211 if (!get_lsa_policy_samr_sid(p
, &dom_pol
, &sid
, &acc_granted
))
2212 return NT_STATUS_INVALID_HANDLE
;
2214 if (!NT_STATUS_IS_OK(nt_status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_CREATE_USER
, "_samr_create_user"))) {
2218 /* find the account: tell the caller if it exists.
2219 lkclXXXX i have *no* idea if this is a problem or not
2220 or even if you are supposed to construct a different
2221 reply if the account already exists...
2224 rpcstr_pull(account
, user_account
.buffer
, sizeof(account
), user_account
.uni_str_len
*2, 0);
2227 pdb_init_sam(&sam_pass
);
2230 ret
= pdb_getsampwnam(sam_pass
, account
);
2233 /* this account exists: say so */
2234 pdb_free_sam(&sam_pass
);
2235 return NT_STATUS_USER_EXISTS
;
2238 pdb_free_sam(&sam_pass
);
2241 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2242 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2243 * that only people with write access to the smbpasswd file will be able
2244 * to create a user. JRA.
2248 * add the user in the /etc/passwd file or the unix authority system.
2249 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2250 * a) local_password_change() checks for us if the /etc/passwd account really exists
2251 * b) smb_create_user() would return an error if the account already exists
2252 * and as it could return an error also if it can't create the account, it would be tricky.
2254 * So we go the easy way, only check after if the account exists.
2255 * JFM (2/3/2001), to clear any possible bad understanding (-:
2257 * We now have seperate script paramaters for adding users/machines so we
2258 * now have some sainity-checking to match.
2261 DEBUG(10,("checking account %s at pos %d for $ termination\n",account
, strlen(account
)-1));
2263 if ((acb_info
& ACB_WSTRUST
) && (account
[strlen(account
)-1] == '$')) {
2264 pstrcpy(add_script
, lp_addmachine_script());
2265 } else if ((!(acb_info
& ACB_WSTRUST
)) && (account
[strlen(account
)-1] != '$')) {
2266 pstrcpy(add_script
, lp_adduser_script());
2268 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2269 pdb_free_sam(&sam_pass
);
2270 return NT_STATUS_UNSUCCESSFUL
;
2275 * we can't check both the ending $ and the acb_info.
2277 * UserManager creates trust accounts (ending in $,
2278 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2281 if (account
[strlen(account
)-1] == '$')
2282 pstrcpy(add_script
, lp_addmachine_script());
2284 pstrcpy(add_script
, lp_adduser_script());
2288 all_string_sub(add_script
, "%u", account
, sizeof(account
));
2289 add_ret
= smbrun(add_script
,NULL
);
2290 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script
, add_ret
));
2293 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_sam(&sam_pass
))) {
2297 pw
= getpwnam_alloc(account
);
2302 if (!uid_to_sid(&user_sid
, pw
->pw_uid
)) {
2303 passwd_free(&pw
); /* done with this now */
2304 pdb_free_sam(&sam_pass
);
2305 DEBUG(1, ("_api_samr_create_user: uid_to_sid failed, cannot add user.\n"));
2306 return NT_STATUS_ACCESS_DENIED
;
2309 if (!pdb_set_user_sid(sam_pass
, &user_sid
, PDB_CHANGED
)) {
2310 passwd_free(&pw
); /* done with this now */
2311 pdb_free_sam(&sam_pass
);
2312 return NT_STATUS_NO_MEMORY
;
2315 if (!gid_to_sid(&group_sid
, pw
->pw_gid
)) {
2316 passwd_free(&pw
); /* done with this now */
2317 pdb_free_sam(&sam_pass
);
2318 DEBUG(1, ("_api_samr_create_user: gid_to_sid failed, cannot add user.\n"));
2319 return NT_STATUS_ACCESS_DENIED
;
2322 if (!pdb_set_group_sid(sam_pass
, &group_sid
, PDB_CHANGED
)) {
2323 passwd_free(&pw
); /* done with this now */
2324 pdb_free_sam(&sam_pass
);
2325 return NT_STATUS_NO_MEMORY
;
2328 passwd_free(&pw
); /* done with this now */
2330 DEBUG(3,("attempting to create non-unix account %s\n", account
));
2334 if (!pdb_set_username(sam_pass
, account
, PDB_CHANGED
)) {
2335 pdb_free_sam(&sam_pass
);
2336 return NT_STATUS_NO_MEMORY
;
2339 pdb_set_acct_ctrl(sam_pass
, acb_info
, PDB_CHANGED
);
2341 if (!pdb_add_sam_account(sam_pass
)) {
2342 pdb_free_sam(&sam_pass
);
2343 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2345 return NT_STATUS_ACCESS_DENIED
;
2348 pdb_reset_sam(sam_pass
);
2350 if (!pdb_getsampwnam(sam_pass
, account
)) {
2351 pdb_free_sam(&sam_pass
);
2352 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n",
2354 return NT_STATUS_ACCESS_DENIED
;
2357 /* Get the user's SID */
2358 sid_copy(&sid
, pdb_get_user_sid(sam_pass
));
2360 samr_make_usr_obj_sd(p
->mem_ctx
, &psd
, &sd_size
, &sid
);
2361 se_map_generic(&des_access
, &usr_generic_mapping
);
2362 if (!NT_STATUS_IS_OK(nt_status
=
2363 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2364 des_access
, &acc_granted
, "_samr_create_user"))) {
2368 /* associate the user's SID with the new handle. */
2369 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
) {
2370 pdb_free_sam(&sam_pass
);
2371 return NT_STATUS_NO_MEMORY
;
2376 info
->acc_granted
= acc_granted
;
2378 /* get a (unique) handle. open a policy on it. */
2379 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
)) {
2380 pdb_free_sam(&sam_pass
);
2381 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2384 r_u
->user_rid
=pdb_get_user_rid(sam_pass
);
2386 r_u
->access_granted
= acc_granted
;
2388 pdb_free_sam(&sam_pass
);
2390 return NT_STATUS_OK
;
2393 /*******************************************************************
2394 samr_reply_connect_anon
2395 ********************************************************************/
2397 NTSTATUS
_samr_connect_anon(pipes_struct
*p
, SAMR_Q_CONNECT_ANON
*q_u
, SAMR_R_CONNECT_ANON
*r_u
)
2399 struct samr_info
*info
= NULL
;
2403 if (!pipe_access_check(p
)) {
2404 DEBUG(3, ("access denied to samr_connect_anon\n"));
2405 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2409 /* set up the SAMR connect_anon response */
2411 r_u
->status
= NT_STATUS_OK
;
2413 /* associate the user's SID with the new handle. */
2414 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2415 return NT_STATUS_NO_MEMORY
;
2417 info
->status
= q_u
->unknown_0
;
2419 /* get a (unique) handle. open a policy on it. */
2420 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2421 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2426 /*******************************************************************
2428 ********************************************************************/
2430 NTSTATUS
_samr_connect(pipes_struct
*p
, SAMR_Q_CONNECT
*q_u
, SAMR_R_CONNECT
*r_u
)
2432 struct samr_info
*info
= NULL
;
2433 SEC_DESC
*psd
= NULL
;
2435 uint32 des_access
= q_u
->access_mask
;
2440 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2444 if (!pipe_access_check(p
)) {
2445 DEBUG(3, ("access denied to samr_connect\n"));
2446 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2450 samr_make_sam_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
2451 se_map_generic(&des_access
, &sam_generic_mapping
);
2452 if (!NT_STATUS_IS_OK(nt_status
=
2453 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2454 des_access
, &acc_granted
, "_samr_connect"))) {
2458 r_u
->status
= NT_STATUS_OK
;
2460 /* associate the user's SID and access granted with the new handle. */
2461 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2462 return NT_STATUS_NO_MEMORY
;
2464 info
->acc_granted
= acc_granted
;
2465 info
->status
= q_u
->access_mask
;
2467 /* get a (unique) handle. open a policy on it. */
2468 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2469 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2471 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2476 /*******************************************************************
2478 ********************************************************************/
2480 NTSTATUS
_samr_connect4(pipes_struct
*p
, SAMR_Q_CONNECT4
*q_u
, SAMR_R_CONNECT4
*r_u
)
2482 struct samr_info
*info
= NULL
;
2483 SEC_DESC
*psd
= NULL
;
2485 uint32 des_access
= q_u
->access_mask
;
2490 DEBUG(5,("_samr_connect4: %d\n", __LINE__
));
2494 if (!pipe_access_check(p
)) {
2495 DEBUG(3, ("access denied to samr_connect4\n"));
2496 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2500 samr_make_sam_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
2501 se_map_generic(&des_access
, &sam_generic_mapping
);
2502 if (!NT_STATUS_IS_OK(nt_status
=
2503 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2504 des_access
, &acc_granted
, "_samr_connect"))) {
2508 r_u
->status
= NT_STATUS_OK
;
2510 /* associate the user's SID and access granted with the new handle. */
2511 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2512 return NT_STATUS_NO_MEMORY
;
2514 info
->acc_granted
= acc_granted
;
2515 info
->status
= q_u
->access_mask
;
2517 /* get a (unique) handle. open a policy on it. */
2518 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2519 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2521 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2526 /**********************************************************************
2527 api_samr_lookup_domain
2528 **********************************************************************/
2530 NTSTATUS
_samr_lookup_domain(pipes_struct
*p
, SAMR_Q_LOOKUP_DOMAIN
*q_u
, SAMR_R_LOOKUP_DOMAIN
*r_u
)
2532 struct samr_info
*info
;
2533 fstring domain_name
;
2536 r_u
->status
= NT_STATUS_OK
;
2538 if (!find_policy_by_hnd(p
, &q_u
->connect_pol
, (void**)&info
))
2539 return NT_STATUS_INVALID_HANDLE
;
2541 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_SAM_OPEN_DOMAIN
, "_samr_lookup_domain"))) {
2545 rpcstr_pull(domain_name
, q_u
->uni_domain
.buffer
, sizeof(domain_name
), q_u
->uni_domain
.uni_str_len
*2, 0);
2549 if (!secrets_fetch_domain_sid(domain_name
, &sid
)) {
2550 r_u
->status
= NT_STATUS_NO_SUCH_DOMAIN
;
2553 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
, sid_string_static(&sid
)));
2555 init_samr_r_lookup_domain(r_u
, &sid
, r_u
->status
);
2560 /******************************************************************
2561 makes a SAMR_R_ENUM_DOMAINS structure.
2562 ********************************************************************/
2564 static BOOL
make_enum_domains(TALLOC_CTX
*ctx
, SAM_ENTRY
**pp_sam
,
2565 UNISTR2
**pp_uni_name
, uint32 num_sam_entries
, fstring doms
[])
2571 DEBUG(5, ("make_enum_domains\n"));
2574 *pp_uni_name
= NULL
;
2576 if (num_sam_entries
== 0)
2579 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
2580 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
2582 if (sam
== NULL
|| uni_name
== NULL
)
2585 for (i
= 0; i
< num_sam_entries
; i
++) {
2586 int len
= doms
[i
] != NULL
? strlen(doms
[i
]) : 0;
2588 init_sam_entry(&sam
[i
], len
, 0);
2589 init_unistr2(&uni_name
[i
], doms
[i
], len
);
2593 *pp_uni_name
= uni_name
;
2598 /**********************************************************************
2599 api_samr_enum_domains
2600 **********************************************************************/
2602 NTSTATUS
_samr_enum_domains(pipes_struct
*p
, SAMR_Q_ENUM_DOMAINS
*q_u
, SAMR_R_ENUM_DOMAINS
*r_u
)
2604 struct samr_info
*info
;
2605 uint32 num_entries
= 2;
2609 r_u
->status
= NT_STATUS_OK
;
2611 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void**)&info
))
2612 return NT_STATUS_INVALID_HANDLE
;
2614 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_SAM_ENUM_DOMAINS
, "_samr_enum_domains"))) {
2618 switch (lp_server_role()) {
2619 case ROLE_DOMAIN_PDC
:
2620 case ROLE_DOMAIN_BDC
:
2621 name
= lp_workgroup();
2624 name
= global_myname();
2627 fstrcpy(dom
[0],name
);
2629 fstrcpy(dom
[1],"Builtin");
2631 if (!make_enum_domains(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_dom_name
, num_entries
, dom
))
2632 return NT_STATUS_NO_MEMORY
;
2634 init_samr_r_enum_domains(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
2639 /*******************************************************************
2641 ********************************************************************/
2643 NTSTATUS
_api_samr_open_alias(pipes_struct
*p
, SAMR_Q_OPEN_ALIAS
*q_u
, SAMR_R_OPEN_ALIAS
*r_u
)
2646 POLICY_HND domain_pol
= q_u
->dom_pol
;
2647 uint32 alias_rid
= q_u
->rid_alias
;
2648 POLICY_HND
*alias_pol
= &r_u
->pol
;
2649 struct samr_info
*info
= NULL
;
2650 SEC_DESC
*psd
= NULL
;
2652 uint32 des_access
= q_u
->access_mask
;
2656 r_u
->status
= NT_STATUS_OK
;
2658 /* find the domain policy and get the SID / access bits stored in the domain policy */
2659 if (!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
, &acc_granted
))
2660 return NT_STATUS_INVALID_HANDLE
;
2662 if (!NT_STATUS_IS_OK(status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_open_alias"))) {
2666 /* append the alias' RID to it */
2667 if (!sid_append_rid(&sid
, alias_rid
))
2668 return NT_STATUS_NO_SUCH_USER
;
2670 /*check if access can be granted as requested by client. */
2671 samr_make_ali_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
2672 se_map_generic(&des_access
,&ali_generic_mapping
);
2673 if (!NT_STATUS_IS_OK(status
=
2674 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2675 des_access
, &acc_granted
, "_samr_open_alias"))) {
2680 * we should check if the rid really exist !!!
2684 /* associate the user's SID with the new handle. */
2685 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
)
2686 return NT_STATUS_NO_MEMORY
;
2688 info
->acc_granted
= acc_granted
;
2690 /* get a (unique) handle. open a policy on it. */
2691 if (!create_policy_hnd(p
, alias_pol
, free_samr_info
, (void *)info
))
2692 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2697 /*******************************************************************
2699 ********************************************************************/
2701 static BOOL
set_user_info_10(const SAM_USER_INFO_10
*id10
, DOM_SID
*sid
)
2703 SAM_ACCOUNT
*pwd
=NULL
;
2708 ret
= pdb_getsampwsid(pwd
, sid
);
2716 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2721 /* FIX ME: check if the value is really changed --metze */
2722 if (!pdb_set_acct_ctrl(pwd
, id10
->acb_info
, PDB_CHANGED
)) {
2727 if(!pdb_update_sam_account(pwd
)) {
2737 /*******************************************************************
2739 ********************************************************************/
2741 static BOOL
set_user_info_12(SAM_USER_INFO_12
*id12
, DOM_SID
*sid
)
2743 SAM_ACCOUNT
*pwd
= NULL
;
2747 if(!pdb_getsampwsid(pwd
, sid
)) {
2753 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2758 if (!pdb_set_lanman_passwd (pwd
, id12
->lm_pwd
, PDB_CHANGED
)) {
2762 if (!pdb_set_nt_passwd (pwd
, id12
->nt_pwd
, PDB_CHANGED
)) {
2766 if (!pdb_set_pass_changed_now (pwd
)) {
2771 if(!pdb_update_sam_account(pwd
)) {
2780 /*******************************************************************
2782 ********************************************************************/
2784 static BOOL
set_user_info_21(SAM_USER_INFO_21
*id21
, DOM_SID
*sid
)
2786 SAM_ACCOUNT
*pwd
= NULL
;
2789 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2795 if (!pdb_getsampwsid(pwd
, sid
)) {
2800 copy_id21_to_sam_passwd(pwd
, id21
);
2803 * The funny part about the previous two calls is
2804 * that pwd still has the password hashes from the
2805 * passdb entry. These have not been updated from
2806 * id21. I don't know if they need to be set. --jerry
2809 /* write the change out */
2810 if(!pdb_update_sam_account(pwd
)) {
2820 /*******************************************************************
2822 ********************************************************************/
2824 static BOOL
set_user_info_23(SAM_USER_INFO_23
*id23
, DOM_SID
*sid
)
2826 SAM_ACCOUNT
*pwd
= NULL
;
2827 pstring plaintext_buf
;
2832 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2838 if (!pdb_getsampwsid(pwd
, sid
)) {
2843 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2844 pdb_get_username(pwd
)));
2846 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2848 if (!decode_pw_buffer((char*)id23
->pass
, plaintext_buf
, 256, &len
)) {
2853 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
2858 copy_id23_to_sam_passwd(pwd
, id23
);
2860 /* if it's a trust account, don't update /etc/passwd */
2861 if ( (!IS_SAM_UNIX_USER(pwd
)) ||
2862 ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2863 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2864 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2865 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2867 /* update the UNIX password */
2868 if (lp_unix_password_sync() )
2869 if(!chgpasswd(pdb_get_username(pwd
), "", plaintext_buf
, True
)) {
2875 ZERO_STRUCT(plaintext_buf
);
2877 if(!pdb_update_sam_account(pwd
)) {
2887 /*******************************************************************
2889 ********************************************************************/
2891 static BOOL
set_user_info_pw(char *pass
, DOM_SID
*sid
)
2893 SAM_ACCOUNT
*pwd
= NULL
;
2895 pstring plaintext_buf
;
2900 if (!pdb_getsampwsid(pwd
, sid
)) {
2905 DEBUG(5, ("Attempting administrator password change for user %s\n",
2906 pdb_get_username(pwd
)));
2908 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2910 ZERO_STRUCT(plaintext_buf
);
2912 if (!decode_pw_buffer(pass
, plaintext_buf
, 256, &len
)) {
2917 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
2922 /* if it's a trust account, don't update /etc/passwd */
2923 if ( (!IS_SAM_UNIX_USER(pwd
)) ||
2924 ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2925 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2926 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2927 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2929 /* update the UNIX password */
2930 if (lp_unix_password_sync()) {
2931 if(!chgpasswd(pdb_get_username(pwd
), "", plaintext_buf
, True
)) {
2938 ZERO_STRUCT(plaintext_buf
);
2940 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2942 /* update the SAMBA password */
2943 if(!pdb_update_sam_account(pwd
)) {
2953 /*******************************************************************
2954 samr_reply_set_userinfo
2955 ********************************************************************/
2957 NTSTATUS
_samr_set_userinfo(pipes_struct
*p
, SAMR_Q_SET_USERINFO
*q_u
, SAMR_R_SET_USERINFO
*r_u
)
2960 POLICY_HND
*pol
= &q_u
->pol
;
2961 uint16 switch_value
= q_u
->switch_value
;
2962 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
2964 uint32 acc_required
;
2966 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__
));
2968 r_u
->status
= NT_STATUS_OK
;
2970 /* find the policy handle. open a policy on it. */
2971 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
, &acc_granted
))
2972 return NT_STATUS_INVALID_HANDLE
;
2974 acc_required
= SA_RIGHT_USER_SET_LOC_COM
| SA_RIGHT_USER_SET_ATTRIBUTES
; /* This is probably wrong */
2975 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, acc_required
, "_samr_set_userinfo"))) {
2979 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid
), switch_value
));
2982 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2983 return NT_STATUS_INVALID_INFO_CLASS
;
2986 /* ok! user info levels (lots: see MSDEV help), off we go... */
2987 switch (switch_value
) {
2989 if (!set_user_info_12(ctr
->info
.id12
, &sid
))
2990 return NT_STATUS_ACCESS_DENIED
;
2994 SamOEMhash(ctr
->info
.id24
->pass
, p
->session_key
, 516);
2996 dump_data(100, (char *)ctr
->info
.id24
->pass
, 516);
2998 if (!set_user_info_pw((char *)ctr
->info
.id24
->pass
, &sid
))
2999 return NT_STATUS_ACCESS_DENIED
;
3005 * Currently we don't really know how to unmarshall
3006 * the level 25 struct, and the password encryption
3007 * is different. This is a placeholder for when we
3008 * do understand it. In the meantime just return INVALID
3009 * info level and W2K SP2 drops down to level 23... JRA.
3012 SamOEMhash(ctr
->info
.id25
->pass
, p
->session_key
, 532);
3014 dump_data(100, (char *)ctr
->info
.id25
->pass
, 532);
3016 if (!set_user_info_pw(ctr
->info
.id25
->pass
, &sid
))
3017 return NT_STATUS_ACCESS_DENIED
;
3020 return NT_STATUS_INVALID_INFO_CLASS
;
3023 SamOEMhash(ctr
->info
.id23
->pass
, p
->session_key
, 516);
3025 dump_data(100, (char *)ctr
->info
.id23
->pass
, 516);
3027 if (!set_user_info_23(ctr
->info
.id23
, &sid
))
3028 return NT_STATUS_ACCESS_DENIED
;
3032 return NT_STATUS_INVALID_INFO_CLASS
;
3038 /*******************************************************************
3039 samr_reply_set_userinfo2
3040 ********************************************************************/
3042 NTSTATUS
_samr_set_userinfo2(pipes_struct
*p
, SAMR_Q_SET_USERINFO2
*q_u
, SAMR_R_SET_USERINFO2
*r_u
)
3045 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
3046 POLICY_HND
*pol
= &q_u
->pol
;
3047 uint16 switch_value
= q_u
->switch_value
;
3049 uint32 acc_required
;
3051 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__
));
3053 r_u
->status
= NT_STATUS_OK
;
3055 /* find the policy handle. open a policy on it. */
3056 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
, &acc_granted
))
3057 return NT_STATUS_INVALID_HANDLE
;
3059 acc_required
= SA_RIGHT_USER_SET_LOC_COM
| SA_RIGHT_USER_SET_ATTRIBUTES
; /* This is probably wrong */
3060 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, acc_required
, "_samr_set_userinfo2"))) {
3064 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid
)));
3067 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3068 return NT_STATUS_INVALID_INFO_CLASS
;
3071 switch_value
=ctr
->switch_value
;
3073 /* ok! user info levels (lots: see MSDEV help), off we go... */
3074 switch (switch_value
) {
3076 if (!set_user_info_21(ctr
->info
.id21
, &sid
))
3077 return NT_STATUS_ACCESS_DENIED
;
3080 if (!set_user_info_10(ctr
->info
.id10
, &sid
))
3081 return NT_STATUS_ACCESS_DENIED
;
3084 /* Used by AS/U JRA. */
3085 if (!set_user_info_12(ctr
->info
.id12
, &sid
))
3086 return NT_STATUS_ACCESS_DENIED
;
3089 return NT_STATUS_INVALID_INFO_CLASS
;
3095 /*********************************************************************
3096 _samr_query_aliasmem
3097 *********************************************************************/
3099 NTSTATUS
_samr_query_useraliases(pipes_struct
*p
, SAMR_Q_QUERY_USERALIASES
*q_u
, SAMR_R_QUERY_USERALIASES
*r_u
)
3101 int num_groups
= 0, tmp_num_groups
=0;
3102 uint32
*rids
=NULL
, *new_rids
=NULL
, *tmp_rids
=NULL
;
3103 struct samr_info
*info
= NULL
;
3109 /* until i see a real useraliases query, we fack one up */
3111 /* I have seen one, JFM 2/12/2001 */
3113 * Explanation of what this call does:
3114 * for all the SID given in the request:
3115 * return a list of alias (local groups)
3116 * that have those SID as members.
3118 * and that's the alias in the domain specified
3119 * in the policy_handle
3121 * if the policy handle is on an incorrect sid
3122 * for example a user's sid
3123 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3126 r_u
->status
= NT_STATUS_OK
;
3128 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__
));
3130 /* find the policy handle. open a policy on it. */
3131 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
3132 return NT_STATUS_INVALID_HANDLE
;
3134 ntstatus1
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM
, "_samr_query_useraliases");
3135 ntstatus2
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_query_useraliases");
3137 if (!NT_STATUS_IS_OK(ntstatus1
) || !NT_STATUS_IS_OK(ntstatus2
)) {
3138 if (!(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus2
)) &&
3139 !(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus1
))) {
3140 return (NT_STATUS_IS_OK(ntstatus1
)) ? ntstatus2
: ntstatus1
;
3144 if (!sid_check_is_domain(&info
->sid
) &&
3145 !sid_check_is_builtin(&info
->sid
))
3146 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3149 for (i
=0; i
<q_u
->num_sids1
; i
++) {
3151 r_u
->status
=get_alias_user_groups(p
->mem_ctx
, &info
->sid
, &tmp_num_groups
, &tmp_rids
, &(q_u
->sid
[i
].sid
));
3154 * if there is an error, we just continue as
3155 * it can be an unfound user or group
3157 if (!NT_STATUS_IS_OK(r_u
->status
)) {
3158 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3162 if (tmp_num_groups
==0) {
3163 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3167 new_rids
=(uint32
*)talloc_realloc(p
->mem_ctx
, rids
, (num_groups
+tmp_num_groups
)*sizeof(uint32
));
3168 if (new_rids
==NULL
) {
3169 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3170 return NT_STATUS_NO_MEMORY
;
3174 for (j
=0; j
<tmp_num_groups
; j
++)
3175 rids
[j
+num_groups
]=tmp_rids
[j
];
3177 safe_free(tmp_rids
);
3179 num_groups
+=tmp_num_groups
;
3182 init_samr_r_query_useraliases(r_u
, num_groups
, rids
, NT_STATUS_OK
);
3183 return NT_STATUS_OK
;
3186 /*********************************************************************
3187 _samr_query_aliasmem
3188 *********************************************************************/
3190 NTSTATUS
_samr_query_aliasmem(pipes_struct
*p
, SAMR_Q_QUERY_ALIASMEM
*q_u
, SAMR_R_QUERY_ALIASMEM
*r_u
)
3202 fstring alias_sid_str
;
3205 SAM_ACCOUNT
*sam_user
= NULL
;
3209 /* find the policy handle. open a policy on it. */
3210 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3211 return NT_STATUS_INVALID_HANDLE
;
3213 if (!NT_STATUS_IS_OK(r_u
->status
=
3214 access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_GET_MEMBERS
, "_samr_query_aliasmem"))) {
3218 sid_copy(&als_sid
, &alias_sid
);
3219 sid_to_string(alias_sid_str
, &alias_sid
);
3220 sid_split_rid(&alias_sid
, &alias_rid
);
3222 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3224 if (sid_equal(&alias_sid
, &global_sid_Builtin
)) {
3225 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3226 if(!get_builtin_group_from_sid(als_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3227 return NT_STATUS_NO_SUCH_ALIAS
;
3229 if (sid_equal(&alias_sid
, get_global_sam_sid())) {
3230 DEBUG(10, ("lookup on Server SID\n"));
3231 if(!get_local_group_from_sid(als_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3232 return NT_STATUS_NO_SUCH_ALIAS
;
3236 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
3237 return NT_STATUS_NO_SUCH_ALIAS
;
3239 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3240 sid
= (DOM_SID2
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_SID2
) * num_uids
);
3241 if (num_uids
!=0 && sid
== NULL
)
3242 return NT_STATUS_NO_MEMORY
;
3244 for (i
= 0; i
< num_uids
; i
++) {
3245 struct passwd
*pass
;
3248 sid_copy(&temp_sid
, get_global_sam_sid());
3250 pass
= getpwuid_alloc(uid
[i
]);
3251 if (!pass
) continue;
3253 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user
))) {
3259 check
= pdb_getsampwnam(sam_user
, pass
->pw_name
);
3262 if (check
!= True
) {
3263 pdb_free_sam(&sam_user
);
3268 rid
= pdb_get_user_rid(sam_user
);
3270 pdb_free_sam(&sam_user
);
3275 pdb_free_sam(&sam_user
);
3278 sid_append_rid(&temp_sid
, rid
);
3280 init_dom_sid2(&sid
[i
], &temp_sid
);
3283 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3284 init_samr_r_query_aliasmem(r_u
, num_uids
, sid
, NT_STATUS_OK
);
3286 return NT_STATUS_OK
;
3289 /*********************************************************************
3290 _samr_query_groupmem
3291 *********************************************************************/
3293 NTSTATUS
_samr_query_groupmem(pipes_struct
*p
, SAMR_Q_QUERY_GROUPMEM
*q_u
, SAMR_R_QUERY_GROUPMEM
*r_u
)
3299 fstring group_sid_str
;
3307 SAM_ACCOUNT
*sam_user
= NULL
;
3311 /* find the policy handle. open a policy on it. */
3312 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
, &acc_granted
))
3313 return NT_STATUS_INVALID_HANDLE
;
3315 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_GET_MEMBERS
, "_samr_query_groupmem"))) {
3319 /* todo: change to use sid_compare_front */
3321 sid_split_rid(&group_sid
, &group_rid
);
3322 sid_to_string(group_sid_str
, &group_sid
);
3323 DEBUG(10, ("sid is %s\n", group_sid_str
));
3325 /* can we get a query for an SID outside our domain ? */
3326 if (!sid_equal(&group_sid
, get_global_sam_sid()))
3327 return NT_STATUS_NO_SUCH_GROUP
;
3329 sid_append_rid(&group_sid
, group_rid
);
3330 DEBUG(10, ("lookup on Domain SID\n"));
3332 if(!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3333 return NT_STATUS_NO_SUCH_GROUP
;
3335 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
3336 return NT_STATUS_NO_SUCH_GROUP
;
3338 rid
=talloc_zero(p
->mem_ctx
, sizeof(uint32
)*num_uids
);
3339 attr
=talloc_zero(p
->mem_ctx
, sizeof(uint32
)*num_uids
);
3341 if (num_uids
!=0 && (rid
==NULL
|| attr
==NULL
))
3342 return NT_STATUS_NO_MEMORY
;
3344 for (i
=0; i
<num_uids
; i
++) {
3345 struct passwd
*pass
;
3348 pass
= getpwuid_alloc(uid
[i
]);
3349 if (!pass
) continue;
3351 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user
))) {
3357 check
= pdb_getsampwnam(sam_user
, pass
->pw_name
);
3360 if (check
!= True
) {
3361 pdb_free_sam(&sam_user
);
3366 urid
= pdb_get_user_rid(sam_user
);
3368 pdb_free_sam(&sam_user
);
3373 pdb_free_sam(&sam_user
);
3377 attr
[i
] = SID_NAME_USER
;
3380 init_samr_r_query_groupmem(r_u
, num_uids
, rid
, attr
, NT_STATUS_OK
);
3382 return NT_STATUS_OK
;
3385 /*********************************************************************
3387 *********************************************************************/
3389 NTSTATUS
_samr_add_aliasmem(pipes_struct
*p
, SAMR_Q_ADD_ALIASMEM
*q_u
, SAMR_R_ADD_ALIASMEM
*r_u
)
3392 fstring alias_sid_str
;
3399 SAM_ACCOUNT
*sam_user
= NULL
;
3403 /* Find the policy handle. Open a policy on it. */
3404 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3405 return NT_STATUS_INVALID_HANDLE
;
3407 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_ADD_MEMBER
, "_samr_add_aliasmem"))) {
3411 sid_to_string(alias_sid_str
, &alias_sid
);
3412 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3414 if (sid_compare(&alias_sid
, get_global_sam_sid())>0) {
3415 DEBUG(10, ("adding member on Server SID\n"));
3416 if(!get_local_group_from_sid(alias_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3417 return NT_STATUS_NO_SUCH_ALIAS
;
3420 if (sid_compare(&alias_sid
, &global_sid_Builtin
)>0) {
3421 DEBUG(10, ("adding member on BUILTIN SID\n"));
3422 if( !get_local_group_from_sid(alias_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3423 return NT_STATUS_NO_SUCH_ALIAS
;
3426 return NT_STATUS_NO_SUCH_ALIAS
;
3429 ret
= pdb_init_sam(&sam_user
);
3430 if (!NT_STATUS_IS_OK(ret
))
3433 check
= pdb_getsampwsid(sam_user
, &q_u
->sid
.sid
);
3435 if (check
!= True
) {
3436 pdb_free_sam(&sam_user
);
3437 return NT_STATUS_NO_SUCH_USER
;
3440 uid
= pdb_get_uid(sam_user
);
3442 pdb_free_sam(&sam_user
);
3443 return NT_STATUS_NO_SUCH_USER
;
3446 pdb_free_sam(&sam_user
);
3448 if ((pwd
=getpwuid_alloc(uid
)) == NULL
) {
3449 return NT_STATUS_NO_SUCH_USER
;
3452 if ((grp
=getgrgid(map
.gid
)) == NULL
) {
3454 return NT_STATUS_NO_SUCH_ALIAS
;
3457 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3458 fstrcpy(grp_name
, grp
->gr_name
);
3460 /* if the user is already in the group */
3461 if(user_in_unix_group_list(pwd
->pw_name
, grp_name
)) {
3463 return NT_STATUS_MEMBER_IN_ALIAS
;
3467 * ok, the group exist, the user exist, the user is not in the group,
3468 * we can (finally) add it to the group !
3470 smb_add_user_group(grp_name
, pwd
->pw_name
);
3472 /* check if the user has been added then ... */
3473 if(!user_in_unix_group_list(pwd
->pw_name
, grp_name
)) {
3475 return NT_STATUS_MEMBER_NOT_IN_ALIAS
; /* don't know what to reply else */
3479 return NT_STATUS_OK
;
3482 /*********************************************************************
3484 *********************************************************************/
3486 NTSTATUS
_samr_del_aliasmem(pipes_struct
*p
, SAMR_Q_DEL_ALIASMEM
*q_u
, SAMR_R_DEL_ALIASMEM
*r_u
)
3489 fstring alias_sid_str
;
3493 SAM_ACCOUNT
*sam_pass
=NULL
;
3496 /* Find the policy handle. Open a policy on it. */
3497 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3498 return NT_STATUS_INVALID_HANDLE
;
3500 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_REMOVE_MEMBER
, "_samr_del_aliasmem"))) {
3504 sid_to_string(alias_sid_str
, &alias_sid
);
3505 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str
));
3507 if (!sid_check_is_in_our_domain(&alias_sid
) &&
3508 !sid_check_is_in_builtin(&alias_sid
)) {
3509 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3510 return NT_STATUS_NO_SUCH_ALIAS
;
3513 if( !get_local_group_from_sid(alias_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3514 return NT_STATUS_NO_SUCH_ALIAS
;
3516 if ((grp
=getgrgid(map
.gid
)) == NULL
)
3517 return NT_STATUS_NO_SUCH_ALIAS
;
3519 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3520 fstrcpy(grp_name
, grp
->gr_name
);
3522 /* check if the user exists before trying to remove it from the group */
3523 pdb_init_sam(&sam_pass
);
3524 if(!pdb_getsampwsid(sam_pass
, &q_u
->sid
.sid
)) {
3525 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass
)));
3526 pdb_free_sam(&sam_pass
);
3527 return NT_STATUS_NO_SUCH_USER
;
3530 /* if the user is not in the group */
3531 if(!user_in_unix_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3532 pdb_free_sam(&sam_pass
);
3533 return NT_STATUS_MEMBER_IN_ALIAS
;
3536 smb_delete_user_group(grp_name
, pdb_get_username(sam_pass
));
3538 /* check if the user has been removed then ... */
3539 if(user_in_unix_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3540 pdb_free_sam(&sam_pass
);
3541 return NT_STATUS_MEMBER_NOT_IN_ALIAS
; /* don't know what to reply else */
3544 pdb_free_sam(&sam_pass
);
3545 return NT_STATUS_OK
;
3548 /*********************************************************************
3550 *********************************************************************/
3552 NTSTATUS
_samr_add_groupmem(pipes_struct
*p
, SAMR_Q_ADD_GROUPMEM
*q_u
, SAMR_R_ADD_GROUPMEM
*r_u
)
3556 fstring group_sid_str
;
3563 SAM_ACCOUNT
*sam_user
=NULL
;
3567 /* Find the policy handle. Open a policy on it. */
3568 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
3569 return NT_STATUS_INVALID_HANDLE
;
3571 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_ADD_MEMBER
, "_samr_add_groupmem"))) {
3575 sid_to_string(group_sid_str
, &group_sid
);
3576 DEBUG(10, ("sid is %s\n", group_sid_str
));
3578 if (sid_compare(&group_sid
, get_global_sam_sid())<=0)
3579 return NT_STATUS_NO_SUCH_GROUP
;
3581 DEBUG(10, ("lookup on Domain SID\n"));
3583 if(!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3584 return NT_STATUS_NO_SUCH_GROUP
;
3586 sid_copy(&user_sid
, get_global_sam_sid());
3587 sid_append_rid(&user_sid
, q_u
->rid
);
3589 ret
= pdb_init_sam(&sam_user
);
3590 if (!NT_STATUS_IS_OK(ret
))
3593 check
= pdb_getsampwsid(sam_user
, &user_sid
);
3595 if (check
!= True
) {
3596 pdb_free_sam(&sam_user
);
3597 return NT_STATUS_NO_SUCH_USER
;
3600 uid
= pdb_get_uid(sam_user
);
3602 pdb_free_sam(&sam_user
);
3603 return NT_STATUS_NO_SUCH_USER
;
3606 pdb_free_sam(&sam_user
);
3608 if ((pwd
=getpwuid_alloc(uid
)) == NULL
) {
3609 return NT_STATUS_NO_SUCH_USER
;
3612 if ((grp
=getgrgid(map
.gid
)) == NULL
) {
3614 return NT_STATUS_NO_SUCH_GROUP
;
3617 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3618 fstrcpy(grp_name
, grp
->gr_name
);
3620 /* if the user is already in the group */
3621 if(user_in_unix_group_list(pwd
->pw_name
, grp_name
)) {
3623 return NT_STATUS_MEMBER_IN_GROUP
;
3627 * ok, the group exist, the user exist, the user is not in the group,
3629 * we can (finally) add it to the group !
3632 smb_add_user_group(grp_name
, pwd
->pw_name
);
3634 /* check if the user has been added then ... */
3635 if(!user_in_unix_group_list(pwd
->pw_name
, grp_name
)) {
3637 return NT_STATUS_MEMBER_NOT_IN_GROUP
; /* don't know what to reply else */
3641 return NT_STATUS_OK
;
3644 /*********************************************************************
3646 *********************************************************************/
3648 NTSTATUS
_samr_del_groupmem(pipes_struct
*p
, SAMR_Q_DEL_GROUPMEM
*q_u
, SAMR_R_DEL_GROUPMEM
*r_u
)
3652 SAM_ACCOUNT
*sam_pass
=NULL
;
3659 * delete the group member named q_u->rid
3660 * who is a member of the sid associated with the handle
3661 * the rid is a user's rid as the group is a domain group.
3664 /* Find the policy handle. Open a policy on it. */
3665 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
3666 return NT_STATUS_INVALID_HANDLE
;
3668 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_REMOVE_MEMBER
, "_samr_del_groupmem"))) {
3672 if (!sid_check_is_in_our_domain(&group_sid
))
3673 return NT_STATUS_NO_SUCH_GROUP
;
3675 sid_copy(&user_sid
, get_global_sam_sid());
3676 sid_append_rid(&user_sid
, q_u
->rid
);
3678 if (!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3679 return NT_STATUS_NO_SUCH_GROUP
;
3681 if ((grp
=getgrgid(map
.gid
)) == NULL
)
3682 return NT_STATUS_NO_SUCH_GROUP
;
3684 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3685 fstrcpy(grp_name
, grp
->gr_name
);
3687 /* check if the user exists before trying to remove it from the group */
3688 pdb_init_sam(&sam_pass
);
3689 if (!pdb_getsampwsid(sam_pass
, &user_sid
)) {
3690 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass
)));
3691 pdb_free_sam(&sam_pass
);
3692 return NT_STATUS_NO_SUCH_USER
;
3695 /* if the user is not in the group */
3696 if (!user_in_unix_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3697 pdb_free_sam(&sam_pass
);
3698 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
3701 smb_delete_user_group(grp_name
, pdb_get_username(sam_pass
));
3703 /* check if the user has been removed then ... */
3704 if (user_in_unix_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3705 pdb_free_sam(&sam_pass
);
3706 return NT_STATUS_ACCESS_DENIED
; /* don't know what to reply else */
3709 pdb_free_sam(&sam_pass
);
3710 return NT_STATUS_OK
;
3714 /****************************************************************************
3715 Delete a UNIX user on demand.
3716 ****************************************************************************/
3718 static int smb_delete_user(const char *unix_user
)
3723 pstrcpy(del_script
, lp_deluser_script());
3726 all_string_sub(del_script
, "%u", unix_user
, sizeof(pstring
));
3727 ret
= smbrun(del_script
,NULL
);
3728 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script
,ret
));
3732 /*********************************************************************
3733 _samr_delete_dom_user
3734 *********************************************************************/
3736 NTSTATUS
_samr_delete_dom_user(pipes_struct
*p
, SAMR_Q_DELETE_DOM_USER
*q_u
, SAMR_R_DELETE_DOM_USER
*r_u
)
3739 SAM_ACCOUNT
*sam_pass
=NULL
;
3742 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__
));
3744 /* Find the policy handle. Open a policy on it. */
3745 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &user_sid
, &acc_granted
))
3746 return NT_STATUS_INVALID_HANDLE
;
3748 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_user"))) {
3752 if (!sid_check_is_in_our_domain(&user_sid
))
3753 return NT_STATUS_CANNOT_DELETE
;
3755 /* check if the user exists before trying to delete */
3756 pdb_init_sam(&sam_pass
);
3757 if(!pdb_getsampwsid(sam_pass
, &user_sid
)) {
3758 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass
)));
3759 pdb_free_sam(&sam_pass
);
3760 return NT_STATUS_NO_SUCH_USER
;
3763 /* delete the unix side */
3765 * note: we don't check if the delete really happened
3766 * as the script is not necessary present
3767 * and maybe the sysadmin doesn't want to delete the unix side
3769 smb_delete_user(pdb_get_username(sam_pass
));
3771 /* and delete the samba side */
3772 if (!pdb_delete_sam_account(sam_pass
)) {
3773 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass
)));
3774 pdb_free_sam(&sam_pass
);
3775 return NT_STATUS_CANNOT_DELETE
;
3778 pdb_free_sam(&sam_pass
);
3780 if (!close_policy_hnd(p
, &q_u
->user_pol
))
3781 return NT_STATUS_OBJECT_NAME_INVALID
;
3783 return NT_STATUS_OK
;
3786 /*********************************************************************
3787 _samr_delete_dom_group
3788 *********************************************************************/
3790 NTSTATUS
_samr_delete_dom_group(pipes_struct
*p
, SAMR_Q_DELETE_DOM_GROUP
*q_u
, SAMR_R_DELETE_DOM_GROUP
*r_u
)
3795 fstring group_sid_str
;
3801 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__
));
3803 /* Find the policy handle. Open a policy on it. */
3804 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
, &acc_granted
))
3805 return NT_STATUS_INVALID_HANDLE
;
3807 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_group"))) {
3811 sid_copy(&dom_sid
, &group_sid
);
3812 sid_to_string(group_sid_str
, &dom_sid
);
3813 sid_split_rid(&dom_sid
, &group_rid
);
3815 DEBUG(10, ("sid is %s\n", group_sid_str
));
3817 /* we check if it's our SID before deleting */
3818 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
3819 return NT_STATUS_NO_SUCH_GROUP
;
3821 DEBUG(10, ("lookup on Domain SID\n"));
3823 if(!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3824 return NT_STATUS_NO_SUCH_GROUP
;
3828 /* check if group really exists */
3829 if ( (grp
=getgrgid(gid
)) == NULL
)
3830 return NT_STATUS_NO_SUCH_GROUP
;
3832 /* we can delete the UNIX group */
3833 smb_delete_group(grp
->gr_name
);
3835 /* check if the group has been successfully deleted */
3836 if ( (grp
=getgrgid(gid
)) != NULL
)
3837 return NT_STATUS_ACCESS_DENIED
;
3839 if(!pdb_delete_group_mapping_entry(group_sid
))
3840 return NT_STATUS_ACCESS_DENIED
;
3842 if (!close_policy_hnd(p
, &q_u
->group_pol
))
3843 return NT_STATUS_OBJECT_NAME_INVALID
;
3845 return NT_STATUS_OK
;
3848 /*********************************************************************
3849 _samr_delete_dom_alias
3850 *********************************************************************/
3852 NTSTATUS
_samr_delete_dom_alias(pipes_struct
*p
, SAMR_Q_DELETE_DOM_ALIAS
*q_u
, SAMR_R_DELETE_DOM_ALIAS
*r_u
)
3857 fstring alias_sid_str
;
3863 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__
));
3865 /* Find the policy handle. Open a policy on it. */
3866 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3867 return NT_STATUS_INVALID_HANDLE
;
3869 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_alias"))) {
3873 sid_copy(&dom_sid
, &alias_sid
);
3874 sid_to_string(alias_sid_str
, &dom_sid
);
3875 sid_split_rid(&dom_sid
, &alias_rid
);
3877 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3879 /* we check if it's our SID before deleting */
3880 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
3881 return NT_STATUS_NO_SUCH_ALIAS
;
3883 DEBUG(10, ("lookup on Local SID\n"));
3885 if(!get_local_group_from_sid(alias_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3886 return NT_STATUS_NO_SUCH_ALIAS
;
3890 /* check if group really exists */
3891 if ( (grp
=getgrgid(gid
)) == NULL
)
3892 return NT_STATUS_NO_SUCH_ALIAS
;
3894 /* we can delete the UNIX group */
3895 smb_delete_group(grp
->gr_name
);
3897 /* check if the group has been successfully deleted */
3898 if ( (grp
=getgrgid(gid
)) != NULL
)
3899 return NT_STATUS_ACCESS_DENIED
;
3901 /* don't check if we removed it as it could be an un-mapped group */
3902 pdb_delete_group_mapping_entry(alias_sid
);
3904 if (!close_policy_hnd(p
, &q_u
->alias_pol
))
3905 return NT_STATUS_OBJECT_NAME_INVALID
;
3907 return NT_STATUS_OK
;
3910 /*********************************************************************
3911 _samr_create_dom_group
3912 *********************************************************************/
3914 NTSTATUS
_samr_create_dom_group(pipes_struct
*p
, SAMR_Q_CREATE_DOM_GROUP
*q_u
, SAMR_R_CREATE_DOM_GROUP
*r_u
)
3921 struct samr_info
*info
;
3922 PRIVILEGE_SET priv_set
;
3926 init_privilege(&priv_set
);
3928 /* Find the policy handle. Open a policy on it. */
3929 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &dom_sid
, &acc_granted
))
3930 return NT_STATUS_INVALID_HANDLE
;
3932 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_CREATE_GROUP
, "_samr_create_dom_group"))) {
3936 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
3937 return NT_STATUS_ACCESS_DENIED
;
3939 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3941 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
3943 /* check if group already exist */
3944 if ((grp
=getgrnam(name
)) != NULL
)
3945 return NT_STATUS_GROUP_EXISTS
;
3947 /* we can create the UNIX group */
3948 if (smb_create_group(name
, &gid
) != 0)
3949 return NT_STATUS_ACCESS_DENIED
;
3951 /* check if the group has been successfully created */
3952 if ((grp
=getgrgid(gid
)) == NULL
)
3953 return NT_STATUS_ACCESS_DENIED
;
3955 r_u
->rid
=pdb_gid_to_group_rid(grp
->gr_gid
);
3957 /* add the group to the mapping table */
3958 sid_copy(&info_sid
, get_global_sam_sid());
3959 sid_append_rid(&info_sid
, r_u
->rid
);
3960 sid_to_string(sid_string
, &info_sid
);
3962 if(!add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_DOM_GRP
, name
, NULL
, priv_set
, PR_ACCESS_FROM_NETWORK
))
3963 return NT_STATUS_ACCESS_DENIED
;
3965 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
3966 return NT_STATUS_NO_MEMORY
;
3968 /* get a (unique) handle. open a policy on it. */
3969 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
3970 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3972 return NT_STATUS_OK
;
3975 /*********************************************************************
3976 _samr_create_dom_alias
3977 *********************************************************************/
3979 NTSTATUS
_samr_create_dom_alias(pipes_struct
*p
, SAMR_Q_CREATE_DOM_ALIAS
*q_u
, SAMR_R_CREATE_DOM_ALIAS
*r_u
)
3986 struct samr_info
*info
;
3987 PRIVILEGE_SET priv_set
;
3991 init_privilege(&priv_set
);
3993 /* Find the policy handle. Open a policy on it. */
3994 if (!get_lsa_policy_samr_sid(p
, &q_u
->dom_pol
, &dom_sid
, &acc_granted
))
3995 return NT_STATUS_INVALID_HANDLE
;
3997 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_CREATE_ALIAS
, "_samr_create_alias"))) {
4001 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
4002 return NT_STATUS_ACCESS_DENIED
;
4004 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4006 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
4008 /* check if group already exists */
4009 if ( (grp
=getgrnam(name
)) != NULL
)
4010 return NT_STATUS_GROUP_EXISTS
;
4012 /* we can create the UNIX group */
4013 if (smb_create_group(name
, &gid
) != 0)
4014 return NT_STATUS_ACCESS_DENIED
;
4016 /* check if the group has been successfully created */
4017 if ((grp
=getgrgid(gid
)) == NULL
)
4018 return NT_STATUS_ACCESS_DENIED
;
4020 r_u
->rid
=pdb_gid_to_group_rid(grp
->gr_gid
);
4022 sid_copy(&info_sid
, get_global_sam_sid());
4023 sid_append_rid(&info_sid
, r_u
->rid
);
4024 sid_to_string(sid_string
, &info_sid
);
4026 /* add the group to the mapping table */
4027 if(!add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_ALIAS
, name
, NULL
, priv_set
, PR_ACCESS_FROM_NETWORK
))
4028 return NT_STATUS_ACCESS_DENIED
;
4030 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4031 return NT_STATUS_NO_MEMORY
;
4033 /* get a (unique) handle. open a policy on it. */
4034 if (!create_policy_hnd(p
, &r_u
->alias_pol
, free_samr_info
, (void *)info
))
4035 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4037 return NT_STATUS_OK
;
4040 /*********************************************************************
4041 _samr_query_groupinfo
4043 sends the name/comment pair of a domain group
4044 level 1 send also the number of users of that group
4045 *********************************************************************/
4047 NTSTATUS
_samr_query_groupinfo(pipes_struct
*p
, SAMR_Q_QUERY_GROUPINFO
*q_u
, SAMR_R_QUERY_GROUPINFO
*r_u
)
4053 GROUP_INFO_CTR
*ctr
;
4056 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
4057 return NT_STATUS_INVALID_HANDLE
;
4059 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_LOOKUP_INFO
, "_samr_query_groupinfo"))) {
4063 if (!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITHOUT_PRIV
))
4064 return NT_STATUS_INVALID_HANDLE
;
4066 ctr
=(GROUP_INFO_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(GROUP_INFO_CTR
));
4068 return NT_STATUS_NO_MEMORY
;
4070 switch (q_u
->switch_level
) {
4072 ctr
->switch_value1
= 1;
4073 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
4074 return NT_STATUS_NO_SUCH_GROUP
;
4075 init_samr_group_info1(&ctr
->group
.info1
, map
.nt_name
, map
.comment
, num_uids
);
4079 ctr
->switch_value1
= 3;
4080 init_samr_group_info3(&ctr
->group
.info3
);
4083 ctr
->switch_value1
= 4;
4084 init_samr_group_info4(&ctr
->group
.info4
, map
.comment
);
4087 return NT_STATUS_INVALID_INFO_CLASS
;
4090 init_samr_r_query_groupinfo(r_u
, ctr
, NT_STATUS_OK
);
4092 return NT_STATUS_OK
;
4095 /*********************************************************************
4098 update a domain group's comment.
4099 *********************************************************************/
4101 NTSTATUS
_samr_set_groupinfo(pipes_struct
*p
, SAMR_Q_SET_GROUPINFO
*q_u
, SAMR_R_SET_GROUPINFO
*r_u
)
4105 GROUP_INFO_CTR
*ctr
;
4108 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
4109 return NT_STATUS_INVALID_HANDLE
;
4111 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_SET_INFO
, "_samr_set_groupinfo"))) {
4115 if (!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITH_PRIV
))
4116 return NT_STATUS_NO_SUCH_GROUP
;
4120 switch (ctr
->switch_value1
) {
4122 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info1
.uni_acct_desc
), sizeof(map
.comment
)-1);
4125 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info4
.uni_acct_desc
), sizeof(map
.comment
)-1);
4128 free_privilege(&map
.priv_set
);
4129 return NT_STATUS_INVALID_INFO_CLASS
;
4132 if(!pdb_update_group_mapping_entry(&map
)) {
4133 free_privilege(&map
.priv_set
);
4134 return NT_STATUS_NO_SUCH_GROUP
;
4137 free_privilege(&map
.priv_set
);
4139 return NT_STATUS_OK
;
4142 /*********************************************************************
4145 update an alias's comment.
4146 *********************************************************************/
4148 NTSTATUS
_samr_set_aliasinfo(pipes_struct
*p
, SAMR_Q_SET_ALIASINFO
*q_u
, SAMR_R_SET_ALIASINFO
*r_u
)
4152 ALIAS_INFO_CTR
*ctr
;
4155 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &group_sid
, &acc_granted
))
4156 return NT_STATUS_INVALID_HANDLE
;
4158 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_SET_INFO
, "_samr_set_aliasinfo"))) {
4162 if (!get_local_group_from_sid(group_sid
, &map
, MAPPING_WITH_PRIV
))
4163 return NT_STATUS_NO_SUCH_GROUP
;
4167 switch (ctr
->switch_value1
) {
4169 unistr2_to_ascii(map
.comment
, &(ctr
->alias
.info3
.uni_acct_desc
), sizeof(map
.comment
)-1);
4172 free_privilege(&map
.priv_set
);
4173 return NT_STATUS_INVALID_INFO_CLASS
;
4176 if(!pdb_update_group_mapping_entry(&map
)) {
4177 free_privilege(&map
.priv_set
);
4178 return NT_STATUS_NO_SUCH_GROUP
;
4181 free_privilege(&map
.priv_set
);
4183 return NT_STATUS_OK
;
4186 /*********************************************************************
4187 _samr_get_dom_pwinfo
4188 *********************************************************************/
4190 NTSTATUS
_samr_get_dom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_DOM_PWINFO
*q_u
, SAMR_R_GET_DOM_PWINFO
*r_u
)
4192 /* Perform access check. Since this rpc does not require a
4193 policy handle it will not be caught by the access checks on
4194 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4196 if (!pipe_access_check(p
)) {
4197 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4198 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
4202 /* Actually, returning zeros here works quite well :-). */
4204 return NT_STATUS_OK
;
4207 /*********************************************************************
4209 *********************************************************************/
4211 NTSTATUS
_samr_open_group(pipes_struct
*p
, SAMR_Q_OPEN_GROUP
*q_u
, SAMR_R_OPEN_GROUP
*r_u
)
4216 struct samr_info
*info
;
4217 SEC_DESC
*psd
= NULL
;
4224 if (!get_lsa_policy_samr_sid(p
, &q_u
->domain_pol
, &sid
, &acc_granted
))
4225 return NT_STATUS_INVALID_HANDLE
;
4227 if (!NT_STATUS_IS_OK(status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_open_group"))) {
4231 /*check if access can be granted as requested by client. */
4232 samr_make_grp_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
4233 se_map_generic(&des_access
,&grp_generic_mapping
);
4234 if (!NT_STATUS_IS_OK(status
=
4235 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
4236 des_access
, &acc_granted
, "_samr_open_group"))) {
4241 /* this should not be hard-coded like this */
4242 if (!sid_equal(&sid
, get_global_sam_sid()))
4243 return NT_STATUS_ACCESS_DENIED
;
4245 sid_copy(&info_sid
, get_global_sam_sid());
4246 sid_append_rid(&info_sid
, q_u
->rid_group
);
4247 sid_to_string(sid_string
, &info_sid
);
4249 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4250 return NT_STATUS_NO_MEMORY
;
4252 info
->acc_granted
= acc_granted
;
4254 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string
));
4256 /* check if that group really exists */
4257 if (!get_domain_group_from_sid(info
->sid
, &map
, MAPPING_WITHOUT_PRIV
))
4258 return NT_STATUS_NO_SUCH_GROUP
;
4260 /* get a (unique) handle. open a policy on it. */
4261 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
4262 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4264 return NT_STATUS_OK
;
4267 /*********************************************************************
4269 *********************************************************************/
4271 NTSTATUS
_samr_unknown_2d(pipes_struct
*p
, SAMR_Q_UNKNOWN_2D
*q_u
, SAMR_R_UNKNOWN_2D
*r_u
)
4273 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4274 return NT_STATUS_NOT_IMPLEMENTED
;
4277 /*******************************************************************
4279 ********************************************************************/
4281 NTSTATUS
_samr_unknown_2e(pipes_struct
*p
, SAMR_Q_UNKNOWN_2E
*q_u
, SAMR_R_UNKNOWN_2E
*r_u
)
4283 struct samr_info
*info
= NULL
;
4285 uint32 min_pass_len
,pass_hist
,flag
;
4286 time_t u_expire
, u_min_age
;
4287 NTTIME nt_expire
, nt_min_age
;
4289 time_t u_lock_duration
, u_reset_time
;
4290 NTTIME nt_lock_duration
, nt_reset_time
;
4296 uint32 num_users
=0, num_groups
=0, num_aliases
=0;
4298 uint32 account_policy_temp
;
4300 if ((ctr
= (SAM_UNK_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_UNK_CTR
))) == NULL
)
4301 return NT_STATUS_NO_MEMORY
;
4305 r_u
->status
= NT_STATUS_OK
;
4307 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__
));
4309 /* find the policy handle. open a policy on it. */
4310 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
4311 return NT_STATUS_INVALID_HANDLE
;
4313 switch (q_u
->switch_value
) {
4315 account_policy_get(AP_MIN_PASSWORD_LEN
, &account_policy_temp
);
4316 min_pass_len
= account_policy_temp
;
4318 account_policy_get(AP_PASSWORD_HISTORY
, &account_policy_temp
);
4319 pass_hist
= account_policy_temp
;
4321 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS
, &account_policy_temp
);
4322 flag
= account_policy_temp
;
4324 account_policy_get(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
4325 u_expire
= account_policy_temp
;
4327 account_policy_get(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
4328 u_min_age
= account_policy_temp
;
4330 unix_to_nt_time_abs(&nt_expire
, u_expire
);
4331 unix_to_nt_time_abs(&nt_min_age
, u_min_age
);
4333 init_unk_info1(&ctr
->info
.inf1
, (uint16
)min_pass_len
, (uint16
)pass_hist
,
4334 flag
, nt_expire
, nt_min_age
);
4338 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
, False
);
4340 if (!NT_STATUS_IS_OK(r_u
->status
)) {
4341 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4344 num_users
=info
->disp_info
.num_user_account
;
4347 r_u
->status
=load_group_domain_entries(info
, get_global_sam_sid());
4348 if (NT_STATUS_IS_ERR(r_u
->status
)) {
4349 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4352 num_groups
=info
->disp_info
.num_group_account
;
4355 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4356 init_unk_info2(&ctr
->info
.inf2
, lp_workgroup(), global_myname(), (uint32
) time(NULL
),
4357 num_users
, num_groups
, num_aliases
);
4360 account_policy_get(AP_TIME_TO_LOGOUT
, &account_policy_temp
);
4361 u_logout
= account_policy_temp
;
4363 unix_to_nt_time_abs(&nt_logout
, u_logout
);
4365 init_unk_info3(&ctr
->info
.inf3
, nt_logout
);
4368 init_unk_info5(&ctr
->info
.inf5
, global_myname());
4371 init_unk_info6(&ctr
->info
.inf6
);
4374 init_unk_info7(&ctr
->info
.inf7
);
4377 account_policy_get(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
4378 u_lock_duration
= account_policy_temp
;
4380 account_policy_get(AP_RESET_COUNT_TIME
, &account_policy_temp
);
4381 u_reset_time
= account_policy_temp
;
4383 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
4384 lockout
= account_policy_temp
;
4386 unix_to_nt_time_abs(&nt_lock_duration
, u_lock_duration
);
4387 unix_to_nt_time_abs(&nt_reset_time
, u_reset_time
);
4389 init_unk_info12(&ctr
->info
.inf12
, nt_lock_duration
, nt_reset_time
, (uint16
)lockout
);
4392 return NT_STATUS_INVALID_INFO_CLASS
;
4395 init_samr_r_samr_unknown_2e(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_OK
);
4397 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__
));
4402 /*******************************************************************
4404 ********************************************************************/
4406 NTSTATUS
_samr_set_dom_info(pipes_struct
*p
, SAMR_Q_SET_DOMAIN_INFO
*q_u
, SAMR_R_SET_DOMAIN_INFO
*r_u
)
4408 time_t u_expire
, u_min_age
;
4410 time_t u_lock_duration
, u_reset_time
;
4412 r_u
->status
= NT_STATUS_OK
;
4414 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__
));
4416 /* find the policy handle. open a policy on it. */
4417 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, NULL
))
4418 return NT_STATUS_INVALID_HANDLE
;
4420 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u
->switch_value
));
4422 switch (q_u
->switch_value
) {
4424 u_expire
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf1
.expire
);
4425 u_min_age
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf1
.min_passwordage
);
4427 account_policy_set(AP_MIN_PASSWORD_LEN
, (uint32
)q_u
->ctr
->info
.inf1
.min_length_password
);
4428 account_policy_set(AP_PASSWORD_HISTORY
, (uint32
)q_u
->ctr
->info
.inf1
.password_history
);
4429 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS
, (uint32
)q_u
->ctr
->info
.inf1
.flag
);
4430 account_policy_set(AP_MAX_PASSWORD_AGE
, (int)u_expire
);
4431 account_policy_set(AP_MIN_PASSWORD_AGE
, (int)u_min_age
);
4436 u_logout
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf3
.logout
);
4437 account_policy_set(AP_TIME_TO_LOGOUT
, (int)u_logout
);
4446 u_lock_duration
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf12
.duration
);
4447 u_reset_time
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf12
.reset_count
);
4449 account_policy_set(AP_LOCK_ACCOUNT_DURATION
, (int)u_lock_duration
);
4450 account_policy_set(AP_RESET_COUNT_TIME
, (int)u_reset_time
);
4451 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT
, (uint32
)q_u
->ctr
->info
.inf12
.bad_attempt_lockout
);
4454 return NT_STATUS_INVALID_INFO_CLASS
;
4457 init_samr_r_set_domain_info(r_u
, NT_STATUS_OK
);
4459 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__
));