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) Jim McDonough <jmcd@us.ibm.com> 2002.
11 * Copyright (C) Gerald (Jerry) Carter 2003.
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 SAM_ACCOUNT
*disp_user_info
;
49 uint32 num_group_account
;
50 DOMAIN_GRP
*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
;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
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 SAM_ACCOUNT
*sam
= &info
->disp_info
.disp_user_info
[i
];
165 /* Not really a free, actually a 'clear' */
169 info
->disp_info
.user_dbloaded
=False
;
170 info
->disp_info
.num_user_account
=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info
*info
)
179 /* Groups are talloced */
181 free_samr_users(info
);
183 info
->disp_info
.group_dbloaded
=False
;
184 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 SAM_ACCOUNT
*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
=(SAM_ACCOUNT
*)talloc_realloc(mem_ctx
, info
->disp_info
.disp_user_info
,
259 (info
->disp_info
.num_user_account
+MAX_SAM_ENTRIES
)*sizeof(SAM_ACCOUNT
));
262 return NT_STATUS_NO_MEMORY
;
264 info
->disp_info
.disp_user_info
=pwd_array
;
267 /* Copy the SAM_ACCOUNT into the array */
268 info
->disp_info
.disp_user_info
[info
->disp_info
.num_user_account
]=*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 DOMAIN_GRP
*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
)) {
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
=(DOMAIN_GRP
*)talloc(mem_ctx
, info
->disp_info
.num_group_account
*sizeof(DOMAIN_GRP
));
317 if (group_entries
!=0 && grp_array
==NULL
) {
318 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
320 return NT_STATUS_NO_MEMORY
;
323 info
->disp_info
.disp_group_info
=grp_array
;
325 for (i
=0; i
<group_entries
; i
++) {
326 fstrcpy(grp_array
[i
].name
, map
[i
].nt_name
);
327 fstrcpy(grp_array
[i
].comment
, map
[i
].comment
);
328 sid_split_rid(&map
[i
].sid
, &grp_array
[i
].rid
);
329 grp_array
[i
].attr
=SID_NAME_DOM_GRP
;
334 /* the snapshoot is in memory, we're ready to enumerate fast */
336 info
->disp_info
.group_dbloaded
=True
;
338 DEBUG(10,("load_group_domain_entries: done\n"));
344 /*******************************************************************
346 ********************************************************************/
348 NTSTATUS
_samr_close_hnd(pipes_struct
*p
, SAMR_Q_CLOSE_HND
*q_u
, SAMR_R_CLOSE_HND
*r_u
)
350 r_u
->status
= NT_STATUS_OK
;
352 /* close the policy handle */
353 if (!close_policy_hnd(p
, &q_u
->pol
))
354 return NT_STATUS_OBJECT_NAME_INVALID
;
356 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__
));
361 /*******************************************************************
362 samr_reply_open_domain
363 ********************************************************************/
365 NTSTATUS
_samr_open_domain(pipes_struct
*p
, SAMR_Q_OPEN_DOMAIN
*q_u
, SAMR_R_OPEN_DOMAIN
*r_u
)
367 struct samr_info
*info
;
368 SEC_DESC
*psd
= NULL
;
370 uint32 des_access
= q_u
->flags
;
374 r_u
->status
= NT_STATUS_OK
;
376 /* find the connection policy handle. */
377 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void**)&info
))
378 return NT_STATUS_INVALID_HANDLE
;
380 if (!NT_STATUS_IS_OK(status
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_SAM_OPEN_DOMAIN
,"_samr_open_domain"))) {
384 /*check if access can be granted as requested by client. */
385 samr_make_dom_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
386 se_map_generic(&des_access
,&dom_generic_mapping
);
388 if (!NT_STATUS_IS_OK(status
=
389 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
390 des_access
, &acc_granted
, "_samr_open_domain"))) {
394 /* associate the domain SID with the (unique) handle. */
395 if ((info
= get_samr_info_by_sid(&q_u
->dom_sid
.sid
))==NULL
)
396 return NT_STATUS_NO_MEMORY
;
397 info
->acc_granted
= acc_granted
;
399 /* get a (unique) handle. open a policy on it. */
400 if (!create_policy_hnd(p
, &r_u
->domain_pol
, free_samr_info
, (void *)info
))
401 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
403 DEBUG(5,("samr_open_domain: %d\n", __LINE__
));
408 /*******************************************************************
409 _samr_get_usrdom_pwinfo
410 ********************************************************************/
412 NTSTATUS
_samr_get_usrdom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_USRDOM_PWINFO
*q_u
, SAMR_R_GET_USRDOM_PWINFO
*r_u
)
414 struct samr_info
*info
= NULL
;
416 r_u
->status
= NT_STATUS_OK
;
418 /* find the policy handle. open a policy on it. */
419 if (!find_policy_by_hnd(p
, &q_u
->user_pol
, (void **)&info
))
420 return NT_STATUS_INVALID_HANDLE
;
422 if (!sid_check_is_in_our_domain(&info
->sid
))
423 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
425 init_samr_r_get_usrdom_pwinfo(r_u
, NT_STATUS_OK
);
427 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__
));
430 * NT sometimes return NT_STATUS_ACCESS_DENIED
431 * I don't know yet why.
437 /*******************************************************************
439 ********************************************************************/
441 static NTSTATUS
samr_make_dom_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
)
443 extern DOM_SID global_sid_World
;
452 sid_copy(&adm_sid
, &global_sid_Builtin
);
453 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
455 sid_copy(&act_sid
, &global_sid_Builtin
);
456 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
458 /*basic access for every one*/
459 init_sec_access(&mask
, GENERIC_RIGHTS_DOMAIN_EXECUTE
| GENERIC_RIGHTS_DOMAIN_READ
);
460 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
462 /*full access for builtin aliases Administrators and Account Operators*/
463 init_sec_access(&mask
, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS
);
464 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
465 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
467 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
468 return NT_STATUS_NO_MEMORY
;
470 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, SEC_DESC_SELF_RELATIVE
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
471 return NT_STATUS_NO_MEMORY
;
476 /*******************************************************************
478 ********************************************************************/
480 static NTSTATUS
samr_make_usr_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
, DOM_SID
*usr_sid
)
482 extern DOM_SID global_sid_World
;
491 sid_copy(&adm_sid
, &global_sid_Builtin
);
492 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
494 sid_copy(&act_sid
, &global_sid_Builtin
);
495 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
497 /*basic access for every one*/
498 init_sec_access(&mask
, GENERIC_RIGHTS_USER_EXECUTE
| GENERIC_RIGHTS_USER_READ
);
499 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
501 /*full access for builtin aliases Administrators and Account Operators*/
502 init_sec_access(&mask
, GENERIC_RIGHTS_USER_ALL_ACCESS
);
503 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
504 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
506 /*extended access for the user*/
507 init_sec_access(&mask
,READ_CONTROL_ACCESS
| SA_RIGHT_USER_CHANGE_PASSWORD
| SA_RIGHT_USER_SET_LOC_COM
);
508 init_sec_ace(&ace
[3], usr_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
510 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 4, ace
)) == NULL
)
511 return NT_STATUS_NO_MEMORY
;
513 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, SEC_DESC_SELF_RELATIVE
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
514 return NT_STATUS_NO_MEMORY
;
519 /*******************************************************************
521 ********************************************************************/
523 static NTSTATUS
samr_make_grp_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
)
525 extern DOM_SID global_sid_World
;
534 sid_copy(&adm_sid
, &global_sid_Builtin
);
535 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
537 sid_copy(&act_sid
, &global_sid_Builtin
);
538 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
540 /*basic access for every one*/
541 init_sec_access(&mask
, GENERIC_RIGHTS_GROUP_EXECUTE
| GENERIC_RIGHTS_GROUP_READ
);
542 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
544 /*full access for builtin aliases Administrators and Account Operators*/
545 init_sec_access(&mask
, GENERIC_RIGHTS_GROUP_ALL_ACCESS
);
546 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
547 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
549 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
550 return NT_STATUS_NO_MEMORY
;
552 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, SEC_DESC_SELF_RELATIVE
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
553 return NT_STATUS_NO_MEMORY
;
558 /*******************************************************************
560 ********************************************************************/
562 static NTSTATUS
samr_make_ali_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
)
564 extern DOM_SID global_sid_World
;
573 sid_copy(&adm_sid
, &global_sid_Builtin
);
574 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
576 sid_copy(&act_sid
, &global_sid_Builtin
);
577 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
579 /*basic access for every one*/
580 init_sec_access(&mask
, GENERIC_RIGHTS_ALIAS_EXECUTE
| GENERIC_RIGHTS_ALIAS_READ
);
581 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
583 /*full access for builtin aliases Administrators and Account Operators*/
584 init_sec_access(&mask
, GENERIC_RIGHTS_ALIAS_ALL_ACCESS
);
585 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
586 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
588 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
589 return NT_STATUS_NO_MEMORY
;
591 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, SEC_DESC_SELF_RELATIVE
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
592 return NT_STATUS_NO_MEMORY
;
597 static BOOL
get_lsa_policy_samr_sid(pipes_struct
*p
, POLICY_HND
*pol
, DOM_SID
*sid
, uint32
*acc_granted
)
599 struct samr_info
*info
= NULL
;
601 /* find the policy handle. open a policy on it. */
602 if (!find_policy_by_hnd(p
, pol
, (void **)&info
))
609 *acc_granted
= info
->acc_granted
;
613 /*******************************************************************
615 ********************************************************************/
617 NTSTATUS
_samr_set_sec_obj(pipes_struct
*p
, SAMR_Q_SET_SEC_OBJ
*q_u
, SAMR_R_SET_SEC_OBJ
*r_u
)
619 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
620 return NT_STATUS_NOT_IMPLEMENTED
;
624 /*******************************************************************
626 ********************************************************************/
628 NTSTATUS
_samr_query_sec_obj(pipes_struct
*p
, SAMR_Q_QUERY_SEC_OBJ
*q_u
, SAMR_R_QUERY_SEC_OBJ
*r_u
)
632 SEC_DESC
* psd
= NULL
;
636 r_u
->status
= NT_STATUS_OK
;
639 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &pol_sid
, &acc_granted
))
640 return NT_STATUS_INVALID_HANDLE
;
644 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
646 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
648 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
649 if (pol_sid
.sid_rev_num
== 0)
651 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
652 r_u
->status
= samr_make_sam_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
654 else if (sid_equal(&pol_sid
,get_global_sam_sid())) /* check if it is our domain SID */
657 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
658 r_u
->status
= samr_make_dom_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
660 else if (sid_equal(&pol_sid
,&global_sid_Builtin
)) /* check if it is the Builtin Domain */
662 /* TODO: Builtin probably needs a different SD with restricted write access*/
663 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
664 r_u
->status
= samr_make_dom_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
666 else if (sid_check_is_in_our_domain(&pol_sid
) ||
667 sid_check_is_in_builtin(&pol_sid
))
669 /* TODO: different SDs have to be generated for aliases groups and users.
670 Currently all three get a default user SD */
671 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
672 r_u
->status
= samr_make_usr_obj_sd(p
->mem_ctx
, &psd
,&sd_size
, &pol_sid
);
674 else return NT_STATUS_OBJECT_TYPE_MISMATCH
;
676 if ((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
677 return NT_STATUS_NO_MEMORY
;
679 if (NT_STATUS_IS_OK(r_u
->status
))
685 /*******************************************************************
686 makes a SAM_ENTRY / UNISTR2* structure from a user list.
687 ********************************************************************/
689 static NTSTATUS
make_user_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
690 uint32 num_entries
, uint32 start_idx
, SAM_ACCOUNT
*disp_user_info
,
696 SAM_ACCOUNT
*pwd
= NULL
;
697 UNISTR2 uni_temp_name
;
698 const char *temp_name
;
699 const DOM_SID
*user_sid
;
701 fstring user_sid_string
;
702 fstring domain_sid_string
;
707 if (num_entries
== 0)
710 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_entries
);
712 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_entries
);
714 if (sam
== NULL
|| uni_name
== NULL
) {
715 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
716 return NT_STATUS_NO_MEMORY
;
719 for (i
= 0; i
< num_entries
; i
++) {
720 pwd
= &disp_user_info
[i
+start_idx
];
721 temp_name
= pdb_get_username(pwd
);
722 init_unistr2(&uni_temp_name
, temp_name
, UNI_STR_TERMINATE
);
723 user_sid
= pdb_get_user_sid(pwd
);
725 if (!sid_peek_check_rid(domain_sid
, user_sid
, &user_rid
)) {
726 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
727 "the domain sid %s. Failing operation.\n",
729 sid_to_string(user_sid_string
, user_sid
),
730 sid_to_string(domain_sid_string
, domain_sid
)));
731 return NT_STATUS_UNSUCCESSFUL
;
734 init_sam_entry(&sam
[i
], &uni_temp_name
, user_rid
);
735 copy_unistr2(&uni_name
[i
], &uni_temp_name
);
739 *uni_name_pp
= uni_name
;
743 /*******************************************************************
744 samr_reply_enum_dom_users
745 ********************************************************************/
747 NTSTATUS
_samr_enum_dom_users(pipes_struct
*p
, SAMR_Q_ENUM_DOM_USERS
*q_u
,
748 SAMR_R_ENUM_DOM_USERS
*r_u
)
750 struct samr_info
*info
= NULL
;
751 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
753 uint32 enum_context
=q_u
->start_idx
;
754 uint32 max_size
=q_u
->max_size
;
756 enum remote_arch_types ra_type
= get_remote_arch();
757 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
758 uint32 max_entries
= max_sam_entries
;
761 r_u
->status
= NT_STATUS_OK
;
763 /* find the policy handle. open a policy on it. */
764 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
765 return NT_STATUS_INVALID_HANDLE
;
767 domain_sid
= info
->sid
;
769 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
,
770 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
,
771 "_samr_enum_dom_users"))) {
775 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
778 r_u
->status
=load_sampwd_entries(info
, q_u
->acb_mask
, False
);
781 if (!NT_STATUS_IS_OK(r_u
->status
))
784 num_account
= info
->disp_info
.num_user_account
;
786 if (enum_context
> num_account
) {
787 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
791 /* verify we won't overflow */
792 if (max_entries
> num_account
-enum_context
) {
793 max_entries
= num_account
-enum_context
;
794 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries
));
797 /* calculate the size and limit on the number of entries we will return */
798 temp_size
=max_entries
*struct_size
;
800 if (temp_size
>max_size
) {
801 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
802 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries
));
806 * Note from JRA. total_entries is not being used here. Currently if there is a
807 * large user base then it looks like NT will enumerate until get_sampwd_entries
808 * returns False due to num_entries being zero. This will cause an access denied
809 * return. I don't think this is right and needs further investigation. Note that
810 * this is also the same in the TNG code (I don't think that has been tested with
811 * a very large user list as MAX_SAM_ENTRIES is set to 600).
813 * I also think that one of the 'num_entries' return parameters is probably
814 * the "max entries" parameter - but in the TNG code they're all currently set to the same
815 * value (again I think this is wrong).
818 r_u
->status
= make_user_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_acct_name
,
819 max_entries
, enum_context
,
820 info
->disp_info
.disp_user_info
,
823 if (!NT_STATUS_IS_OK(r_u
->status
))
826 if (enum_context
+max_entries
< num_account
)
827 r_u
->status
= STATUS_MORE_ENTRIES
;
829 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__
));
831 init_samr_r_enum_dom_users(r_u
, q_u
->start_idx
+ max_entries
, max_entries
);
833 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
838 /*******************************************************************
839 makes a SAM_ENTRY / UNISTR2* structure from a group list.
840 ********************************************************************/
842 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
843 uint32 num_sam_entries
, DOMAIN_GRP
*grp
)
852 if (num_sam_entries
== 0)
855 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
857 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
859 if (sam
== NULL
|| uni_name
== NULL
) {
860 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
864 for (i
= 0; i
< num_sam_entries
; i
++) {
866 * JRA. I think this should include the null. TNG does not.
868 init_unistr2(&uni_name
[i
], grp
[i
].name
, UNI_STR_TERMINATE
);
869 init_sam_entry(&sam
[i
], &uni_name
[i
], grp
[i
].rid
);
873 *uni_name_pp
= uni_name
;
876 /*******************************************************************
877 Get the group entries - similar to get_sampwd_entries().
878 ********************************************************************/
880 static NTSTATUS
get_group_alias_entries(TALLOC_CTX
*ctx
, DOMAIN_GRP
**d_grp
, DOM_SID
*sid
, uint32 start_idx
,
881 uint32
*p_num_entries
, uint32 max_entries
)
884 uint32 num_entries
= 0;
887 GROUP_MAP
*map
= NULL
;
889 sid_to_string(sid_str
, sid
);
890 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str
));
894 /* well-known aliases */
895 if (sid_equal(sid
, &global_sid_Builtin
) && !lp_hide_local_users()) {
897 pdb_enum_group_mapping(SID_NAME_WKN_GRP
, &map
, (int *)&num_entries
, ENUM_ONLY_MAPPED
);
899 if (num_entries
!= 0) {
900 *d_grp
=(DOMAIN_GRP
*)talloc_zero(ctx
, num_entries
*sizeof(DOMAIN_GRP
));
902 return NT_STATUS_NO_MEMORY
;
904 for(i
=0; i
<num_entries
&& i
<max_entries
; i
++) {
905 fstrcpy((*d_grp
)[i
].name
, map
[i
+start_idx
].nt_name
);
906 sid_split_rid(&map
[i
+start_idx
].sid
, &(*d_grp
)[i
].rid
);
912 } else if (sid_equal(sid
, get_global_sam_sid()) && !lp_hide_local_users()) {
913 struct sys_grent
*glist
;
914 struct sys_grent
*grp
;
915 gid_t winbind_gid_low
, winbind_gid_high
;
916 BOOL winbind_groups_exist
= lp_idmap_gid(&winbind_gid_low
, &winbind_gid_high
);
919 /* we return the UNIX groups here. This seems to be the right */
920 /* thing to do, since NT member servers return their local */
921 /* groups in the same situation. */
923 /* use getgrent_list() to retrieve the list of groups to avoid
924 * problems with getgrent possible infinite loop by internal
925 * libc grent structures overwrites by called functions */
926 grp
= glist
= getgrent_list();
928 return NT_STATUS_NO_MEMORY
;
930 for (; (num_entries
< max_entries
) && (grp
!= NULL
); grp
= grp
->next
) {
933 if(!pdb_getgrgid(&smap
, grp
->gr_gid
))
936 if (smap
.sid_name_use
!=SID_NAME_ALIAS
) {
940 sid_split_rid(&smap
.sid
, &trid
);
942 if (!sid_equal(sid
, &smap
.sid
))
945 /* Don't return winbind groups as they are not local! */
946 if (winbind_groups_exist
&& (grp
->gr_gid
>= winbind_gid_low
)&&(grp
->gr_gid
<= winbind_gid_high
)) {
947 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap
.nt_name
));
951 /* Don't return user private groups... */
953 if (Get_Pwnam(smap
.nt_name
) != 0) {
954 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap
.nt_name
));
958 for( i
= 0; i
< num_entries
; i
++)
959 if ( (*d_grp
)[i
].rid
== trid
)
962 if ( i
< num_entries
) {
963 continue; /* rid was there, dup! */
966 /* JRA - added this for large group db enumeration... */
969 /* skip the requested number of entries.
970 not very efficient, but hey...
976 *d_grp
=talloc_realloc(ctx
,*d_grp
, (num_entries
+1)*sizeof(DOMAIN_GRP
));
979 return NT_STATUS_NO_MEMORY
;
982 fstrcpy((*d_grp
)[num_entries
].name
, smap
.nt_name
);
983 (*d_grp
)[num_entries
].rid
= trid
;
985 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries
, trid
));
991 *p_num_entries
= num_entries
;
993 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries
));
995 if (num_entries
>= max_entries
)
996 return STATUS_MORE_ENTRIES
;
1000 /*******************************************************************
1001 Get the group entries - similar to get_sampwd_entries().
1002 ********************************************************************/
1004 static NTSTATUS
get_group_domain_entries(TALLOC_CTX
*ctx
, DOMAIN_GRP
**d_grp
, DOM_SID
*sid
, uint32 start_idx
,
1005 uint32
*p_num_entries
, uint32 max_entries
)
1007 GROUP_MAP
*map
=NULL
;
1009 uint32 group_entries
= 0;
1010 uint32 num_entries
= 0;
1014 /* access checks for the users were performed higher up. become/unbecome_root()
1015 needed for some passdb backends to enumerate groups */
1018 pdb_enum_group_mapping(SID_NAME_DOM_GRP
, &map
, (int *)&group_entries
, ENUM_ONLY_MAPPED
);
1021 num_entries
=group_entries
-start_idx
;
1023 /* limit the number of entries */
1024 if (num_entries
>max_entries
) {
1025 DEBUG(5,("Limiting to %d entries\n", max_entries
));
1026 num_entries
=max_entries
;
1029 *d_grp
=(DOMAIN_GRP
*)talloc_zero(ctx
, num_entries
*sizeof(DOMAIN_GRP
));
1030 if (num_entries
!=0 && *d_grp
==NULL
){
1032 return NT_STATUS_NO_MEMORY
;
1035 for (i
=0; i
<num_entries
; i
++) {
1036 fstrcpy((*d_grp
)[i
].name
, map
[i
+start_idx
].nt_name
);
1037 fstrcpy((*d_grp
)[i
].comment
, map
[i
+start_idx
].comment
);
1038 sid_split_rid(&map
[i
+start_idx
].sid
, &(*d_grp
)[i
].rid
);
1039 (*d_grp
)[i
].attr
=SID_NAME_DOM_GRP
;
1044 *p_num_entries
= num_entries
;
1046 return NT_STATUS_OK
;
1049 /*******************************************************************
1050 samr_reply_enum_dom_groups
1051 ********************************************************************/
1053 NTSTATUS
_samr_enum_dom_groups(pipes_struct
*p
, SAMR_Q_ENUM_DOM_GROUPS
*q_u
, SAMR_R_ENUM_DOM_GROUPS
*r_u
)
1055 DOMAIN_GRP
*grp
=NULL
;
1060 r_u
->status
= NT_STATUS_OK
;
1062 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
1063 return NT_STATUS_INVALID_HANDLE
;
1065 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
, "_samr_enum_dom_groups"))) {
1069 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__
));
1071 /* the domain group array is being allocated in the function below */
1072 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
))) {
1076 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
1078 init_samr_r_enum_dom_groups(r_u
, q_u
->start_idx
, num_entries
);
1080 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__
));
1086 /*******************************************************************
1087 samr_reply_enum_dom_aliases
1088 ********************************************************************/
1090 NTSTATUS
_samr_enum_dom_aliases(pipes_struct
*p
, SAMR_Q_ENUM_DOM_ALIASES
*q_u
, SAMR_R_ENUM_DOM_ALIASES
*r_u
)
1092 DOMAIN_GRP
*grp
=NULL
;
1093 uint32 num_entries
= 0;
1099 r_u
->status
= NT_STATUS_OK
;
1101 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
1102 return NT_STATUS_INVALID_HANDLE
;
1104 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
, "_samr_enum_dom_aliases"))) {
1108 sid_to_string(sid_str
, &sid
);
1109 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str
));
1111 status
= get_group_alias_entries(p
->mem_ctx
, &grp
, &sid
, q_u
->start_idx
,
1112 &num_entries
, MAX_SAM_ENTRIES
);
1113 if (NT_STATUS_IS_ERR(status
)) return status
;
1115 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
1119 init_samr_r_enum_dom_aliases(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
1121 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__
));
1126 /*******************************************************************
1127 samr_reply_query_dispinfo
1128 ********************************************************************/
1130 NTSTATUS
_samr_query_dispinfo(pipes_struct
*p
, SAMR_Q_QUERY_DISPINFO
*q_u
,
1131 SAMR_R_QUERY_DISPINFO
*r_u
)
1133 struct samr_info
*info
= NULL
;
1134 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
1136 uint32 max_entries
=q_u
->max_entries
;
1137 uint32 enum_context
=q_u
->start_idx
;
1138 uint32 max_size
=q_u
->max_size
;
1140 SAM_DISPINFO_CTR
*ctr
;
1141 uint32 temp_size
=0, total_data_size
=0;
1143 uint32 num_account
= 0;
1144 enum remote_arch_types ra_type
= get_remote_arch();
1145 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
1148 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__
));
1149 r_u
->status
= NT_STATUS_OK
;
1151 /* find the policy handle. open a policy on it. */
1152 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
1153 return NT_STATUS_INVALID_HANDLE
;
1155 domain_sid
= info
->sid
;
1158 * calculate how many entries we will return.
1160 * - the number of entries the client asked
1161 * - our limit on that
1162 * - the starting point (enumeration context)
1163 * - the buffer size the client will accept
1167 * We are a lot more like W2K. Instead of reading the SAM
1168 * each time to find the records we need to send back,
1169 * we read it once and link that copy to the sam handle.
1170 * For large user list (over the MAX_SAM_ENTRIES)
1171 * it's a definitive win.
1172 * second point to notice: between enumerations
1173 * our sam is now the same as it's a snapshoot.
1174 * third point: got rid of the static SAM_USER_21 struct
1175 * no more intermediate.
1176 * con: it uses much more memory, as a full copy is stored
1179 * If you want to change it, think twice and think
1180 * of the second point , that's really important.
1185 /* Get what we need from the password database */
1186 switch (q_u
->switch_level
) {
1188 /* When playing with usrmgr, this is necessary
1189 if you want immediate refresh after editing
1190 a user. I would like to do this after the
1191 setuserinfo2, but we do not have access to
1192 the domain handle in that call, only to the
1193 user handle. Where else does this hurt?
1197 /* We cannot do this here - it kills performace. JRA. */
1198 free_samr_users(info
);
1203 /* Level 2 is for all machines, otherwise only 'normal' users */
1204 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
, q_u
->switch_level
==2);
1206 if (!NT_STATUS_IS_OK(r_u
->status
)) {
1207 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1210 num_account
= info
->disp_info
.num_user_account
;
1214 r_u
->status
= load_group_domain_entries(info
, &info
->sid
);
1215 if (!NT_STATUS_IS_OK(r_u
->status
))
1217 num_account
= info
->disp_info
.num_group_account
;
1220 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u
->switch_level
));
1221 return NT_STATUS_INVALID_INFO_CLASS
;
1224 /* first limit the number of entries we will return */
1225 if(max_entries
> max_sam_entries
) {
1226 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries
, max_sam_entries
));
1227 max_entries
= max_sam_entries
;
1230 if (enum_context
> num_account
) {
1231 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1232 return NT_STATUS_NO_MORE_ENTRIES
;
1235 /* verify we won't overflow */
1236 if (max_entries
> num_account
-enum_context
) {
1237 max_entries
= num_account
-enum_context
;
1238 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries
));
1241 /* calculate the size and limit on the number of entries we will return */
1242 temp_size
=max_entries
*struct_size
;
1244 if (temp_size
>max_size
) {
1245 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
1246 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries
));
1249 if (!(ctr
= (SAM_DISPINFO_CTR
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_DISPINFO_CTR
))))
1250 return NT_STATUS_NO_MEMORY
;
1254 /* Now create reply structure */
1255 switch (q_u
->switch_level
) {
1258 if (!(ctr
->sam
.info1
= (SAM_DISPINFO_1
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_1
))))
1259 return NT_STATUS_NO_MEMORY
;
1261 disp_ret
= init_sam_dispinfo_1(p
->mem_ctx
, ctr
->sam
.info1
, max_entries
, enum_context
,
1262 info
->disp_info
.disp_user_info
, &domain_sid
);
1263 if (!NT_STATUS_IS_OK(disp_ret
))
1268 if (!(ctr
->sam
.info2
= (SAM_DISPINFO_2
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_2
))))
1269 return NT_STATUS_NO_MEMORY
;
1271 disp_ret
= init_sam_dispinfo_2(p
->mem_ctx
, ctr
->sam
.info2
, max_entries
, enum_context
,
1272 info
->disp_info
.disp_user_info
, &domain_sid
);
1273 if (!NT_STATUS_IS_OK(disp_ret
))
1278 if (!(ctr
->sam
.info3
= (SAM_DISPINFO_3
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_3
))))
1279 return NT_STATUS_NO_MEMORY
;
1281 disp_ret
= init_sam_dispinfo_3(p
->mem_ctx
, ctr
->sam
.info3
, max_entries
, enum_context
, info
->disp_info
.disp_group_info
);
1282 if (!NT_STATUS_IS_OK(disp_ret
))
1287 if (!(ctr
->sam
.info4
= (SAM_DISPINFO_4
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_4
))))
1288 return NT_STATUS_NO_MEMORY
;
1290 disp_ret
= init_sam_dispinfo_4(p
->mem_ctx
, ctr
->sam
.info4
, max_entries
, enum_context
, info
->disp_info
.disp_user_info
);
1291 if (!NT_STATUS_IS_OK(disp_ret
))
1296 if (!(ctr
->sam
.info5
= (SAM_DISPINFO_5
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_5
))))
1297 return NT_STATUS_NO_MEMORY
;
1299 disp_ret
= init_sam_dispinfo_5(p
->mem_ctx
, ctr
->sam
.info5
, max_entries
, enum_context
, info
->disp_info
.disp_group_info
);
1300 if (!NT_STATUS_IS_OK(disp_ret
))
1305 ctr
->sam
.info
= NULL
;
1306 return NT_STATUS_INVALID_INFO_CLASS
;
1309 /* calculate the total size */
1310 total_data_size
=num_account
*struct_size
;
1312 if (enum_context
+max_entries
< num_account
)
1313 r_u
->status
= STATUS_MORE_ENTRIES
;
1315 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__
));
1317 init_samr_r_query_dispinfo(r_u
, max_entries
, total_data_size
, temp_size
, q_u
->switch_level
, ctr
, r_u
->status
);
1323 /*******************************************************************
1324 samr_reply_query_aliasinfo
1325 ********************************************************************/
1327 NTSTATUS
_samr_query_aliasinfo(pipes_struct
*p
, SAMR_Q_QUERY_ALIASINFO
*q_u
, SAMR_R_QUERY_ALIASINFO
*r_u
)
1333 r_u
->status
= NT_STATUS_OK
;
1335 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1337 /* find the policy handle. open a policy on it. */
1338 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
1339 return NT_STATUS_INVALID_HANDLE
;
1340 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_LOOKUP_INFO
, "_samr_query_aliasinfo"))) {
1344 if (!sid_check_is_in_our_domain(&sid
) &&
1345 !sid_check_is_in_builtin(&sid
))
1346 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1348 if (!pdb_getgrsid(&map
, sid
))
1349 return NT_STATUS_NO_SUCH_ALIAS
;
1351 switch (q_u
->switch_level
) {
1354 r_u
->ctr
.switch_value1
= 1;
1355 init_samr_alias_info1(&r_u
->ctr
.alias
.info1
, map
.nt_name
, 1, map
.comment
);
1359 r_u
->ctr
.switch_value1
= 3;
1360 init_samr_alias_info3(&r_u
->ctr
.alias
.info3
, map
.comment
);
1363 return NT_STATUS_INVALID_INFO_CLASS
;
1366 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1372 /*******************************************************************
1373 samr_reply_lookup_ids
1374 ********************************************************************/
1376 uint32
_samr_lookup_ids(pipes_struct
*p
, SAMR_Q_LOOKUP_IDS
*q_u
, SAMR_R_LOOKUP_IDS
*r_u
)
1378 uint32 rid
[MAX_SAM_ENTRIES
];
1379 int num_rids
= q_u
->num_sids1
;
1381 r_u
->status
= NT_STATUS_OK
;
1383 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1385 if (num_rids
> MAX_SAM_ENTRIES
) {
1386 num_rids
= MAX_SAM_ENTRIES
;
1387 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids
));
1392 SMB_ASSERT_ARRAY(q_u
->uni_user_name
, num_rids
);
1394 for (i
= 0; i
< num_rids
&& status
== 0; i
++)
1396 struct sam_passwd
*sam_pass
;
1400 fstrcpy(user_name
, unistrn2(q_u
->uni_user_name
[i
].buffer
,
1401 q_u
->uni_user_name
[i
].uni_str_len
));
1403 /* find the user account */
1405 sam_pass
= get_smb21pwd_entry(user_name
, 0);
1408 if (sam_pass
== NULL
)
1410 status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1415 rid
[i
] = sam_pass
->user_rid
;
1421 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
1423 init_samr_r_lookup_ids(&r_u
, num_rids
, rid
, NT_STATUS_OK
);
1425 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1431 /*******************************************************************
1433 ********************************************************************/
1435 NTSTATUS
_samr_lookup_names(pipes_struct
*p
, SAMR_Q_LOOKUP_NAMES
*q_u
, SAMR_R_LOOKUP_NAMES
*r_u
)
1437 uint32 rid
[MAX_SAM_ENTRIES
];
1439 enum SID_NAME_USE type
[MAX_SAM_ENTRIES
];
1440 enum SID_NAME_USE local_type
;
1442 int num_rids
= q_u
->num_names2
;
1447 r_u
->status
= NT_STATUS_OK
;
1449 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1454 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
, &acc_granted
)) {
1455 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, 0, NULL
, NULL
, NT_STATUS_OBJECT_TYPE_MISMATCH
);
1459 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 */
1463 if (num_rids
> MAX_SAM_ENTRIES
) {
1464 num_rids
= MAX_SAM_ENTRIES
;
1465 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids
));
1468 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str
, &pol_sid
)));
1470 become_root(); /* local_lookup_name can require root privs */
1472 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 ret
= 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.
1496 if ((ret
> 0) && local_lookup_name(name
, &sid
, &local_type
)) {
1497 sid_split_rid(&sid
, &local_rid
);
1499 if (sid_equal(&sid
, &pol_sid
)) {
1502 r_u
->status
= NT_STATUS_OK
;
1509 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, num_rids
, rid
, (uint32
*)type
, r_u
->status
);
1511 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1516 /*******************************************************************
1517 _samr_chgpasswd_user
1518 ********************************************************************/
1520 NTSTATUS
_samr_chgpasswd_user(pipes_struct
*p
, SAMR_Q_CHGPASSWD_USER
*q_u
, SAMR_R_CHGPASSWD_USER
*r_u
)
1525 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1527 r_u
->status
= NT_STATUS_OK
;
1529 rpcstr_pull(user_name
, q_u
->uni_user_name
.buffer
, sizeof(user_name
), q_u
->uni_user_name
.uni_str_len
*2, 0);
1530 rpcstr_pull(wks
, q_u
->uni_dest_host
.buffer
, sizeof(wks
), q_u
->uni_dest_host
.uni_str_len
*2,0);
1532 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name
, wks
));
1535 * Pass the user through the NT -> unix user mapping
1539 (void)map_username(user_name
);
1542 * UNIX username case mangling not required, pass_oem_change
1543 * is case insensitive.
1546 r_u
->status
= pass_oem_change(user_name
, q_u
->lm_newpass
.pass
, q_u
->lm_oldhash
.hash
,
1547 q_u
->nt_newpass
.pass
, q_u
->nt_oldhash
.hash
);
1549 init_samr_r_chgpasswd_user(r_u
, r_u
->status
);
1551 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1556 /*******************************************************************
1557 makes a SAMR_R_LOOKUP_RIDS structure.
1558 ********************************************************************/
1560 static BOOL
make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
, fstring names
[],
1561 UNIHDR
**pp_hdr_name
, UNISTR2
**pp_uni_name
)
1564 UNIHDR
*hdr_name
=NULL
;
1565 UNISTR2
*uni_name
=NULL
;
1567 *pp_uni_name
= NULL
;
1568 *pp_hdr_name
= NULL
;
1570 if (num_names
!= 0) {
1571 hdr_name
= (UNIHDR
*)talloc_zero(ctx
, sizeof(UNIHDR
)*num_names
);
1572 if (hdr_name
== NULL
)
1575 uni_name
= (UNISTR2
*)talloc_zero(ctx
,sizeof(UNISTR2
)*num_names
);
1576 if (uni_name
== NULL
)
1580 for (i
= 0; i
< num_names
; i
++) {
1581 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
] ? names
[i
] : ""));
1582 init_unistr2(&uni_name
[i
], names
[i
], UNI_FLAGS_NONE
);
1583 init_uni_hdr(&hdr_name
[i
], &uni_name
[i
]);
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 _samr_open_user. Safe - gives out no passwd info.
1665 ********************************************************************/
1667 NTSTATUS
_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
, (unsigned 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 /*******************************************************************
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
_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
;
2209 /* check this, when giving away 'add computer to domain' privs */
2210 uint32 des_access
= GENERIC_RIGHTS_USER_ALL_ACCESS
;
2212 /* Get the domain SID stored in the domain policy */
2213 if (!get_lsa_policy_samr_sid(p
, &dom_pol
, &sid
, &acc_granted
))
2214 return NT_STATUS_INVALID_HANDLE
;
2216 if (!NT_STATUS_IS_OK(nt_status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_CREATE_USER
, "_samr_create_user"))) {
2220 /* find the account: tell the caller if it exists.
2221 lkclXXXX i have *no* idea if this is a problem or not
2222 or even if you are supposed to construct a different
2223 reply if the account already exists...
2226 rpcstr_pull(account
, user_account
.buffer
, sizeof(account
), user_account
.uni_str_len
*2, 0);
2227 strlower_m(account
);
2229 pdb_init_sam(&sam_pass
);
2232 ret
= pdb_getsampwnam(sam_pass
, account
);
2235 /* this account exists: say so */
2236 pdb_free_sam(&sam_pass
);
2237 return NT_STATUS_USER_EXISTS
;
2240 pdb_free_sam(&sam_pass
);
2243 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2244 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2245 * that only people with write access to the smbpasswd file will be able
2246 * to create a user. JRA.
2250 * add the user in the /etc/passwd file or the unix authority system.
2251 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2252 * a) local_password_change() checks for us if the /etc/passwd account really exists
2253 * b) smb_create_user() would return an error if the account already exists
2254 * and as it could return an error also if it can't create the account, it would be tricky.
2256 * So we go the easy way, only check after if the account exists.
2257 * JFM (2/3/2001), to clear any possible bad understanding (-:
2259 * We now have seperate script paramaters for adding users/machines so we
2260 * now have some sainity-checking to match.
2263 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account
, (unsigned long)strlen(account
)-1));
2266 * we used to have code here that made sure the acb_info flags
2267 * matched with the users named (e.g. an account flags as a machine
2268 * trust account ended in '$'). It has been ifdef'd out for a long
2269 * time, so I replaced it with this comment. --jerry
2272 /* the passdb lookup has failed; check to see if we need to run the
2273 add user/machine script */
2275 pw
= Get_Pwnam(account
);
2277 /*********************************************************************
2278 * HEADS UP! If we have to create a new user account, we have to get
2279 * a new RID from somewhere. This used to be done by the passdb
2280 * backend. It has been moved into idmap now. Since idmap is now
2281 * wrapped up behind winbind, this means you have to run winbindd if you
2282 * want new accounts to get a new RID when "enable rid algorithm = no".
2283 * Tough. We now have a uniform way of allocating RIDs regardless
2284 * of what ever passdb backend people may use.
2285 * --jerry (2003-07-10)
2286 *********************************************************************/
2290 * we can't check both the ending $ and the acb_info.
2292 * UserManager creates trust accounts (ending in $,
2293 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2296 if (account
[strlen(account
)-1] == '$')
2297 pstrcpy(add_script
, lp_addmachine_script());
2299 pstrcpy(add_script
, lp_adduser_script());
2303 all_string_sub(add_script
, "%u", account
, sizeof(account
));
2304 add_ret
= smbrun(add_script
,NULL
);
2305 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script
, add_ret
));
2307 else /* no add user script -- ask winbindd to do it */
2309 if ( !winbind_create_user( account
, &new_rid
) ) {
2310 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2317 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2319 if ( !NT_STATUS_IS_OK(nt_status
= pdb_init_sam_new(&sam_pass
, account
, new_rid
)) )
2322 pdb_set_acct_ctrl(sam_pass
, acb_info
, PDB_CHANGED
);
2324 if (!pdb_add_sam_account(sam_pass
)) {
2325 pdb_free_sam(&sam_pass
);
2326 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2328 return NT_STATUS_ACCESS_DENIED
;
2331 /* Get the user's SID */
2332 sid_copy(&sid
, pdb_get_user_sid(sam_pass
));
2334 samr_make_usr_obj_sd(p
->mem_ctx
, &psd
, &sd_size
, &sid
);
2335 se_map_generic(&des_access
, &usr_generic_mapping
);
2336 if (!NT_STATUS_IS_OK(nt_status
=
2337 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2338 des_access
, &acc_granted
, "_samr_create_user"))) {
2342 /* associate the user's SID with the new handle. */
2343 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
) {
2344 pdb_free_sam(&sam_pass
);
2345 return NT_STATUS_NO_MEMORY
;
2350 info
->acc_granted
= acc_granted
;
2352 /* get a (unique) handle. open a policy on it. */
2353 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
)) {
2354 pdb_free_sam(&sam_pass
);
2355 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2358 r_u
->user_rid
=pdb_get_user_rid(sam_pass
);
2360 r_u
->access_granted
= acc_granted
;
2362 pdb_free_sam(&sam_pass
);
2364 return NT_STATUS_OK
;
2367 /*******************************************************************
2368 samr_reply_connect_anon
2369 ********************************************************************/
2371 NTSTATUS
_samr_connect_anon(pipes_struct
*p
, SAMR_Q_CONNECT_ANON
*q_u
, SAMR_R_CONNECT_ANON
*r_u
)
2373 struct samr_info
*info
= NULL
;
2374 uint32 des_access
= q_u
->access_mask
;
2378 if (!pipe_access_check(p
)) {
2379 DEBUG(3, ("access denied to samr_connect_anon\n"));
2380 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2384 /* set up the SAMR connect_anon response */
2386 r_u
->status
= NT_STATUS_OK
;
2388 /* associate the user's SID with the new handle. */
2389 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2390 return NT_STATUS_NO_MEMORY
;
2392 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2393 was observed from a win98 client trying to enumerate users (when configured
2394 user level access control on shares) --jerry */
2396 se_map_generic( &des_access
, &sam_generic_mapping
);
2397 info
->acc_granted
= des_access
& (SA_RIGHT_SAM_ENUM_DOMAINS
|SA_RIGHT_SAM_OPEN_DOMAIN
);
2399 info
->status
= q_u
->unknown_0
;
2401 /* get a (unique) handle. open a policy on it. */
2402 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2403 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2408 /*******************************************************************
2410 ********************************************************************/
2412 NTSTATUS
_samr_connect(pipes_struct
*p
, SAMR_Q_CONNECT
*q_u
, SAMR_R_CONNECT
*r_u
)
2414 struct samr_info
*info
= NULL
;
2415 SEC_DESC
*psd
= NULL
;
2417 uint32 des_access
= q_u
->access_mask
;
2422 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2426 if (!pipe_access_check(p
)) {
2427 DEBUG(3, ("access denied to samr_connect\n"));
2428 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2432 samr_make_sam_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
2433 se_map_generic(&des_access
, &sam_generic_mapping
);
2434 if (!NT_STATUS_IS_OK(nt_status
=
2435 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2436 des_access
, &acc_granted
, "_samr_connect"))) {
2440 r_u
->status
= NT_STATUS_OK
;
2442 /* associate the user's SID and access granted with the new handle. */
2443 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2444 return NT_STATUS_NO_MEMORY
;
2446 info
->acc_granted
= acc_granted
;
2447 info
->status
= q_u
->access_mask
;
2449 /* get a (unique) handle. open a policy on it. */
2450 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2451 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2453 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2458 /*******************************************************************
2460 ********************************************************************/
2462 NTSTATUS
_samr_connect4(pipes_struct
*p
, SAMR_Q_CONNECT4
*q_u
, SAMR_R_CONNECT4
*r_u
)
2464 struct samr_info
*info
= NULL
;
2465 SEC_DESC
*psd
= NULL
;
2467 uint32 des_access
= q_u
->access_mask
;
2472 DEBUG(5,("_samr_connect4: %d\n", __LINE__
));
2476 if (!pipe_access_check(p
)) {
2477 DEBUG(3, ("access denied to samr_connect4\n"));
2478 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2482 samr_make_sam_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
2483 se_map_generic(&des_access
, &sam_generic_mapping
);
2484 if (!NT_STATUS_IS_OK(nt_status
=
2485 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2486 des_access
, &acc_granted
, "_samr_connect"))) {
2490 r_u
->status
= NT_STATUS_OK
;
2492 /* associate the user's SID and access granted with the new handle. */
2493 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2494 return NT_STATUS_NO_MEMORY
;
2496 info
->acc_granted
= acc_granted
;
2497 info
->status
= q_u
->access_mask
;
2499 /* get a (unique) handle. open a policy on it. */
2500 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2501 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2503 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2508 /**********************************************************************
2509 api_samr_lookup_domain
2510 **********************************************************************/
2512 NTSTATUS
_samr_lookup_domain(pipes_struct
*p
, SAMR_Q_LOOKUP_DOMAIN
*q_u
, SAMR_R_LOOKUP_DOMAIN
*r_u
)
2514 struct samr_info
*info
;
2515 fstring domain_name
;
2518 r_u
->status
= NT_STATUS_OK
;
2520 if (!find_policy_by_hnd(p
, &q_u
->connect_pol
, (void**)&info
))
2521 return NT_STATUS_INVALID_HANDLE
;
2523 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
,
2524 SA_RIGHT_SAM_ENUM_DOMAINS
, "_samr_lookup_domain")))
2529 rpcstr_pull(domain_name
, q_u
->uni_domain
.buffer
, sizeof(domain_name
), q_u
->uni_domain
.uni_str_len
*2, 0);
2533 if (!secrets_fetch_domain_sid(domain_name
, &sid
)) {
2534 r_u
->status
= NT_STATUS_NO_SUCH_DOMAIN
;
2537 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
, sid_string_static(&sid
)));
2539 init_samr_r_lookup_domain(r_u
, &sid
, r_u
->status
);
2544 /******************************************************************
2545 makes a SAMR_R_ENUM_DOMAINS structure.
2546 ********************************************************************/
2548 static BOOL
make_enum_domains(TALLOC_CTX
*ctx
, SAM_ENTRY
**pp_sam
,
2549 UNISTR2
**pp_uni_name
, uint32 num_sam_entries
, fstring doms
[])
2555 DEBUG(5, ("make_enum_domains\n"));
2558 *pp_uni_name
= NULL
;
2560 if (num_sam_entries
== 0)
2563 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
2564 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
2566 if (sam
== NULL
|| uni_name
== NULL
)
2569 for (i
= 0; i
< num_sam_entries
; i
++) {
2570 init_unistr2(&uni_name
[i
], doms
[i
], UNI_FLAGS_NONE
);
2571 init_sam_entry(&sam
[i
], &uni_name
[i
], 0);
2575 *pp_uni_name
= uni_name
;
2580 /**********************************************************************
2581 api_samr_enum_domains
2582 **********************************************************************/
2584 NTSTATUS
_samr_enum_domains(pipes_struct
*p
, SAMR_Q_ENUM_DOMAINS
*q_u
, SAMR_R_ENUM_DOMAINS
*r_u
)
2586 struct samr_info
*info
;
2587 uint32 num_entries
= 2;
2591 r_u
->status
= NT_STATUS_OK
;
2593 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void**)&info
))
2594 return NT_STATUS_INVALID_HANDLE
;
2596 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_SAM_ENUM_DOMAINS
, "_samr_enum_domains"))) {
2600 name
= get_global_sam_name();
2602 fstrcpy(dom
[0],name
);
2604 fstrcpy(dom
[1],"Builtin");
2606 if (!make_enum_domains(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_dom_name
, num_entries
, dom
))
2607 return NT_STATUS_NO_MEMORY
;
2609 init_samr_r_enum_domains(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
2614 /*******************************************************************
2616 ********************************************************************/
2618 NTSTATUS
_samr_open_alias(pipes_struct
*p
, SAMR_Q_OPEN_ALIAS
*q_u
, SAMR_R_OPEN_ALIAS
*r_u
)
2621 POLICY_HND domain_pol
= q_u
->dom_pol
;
2622 uint32 alias_rid
= q_u
->rid_alias
;
2623 POLICY_HND
*alias_pol
= &r_u
->pol
;
2624 struct samr_info
*info
= NULL
;
2625 SEC_DESC
*psd
= NULL
;
2627 uint32 des_access
= q_u
->access_mask
;
2631 r_u
->status
= NT_STATUS_OK
;
2633 /* find the domain policy and get the SID / access bits stored in the domain policy */
2634 if (!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
, &acc_granted
))
2635 return NT_STATUS_INVALID_HANDLE
;
2637 if (!NT_STATUS_IS_OK(status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_open_alias"))) {
2641 /* append the alias' RID to it */
2642 if (!sid_append_rid(&sid
, alias_rid
))
2643 return NT_STATUS_NO_SUCH_USER
;
2645 /*check if access can be granted as requested by client. */
2646 samr_make_ali_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
2647 se_map_generic(&des_access
,&ali_generic_mapping
);
2648 if (!NT_STATUS_IS_OK(status
=
2649 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2650 des_access
, &acc_granted
, "_samr_open_alias"))) {
2655 * we should check if the rid really exist !!!
2659 /* associate the user's SID with the new handle. */
2660 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
)
2661 return NT_STATUS_NO_MEMORY
;
2663 info
->acc_granted
= acc_granted
;
2665 /* get a (unique) handle. open a policy on it. */
2666 if (!create_policy_hnd(p
, alias_pol
, free_samr_info
, (void *)info
))
2667 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2672 /*******************************************************************
2674 ********************************************************************/
2676 static BOOL
set_user_info_10(const SAM_USER_INFO_10
*id10
, DOM_SID
*sid
)
2678 SAM_ACCOUNT
*pwd
=NULL
;
2683 ret
= pdb_getsampwsid(pwd
, sid
);
2691 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2696 /* FIX ME: check if the value is really changed --metze */
2697 if (!pdb_set_acct_ctrl(pwd
, id10
->acb_info
, PDB_CHANGED
)) {
2702 if(!pdb_update_sam_account(pwd
)) {
2712 /*******************************************************************
2714 ********************************************************************/
2716 static BOOL
set_user_info_12(SAM_USER_INFO_12
*id12
, DOM_SID
*sid
)
2718 SAM_ACCOUNT
*pwd
= NULL
;
2722 if(!pdb_getsampwsid(pwd
, sid
)) {
2728 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2733 if (!pdb_set_lanman_passwd (pwd
, id12
->lm_pwd
, PDB_CHANGED
)) {
2737 if (!pdb_set_nt_passwd (pwd
, id12
->nt_pwd
, PDB_CHANGED
)) {
2741 if (!pdb_set_pass_changed_now (pwd
)) {
2746 if(!pdb_update_sam_account(pwd
)) {
2755 /*******************************************************************
2756 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2757 ********************************************************************/
2758 static BOOL
set_unix_primary_group(SAM_ACCOUNT
*sampass
)
2763 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass
),
2765 DEBUG(2,("Could not get gid for primary group of "
2766 "user %s\n", pdb_get_username(sampass
)));
2770 grp
= getgrgid(gid
);
2773 DEBUG(2,("Could not find primary group %lu for "
2774 "user %s\n", (unsigned long)gid
,
2775 pdb_get_username(sampass
)));
2779 if (smb_set_primary_group(grp
->gr_name
,
2780 pdb_get_username(sampass
)) != 0) {
2781 DEBUG(2,("Could not set primary group for user %s to "
2783 pdb_get_username(sampass
), grp
->gr_name
));
2791 /*******************************************************************
2793 ********************************************************************/
2795 static BOOL
set_user_info_20(SAM_USER_INFO_20
*id20
, DOM_SID
*sid
)
2797 SAM_ACCOUNT
*pwd
= NULL
;
2800 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2806 if (!pdb_getsampwsid(pwd
, sid
)) {
2811 copy_id20_to_sam_passwd(pwd
, id20
);
2813 /* write the change out */
2814 if(!pdb_update_sam_account(pwd
)) {
2823 /*******************************************************************
2825 ********************************************************************/
2827 static BOOL
set_user_info_21(SAM_USER_INFO_21
*id21
, DOM_SID
*sid
)
2829 SAM_ACCOUNT
*pwd
= NULL
;
2832 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2838 if (!pdb_getsampwsid(pwd
, sid
)) {
2843 copy_id21_to_sam_passwd(pwd
, id21
);
2846 * The funny part about the previous two calls is
2847 * that pwd still has the password hashes from the
2848 * passdb entry. These have not been updated from
2849 * id21. I don't know if they need to be set. --jerry
2852 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
))
2853 set_unix_primary_group(pwd
);
2855 /* write the change out */
2856 if(!pdb_update_sam_account(pwd
)) {
2866 /*******************************************************************
2868 ********************************************************************/
2870 static BOOL
set_user_info_23(SAM_USER_INFO_23
*id23
, DOM_SID
*sid
)
2872 SAM_ACCOUNT
*pwd
= NULL
;
2873 pstring plaintext_buf
;
2878 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2884 if (!pdb_getsampwsid(pwd
, sid
)) {
2889 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2890 pdb_get_username(pwd
)));
2892 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2894 if (!decode_pw_buffer((char*)id23
->pass
, plaintext_buf
, 256, &len
)) {
2899 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
2904 copy_id23_to_sam_passwd(pwd
, id23
);
2906 /* if it's a trust account, don't update /etc/passwd */
2907 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2908 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2909 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2910 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2912 /* update the UNIX password */
2913 if (lp_unix_password_sync() )
2914 if(!chgpasswd(pdb_get_username(pwd
), "", plaintext_buf
, True
)) {
2920 ZERO_STRUCT(plaintext_buf
);
2922 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
))
2923 set_unix_primary_group(pwd
);
2925 if(!pdb_update_sam_account(pwd
)) {
2935 /*******************************************************************
2937 ********************************************************************/
2939 static BOOL
set_user_info_pw(char *pass
, DOM_SID
*sid
)
2941 SAM_ACCOUNT
*pwd
= NULL
;
2943 pstring plaintext_buf
;
2948 if (!pdb_getsampwsid(pwd
, sid
)) {
2953 DEBUG(5, ("Attempting administrator password change for user %s\n",
2954 pdb_get_username(pwd
)));
2956 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2958 ZERO_STRUCT(plaintext_buf
);
2960 if (!decode_pw_buffer(pass
, plaintext_buf
, 256, &len
)) {
2965 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
2970 /* if it's a trust account, don't update /etc/passwd */
2971 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2972 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2973 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2974 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2976 /* update the UNIX password */
2977 if (lp_unix_password_sync()) {
2978 if(!chgpasswd(pdb_get_username(pwd
), "", plaintext_buf
, True
)) {
2985 ZERO_STRUCT(plaintext_buf
);
2987 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2989 /* update the SAMBA password */
2990 if(!pdb_update_sam_account(pwd
)) {
3000 /*******************************************************************
3001 samr_reply_set_userinfo
3002 ********************************************************************/
3004 NTSTATUS
_samr_set_userinfo(pipes_struct
*p
, SAMR_Q_SET_USERINFO
*q_u
, SAMR_R_SET_USERINFO
*r_u
)
3007 POLICY_HND
*pol
= &q_u
->pol
;
3008 uint16 switch_value
= q_u
->switch_value
;
3009 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
3011 uint32 acc_required
;
3013 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__
));
3015 r_u
->status
= NT_STATUS_OK
;
3017 /* find the policy handle. open a policy on it. */
3018 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
, &acc_granted
))
3019 return NT_STATUS_INVALID_HANDLE
;
3021 acc_required
= SA_RIGHT_USER_SET_LOC_COM
| SA_RIGHT_USER_SET_ATTRIBUTES
; /* This is probably wrong */
3022 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, acc_required
, "_samr_set_userinfo"))) {
3026 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid
), switch_value
));
3029 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3030 return NT_STATUS_INVALID_INFO_CLASS
;
3033 /* ok! user info levels (lots: see MSDEV help), off we go... */
3034 switch (switch_value
) {
3036 if (!set_user_info_12(ctr
->info
.id12
, &sid
))
3037 return NT_STATUS_ACCESS_DENIED
;
3041 SamOEMhash(ctr
->info
.id24
->pass
, p
->session_key
, 516);
3043 dump_data(100, (char *)ctr
->info
.id24
->pass
, 516);
3045 if (!set_user_info_pw((char *)ctr
->info
.id24
->pass
, &sid
))
3046 return NT_STATUS_ACCESS_DENIED
;
3052 * Currently we don't really know how to unmarshall
3053 * the level 25 struct, and the password encryption
3054 * is different. This is a placeholder for when we
3055 * do understand it. In the meantime just return INVALID
3056 * info level and W2K SP2 drops down to level 23... JRA.
3059 SamOEMhash(ctr
->info
.id25
->pass
, p
->session_key
, 532);
3061 dump_data(100, (char *)ctr
->info
.id25
->pass
, 532);
3063 if (!set_user_info_pw(ctr
->info
.id25
->pass
, &sid
))
3064 return NT_STATUS_ACCESS_DENIED
;
3067 return NT_STATUS_INVALID_INFO_CLASS
;
3070 SamOEMhash(ctr
->info
.id23
->pass
, p
->session_key
, 516);
3072 dump_data(100, (char *)ctr
->info
.id23
->pass
, 516);
3074 if (!set_user_info_23(ctr
->info
.id23
, &sid
))
3075 return NT_STATUS_ACCESS_DENIED
;
3079 return NT_STATUS_INVALID_INFO_CLASS
;
3085 /*******************************************************************
3086 samr_reply_set_userinfo2
3087 ********************************************************************/
3089 NTSTATUS
_samr_set_userinfo2(pipes_struct
*p
, SAMR_Q_SET_USERINFO2
*q_u
, SAMR_R_SET_USERINFO2
*r_u
)
3092 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
3093 POLICY_HND
*pol
= &q_u
->pol
;
3094 uint16 switch_value
= q_u
->switch_value
;
3096 uint32 acc_required
;
3098 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__
));
3100 r_u
->status
= NT_STATUS_OK
;
3102 /* find the policy handle. open a policy on it. */
3103 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
, &acc_granted
))
3104 return NT_STATUS_INVALID_HANDLE
;
3106 acc_required
= SA_RIGHT_USER_SET_LOC_COM
| SA_RIGHT_USER_SET_ATTRIBUTES
; /* This is probably wrong */
3107 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, acc_required
, "_samr_set_userinfo2"))) {
3111 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid
)));
3114 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3115 return NT_STATUS_INVALID_INFO_CLASS
;
3118 switch_value
=ctr
->switch_value
;
3120 /* ok! user info levels (lots: see MSDEV help), off we go... */
3121 switch (switch_value
) {
3123 if (!set_user_info_21(ctr
->info
.id21
, &sid
))
3124 return NT_STATUS_ACCESS_DENIED
;
3127 if (!set_user_info_20(ctr
->info
.id20
, &sid
))
3128 return NT_STATUS_ACCESS_DENIED
;
3131 if (!set_user_info_10(ctr
->info
.id10
, &sid
))
3132 return NT_STATUS_ACCESS_DENIED
;
3135 /* Used by AS/U JRA. */
3136 if (!set_user_info_12(ctr
->info
.id12
, &sid
))
3137 return NT_STATUS_ACCESS_DENIED
;
3140 return NT_STATUS_INVALID_INFO_CLASS
;
3146 /*********************************************************************
3147 _samr_query_aliasmem
3148 *********************************************************************/
3150 NTSTATUS
_samr_query_useraliases(pipes_struct
*p
, SAMR_Q_QUERY_USERALIASES
*q_u
, SAMR_R_QUERY_USERALIASES
*r_u
)
3152 int num_groups
= 0, tmp_num_groups
=0;
3153 uint32
*rids
=NULL
, *new_rids
=NULL
, *tmp_rids
=NULL
;
3154 struct samr_info
*info
= NULL
;
3160 /* until i see a real useraliases query, we fack one up */
3162 /* I have seen one, JFM 2/12/2001 */
3164 * Explanation of what this call does:
3165 * for all the SID given in the request:
3166 * return a list of alias (local groups)
3167 * that have those SID as members.
3169 * and that's the alias in the domain specified
3170 * in the policy_handle
3172 * if the policy handle is on an incorrect sid
3173 * for example a user's sid
3174 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3177 r_u
->status
= NT_STATUS_OK
;
3179 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__
));
3181 /* find the policy handle. open a policy on it. */
3182 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
3183 return NT_STATUS_INVALID_HANDLE
;
3185 ntstatus1
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM
, "_samr_query_useraliases");
3186 ntstatus2
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_query_useraliases");
3188 if (!NT_STATUS_IS_OK(ntstatus1
) || !NT_STATUS_IS_OK(ntstatus2
)) {
3189 if (!(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus2
)) &&
3190 !(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus1
))) {
3191 return (NT_STATUS_IS_OK(ntstatus1
)) ? ntstatus2
: ntstatus1
;
3195 if (!sid_check_is_domain(&info
->sid
) &&
3196 !sid_check_is_builtin(&info
->sid
))
3197 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3200 for (i
=0; i
<q_u
->num_sids1
; i
++) {
3202 r_u
->status
=get_alias_user_groups(p
->mem_ctx
, &info
->sid
, &tmp_num_groups
, &tmp_rids
, &(q_u
->sid
[i
].sid
));
3205 * if there is an error, we just continue as
3206 * it can be an unfound user or group
3208 if (!NT_STATUS_IS_OK(r_u
->status
)) {
3209 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3213 if (tmp_num_groups
==0) {
3214 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3218 new_rids
=(uint32
*)talloc_realloc(p
->mem_ctx
, rids
, (num_groups
+tmp_num_groups
)*sizeof(uint32
));
3219 if (new_rids
==NULL
) {
3220 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3221 return NT_STATUS_NO_MEMORY
;
3225 for (j
=0; j
<tmp_num_groups
; j
++)
3226 rids
[j
+num_groups
]=tmp_rids
[j
];
3228 safe_free(tmp_rids
);
3230 num_groups
+=tmp_num_groups
;
3233 init_samr_r_query_useraliases(r_u
, num_groups
, rids
, NT_STATUS_OK
);
3234 return NT_STATUS_OK
;
3237 /*********************************************************************
3238 _samr_query_aliasmem
3239 *********************************************************************/
3241 NTSTATUS
_samr_query_aliasmem(pipes_struct
*p
, SAMR_Q_QUERY_ALIASMEM
*q_u
, SAMR_R_QUERY_ALIASMEM
*r_u
)
3253 fstring alias_sid_str
;
3256 SAM_ACCOUNT
*sam_user
= NULL
;
3260 /* find the policy handle. open a policy on it. */
3261 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3262 return NT_STATUS_INVALID_HANDLE
;
3264 if (!NT_STATUS_IS_OK(r_u
->status
=
3265 access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_GET_MEMBERS
, "_samr_query_aliasmem"))) {
3269 sid_copy(&als_sid
, &alias_sid
);
3270 sid_to_string(alias_sid_str
, &alias_sid
);
3271 sid_split_rid(&alias_sid
, &alias_rid
);
3273 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3275 if (sid_equal(&alias_sid
, &global_sid_Builtin
)) {
3276 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3277 if(!get_builtin_group_from_sid(als_sid
, &map
))
3278 return NT_STATUS_NO_SUCH_ALIAS
;
3280 if (sid_equal(&alias_sid
, get_global_sam_sid())) {
3281 DEBUG(10, ("lookup on Server SID\n"));
3282 if(!get_local_group_from_sid(als_sid
, &map
))
3283 return NT_STATUS_NO_SUCH_ALIAS
;
3287 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
3288 return NT_STATUS_NO_SUCH_ALIAS
;
3290 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3291 sid
= (DOM_SID2
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_SID2
) * num_uids
);
3292 if (num_uids
!=0 && sid
== NULL
)
3293 return NT_STATUS_NO_MEMORY
;
3295 for (i
= 0; i
< num_uids
; i
++) {
3296 struct passwd
*pass
;
3299 sid_copy(&temp_sid
, get_global_sam_sid());
3301 pass
= getpwuid_alloc(uid
[i
]);
3302 if (!pass
) continue;
3304 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user
))) {
3310 check
= pdb_getsampwnam(sam_user
, pass
->pw_name
);
3313 if (check
!= True
) {
3314 pdb_free_sam(&sam_user
);
3319 rid
= pdb_get_user_rid(sam_user
);
3321 pdb_free_sam(&sam_user
);
3326 pdb_free_sam(&sam_user
);
3329 sid_append_rid(&temp_sid
, rid
);
3331 init_dom_sid2(&sid
[i
], &temp_sid
);
3334 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3335 init_samr_r_query_aliasmem(r_u
, num_uids
, sid
, NT_STATUS_OK
);
3337 return NT_STATUS_OK
;
3340 /*********************************************************************
3341 _samr_query_groupmem
3342 *********************************************************************/
3344 NTSTATUS
_samr_query_groupmem(pipes_struct
*p
, SAMR_Q_QUERY_GROUPMEM
*q_u
, SAMR_R_QUERY_GROUPMEM
*r_u
)
3350 fstring group_sid_str
;
3358 SAM_ACCOUNT
*sam_user
= NULL
;
3362 /* find the policy handle. open a policy on it. */
3363 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
, &acc_granted
))
3364 return NT_STATUS_INVALID_HANDLE
;
3366 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_GET_MEMBERS
, "_samr_query_groupmem"))) {
3370 /* todo: change to use sid_compare_front */
3372 sid_split_rid(&group_sid
, &group_rid
);
3373 sid_to_string(group_sid_str
, &group_sid
);
3374 DEBUG(10, ("sid is %s\n", group_sid_str
));
3376 /* can we get a query for an SID outside our domain ? */
3377 if (!sid_equal(&group_sid
, get_global_sam_sid()))
3378 return NT_STATUS_NO_SUCH_GROUP
;
3380 sid_append_rid(&group_sid
, group_rid
);
3381 DEBUG(10, ("lookup on Domain SID\n"));
3383 if(!get_domain_group_from_sid(group_sid
, &map
))
3384 return NT_STATUS_NO_SUCH_GROUP
;
3386 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
3387 return NT_STATUS_NO_SUCH_GROUP
;
3389 rid
=talloc_zero(p
->mem_ctx
, sizeof(uint32
)*num_uids
);
3390 attr
=talloc_zero(p
->mem_ctx
, sizeof(uint32
)*num_uids
);
3392 if (num_uids
!=0 && (rid
==NULL
|| attr
==NULL
))
3393 return NT_STATUS_NO_MEMORY
;
3395 for (i
=0; i
<num_uids
; i
++) {
3396 struct passwd
*pass
;
3399 pass
= getpwuid_alloc(uid
[i
]);
3400 if (!pass
) continue;
3402 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user
))) {
3408 check
= pdb_getsampwnam(sam_user
, pass
->pw_name
);
3411 if (check
!= True
) {
3412 pdb_free_sam(&sam_user
);
3417 urid
= pdb_get_user_rid(sam_user
);
3419 pdb_free_sam(&sam_user
);
3424 pdb_free_sam(&sam_user
);
3428 attr
[i
] = SID_NAME_USER
;
3431 init_samr_r_query_groupmem(r_u
, num_uids
, rid
, attr
, NT_STATUS_OK
);
3433 return NT_STATUS_OK
;
3436 /*********************************************************************
3438 *********************************************************************/
3440 NTSTATUS
_samr_add_aliasmem(pipes_struct
*p
, SAMR_Q_ADD_ALIASMEM
*q_u
, SAMR_R_ADD_ALIASMEM
*r_u
)
3443 fstring alias_sid_str
;
3450 SAM_ACCOUNT
*sam_user
= NULL
;
3454 /* Find the policy handle. Open a policy on it. */
3455 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3456 return NT_STATUS_INVALID_HANDLE
;
3458 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_ADD_MEMBER
, "_samr_add_aliasmem"))) {
3462 sid_to_string(alias_sid_str
, &alias_sid
);
3463 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3465 if (sid_compare(&alias_sid
, get_global_sam_sid())>0) {
3466 DEBUG(10, ("adding member on Server SID\n"));
3467 if(!get_local_group_from_sid(alias_sid
, &map
))
3468 return NT_STATUS_NO_SUCH_ALIAS
;
3471 if (sid_compare(&alias_sid
, &global_sid_Builtin
)>0) {
3472 DEBUG(10, ("adding member on BUILTIN SID\n"));
3473 if( !get_local_group_from_sid(alias_sid
, &map
))
3474 return NT_STATUS_NO_SUCH_ALIAS
;
3477 return NT_STATUS_NO_SUCH_ALIAS
;
3480 ret
= pdb_init_sam(&sam_user
);
3481 if (!NT_STATUS_IS_OK(ret
))
3484 check
= pdb_getsampwsid(sam_user
, &q_u
->sid
.sid
);
3486 if (check
!= True
) {
3487 pdb_free_sam(&sam_user
);
3488 return NT_STATUS_NO_SUCH_USER
;
3491 /* check a real user exist before we run the script to add a user to a group */
3492 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user
), &uid
))) {
3493 pdb_free_sam(&sam_user
);
3494 return NT_STATUS_NO_SUCH_USER
;
3497 pdb_free_sam(&sam_user
);
3499 if ((pwd
=getpwuid_alloc(uid
)) == NULL
) {
3500 return NT_STATUS_NO_SUCH_USER
;
3503 if ((grp
=getgrgid(map
.gid
)) == NULL
) {
3505 return NT_STATUS_NO_SUCH_ALIAS
;
3508 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3509 fstrcpy(grp_name
, grp
->gr_name
);
3511 /* if the user is already in the group */
3512 if(user_in_unix_group_list(pwd
->pw_name
, grp_name
)) {
3514 return NT_STATUS_MEMBER_IN_ALIAS
;
3518 * ok, the group exist, the user exist, the user is not in the group,
3519 * we can (finally) add it to the group !
3521 smb_add_user_group(grp_name
, pwd
->pw_name
);
3523 /* check if the user has been added then ... */
3524 if(!user_in_unix_group_list(pwd
->pw_name
, grp_name
)) {
3526 return NT_STATUS_MEMBER_NOT_IN_ALIAS
; /* don't know what to reply else */
3530 return NT_STATUS_OK
;
3533 /*********************************************************************
3535 *********************************************************************/
3537 NTSTATUS
_samr_del_aliasmem(pipes_struct
*p
, SAMR_Q_DEL_ALIASMEM
*q_u
, SAMR_R_DEL_ALIASMEM
*r_u
)
3540 fstring alias_sid_str
;
3544 SAM_ACCOUNT
*sam_pass
=NULL
;
3547 /* Find the policy handle. Open a policy on it. */
3548 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3549 return NT_STATUS_INVALID_HANDLE
;
3551 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_REMOVE_MEMBER
, "_samr_del_aliasmem"))) {
3555 sid_to_string(alias_sid_str
, &alias_sid
);
3556 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str
));
3558 if (!sid_check_is_in_our_domain(&alias_sid
) &&
3559 !sid_check_is_in_builtin(&alias_sid
)) {
3560 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3561 return NT_STATUS_NO_SUCH_ALIAS
;
3564 if( !get_local_group_from_sid(alias_sid
, &map
))
3565 return NT_STATUS_NO_SUCH_ALIAS
;
3567 if ((grp
=getgrgid(map
.gid
)) == NULL
)
3568 return NT_STATUS_NO_SUCH_ALIAS
;
3570 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3571 fstrcpy(grp_name
, grp
->gr_name
);
3573 /* check if the user exists before trying to remove it from the group */
3574 pdb_init_sam(&sam_pass
);
3575 if(!pdb_getsampwsid(sam_pass
, &q_u
->sid
.sid
)) {
3576 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass
)));
3577 pdb_free_sam(&sam_pass
);
3578 return NT_STATUS_NO_SUCH_USER
;
3581 /* if the user is not in the group */
3582 if(!user_in_unix_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3583 pdb_free_sam(&sam_pass
);
3584 return NT_STATUS_MEMBER_IN_ALIAS
;
3587 smb_delete_user_group(grp_name
, pdb_get_username(sam_pass
));
3589 /* check if the user has been removed then ... */
3590 if(user_in_unix_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3591 pdb_free_sam(&sam_pass
);
3592 return NT_STATUS_MEMBER_NOT_IN_ALIAS
; /* don't know what to reply else */
3595 pdb_free_sam(&sam_pass
);
3596 return NT_STATUS_OK
;
3599 /*********************************************************************
3601 *********************************************************************/
3603 NTSTATUS
_samr_add_groupmem(pipes_struct
*p
, SAMR_Q_ADD_GROUPMEM
*q_u
, SAMR_R_ADD_GROUPMEM
*r_u
)
3607 fstring group_sid_str
;
3614 SAM_ACCOUNT
*sam_user
=NULL
;
3618 /* Find the policy handle. Open a policy on it. */
3619 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
3620 return NT_STATUS_INVALID_HANDLE
;
3622 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_ADD_MEMBER
, "_samr_add_groupmem"))) {
3626 sid_to_string(group_sid_str
, &group_sid
);
3627 DEBUG(10, ("sid is %s\n", group_sid_str
));
3629 if (sid_compare(&group_sid
, get_global_sam_sid())<=0)
3630 return NT_STATUS_NO_SUCH_GROUP
;
3632 DEBUG(10, ("lookup on Domain SID\n"));
3634 if(!get_domain_group_from_sid(group_sid
, &map
))
3635 return NT_STATUS_NO_SUCH_GROUP
;
3637 sid_copy(&user_sid
, get_global_sam_sid());
3638 sid_append_rid(&user_sid
, q_u
->rid
);
3640 ret
= pdb_init_sam(&sam_user
);
3641 if (!NT_STATUS_IS_OK(ret
))
3644 check
= pdb_getsampwsid(sam_user
, &user_sid
);
3646 if (check
!= True
) {
3647 pdb_free_sam(&sam_user
);
3648 return NT_STATUS_NO_SUCH_USER
;
3651 /* check a real user exist before we run the script to add a user to a group */
3652 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user
), &uid
))) {
3653 pdb_free_sam(&sam_user
);
3654 return NT_STATUS_NO_SUCH_USER
;
3657 pdb_free_sam(&sam_user
);
3659 if ((pwd
=getpwuid_alloc(uid
)) == NULL
) {
3660 return NT_STATUS_NO_SUCH_USER
;
3663 if ((grp
=getgrgid(map
.gid
)) == NULL
) {
3665 return NT_STATUS_NO_SUCH_GROUP
;
3668 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3669 fstrcpy(grp_name
, grp
->gr_name
);
3671 /* if the user is already in the group */
3672 if(user_in_unix_group_list(pwd
->pw_name
, grp_name
)) {
3674 return NT_STATUS_MEMBER_IN_GROUP
;
3678 * ok, the group exist, the user exist, the user is not in the group,
3680 * we can (finally) add it to the group !
3683 smb_add_user_group(grp_name
, pwd
->pw_name
);
3685 /* check if the user has been added then ... */
3686 if(!user_in_unix_group_list(pwd
->pw_name
, grp_name
)) {
3688 return NT_STATUS_MEMBER_NOT_IN_GROUP
; /* don't know what to reply else */
3692 return NT_STATUS_OK
;
3695 /*********************************************************************
3697 *********************************************************************/
3699 NTSTATUS
_samr_del_groupmem(pipes_struct
*p
, SAMR_Q_DEL_GROUPMEM
*q_u
, SAMR_R_DEL_GROUPMEM
*r_u
)
3703 SAM_ACCOUNT
*sam_pass
=NULL
;
3710 * delete the group member named q_u->rid
3711 * who is a member of the sid associated with the handle
3712 * the rid is a user's rid as the group is a domain group.
3715 /* Find the policy handle. Open a policy on it. */
3716 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
3717 return NT_STATUS_INVALID_HANDLE
;
3719 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_REMOVE_MEMBER
, "_samr_del_groupmem"))) {
3723 if (!sid_check_is_in_our_domain(&group_sid
))
3724 return NT_STATUS_NO_SUCH_GROUP
;
3726 sid_copy(&user_sid
, get_global_sam_sid());
3727 sid_append_rid(&user_sid
, q_u
->rid
);
3729 if (!get_domain_group_from_sid(group_sid
, &map
))
3730 return NT_STATUS_NO_SUCH_GROUP
;
3732 if ((grp
=getgrgid(map
.gid
)) == NULL
)
3733 return NT_STATUS_NO_SUCH_GROUP
;
3735 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3736 fstrcpy(grp_name
, grp
->gr_name
);
3738 /* check if the user exists before trying to remove it from the group */
3739 pdb_init_sam(&sam_pass
);
3740 if (!pdb_getsampwsid(sam_pass
, &user_sid
)) {
3741 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass
)));
3742 pdb_free_sam(&sam_pass
);
3743 return NT_STATUS_NO_SUCH_USER
;
3746 /* if the user is not in the group */
3747 if (!user_in_unix_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3748 pdb_free_sam(&sam_pass
);
3749 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
3752 smb_delete_user_group(grp_name
, pdb_get_username(sam_pass
));
3754 /* check if the user has been removed then ... */
3755 if (user_in_unix_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3756 pdb_free_sam(&sam_pass
);
3757 return NT_STATUS_ACCESS_DENIED
; /* don't know what to reply else */
3760 pdb_free_sam(&sam_pass
);
3761 return NT_STATUS_OK
;
3765 /****************************************************************************
3766 Delete a UNIX user on demand.
3767 ****************************************************************************/
3769 static int smb_delete_user(const char *unix_user
)
3774 /* try winbindd first since it is impossible to determine where
3775 a user came from via NSS. Try the delete user script if this fails
3776 meaning the user did not exist in winbindd's list of accounts */
3778 if ( winbind_delete_user( unix_user
) ) {
3779 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user
));
3784 /* fall back to 'delete user script' */
3786 pstrcpy(del_script
, lp_deluser_script());
3789 all_string_sub(del_script
, "%u", unix_user
, sizeof(pstring
));
3790 ret
= smbrun(del_script
,NULL
);
3791 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script
,ret
));
3796 /*********************************************************************
3797 _samr_delete_dom_user
3798 *********************************************************************/
3800 NTSTATUS
_samr_delete_dom_user(pipes_struct
*p
, SAMR_Q_DELETE_DOM_USER
*q_u
, SAMR_R_DELETE_DOM_USER
*r_u
)
3803 SAM_ACCOUNT
*sam_pass
=NULL
;
3806 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__
));
3808 /* Find the policy handle. Open a policy on it. */
3809 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &user_sid
, &acc_granted
))
3810 return NT_STATUS_INVALID_HANDLE
;
3812 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_user"))) {
3816 if (!sid_check_is_in_our_domain(&user_sid
))
3817 return NT_STATUS_CANNOT_DELETE
;
3819 /* check if the user exists before trying to delete */
3820 pdb_init_sam(&sam_pass
);
3821 if(!pdb_getsampwsid(sam_pass
, &user_sid
)) {
3822 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3823 sid_string_static(&user_sid
)));
3824 pdb_free_sam(&sam_pass
);
3825 return NT_STATUS_NO_SUCH_USER
;
3828 /* delete the unix side */
3830 * note: we don't check if the delete really happened
3831 * as the script is not necessary present
3832 * and maybe the sysadmin doesn't want to delete the unix side
3834 smb_delete_user(pdb_get_username(sam_pass
));
3836 /* and delete the samba side */
3837 if (!pdb_delete_sam_account(sam_pass
)) {
3838 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass
)));
3839 pdb_free_sam(&sam_pass
);
3840 return NT_STATUS_CANNOT_DELETE
;
3843 pdb_free_sam(&sam_pass
);
3845 if (!close_policy_hnd(p
, &q_u
->user_pol
))
3846 return NT_STATUS_OBJECT_NAME_INVALID
;
3848 return NT_STATUS_OK
;
3851 /*********************************************************************
3852 _samr_delete_dom_group
3853 *********************************************************************/
3855 NTSTATUS
_samr_delete_dom_group(pipes_struct
*p
, SAMR_Q_DELETE_DOM_GROUP
*q_u
, SAMR_R_DELETE_DOM_GROUP
*r_u
)
3860 fstring group_sid_str
;
3866 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__
));
3868 /* Find the policy handle. Open a policy on it. */
3869 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
, &acc_granted
))
3870 return NT_STATUS_INVALID_HANDLE
;
3872 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_group"))) {
3876 sid_copy(&dom_sid
, &group_sid
);
3877 sid_to_string(group_sid_str
, &dom_sid
);
3878 sid_split_rid(&dom_sid
, &group_rid
);
3880 DEBUG(10, ("sid is %s\n", group_sid_str
));
3882 /* we check if it's our SID before deleting */
3883 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
3884 return NT_STATUS_NO_SUCH_GROUP
;
3886 DEBUG(10, ("lookup on Domain SID\n"));
3888 if(!get_domain_group_from_sid(group_sid
, &map
))
3889 return NT_STATUS_NO_SUCH_GROUP
;
3893 /* check if group really exists */
3894 if ( (grp
=getgrgid(gid
)) == NULL
)
3895 return NT_STATUS_NO_SUCH_GROUP
;
3897 /* we can delete the UNIX group */
3898 smb_delete_group(grp
->gr_name
);
3900 /* check if the group has been successfully deleted */
3901 if ( (grp
=getgrgid(gid
)) != NULL
)
3902 return NT_STATUS_ACCESS_DENIED
;
3904 if(!pdb_delete_group_mapping_entry(group_sid
))
3905 return NT_STATUS_ACCESS_DENIED
;
3907 if (!close_policy_hnd(p
, &q_u
->group_pol
))
3908 return NT_STATUS_OBJECT_NAME_INVALID
;
3910 return NT_STATUS_OK
;
3913 /*********************************************************************
3914 _samr_delete_dom_alias
3915 *********************************************************************/
3917 NTSTATUS
_samr_delete_dom_alias(pipes_struct
*p
, SAMR_Q_DELETE_DOM_ALIAS
*q_u
, SAMR_R_DELETE_DOM_ALIAS
*r_u
)
3922 fstring alias_sid_str
;
3928 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__
));
3930 /* Find the policy handle. Open a policy on it. */
3931 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3932 return NT_STATUS_INVALID_HANDLE
;
3934 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_alias"))) {
3938 sid_copy(&dom_sid
, &alias_sid
);
3939 sid_to_string(alias_sid_str
, &dom_sid
);
3940 sid_split_rid(&dom_sid
, &alias_rid
);
3942 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3944 /* we check if it's our SID before deleting */
3945 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
3946 return NT_STATUS_NO_SUCH_ALIAS
;
3948 DEBUG(10, ("lookup on Local SID\n"));
3950 if(!get_local_group_from_sid(alias_sid
, &map
))
3951 return NT_STATUS_NO_SUCH_ALIAS
;
3955 /* check if group really exists */
3956 if ( (grp
=getgrgid(gid
)) == NULL
)
3957 return NT_STATUS_NO_SUCH_ALIAS
;
3959 /* we can delete the UNIX group */
3960 smb_delete_group(grp
->gr_name
);
3962 /* check if the group has been successfully deleted */
3963 if ( (grp
=getgrgid(gid
)) != NULL
)
3964 return NT_STATUS_ACCESS_DENIED
;
3966 /* don't check if we removed it as it could be an un-mapped group */
3967 pdb_delete_group_mapping_entry(alias_sid
);
3969 if (!close_policy_hnd(p
, &q_u
->alias_pol
))
3970 return NT_STATUS_OBJECT_NAME_INVALID
;
3972 return NT_STATUS_OK
;
3975 /*********************************************************************
3976 _samr_create_dom_group
3977 *********************************************************************/
3979 NTSTATUS
_samr_create_dom_group(pipes_struct
*p
, SAMR_Q_CREATE_DOM_GROUP
*q_u
, SAMR_R_CREATE_DOM_GROUP
*r_u
)
3986 struct samr_info
*info
;
3990 /* Find the policy handle. Open a policy on it. */
3991 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &dom_sid
, &acc_granted
))
3992 return NT_STATUS_INVALID_HANDLE
;
3994 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_CREATE_GROUP
, "_samr_create_dom_group"))) {
3998 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
3999 return NT_STATUS_ACCESS_DENIED
;
4001 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4003 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
4005 /* check if group already exist */
4006 if ((grp
=getgrnam(name
)) != NULL
)
4007 return NT_STATUS_GROUP_EXISTS
;
4009 /* we can create the UNIX group */
4010 if (smb_create_group(name
, &gid
) != 0)
4011 return NT_STATUS_ACCESS_DENIED
;
4013 /* check if the group has been successfully created */
4014 if ((grp
=getgrgid(gid
)) == NULL
)
4015 return NT_STATUS_ACCESS_DENIED
;
4017 r_u
->rid
=pdb_gid_to_group_rid(grp
->gr_gid
);
4019 /* add the group to the mapping table */
4020 sid_copy(&info_sid
, get_global_sam_sid());
4021 sid_append_rid(&info_sid
, r_u
->rid
);
4022 sid_to_string(sid_string
, &info_sid
);
4024 if(!add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_DOM_GRP
, name
, NULL
))
4025 return NT_STATUS_ACCESS_DENIED
;
4027 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4028 return NT_STATUS_NO_MEMORY
;
4030 /* get a (unique) handle. open a policy on it. */
4031 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
4032 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4034 return NT_STATUS_OK
;
4037 /*********************************************************************
4038 _samr_create_dom_alias
4039 *********************************************************************/
4041 NTSTATUS
_samr_create_dom_alias(pipes_struct
*p
, SAMR_Q_CREATE_DOM_ALIAS
*q_u
, SAMR_R_CREATE_DOM_ALIAS
*r_u
)
4048 struct samr_info
*info
;
4052 /* Find the policy handle. Open a policy on it. */
4053 if (!get_lsa_policy_samr_sid(p
, &q_u
->dom_pol
, &dom_sid
, &acc_granted
))
4054 return NT_STATUS_INVALID_HANDLE
;
4056 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_CREATE_ALIAS
, "_samr_create_alias"))) {
4060 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
4061 return NT_STATUS_ACCESS_DENIED
;
4063 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4065 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
4067 /* check if group already exists */
4068 if ( (grp
=getgrnam(name
)) != NULL
)
4069 return NT_STATUS_GROUP_EXISTS
;
4071 /* we can create the UNIX group */
4072 if (smb_create_group(name
, &gid
) != 0)
4073 return NT_STATUS_ACCESS_DENIED
;
4075 /* check if the group has been successfully created */
4076 if ((grp
=getgrgid(gid
)) == NULL
)
4077 return NT_STATUS_ACCESS_DENIED
;
4079 r_u
->rid
=pdb_gid_to_group_rid(grp
->gr_gid
);
4081 sid_copy(&info_sid
, get_global_sam_sid());
4082 sid_append_rid(&info_sid
, r_u
->rid
);
4083 sid_to_string(sid_string
, &info_sid
);
4085 /* add the group to the mapping table */
4086 if(!add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_ALIAS
, name
, NULL
))
4087 return NT_STATUS_ACCESS_DENIED
;
4089 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4090 return NT_STATUS_NO_MEMORY
;
4092 /* get a (unique) handle. open a policy on it. */
4093 if (!create_policy_hnd(p
, &r_u
->alias_pol
, free_samr_info
, (void *)info
))
4094 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4096 return NT_STATUS_OK
;
4099 /*********************************************************************
4100 _samr_query_groupinfo
4102 sends the name/comment pair of a domain group
4103 level 1 send also the number of users of that group
4104 *********************************************************************/
4106 NTSTATUS
_samr_query_groupinfo(pipes_struct
*p
, SAMR_Q_QUERY_GROUPINFO
*q_u
, SAMR_R_QUERY_GROUPINFO
*r_u
)
4112 GROUP_INFO_CTR
*ctr
;
4115 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
4116 return NT_STATUS_INVALID_HANDLE
;
4118 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_LOOKUP_INFO
, "_samr_query_groupinfo"))) {
4122 if (!get_domain_group_from_sid(group_sid
, &map
))
4123 return NT_STATUS_INVALID_HANDLE
;
4125 ctr
=(GROUP_INFO_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(GROUP_INFO_CTR
));
4127 return NT_STATUS_NO_MEMORY
;
4129 switch (q_u
->switch_level
) {
4131 ctr
->switch_value1
= 1;
4132 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
4133 return NT_STATUS_NO_SUCH_GROUP
;
4134 init_samr_group_info1(&ctr
->group
.info1
, map
.nt_name
, map
.comment
, num_uids
);
4138 ctr
->switch_value1
= 3;
4139 init_samr_group_info3(&ctr
->group
.info3
);
4142 ctr
->switch_value1
= 4;
4143 init_samr_group_info4(&ctr
->group
.info4
, map
.comment
);
4146 return NT_STATUS_INVALID_INFO_CLASS
;
4149 init_samr_r_query_groupinfo(r_u
, ctr
, NT_STATUS_OK
);
4151 return NT_STATUS_OK
;
4154 /*********************************************************************
4157 update a domain group's comment.
4158 *********************************************************************/
4160 NTSTATUS
_samr_set_groupinfo(pipes_struct
*p
, SAMR_Q_SET_GROUPINFO
*q_u
, SAMR_R_SET_GROUPINFO
*r_u
)
4164 GROUP_INFO_CTR
*ctr
;
4167 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
4168 return NT_STATUS_INVALID_HANDLE
;
4170 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_SET_INFO
, "_samr_set_groupinfo"))) {
4174 if (!get_domain_group_from_sid(group_sid
, &map
))
4175 return NT_STATUS_NO_SUCH_GROUP
;
4179 switch (ctr
->switch_value1
) {
4181 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info1
.uni_acct_desc
), sizeof(map
.comment
)-1);
4184 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info4
.uni_acct_desc
), sizeof(map
.comment
)-1);
4187 return NT_STATUS_INVALID_INFO_CLASS
;
4190 if(!pdb_update_group_mapping_entry(&map
)) {
4191 return NT_STATUS_NO_SUCH_GROUP
;
4194 return NT_STATUS_OK
;
4197 /*********************************************************************
4200 update an alias's comment.
4201 *********************************************************************/
4203 NTSTATUS
_samr_set_aliasinfo(pipes_struct
*p
, SAMR_Q_SET_ALIASINFO
*q_u
, SAMR_R_SET_ALIASINFO
*r_u
)
4207 ALIAS_INFO_CTR
*ctr
;
4210 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &group_sid
, &acc_granted
))
4211 return NT_STATUS_INVALID_HANDLE
;
4213 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_SET_INFO
, "_samr_set_aliasinfo"))) {
4217 if (!get_local_group_from_sid(group_sid
, &map
))
4218 return NT_STATUS_NO_SUCH_GROUP
;
4222 switch (ctr
->switch_value1
) {
4224 unistr2_to_ascii(map
.comment
, &(ctr
->alias
.info3
.uni_acct_desc
), sizeof(map
.comment
)-1);
4227 return NT_STATUS_INVALID_INFO_CLASS
;
4230 if(!pdb_update_group_mapping_entry(&map
)) {
4231 return NT_STATUS_NO_SUCH_GROUP
;
4234 return NT_STATUS_OK
;
4237 /*********************************************************************
4238 _samr_get_dom_pwinfo
4239 *********************************************************************/
4241 NTSTATUS
_samr_get_dom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_DOM_PWINFO
*q_u
, SAMR_R_GET_DOM_PWINFO
*r_u
)
4243 /* Perform access check. Since this rpc does not require a
4244 policy handle it will not be caught by the access checks on
4245 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4247 if (!pipe_access_check(p
)) {
4248 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4249 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
4253 /* Actually, returning zeros here works quite well :-). */
4255 return NT_STATUS_OK
;
4258 /*********************************************************************
4260 *********************************************************************/
4262 NTSTATUS
_samr_open_group(pipes_struct
*p
, SAMR_Q_OPEN_GROUP
*q_u
, SAMR_R_OPEN_GROUP
*r_u
)
4267 struct samr_info
*info
;
4268 SEC_DESC
*psd
= NULL
;
4270 uint32 des_access
= q_u
->access_mask
;
4275 if (!get_lsa_policy_samr_sid(p
, &q_u
->domain_pol
, &sid
, &acc_granted
))
4276 return NT_STATUS_INVALID_HANDLE
;
4278 if (!NT_STATUS_IS_OK(status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_open_group"))) {
4282 /*check if access can be granted as requested by client. */
4283 samr_make_grp_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
4284 se_map_generic(&des_access
,&grp_generic_mapping
);
4285 if (!NT_STATUS_IS_OK(status
=
4286 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
4287 des_access
, &acc_granted
, "_samr_open_group"))) {
4292 /* this should not be hard-coded like this */
4293 if (!sid_equal(&sid
, get_global_sam_sid()))
4294 return NT_STATUS_ACCESS_DENIED
;
4296 sid_copy(&info_sid
, get_global_sam_sid());
4297 sid_append_rid(&info_sid
, q_u
->rid_group
);
4298 sid_to_string(sid_string
, &info_sid
);
4300 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4301 return NT_STATUS_NO_MEMORY
;
4303 info
->acc_granted
= acc_granted
;
4305 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string
));
4307 /* check if that group really exists */
4308 if (!get_domain_group_from_sid(info
->sid
, &map
))
4309 return NT_STATUS_NO_SUCH_GROUP
;
4311 /* get a (unique) handle. open a policy on it. */
4312 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
4313 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4315 return NT_STATUS_OK
;
4318 /*********************************************************************
4319 _samr_remove_user_foreign_domain
4320 *********************************************************************/
4322 NTSTATUS
_samr_remove_user_foreign_domain(pipes_struct
*p
,
4323 SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN
*q_u
,
4324 SAMR_R_REMOVE_USER_FOREIGN_DOMAIN
*r_u
)
4326 DOM_SID user_sid
, dom_sid
;
4327 SAM_ACCOUNT
*sam_pass
=NULL
;
4330 sid_copy( &user_sid
, &q_u
->sid
.sid
);
4332 DEBUG(5,("_samr_remove_user_foreign_domain: removing user [%s]\n",
4333 sid_string_static(&user_sid
)));
4335 /* Find the policy handle. Open a policy on it. */
4337 if (!get_lsa_policy_samr_sid(p
, &q_u
->dom_pol
, &dom_sid
, &acc_granted
))
4338 return NT_STATUS_INVALID_HANDLE
;
4340 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
,
4341 STD_RIGHT_DELETE_ACCESS
, "_samr_remove_user_foreign_domain")))
4346 if ( !sid_check_is_in_our_domain(&user_sid
) ) {
4347 DEBUG(5,("_samr_remove_user_foreign_domain: user not is our domain!\n"));
4348 return NT_STATUS_NO_SUCH_USER
;
4351 /* check if the user exists before trying to delete */
4353 pdb_init_sam(&sam_pass
);
4355 if ( !pdb_getsampwsid(sam_pass
, &user_sid
) ) {
4357 DEBUG(5,("_samr_remove_user_foreign_domain:User %s doesn't exist.\n",
4358 sid_string_static(&user_sid
)));
4360 pdb_free_sam(&sam_pass
);
4362 return NT_STATUS_NO_SUCH_USER
;
4366 * delete the unix side
4368 * note: we don't check if the delete really happened
4369 * as the script is not necessary present
4370 * and maybe the sysadmin doesn't want to delete the unix side
4373 smb_delete_user(pdb_get_username(sam_pass
));
4375 /* and delete the samba side */
4377 if ( !pdb_delete_sam_account(sam_pass
) ) {
4379 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass
)));
4380 pdb_free_sam(&sam_pass
);
4382 return NT_STATUS_CANNOT_DELETE
;
4385 pdb_free_sam(&sam_pass
);
4387 return NT_STATUS_OK
;
4390 /*******************************************************************
4392 ********************************************************************/
4394 NTSTATUS
_samr_unknown_2e(pipes_struct
*p
, SAMR_Q_UNKNOWN_2E
*q_u
, SAMR_R_UNKNOWN_2E
*r_u
)
4396 struct samr_info
*info
= NULL
;
4398 uint32 min_pass_len
,pass_hist
,flag
;
4399 time_t u_expire
, u_min_age
;
4400 NTTIME nt_expire
, nt_min_age
;
4402 time_t u_lock_duration
, u_reset_time
;
4403 NTTIME nt_lock_duration
, nt_reset_time
;
4409 uint32 num_users
=0, num_groups
=0, num_aliases
=0;
4411 uint32 account_policy_temp
;
4413 if ((ctr
= (SAM_UNK_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_UNK_CTR
))) == NULL
)
4414 return NT_STATUS_NO_MEMORY
;
4418 r_u
->status
= NT_STATUS_OK
;
4420 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__
));
4422 /* find the policy handle. open a policy on it. */
4423 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
4424 return NT_STATUS_INVALID_HANDLE
;
4426 switch (q_u
->switch_value
) {
4428 account_policy_get(AP_MIN_PASSWORD_LEN
, &account_policy_temp
);
4429 min_pass_len
= account_policy_temp
;
4431 account_policy_get(AP_PASSWORD_HISTORY
, &account_policy_temp
);
4432 pass_hist
= account_policy_temp
;
4434 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS
, &account_policy_temp
);
4435 flag
= account_policy_temp
;
4437 account_policy_get(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
4438 u_expire
= account_policy_temp
;
4440 account_policy_get(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
4441 u_min_age
= account_policy_temp
;
4443 unix_to_nt_time_abs(&nt_expire
, u_expire
);
4444 unix_to_nt_time_abs(&nt_min_age
, u_min_age
);
4446 init_unk_info1(&ctr
->info
.inf1
, (uint16
)min_pass_len
, (uint16
)pass_hist
,
4447 flag
, nt_expire
, nt_min_age
);
4451 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
, False
);
4453 if (!NT_STATUS_IS_OK(r_u
->status
)) {
4454 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4457 num_users
=info
->disp_info
.num_user_account
;
4460 r_u
->status
=load_group_domain_entries(info
, get_global_sam_sid());
4461 if (NT_STATUS_IS_ERR(r_u
->status
)) {
4462 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4465 num_groups
=info
->disp_info
.num_group_account
;
4468 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4469 init_unk_info2(&ctr
->info
.inf2
, lp_workgroup(), global_myname(), (uint32
) time(NULL
),
4470 num_users
, num_groups
, num_aliases
);
4473 account_policy_get(AP_TIME_TO_LOGOUT
, &account_policy_temp
);
4474 u_logout
= account_policy_temp
;
4476 unix_to_nt_time_abs(&nt_logout
, u_logout
);
4478 init_unk_info3(&ctr
->info
.inf3
, nt_logout
);
4481 init_unk_info5(&ctr
->info
.inf5
, global_myname());
4484 init_unk_info6(&ctr
->info
.inf6
);
4487 init_unk_info7(&ctr
->info
.inf7
);
4490 account_policy_get(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
4491 u_lock_duration
= account_policy_temp
;
4493 account_policy_get(AP_RESET_COUNT_TIME
, &account_policy_temp
);
4494 u_reset_time
= account_policy_temp
;
4496 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
4497 lockout
= account_policy_temp
;
4499 unix_to_nt_time_abs(&nt_lock_duration
, u_lock_duration
);
4500 unix_to_nt_time_abs(&nt_reset_time
, u_reset_time
);
4502 init_unk_info12(&ctr
->info
.inf12
, nt_lock_duration
, nt_reset_time
, (uint16
)lockout
);
4505 return NT_STATUS_INVALID_INFO_CLASS
;
4508 init_samr_r_samr_unknown_2e(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_OK
);
4510 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__
));
4515 /*******************************************************************
4517 ********************************************************************/
4519 NTSTATUS
_samr_set_dom_info(pipes_struct
*p
, SAMR_Q_SET_DOMAIN_INFO
*q_u
, SAMR_R_SET_DOMAIN_INFO
*r_u
)
4521 time_t u_expire
, u_min_age
;
4523 time_t u_lock_duration
, u_reset_time
;
4525 r_u
->status
= NT_STATUS_OK
;
4527 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__
));
4529 /* find the policy handle. open a policy on it. */
4530 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, NULL
))
4531 return NT_STATUS_INVALID_HANDLE
;
4533 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u
->switch_value
));
4535 switch (q_u
->switch_value
) {
4537 u_expire
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf1
.expire
);
4538 u_min_age
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf1
.min_passwordage
);
4540 account_policy_set(AP_MIN_PASSWORD_LEN
, (uint32
)q_u
->ctr
->info
.inf1
.min_length_password
);
4541 account_policy_set(AP_PASSWORD_HISTORY
, (uint32
)q_u
->ctr
->info
.inf1
.password_history
);
4542 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS
, (uint32
)q_u
->ctr
->info
.inf1
.flag
);
4543 account_policy_set(AP_MAX_PASSWORD_AGE
, (int)u_expire
);
4544 account_policy_set(AP_MIN_PASSWORD_AGE
, (int)u_min_age
);
4549 u_logout
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf3
.logout
);
4550 account_policy_set(AP_TIME_TO_LOGOUT
, (int)u_logout
);
4559 u_lock_duration
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf12
.duration
);
4560 u_reset_time
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf12
.reset_count
);
4562 account_policy_set(AP_LOCK_ACCOUNT_DURATION
, (int)u_lock_duration
);
4563 account_policy_set(AP_RESET_COUNT_TIME
, (int)u_reset_time
);
4564 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT
, (uint32
)q_u
->ctr
->info
.inf12
.bad_attempt_lockout
);
4567 return NT_STATUS_INVALID_INFO_CLASS
;
4570 init_samr_r_set_domain_info(r_u
, NT_STATUS_OK
);
4572 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__
));