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 = TALLOC_P(mem_ctx, 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=TALLOC_REALLOC_ARRAY(mem_ctx, info->disp_info.disp_user_info, SAM_ACCOUNT,
259 info->disp_info.num_user_account+MAX_SAM_ENTRIES);
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;
297 DEBUG(10,("load_group_domain_entries\n"));
299 /* if the snapshoot is already loaded, return */
300 if (info->disp_info.group_dbloaded==True) {
301 DEBUG(10,("load_group_domain_entries: already in memory\n"));
305 if (sid_equal(sid, &global_sid_Builtin)) {
306 /* No domain groups for now in the BUILTIN domain */
307 info->disp_info.num_group_account=0;
308 info->disp_info.disp_group_info=NULL;
309 info->disp_info.group_dbloaded=True;
314 ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
318 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
319 return NT_STATUS_NO_MEMORY;
323 info->disp_info.num_group_account=group_entries;
325 grp_array=TALLOC_ARRAY(mem_ctx, DOMAIN_GRP, info->disp_info.num_group_account);
326 if (group_entries!=0 && grp_array==NULL) {
327 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
329 return NT_STATUS_NO_MEMORY;
332 info->disp_info.disp_group_info=grp_array;
334 for (i=0; i<group_entries; i++) {
335 fstrcpy(grp_array[i].name, map[i].nt_name);
336 fstrcpy(grp_array[i].comment, map[i].comment);
337 sid_split_rid(&map[i].sid, &grp_array[i].rid);
338 grp_array[i].attr=SID_NAME_DOM_GRP;
343 /* the snapshoot is in memory, we're ready to enumerate fast */
345 info->disp_info.group_dbloaded=True;
347 DEBUG(10,("load_group_domain_entries: done\n"));
353 /*******************************************************************
355 ********************************************************************/
357 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
359 r_u->status = NT_STATUS_OK;
361 /* close the policy handle */
362 if (!close_policy_hnd(p, &q_u->pol))
363 return NT_STATUS_OBJECT_NAME_INVALID;
365 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
370 /*******************************************************************
371 samr_reply_open_domain
372 ********************************************************************/
374 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
376 struct samr_info *info;
377 SEC_DESC *psd = NULL;
379 uint32 des_access = q_u->flags;
383 r_u->status = NT_STATUS_OK;
385 /* find the connection policy handle. */
386 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
387 return NT_STATUS_INVALID_HANDLE;
389 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
393 /*check if access can be granted as requested by client. */
394 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
395 se_map_generic(&des_access,&dom_generic_mapping);
397 if (!NT_STATUS_IS_OK(status =
398 access_check_samr_object(psd, p->pipe_user.nt_user_token,
399 des_access, &acc_granted, "_samr_open_domain"))) {
403 /* associate the domain SID with the (unique) handle. */
404 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
405 return NT_STATUS_NO_MEMORY;
406 info->acc_granted = acc_granted;
408 /* get a (unique) handle. open a policy on it. */
409 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
410 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
412 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
417 /*******************************************************************
418 _samr_get_usrdom_pwinfo
419 ********************************************************************/
421 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
423 struct samr_info *info = NULL;
425 r_u->status = NT_STATUS_OK;
427 /* find the policy handle. open a policy on it. */
428 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
429 return NT_STATUS_INVALID_HANDLE;
431 if (!sid_check_is_in_our_domain(&info->sid))
432 return NT_STATUS_OBJECT_TYPE_MISMATCH;
434 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
436 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
439 * NT sometimes return NT_STATUS_ACCESS_DENIED
440 * I don't know yet why.
446 /*******************************************************************
448 ********************************************************************/
450 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
452 extern DOM_SID global_sid_World;
461 sid_copy(&adm_sid, &global_sid_Builtin);
462 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
464 sid_copy(&act_sid, &global_sid_Builtin);
465 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
467 /*basic access for every one*/
468 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
469 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
471 /*full access for builtin aliases Administrators and Account Operators*/
472 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
473 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
474 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
476 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
477 return NT_STATUS_NO_MEMORY;
479 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
480 return NT_STATUS_NO_MEMORY;
485 /*******************************************************************
487 ********************************************************************/
489 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
491 extern DOM_SID global_sid_World;
500 sid_copy(&adm_sid, &global_sid_Builtin);
501 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
503 sid_copy(&act_sid, &global_sid_Builtin);
504 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
506 /*basic access for every one*/
507 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
508 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 /*full access for builtin aliases Administrators and Account Operators*/
511 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
512 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
513 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
515 /*extended access for the user*/
516 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
517 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
519 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
520 return NT_STATUS_NO_MEMORY;
522 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
523 return NT_STATUS_NO_MEMORY;
528 /*******************************************************************
530 ********************************************************************/
532 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
534 extern DOM_SID global_sid_World;
543 sid_copy(&adm_sid, &global_sid_Builtin);
544 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
546 sid_copy(&act_sid, &global_sid_Builtin);
547 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
549 /*basic access for every one*/
550 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
551 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
553 /*full access for builtin aliases Administrators and Account Operators*/
554 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
555 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
556 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
558 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
559 return NT_STATUS_NO_MEMORY;
561 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
562 return NT_STATUS_NO_MEMORY;
567 /*******************************************************************
569 ********************************************************************/
571 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
573 extern DOM_SID global_sid_World;
582 sid_copy(&adm_sid, &global_sid_Builtin);
583 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
585 sid_copy(&act_sid, &global_sid_Builtin);
586 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
588 /*basic access for every one*/
589 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
590 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
592 /*full access for builtin aliases Administrators and Account Operators*/
593 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
594 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
595 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
597 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
598 return NT_STATUS_NO_MEMORY;
600 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
601 return NT_STATUS_NO_MEMORY;
606 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
608 struct samr_info *info = NULL;
610 /* find the policy handle. open a policy on it. */
611 if (!find_policy_by_hnd(p, pol, (void **)&info))
618 *acc_granted = info->acc_granted;
622 /*******************************************************************
624 ********************************************************************/
626 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
628 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
629 return NT_STATUS_NOT_IMPLEMENTED;
633 /*******************************************************************
635 ********************************************************************/
637 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
641 SEC_DESC * psd = NULL;
645 r_u->status = NT_STATUS_OK;
648 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
649 return NT_STATUS_INVALID_HANDLE;
653 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
655 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
657 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
658 if (pol_sid.sid_rev_num == 0)
660 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
661 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
663 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
666 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
667 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
669 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
671 /* TODO: Builtin probably needs a different SD with restricted write access*/
672 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
673 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
675 else if (sid_check_is_in_our_domain(&pol_sid) ||
676 sid_check_is_in_builtin(&pol_sid))
678 /* TODO: different SDs have to be generated for aliases groups and users.
679 Currently all three get a default user SD */
680 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
681 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
683 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
685 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
686 return NT_STATUS_NO_MEMORY;
688 if (NT_STATUS_IS_OK(r_u->status))
694 /*******************************************************************
695 makes a SAM_ENTRY / UNISTR2* structure from a user list.
696 ********************************************************************/
698 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
699 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
705 SAM_ACCOUNT *pwd = NULL;
706 UNISTR2 uni_temp_name;
707 const char *temp_name;
708 const DOM_SID *user_sid;
710 fstring user_sid_string;
711 fstring domain_sid_string;
716 if (num_entries == 0)
719 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries);
721 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_entries);
723 if (sam == NULL || uni_name == NULL) {
724 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
725 return NT_STATUS_NO_MEMORY;
728 for (i = 0; i < num_entries; i++) {
729 pwd = &disp_user_info[i+start_idx];
730 temp_name = pdb_get_username(pwd);
733 * usrmgr expects a non-NULL terminated string with
734 * trust relationships
736 if (pdb_get_acct_ctrl(pwd) & ACB_DOMTRUST) {
737 init_unistr2(&uni_temp_name, temp_name, UNI_FLAGS_NONE);
739 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
742 user_sid = pdb_get_user_sid(pwd);
744 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
745 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
746 "the domain sid %s. Failing operation.\n",
748 sid_to_string(user_sid_string, user_sid),
749 sid_to_string(domain_sid_string, domain_sid)));
750 return NT_STATUS_UNSUCCESSFUL;
753 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
754 copy_unistr2(&uni_name[i], &uni_temp_name);
758 *uni_name_pp = uni_name;
762 /*******************************************************************
763 samr_reply_enum_dom_users
764 ********************************************************************/
766 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
767 SAMR_R_ENUM_DOM_USERS *r_u)
769 struct samr_info *info = NULL;
770 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
772 uint32 enum_context=q_u->start_idx;
773 uint32 max_size=q_u->max_size;
775 enum remote_arch_types ra_type = get_remote_arch();
776 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
777 uint32 max_entries = max_sam_entries;
780 r_u->status = NT_STATUS_OK;
782 /* find the policy handle. open a policy on it. */
783 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
784 return NT_STATUS_INVALID_HANDLE;
786 domain_sid = info->sid;
788 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
789 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
790 "_samr_enum_dom_users"))) {
794 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
797 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
800 if (!NT_STATUS_IS_OK(r_u->status))
803 num_account = info->disp_info.num_user_account;
805 if (enum_context > num_account) {
806 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
810 /* verify we won't overflow */
811 if (max_entries > num_account-enum_context) {
812 max_entries = num_account-enum_context;
813 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
816 /* calculate the size and limit on the number of entries we will return */
817 temp_size=max_entries*struct_size;
819 if (temp_size>max_size) {
820 max_entries=MIN((max_size/struct_size),max_entries);;
821 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
825 * Note from JRA. total_entries is not being used here. Currently if there is a
826 * large user base then it looks like NT will enumerate until get_sampwd_entries
827 * returns False due to num_entries being zero. This will cause an access denied
828 * return. I don't think this is right and needs further investigation. Note that
829 * this is also the same in the TNG code (I don't think that has been tested with
830 * a very large user list as MAX_SAM_ENTRIES is set to 600).
832 * I also think that one of the 'num_entries' return parameters is probably
833 * the "max entries" parameter - but in the TNG code they're all currently set to the same
834 * value (again I think this is wrong).
837 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
838 max_entries, enum_context,
839 info->disp_info.disp_user_info,
842 if (!NT_STATUS_IS_OK(r_u->status))
845 if (enum_context+max_entries < num_account)
846 r_u->status = STATUS_MORE_ENTRIES;
848 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
850 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
852 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
857 /*******************************************************************
858 makes a SAM_ENTRY / UNISTR2* structure from a group list.
859 ********************************************************************/
861 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
862 uint32 num_sam_entries, DOMAIN_GRP *grp)
871 if (num_sam_entries == 0)
874 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
875 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
877 if (sam == NULL || uni_name == NULL) {
878 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
882 for (i = 0; i < num_sam_entries; i++) {
884 * JRA. I think this should include the null. TNG does not.
886 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
887 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
891 *uni_name_pp = uni_name;
894 /*******************************************************************
895 Get the group entries - similar to get_sampwd_entries().
896 ******************************************************************/
898 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
899 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
900 uint32 *p_num_entries, uint32 max_entries )
904 uint32 group_entries = 0;
905 uint32 num_entries = 0;
909 /* access checks for the users were performed higher up. become/unbecome_root()
910 needed for some passdb backends to enumerate groups */
913 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
917 num_entries=group_entries-start_idx;
919 /* limit the number of entries */
920 if (num_entries>max_entries) {
921 DEBUG(5,("Limiting to %d entries\n", max_entries));
922 num_entries=max_entries;
925 *d_grp=TALLOC_ZERO_ARRAY(ctx, DOMAIN_GRP, num_entries);
926 if (num_entries!=0 && *d_grp==NULL){
928 return NT_STATUS_NO_MEMORY;
931 for (i=0; i<num_entries; i++) {
932 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
933 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
934 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
935 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
940 *p_num_entries = num_entries;
942 DEBUG(10,("get_group_domain_entries: returning %d entries\n",
948 /*******************************************************************
949 Wrapper for enumerating local groups
950 ******************************************************************/
952 static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
953 const DOM_SID *sid, uint32 start_idx,
954 uint32 *p_num_entries, uint32 max_entries )
956 struct acct_info *info;
961 res = pdb_enum_aliases(sid, start_idx, max_entries,
962 p_num_entries, &info);
966 return NT_STATUS_ACCESS_DENIED;
968 if (*p_num_entries == 0)
971 *d_grp = TALLOC_ARRAY(ctx, DOMAIN_GRP, *p_num_entries);
973 if (*d_grp == NULL) {
975 return NT_STATUS_NO_MEMORY;
978 for (i=0; i<*p_num_entries; i++) {
979 fstrcpy((*d_grp)[i].name, info[i].acct_name);
980 fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
981 (*d_grp)[i].rid = info[i].rid;
982 (*d_grp)[i].attr = SID_NAME_ALIAS;
989 /*******************************************************************
990 samr_reply_enum_dom_groups
991 ********************************************************************/
993 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
995 DOMAIN_GRP *grp=NULL;
1000 r_u->status = NT_STATUS_OK;
1002 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1003 return NT_STATUS_INVALID_HANDLE;
1005 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1009 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1011 /* the domain group array is being allocated in the function below */
1012 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))) {
1016 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1018 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1020 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1026 /*******************************************************************
1027 samr_reply_enum_dom_aliases
1028 ********************************************************************/
1030 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1032 DOMAIN_GRP *grp=NULL;
1033 uint32 num_entries = 0;
1039 r_u->status = NT_STATUS_OK;
1041 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1042 return NT_STATUS_INVALID_HANDLE;
1044 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1048 sid_to_string(sid_str, &sid);
1049 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1051 status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1052 &num_entries, MAX_SAM_ENTRIES);
1053 if (!NT_STATUS_IS_OK(status)) return status;
1055 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1059 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1061 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1066 /*******************************************************************
1067 samr_reply_query_dispinfo
1068 ********************************************************************/
1070 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1071 SAMR_R_QUERY_DISPINFO *r_u)
1073 struct samr_info *info = NULL;
1074 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1076 uint32 max_entries=q_u->max_entries;
1077 uint32 enum_context=q_u->start_idx;
1078 uint32 max_size=q_u->max_size;
1080 SAM_DISPINFO_CTR *ctr;
1081 uint32 temp_size=0, total_data_size=0;
1083 uint32 num_account = 0;
1084 enum remote_arch_types ra_type = get_remote_arch();
1085 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1088 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1089 r_u->status = NT_STATUS_OK;
1091 /* find the policy handle. open a policy on it. */
1092 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1093 return NT_STATUS_INVALID_HANDLE;
1095 domain_sid = info->sid;
1098 * calculate how many entries we will return.
1100 * - the number of entries the client asked
1101 * - our limit on that
1102 * - the starting point (enumeration context)
1103 * - the buffer size the client will accept
1107 * We are a lot more like W2K. Instead of reading the SAM
1108 * each time to find the records we need to send back,
1109 * we read it once and link that copy to the sam handle.
1110 * For large user list (over the MAX_SAM_ENTRIES)
1111 * it's a definitive win.
1112 * second point to notice: between enumerations
1113 * our sam is now the same as it's a snapshoot.
1114 * third point: got rid of the static SAM_USER_21 struct
1115 * no more intermediate.
1116 * con: it uses much more memory, as a full copy is stored
1119 * If you want to change it, think twice and think
1120 * of the second point , that's really important.
1125 /* Get what we need from the password database */
1126 switch (q_u->switch_level) {
1128 /* When playing with usrmgr, this is necessary
1129 if you want immediate refresh after editing
1130 a user. I would like to do this after the
1131 setuserinfo2, but we do not have access to
1132 the domain handle in that call, only to the
1133 user handle. Where else does this hurt?
1137 /* We cannot do this here - it kills performace. JRA. */
1138 free_samr_users(info);
1143 /* Level 2 is for all machines, otherwise only 'normal' users */
1144 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1146 if (!NT_STATUS_IS_OK(r_u->status)) {
1147 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1150 num_account = info->disp_info.num_user_account;
1154 r_u->status = load_group_domain_entries(info, &info->sid);
1155 if (!NT_STATUS_IS_OK(r_u->status))
1157 num_account = info->disp_info.num_group_account;
1160 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1161 return NT_STATUS_INVALID_INFO_CLASS;
1164 /* first limit the number of entries we will return */
1165 if(max_entries > max_sam_entries) {
1166 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1167 max_entries = max_sam_entries;
1170 if (enum_context > num_account) {
1171 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1172 return NT_STATUS_NO_MORE_ENTRIES;
1175 /* verify we won't overflow */
1176 if (max_entries > num_account-enum_context) {
1177 max_entries = num_account-enum_context;
1178 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1181 /* calculate the size and limit on the number of entries we will return */
1182 temp_size=max_entries*struct_size;
1184 if (temp_size>max_size) {
1185 max_entries=MIN((max_size/struct_size),max_entries);;
1186 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1189 if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
1190 return NT_STATUS_NO_MEMORY;
1194 /* Now create reply structure */
1195 switch (q_u->switch_level) {
1198 if (!(ctr->sam.info1 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_1,max_entries)))
1199 return NT_STATUS_NO_MEMORY;
1201 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1202 info->disp_info.disp_user_info, &domain_sid);
1203 if (!NT_STATUS_IS_OK(disp_ret))
1208 if (!(ctr->sam.info2 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_2,max_entries)))
1209 return NT_STATUS_NO_MEMORY;
1211 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1212 info->disp_info.disp_user_info, &domain_sid);
1213 if (!NT_STATUS_IS_OK(disp_ret))
1218 if (!(ctr->sam.info3 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_3,max_entries)))
1219 return NT_STATUS_NO_MEMORY;
1221 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1222 if (!NT_STATUS_IS_OK(disp_ret))
1227 if (!(ctr->sam.info4 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_4,max_entries)))
1228 return NT_STATUS_NO_MEMORY;
1230 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1231 if (!NT_STATUS_IS_OK(disp_ret))
1236 if (!(ctr->sam.info5 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_5,max_entries)))
1237 return NT_STATUS_NO_MEMORY;
1239 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1240 if (!NT_STATUS_IS_OK(disp_ret))
1245 ctr->sam.info = NULL;
1246 return NT_STATUS_INVALID_INFO_CLASS;
1249 /* calculate the total size */
1250 total_data_size=num_account*struct_size;
1252 if (enum_context+max_entries < num_account)
1253 r_u->status = STATUS_MORE_ENTRIES;
1255 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1257 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1263 /*******************************************************************
1264 samr_reply_query_aliasinfo
1265 ********************************************************************/
1267 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1270 struct acct_info info;
1274 r_u->status = NT_STATUS_OK;
1276 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1278 /* find the policy handle. open a policy on it. */
1279 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1280 return NT_STATUS_INVALID_HANDLE;
1281 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1286 ret = pdb_get_aliasinfo(&sid, &info);
1290 return NT_STATUS_NO_SUCH_ALIAS;
1292 switch (q_u->switch_level) {
1295 r_u->ctr.switch_value1 = 1;
1296 init_samr_alias_info1(&r_u->ctr.alias.info1,
1297 info.acct_name, 1, info.acct_desc);
1301 r_u->ctr.switch_value1 = 3;
1302 init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1305 return NT_STATUS_INVALID_INFO_CLASS;
1308 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1314 /*******************************************************************
1315 samr_reply_lookup_ids
1316 ********************************************************************/
1318 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1320 uint32 rid[MAX_SAM_ENTRIES];
1321 int num_rids = q_u->num_sids1;
1323 r_u->status = NT_STATUS_OK;
1325 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1327 if (num_rids > MAX_SAM_ENTRIES) {
1328 num_rids = MAX_SAM_ENTRIES;
1329 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1334 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1336 for (i = 0; i < num_rids && status == 0; i++)
1338 struct sam_passwd *sam_pass;
1342 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1343 q_u->uni_user_name[i].uni_str_len));
1345 /* find the user account */
1347 sam_pass = get_smb21pwd_entry(user_name, 0);
1350 if (sam_pass == NULL)
1352 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1357 rid[i] = sam_pass->user_rid;
1363 rid[0] = BUILTIN_ALIAS_RID_USERS;
1365 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1367 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1373 /*******************************************************************
1375 ********************************************************************/
1377 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1379 uint32 rid[MAX_SAM_ENTRIES];
1381 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1382 enum SID_NAME_USE local_type;
1384 int num_rids = q_u->num_names2;
1389 r_u->status = NT_STATUS_OK;
1391 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1396 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1397 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1401 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 */
1405 if (num_rids > MAX_SAM_ENTRIES) {
1406 num_rids = MAX_SAM_ENTRIES;
1407 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1410 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1412 for (i = 0; i < num_rids; i++) {
1417 r_u->status = NT_STATUS_NONE_MAPPED;
1419 rid [i] = 0xffffffff;
1420 type[i] = SID_NAME_UNKNOWN;
1422 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1425 * we are only looking for a name
1426 * the SID we get back can be outside
1427 * the scope of the pol_sid
1429 * in clear: it prevents to reply to domain\group: yes
1430 * when only builtin\group exists.
1432 * a cleaner code is to add the sid of the domain we're looking in
1433 * to the local_lookup_name function.
1436 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1437 sid_split_rid(&sid, &local_rid);
1439 if (sid_equal(&sid, &pol_sid)) {
1442 /* Windows does not return WKN_GRP here, even
1443 * on lookups in builtin */
1444 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1445 SID_NAME_ALIAS : local_type;
1447 r_u->status = NT_STATUS_OK;
1452 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1454 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1459 /*******************************************************************
1460 _samr_chgpasswd_user
1461 ********************************************************************/
1463 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1468 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1470 r_u->status = NT_STATUS_OK;
1472 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1473 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1475 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1478 * Pass the user through the NT -> unix user mapping
1482 (void)map_username(user_name);
1485 * UNIX username case mangling not required, pass_oem_change
1486 * is case insensitive.
1489 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1490 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1492 init_samr_r_chgpasswd_user(r_u, r_u->status);
1494 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1499 /*******************************************************************
1500 makes a SAMR_R_LOOKUP_RIDS structure.
1501 ********************************************************************/
1503 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1504 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1507 UNIHDR *hdr_name=NULL;
1508 UNISTR2 *uni_name=NULL;
1510 *pp_uni_name = NULL;
1511 *pp_hdr_name = NULL;
1513 if (num_names != 0) {
1514 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1515 if (hdr_name == NULL)
1518 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1519 if (uni_name == NULL)
1523 for (i = 0; i < num_names; i++) {
1524 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1525 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1526 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1529 *pp_uni_name = uni_name;
1530 *pp_hdr_name = hdr_name;
1535 /*******************************************************************
1537 ********************************************************************/
1539 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1541 fstring group_names[MAX_SAM_ENTRIES];
1542 uint32 *group_attrs = NULL;
1543 UNIHDR *hdr_name = NULL;
1544 UNISTR2 *uni_name = NULL;
1546 int num_rids = q_u->num_rids1;
1550 r_u->status = NT_STATUS_OK;
1552 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1554 /* find the policy handle. open a policy on it. */
1555 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1556 return NT_STATUS_INVALID_HANDLE;
1558 if (num_rids > MAX_SAM_ENTRIES) {
1559 num_rids = MAX_SAM_ENTRIES;
1560 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1564 if ((group_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids )) == NULL)
1565 return NT_STATUS_NO_MEMORY;
1568 r_u->status = NT_STATUS_NONE_MAPPED;
1570 become_root(); /* lookup_sid can require root privs */
1572 for (i = 0; i < num_rids; i++) {
1576 enum SID_NAME_USE type;
1578 group_attrs[i] = SID_NAME_UNKNOWN;
1579 *group_names[i] = '\0';
1581 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1582 sid_copy(&sid, &pol_sid);
1583 sid_append_rid(&sid, q_u->rid[i]);
1585 if (lookup_sid(&sid, domname, tmpname, &type)) {
1586 r_u->status = NT_STATUS_OK;
1587 group_attrs[i] = (uint32)type;
1588 fstrcpy(group_names[i],tmpname);
1589 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1596 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1597 return NT_STATUS_NO_MEMORY;
1599 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1601 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1606 /*******************************************************************
1607 _samr_open_user. Safe - gives out no passwd info.
1608 ********************************************************************/
1610 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1612 SAM_ACCOUNT *sampass=NULL;
1614 POLICY_HND domain_pol = q_u->domain_pol;
1615 POLICY_HND *user_pol = &r_u->user_pol;
1616 struct samr_info *info = NULL;
1617 SEC_DESC *psd = NULL;
1619 uint32 des_access = q_u->access_mask;
1624 r_u->status = NT_STATUS_OK;
1626 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1627 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1628 return NT_STATUS_INVALID_HANDLE;
1630 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1634 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1635 if (!NT_STATUS_IS_OK(nt_status)) {
1639 /* append the user's RID to it */
1640 if (!sid_append_rid(&sid, q_u->user_rid))
1641 return NT_STATUS_NO_SUCH_USER;
1643 /* check if access can be granted as requested by client. */
1644 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1645 se_map_generic(&des_access, &usr_generic_mapping);
1646 if (!NT_STATUS_IS_OK(nt_status =
1647 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1648 des_access, &acc_granted, "_samr_open_user"))) {
1653 ret=pdb_getsampwsid(sampass, &sid);
1656 /* check that the SID exists in our domain. */
1658 return NT_STATUS_NO_SUCH_USER;
1661 pdb_free_sam(&sampass);
1663 /* associate the user's SID and access bits with the new handle. */
1664 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1665 return NT_STATUS_NO_MEMORY;
1666 info->acc_granted = acc_granted;
1668 /* get a (unique) handle. open a policy on it. */
1669 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1670 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1675 /*************************************************************************
1676 get_user_info_10. Safe. Only gives out acb bits.
1677 *************************************************************************/
1679 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1681 SAM_ACCOUNT *smbpass=NULL;
1685 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1687 if (!NT_STATUS_IS_OK(nt_status)) {
1692 ret = pdb_getsampwsid(smbpass, user_sid);
1696 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1697 return NT_STATUS_NO_SUCH_USER;
1700 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1703 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1705 pdb_free_sam(&smbpass);
1707 return NT_STATUS_OK;
1710 /*************************************************************************
1711 get_user_info_12. OK - this is the killer as it gives out password info.
1712 Ensure that this is only allowed on an encrypted connection with a root
1714 *************************************************************************/
1716 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1718 SAM_ACCOUNT *smbpass=NULL;
1722 if (!p->ntlmssp_auth_validated)
1723 return NT_STATUS_ACCESS_DENIED;
1725 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1726 return NT_STATUS_ACCESS_DENIED;
1729 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1732 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1734 if (!NT_STATUS_IS_OK(nt_status)) {
1738 ret = pdb_getsampwsid(smbpass, user_sid);
1741 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1742 pdb_free_sam(&smbpass);
1743 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1746 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1748 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1749 pdb_free_sam(&smbpass);
1750 return NT_STATUS_ACCOUNT_DISABLED;
1754 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1756 pdb_free_sam(&smbpass);
1758 return NT_STATUS_OK;
1761 /*************************************************************************
1763 *************************************************************************/
1765 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1767 SAM_ACCOUNT *sampass=NULL;
1770 pdb_init_sam_talloc(mem_ctx, &sampass);
1773 ret = pdb_getsampwsid(sampass, user_sid);
1777 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1778 return NT_STATUS_NO_SUCH_USER;
1781 samr_clear_sam_passwd(sampass);
1783 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1786 init_sam_user_info20A(id20, sampass);
1788 pdb_free_sam(&sampass);
1790 return NT_STATUS_OK;
1793 /*************************************************************************
1795 *************************************************************************/
1797 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1798 DOM_SID *user_sid, DOM_SID *domain_sid)
1800 SAM_ACCOUNT *sampass=NULL;
1804 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1805 if (!NT_STATUS_IS_OK(nt_status)) {
1810 ret = pdb_getsampwsid(sampass, user_sid);
1814 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1815 return NT_STATUS_NO_SUCH_USER;
1818 samr_clear_sam_passwd(sampass);
1820 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1823 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1825 pdb_free_sam(&sampass);
1827 return NT_STATUS_OK;
1830 /*******************************************************************
1831 _samr_query_userinfo
1832 ********************************************************************/
1834 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1836 SAM_USERINFO_CTR *ctr;
1837 struct samr_info *info = NULL;
1841 r_u->status=NT_STATUS_OK;
1843 /* search for the handle */
1844 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1845 return NT_STATUS_INVALID_HANDLE;
1847 domain_sid = info->sid;
1849 sid_split_rid(&domain_sid, &rid);
1851 if (!sid_check_is_in_our_domain(&info->sid))
1852 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1854 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1856 ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
1858 return NT_STATUS_NO_MEMORY;
1862 /* ok! user info levels (lots: see MSDEV help), off we go... */
1863 ctr->switch_value = q_u->switch_value;
1865 switch (q_u->switch_value) {
1867 ctr->info.id10 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_10);
1868 if (ctr->info.id10 == NULL)
1869 return NT_STATUS_NO_MEMORY;
1871 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1876 /* whoops - got this wrong. i think. or don't understand what's happening. */
1880 info = (void *)&id11;
1882 expire.low = 0xffffffff;
1883 expire.high = 0x7fffffff;
1885 ctr->info.id = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_11));
1886 ZERO_STRUCTP(ctr->info.id11);
1887 init_sam_user_info11(ctr->info.id11, &expire,
1888 "BROOKFIELDS$", /* name */
1889 0x03ef, /* user rid */
1890 0x201, /* group rid */
1891 0x0080); /* acb info */
1898 ctr->info.id12 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_12);
1899 if (ctr->info.id12 == NULL)
1900 return NT_STATUS_NO_MEMORY;
1902 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1907 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
1908 if (ctr->info.id20 == NULL)
1909 return NT_STATUS_NO_MEMORY;
1910 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1915 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
1916 if (ctr->info.id21 == NULL)
1917 return NT_STATUS_NO_MEMORY;
1918 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1919 &info->sid, &domain_sid)))
1924 return NT_STATUS_INVALID_INFO_CLASS;
1927 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1929 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1934 /*******************************************************************
1935 samr_reply_query_usergroups
1936 ********************************************************************/
1938 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1940 SAM_ACCOUNT *sam_pass=NULL;
1941 struct passwd *passwd;
1944 DOM_GID *gids = NULL;
1947 int i, num_gids, num_sids;
1953 * from the SID in the request:
1954 * we should send back the list of DOMAIN GROUPS
1955 * the user is a member of
1957 * and only the DOMAIN GROUPS
1958 * no ALIASES !!! neither aliases of the domain
1959 * nor aliases of the builtin SID
1964 r_u->status = NT_STATUS_OK;
1966 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1968 /* find the policy handle. open a policy on it. */
1969 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1970 return NT_STATUS_INVALID_HANDLE;
1972 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1976 if (!sid_check_is_in_our_domain(&sid))
1977 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1979 pdb_init_sam(&sam_pass);
1982 ret = pdb_getsampwsid(sam_pass, &sid);
1986 pdb_free_sam(&sam_pass);
1987 return NT_STATUS_NO_SUCH_USER;
1990 passwd = getpwnam_alloc(pdb_get_username(sam_pass));
1991 if (passwd == NULL) {
1992 pdb_free_sam(&sam_pass);
1993 return NT_STATUS_NO_SUCH_USER;
2000 result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
2002 &sids, &unix_gids, &num_groups);
2005 pdb_free_sam(&sam_pass);
2006 passwd_free(&passwd);
2008 if (!NT_STATUS_IS_OK(result))
2011 SAFE_FREE(unix_gids);
2016 for (i=0; i<num_groups; i++) {
2019 if (!sid_peek_check_rid(get_global_sam_sid(),
2023 gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1);
2024 gids[num_gids].attr=7;
2025 gids[num_gids].g_rid = rid;
2030 /* construct the response. lkclXXXX: gids are not copied! */
2031 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2033 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2038 /*******************************************************************
2039 _samr_query_dom_info
2040 ********************************************************************/
2042 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2044 struct samr_info *info = NULL;
2046 uint32 min_pass_len,pass_hist,flag;
2047 time_t u_expire, u_min_age;
2048 NTTIME nt_expire, nt_min_age;
2050 time_t u_lock_duration, u_reset_time;
2051 NTTIME nt_lock_duration, nt_reset_time;
2057 uint32 account_policy_temp;
2059 uint32 num_users=0, num_groups=0, num_aliases=0;
2061 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2062 return NT_STATUS_NO_MEMORY;
2066 r_u->status = NT_STATUS_OK;
2068 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2070 /* find the policy handle. open a policy on it. */
2071 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2072 return NT_STATUS_INVALID_HANDLE;
2074 switch (q_u->switch_value) {
2077 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2078 min_pass_len = account_policy_temp;
2080 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2081 pass_hist = account_policy_temp;
2083 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2084 flag = account_policy_temp;
2086 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2087 u_expire = account_policy_temp;
2089 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2090 u_min_age = account_policy_temp;
2092 unix_to_nt_time_abs(&nt_expire, u_expire);
2093 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2095 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2096 flag, nt_expire, nt_min_age);
2100 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2102 if (!NT_STATUS_IS_OK(r_u->status)) {
2103 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2106 num_users=info->disp_info.num_user_account;
2109 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2110 if (!NT_STATUS_IS_OK(r_u->status)) {
2111 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2114 num_groups=info->disp_info.num_group_account;
2117 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2118 init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
2119 num_users, num_groups, num_aliases);
2122 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2123 unix_to_nt_time_abs(&nt_logout, u_logout);
2125 init_unk_info3(&ctr->info.inf3, nt_logout);
2128 init_unk_info5(&ctr->info.inf5, global_myname());
2131 init_unk_info6(&ctr->info.inf6);
2134 init_unk_info7(&ctr->info.inf7);
2137 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
2140 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2141 u_lock_duration = account_policy_temp * 60;
2143 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2144 u_reset_time = account_policy_temp * 60;
2146 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2147 lockout = account_policy_temp;
2149 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2150 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2152 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2155 return NT_STATUS_INVALID_INFO_CLASS;
2158 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2160 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2165 /*******************************************************************
2167 Create an account, can be either a normal user or a machine.
2168 This funcion will need to be updated for bdc/domain trusts.
2169 ********************************************************************/
2171 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2173 SAM_ACCOUNT *sam_pass=NULL;
2177 POLICY_HND dom_pol = q_u->domain_pol;
2178 UNISTR2 user_account = q_u->uni_name;
2179 uint16 acb_info = q_u->acb_info;
2180 POLICY_HND *user_pol = &r_u->user_pol;
2181 struct samr_info *info = NULL;
2189 /* check this, when giving away 'add computer to domain' privs */
2190 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2192 /* Get the domain SID stored in the domain policy */
2193 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2194 return NT_STATUS_INVALID_HANDLE;
2196 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2200 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2201 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2202 this parameter is not an account type */
2203 return NT_STATUS_INVALID_PARAMETER;
2206 /* find the account: tell the caller if it exists.
2207 lkclXXXX i have *no* idea if this is a problem or not
2208 or even if you are supposed to construct a different
2209 reply if the account already exists...
2212 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2213 strlower_m(account);
2215 pdb_init_sam(&sam_pass);
2218 ret = pdb_getsampwnam(sam_pass, account);
2221 /* this account exists: say so */
2222 pdb_free_sam(&sam_pass);
2223 return NT_STATUS_USER_EXISTS;
2226 pdb_free_sam(&sam_pass);
2229 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2230 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2231 * that only people with write access to the smbpasswd file will be able
2232 * to create a user. JRA.
2236 * add the user in the /etc/passwd file or the unix authority system.
2237 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2238 * a) local_password_change() checks for us if the /etc/passwd account really exists
2239 * b) smb_create_user() would return an error if the account already exists
2240 * and as it could return an error also if it can't create the account, it would be tricky.
2242 * So we go the easy way, only check after if the account exists.
2243 * JFM (2/3/2001), to clear any possible bad understanding (-:
2245 * We now have seperate script paramaters for adding users/machines so we
2246 * now have some sainity-checking to match.
2249 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2252 * we used to have code here that made sure the acb_info flags
2253 * matched with the users named (e.g. an account flags as a machine
2254 * trust account ended in '$'). It has been ifdef'd out for a long
2255 * time, so I replaced it with this comment. --jerry
2258 /* the passdb lookup has failed; check to see if we need to run the
2259 add user/machine script */
2261 pw = Get_Pwnam(account);
2263 /*********************************************************************
2264 * HEADS UP! If we have to create a new user account, we have to get
2265 * a new RID from somewhere. This used to be done by the passdb
2266 * backend. It has been moved into idmap now. Since idmap is now
2267 * wrapped up behind winbind, this means you have to run winbindd if you
2268 * want new accounts to get a new RID when "enable rid algorithm = no".
2269 * Tough. We now have a uniform way of allocating RIDs regardless
2270 * of what ever passdb backend people may use.
2271 * --jerry (2003-07-10)
2272 *********************************************************************/
2276 * we can't check both the ending $ and the acb_info.
2278 * UserManager creates trust accounts (ending in $,
2279 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2282 if (account[strlen(account)-1] == '$')
2283 pstrcpy(add_script, lp_addmachine_script());
2285 pstrcpy(add_script, lp_adduser_script());
2289 all_string_sub(add_script, "%u", account, sizeof(add_script));
2290 add_ret = smbrun(add_script,NULL);
2291 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2293 else /* no add user script -- ask winbindd to do it */
2295 if ( !winbind_create_user( account, &new_rid ) ) {
2296 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2303 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2305 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2308 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2310 if (!pdb_add_sam_account(sam_pass)) {
2311 pdb_free_sam(&sam_pass);
2312 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2314 return NT_STATUS_ACCESS_DENIED;
2317 /* Get the user's SID */
2318 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2320 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2321 se_map_generic(&des_access, &usr_generic_mapping);
2322 if (!NT_STATUS_IS_OK(nt_status =
2323 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2324 des_access, &acc_granted, "_samr_create_user"))) {
2328 /* associate the user's SID with the new handle. */
2329 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2330 pdb_free_sam(&sam_pass);
2331 return NT_STATUS_NO_MEMORY;
2336 info->acc_granted = acc_granted;
2338 /* get a (unique) handle. open a policy on it. */
2339 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2340 pdb_free_sam(&sam_pass);
2341 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2344 r_u->user_rid=pdb_get_user_rid(sam_pass);
2346 r_u->access_granted = acc_granted;
2348 pdb_free_sam(&sam_pass);
2350 return NT_STATUS_OK;
2353 /*******************************************************************
2354 samr_reply_connect_anon
2355 ********************************************************************/
2357 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2359 struct samr_info *info = NULL;
2360 uint32 des_access = q_u->access_mask;
2364 if (!pipe_access_check(p)) {
2365 DEBUG(3, ("access denied to samr_connect_anon\n"));
2366 r_u->status = NT_STATUS_ACCESS_DENIED;
2370 /* set up the SAMR connect_anon response */
2372 r_u->status = NT_STATUS_OK;
2374 /* associate the user's SID with the new handle. */
2375 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2376 return NT_STATUS_NO_MEMORY;
2378 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2379 was observed from a win98 client trying to enumerate users (when configured
2380 user level access control on shares) --jerry */
2382 se_map_generic( &des_access, &sam_generic_mapping );
2383 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2385 info->status = q_u->unknown_0;
2387 /* get a (unique) handle. open a policy on it. */
2388 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2389 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2394 /*******************************************************************
2396 ********************************************************************/
2398 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2400 struct samr_info *info = NULL;
2401 SEC_DESC *psd = NULL;
2403 uint32 des_access = q_u->access_mask;
2408 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2412 if (!pipe_access_check(p)) {
2413 DEBUG(3, ("access denied to samr_connect\n"));
2414 r_u->status = NT_STATUS_ACCESS_DENIED;
2418 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2419 se_map_generic(&des_access, &sam_generic_mapping);
2420 if (!NT_STATUS_IS_OK(nt_status =
2421 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2422 des_access, &acc_granted, "_samr_connect"))) {
2426 r_u->status = NT_STATUS_OK;
2428 /* associate the user's SID and access granted with the new handle. */
2429 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2430 return NT_STATUS_NO_MEMORY;
2432 info->acc_granted = acc_granted;
2433 info->status = q_u->access_mask;
2435 /* get a (unique) handle. open a policy on it. */
2436 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2437 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2439 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2444 /*******************************************************************
2446 ********************************************************************/
2448 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2450 struct samr_info *info = NULL;
2451 SEC_DESC *psd = NULL;
2453 uint32 des_access = q_u->access_mask;
2458 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2462 if (!pipe_access_check(p)) {
2463 DEBUG(3, ("access denied to samr_connect4\n"));
2464 r_u->status = NT_STATUS_ACCESS_DENIED;
2468 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2469 se_map_generic(&des_access, &sam_generic_mapping);
2470 if (!NT_STATUS_IS_OK(nt_status =
2471 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2472 des_access, &acc_granted, "_samr_connect"))) {
2476 r_u->status = NT_STATUS_OK;
2478 /* associate the user's SID and access granted with the new handle. */
2479 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2480 return NT_STATUS_NO_MEMORY;
2482 info->acc_granted = acc_granted;
2483 info->status = q_u->access_mask;
2485 /* get a (unique) handle. open a policy on it. */
2486 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2487 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2489 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2494 /**********************************************************************
2495 api_samr_lookup_domain
2496 **********************************************************************/
2498 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2500 struct samr_info *info;
2501 fstring domain_name;
2504 r_u->status = NT_STATUS_OK;
2506 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2507 return NT_STATUS_INVALID_HANDLE;
2509 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2510 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2515 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2519 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2520 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2523 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2525 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2530 /******************************************************************
2531 makes a SAMR_R_ENUM_DOMAINS structure.
2532 ********************************************************************/
2534 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2535 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2541 DEBUG(5, ("make_enum_domains\n"));
2544 *pp_uni_name = NULL;
2546 if (num_sam_entries == 0)
2549 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2550 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2552 if (sam == NULL || uni_name == NULL)
2555 for (i = 0; i < num_sam_entries; i++) {
2556 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2557 init_sam_entry(&sam[i], &uni_name[i], 0);
2561 *pp_uni_name = uni_name;
2566 /**********************************************************************
2567 api_samr_enum_domains
2568 **********************************************************************/
2570 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2572 struct samr_info *info;
2573 uint32 num_entries = 2;
2577 r_u->status = NT_STATUS_OK;
2579 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2580 return NT_STATUS_INVALID_HANDLE;
2582 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2586 name = get_global_sam_name();
2588 fstrcpy(dom[0],name);
2590 fstrcpy(dom[1],"Builtin");
2592 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2593 return NT_STATUS_NO_MEMORY;
2595 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2600 /*******************************************************************
2602 ********************************************************************/
2604 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2607 POLICY_HND domain_pol = q_u->dom_pol;
2608 uint32 alias_rid = q_u->rid_alias;
2609 POLICY_HND *alias_pol = &r_u->pol;
2610 struct samr_info *info = NULL;
2611 SEC_DESC *psd = NULL;
2613 uint32 des_access = q_u->access_mask;
2617 r_u->status = NT_STATUS_OK;
2619 /* find the domain policy and get the SID / access bits stored in the domain policy */
2620 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2621 return NT_STATUS_INVALID_HANDLE;
2623 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2627 /* append the alias' RID to it */
2628 if (!sid_append_rid(&sid, alias_rid))
2629 return NT_STATUS_NO_SUCH_USER;
2631 /*check if access can be granted as requested by client. */
2632 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2633 se_map_generic(&des_access,&ali_generic_mapping);
2634 if (!NT_STATUS_IS_OK(status =
2635 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2636 des_access, &acc_granted, "_samr_open_alias"))) {
2641 * we should check if the rid really exist !!!
2645 /* associate the user's SID with the new handle. */
2646 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2647 return NT_STATUS_NO_MEMORY;
2649 info->acc_granted = acc_granted;
2651 /* get a (unique) handle. open a policy on it. */
2652 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2653 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2658 /*******************************************************************
2660 ********************************************************************/
2662 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2664 SAM_ACCOUNT *pwd =NULL;
2669 ret = pdb_getsampwsid(pwd, sid);
2677 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2682 /* FIX ME: check if the value is really changed --metze */
2683 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2688 if(!pdb_update_sam_account(pwd)) {
2698 /*******************************************************************
2700 ********************************************************************/
2702 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2704 SAM_ACCOUNT *pwd = NULL;
2708 if(!pdb_getsampwsid(pwd, sid)) {
2714 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2719 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2723 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2727 if (!pdb_set_pass_changed_now (pwd)) {
2732 if(!pdb_update_sam_account(pwd)) {
2741 /*******************************************************************
2742 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2743 ********************************************************************/
2744 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2749 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2751 DEBUG(2,("Could not get gid for primary group of "
2752 "user %s\n", pdb_get_username(sampass)));
2756 grp = getgrgid(gid);
2759 DEBUG(2,("Could not find primary group %lu for "
2760 "user %s\n", (unsigned long)gid,
2761 pdb_get_username(sampass)));
2765 if (smb_set_primary_group(grp->gr_name,
2766 pdb_get_username(sampass)) != 0) {
2767 DEBUG(2,("Could not set primary group for user %s to "
2769 pdb_get_username(sampass), grp->gr_name));
2777 /*******************************************************************
2779 ********************************************************************/
2781 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2783 SAM_ACCOUNT *pwd = NULL;
2786 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2792 if (!pdb_getsampwsid(pwd, sid)) {
2797 copy_id20_to_sam_passwd(pwd, id20);
2799 /* write the change out */
2800 if(!pdb_update_sam_account(pwd)) {
2809 /*******************************************************************
2811 ********************************************************************/
2813 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2815 SAM_ACCOUNT *pwd = NULL;
2818 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2824 if (!pdb_getsampwsid(pwd, sid)) {
2829 copy_id21_to_sam_passwd(pwd, id21);
2832 * The funny part about the previous two calls is
2833 * that pwd still has the password hashes from the
2834 * passdb entry. These have not been updated from
2835 * id21. I don't know if they need to be set. --jerry
2838 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2839 set_unix_primary_group(pwd);
2841 /* write the change out */
2842 if(!pdb_update_sam_account(pwd)) {
2852 /*******************************************************************
2854 ********************************************************************/
2856 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2858 SAM_ACCOUNT *pwd = NULL;
2859 pstring plaintext_buf;
2864 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2870 if (!pdb_getsampwsid(pwd, sid)) {
2875 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2876 pdb_get_username(pwd)));
2878 acct_ctrl = pdb_get_acct_ctrl(pwd);
2880 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2885 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2890 copy_id23_to_sam_passwd(pwd, id23);
2892 /* if it's a trust account, don't update /etc/passwd */
2893 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2894 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2895 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2896 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2898 /* update the UNIX password */
2899 if (lp_unix_password_sync() ) {
2900 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2902 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2905 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2912 ZERO_STRUCT(plaintext_buf);
2914 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2915 set_unix_primary_group(pwd);
2917 if(!pdb_update_sam_account(pwd)) {
2927 /*******************************************************************
2929 ********************************************************************/
2931 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2933 SAM_ACCOUNT *pwd = NULL;
2935 pstring plaintext_buf;
2940 if (!pdb_getsampwsid(pwd, sid)) {
2945 DEBUG(5, ("Attempting administrator password change for user %s\n",
2946 pdb_get_username(pwd)));
2948 acct_ctrl = pdb_get_acct_ctrl(pwd);
2950 ZERO_STRUCT(plaintext_buf);
2952 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2957 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2962 /* if it's a trust account, don't update /etc/passwd */
2963 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2964 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2965 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2966 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2968 /* update the UNIX password */
2969 if (lp_unix_password_sync()) {
2970 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2972 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2975 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2982 ZERO_STRUCT(plaintext_buf);
2984 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2986 /* update the SAMBA password */
2987 if(!pdb_update_sam_account(pwd)) {
2997 /*******************************************************************
2998 samr_reply_set_userinfo
2999 ********************************************************************/
3001 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3004 POLICY_HND *pol = &q_u->pol;
3005 uint16 switch_value = q_u->switch_value;
3006 SAM_USERINFO_CTR *ctr = q_u->ctr;
3008 uint32 acc_required;
3010 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3012 r_u->status = NT_STATUS_OK;
3014 /* find the policy handle. open a policy on it. */
3015 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3016 return NT_STATUS_INVALID_HANDLE;
3018 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3019 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3023 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3026 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3027 return NT_STATUS_INVALID_INFO_CLASS;
3030 /* ok! user info levels (lots: see MSDEV help), off we go... */
3031 switch (switch_value) {
3033 if (!set_user_info_12(ctr->info.id12, &sid))
3034 return NT_STATUS_ACCESS_DENIED;
3038 if (!p->session_key.length) {
3039 return NT_STATUS_NO_USER_SESSION_KEY;
3041 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
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 if (!p->session_key.length) {
3060 return NT_STATUS_NO_USER_SESSION_KEY;
3062 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3064 dump_data(100, (char *)ctr->info.id25->pass, 532);
3066 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3067 return NT_STATUS_ACCESS_DENIED;
3070 return NT_STATUS_INVALID_INFO_CLASS;
3073 if (!p->session_key.length) {
3074 return NT_STATUS_NO_USER_SESSION_KEY;
3076 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3078 dump_data(100, (char *)ctr->info.id23->pass, 516);
3080 if (!set_user_info_23(ctr->info.id23, &sid))
3081 return NT_STATUS_ACCESS_DENIED;
3085 return NT_STATUS_INVALID_INFO_CLASS;
3091 /*******************************************************************
3092 samr_reply_set_userinfo2
3093 ********************************************************************/
3095 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3098 SAM_USERINFO_CTR *ctr = q_u->ctr;
3099 POLICY_HND *pol = &q_u->pol;
3100 uint16 switch_value = q_u->switch_value;
3102 uint32 acc_required;
3104 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3106 r_u->status = NT_STATUS_OK;
3108 /* find the policy handle. open a policy on it. */
3109 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3110 return NT_STATUS_INVALID_HANDLE;
3112 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3113 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3117 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3120 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3121 return NT_STATUS_INVALID_INFO_CLASS;
3124 switch_value=ctr->switch_value;
3126 /* ok! user info levels (lots: see MSDEV help), off we go... */
3127 switch (switch_value) {
3129 if (!set_user_info_21(ctr->info.id21, &sid))
3130 return NT_STATUS_ACCESS_DENIED;
3133 if (!set_user_info_20(ctr->info.id20, &sid))
3134 return NT_STATUS_ACCESS_DENIED;
3137 if (!set_user_info_10(ctr->info.id10, &sid))
3138 return NT_STATUS_ACCESS_DENIED;
3141 /* Used by AS/U JRA. */
3142 if (!set_user_info_12(ctr->info.id12, &sid))
3143 return NT_STATUS_ACCESS_DENIED;
3146 return NT_STATUS_INVALID_INFO_CLASS;
3152 /*********************************************************************
3153 _samr_query_aliasmem
3154 *********************************************************************/
3156 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3160 struct samr_info *info = NULL;
3171 r_u->status = NT_STATUS_OK;
3173 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3175 /* find the policy handle. open a policy on it. */
3176 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3177 return NT_STATUS_INVALID_HANDLE;
3179 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3180 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3182 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3183 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3184 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3185 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3189 if (!sid_check_is_domain(&info->sid) &&
3190 !sid_check_is_builtin(&info->sid))
3191 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3193 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3195 if (members == NULL)
3196 return NT_STATUS_NO_MEMORY;
3198 for (i=0; i<q_u->num_sids1; i++)
3199 sid_copy(&members[i], &q_u->sid[i].sid);
3202 res = pdb_enum_alias_memberships(members,
3203 q_u->num_sids1, &aliases,
3208 return NT_STATUS_UNSUCCESSFUL;
3213 for (i=0; i<num_aliases; i++) {
3216 if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
3219 rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
3222 return NT_STATUS_NO_MEMORY;
3224 rids[num_groups] = rid;
3229 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3230 return NT_STATUS_OK;
3233 /*********************************************************************
3234 _samr_query_aliasmem
3235 *********************************************************************/
3237 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3249 /* find the policy handle. open a policy on it. */
3250 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3251 return NT_STATUS_INVALID_HANDLE;
3253 if (!NT_STATUS_IS_OK(r_u->status =
3254 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3258 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3260 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3261 return NT_STATUS_NO_SUCH_ALIAS;
3263 sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);
3264 if (num_sids!=0 && sid == NULL) {
3266 return NT_STATUS_NO_MEMORY;
3269 for (i = 0; i < num_sids; i++) {
3270 init_dom_sid2(&sid[i], &sids[i]);
3273 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3277 return NT_STATUS_OK;
3280 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3284 for (i=0; i<*num; i++) {
3285 if ((*uids)[i] == uid)
3289 *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3294 (*uids)[*num] = uid;
3299 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3303 struct sys_pwent *userlist, *user;
3308 /* We only look at our own sam, so don't care about imported stuff */
3312 if ((grp = getgrgid(gid)) == NULL) {
3317 /* Primary group members */
3319 userlist = getpwent_list();
3321 for (user = userlist; user != NULL; user = user->next) {
3322 if (user->pw_gid != gid)
3324 add_uid_to_array_unique(user->pw_uid, uids, num);
3327 pwent_free(userlist);
3329 /* Secondary group members */
3331 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3332 struct passwd *pw = getpwnam(*gr);
3336 add_uid_to_array_unique(pw->pw_uid, uids, num);
3344 /*********************************************************************
3345 _samr_query_groupmem
3346 *********************************************************************/
3348 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3350 int final_num_rids, i;
3352 fstring group_sid_str;
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 sid_to_string(group_sid_str, &group_sid);
3371 DEBUG(10, ("sid is %s\n", group_sid_str));
3373 if (!sid_check_is_in_our_domain(&group_sid)) {
3374 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3375 return NT_STATUS_NO_SUCH_GROUP;
3378 DEBUG(10, ("lookup on Domain SID\n"));
3380 if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3381 return NT_STATUS_NO_SUCH_GROUP;
3383 if(!get_memberuids(gid, &uids, &num))
3384 return NT_STATUS_NO_SUCH_GROUP;
3386 rid=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3387 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3389 if (num!=0 && (rid==NULL || attr==NULL))
3390 return NT_STATUS_NO_MEMORY;
3394 for (i=0; i<num; i++) {
3397 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3398 DEBUG(1, ("Could not map member uid to SID\n"));
3402 if (!sid_check_is_in_our_domain(&sid)) {
3403 DEBUG(1, ("Inconsistent SAM -- group member uid not "
3404 "in our domain\n"));
3408 sid_peek_rid(&sid, &rid[final_num_rids]);
3410 /* Hmm. In a trace I got the constant 7 here from NT. */
3411 attr[final_num_rids] = SID_NAME_USER;
3413 final_num_rids += 1;
3418 init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3421 return NT_STATUS_OK;
3424 /*********************************************************************
3426 *********************************************************************/
3428 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3433 /* Find the policy handle. Open a policy on it. */
3434 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3435 return NT_STATUS_INVALID_HANDLE;
3437 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3441 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3443 if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
3444 return NT_STATUS_ACCESS_DENIED;
3446 return NT_STATUS_OK;
3449 /*********************************************************************
3451 *********************************************************************/
3453 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3458 /* Find the policy handle. Open a policy on it. */
3459 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3460 return NT_STATUS_INVALID_HANDLE;
3462 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3466 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3467 sid_string_static(&alias_sid)));
3469 if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
3470 return NT_STATUS_ACCESS_DENIED;
3472 return NT_STATUS_OK;
3475 /*********************************************************************
3477 *********************************************************************/
3479 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3483 fstring group_sid_str;
3490 SAM_ACCOUNT *sam_user=NULL;
3494 /* Find the policy handle. Open a policy on it. */
3495 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3496 return NT_STATUS_INVALID_HANDLE;
3498 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3502 sid_to_string(group_sid_str, &group_sid);
3503 DEBUG(10, ("sid is %s\n", group_sid_str));
3505 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3506 return NT_STATUS_NO_SUCH_GROUP;
3508 DEBUG(10, ("lookup on Domain SID\n"));
3510 if(!get_domain_group_from_sid(group_sid, &map))
3511 return NT_STATUS_NO_SUCH_GROUP;
3513 sid_copy(&user_sid, get_global_sam_sid());
3514 sid_append_rid(&user_sid, q_u->rid);
3516 ret = pdb_init_sam(&sam_user);
3517 if (!NT_STATUS_IS_OK(ret))
3520 check = pdb_getsampwsid(sam_user, &user_sid);
3522 if (check != True) {
3523 pdb_free_sam(&sam_user);
3524 return NT_STATUS_NO_SUCH_USER;
3527 /* check a real user exist before we run the script to add a user to a group */
3528 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3529 pdb_free_sam(&sam_user);
3530 return NT_STATUS_NO_SUCH_USER;
3533 pdb_free_sam(&sam_user);
3535 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3536 return NT_STATUS_NO_SUCH_USER;
3539 if ((grp=getgrgid(map.gid)) == NULL) {
3541 return NT_STATUS_NO_SUCH_GROUP;
3544 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3545 fstrcpy(grp_name, grp->gr_name);
3547 /* if the user is already in the group */
3548 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3550 return NT_STATUS_MEMBER_IN_GROUP;
3554 * ok, the group exist, the user exist, the user is not in the group,
3556 * we can (finally) add it to the group !
3559 smb_add_user_group(grp_name, pwd->pw_name);
3561 /* check if the user has been added then ... */
3562 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3564 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3568 return NT_STATUS_OK;
3571 /*********************************************************************
3573 *********************************************************************/
3575 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3579 SAM_ACCOUNT *sam_pass=NULL;
3586 * delete the group member named q_u->rid
3587 * who is a member of the sid associated with the handle
3588 * the rid is a user's rid as the group is a domain group.
3591 /* Find the policy handle. Open a policy on it. */
3592 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3593 return NT_STATUS_INVALID_HANDLE;
3595 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3599 if (!sid_check_is_in_our_domain(&group_sid))
3600 return NT_STATUS_NO_SUCH_GROUP;
3602 sid_copy(&user_sid, get_global_sam_sid());
3603 sid_append_rid(&user_sid, q_u->rid);
3605 if (!get_domain_group_from_sid(group_sid, &map))
3606 return NT_STATUS_NO_SUCH_GROUP;
3608 if ((grp=getgrgid(map.gid)) == NULL)
3609 return NT_STATUS_NO_SUCH_GROUP;
3611 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3612 fstrcpy(grp_name, grp->gr_name);
3614 /* check if the user exists before trying to remove it from the group */
3615 pdb_init_sam(&sam_pass);
3616 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3617 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3618 pdb_free_sam(&sam_pass);
3619 return NT_STATUS_NO_SUCH_USER;
3622 /* if the user is not in the group */
3623 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3624 pdb_free_sam(&sam_pass);
3625 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3628 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3630 /* check if the user has been removed then ... */
3631 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3632 pdb_free_sam(&sam_pass);
3633 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3636 pdb_free_sam(&sam_pass);
3637 return NT_STATUS_OK;
3641 /****************************************************************************
3642 Delete a UNIX user on demand.
3643 ****************************************************************************/
3645 static int smb_delete_user(const char *unix_user)
3650 /* try winbindd first since it is impossible to determine where
3651 a user came from via NSS. Try the delete user script if this fails
3652 meaning the user did not exist in winbindd's list of accounts */
3654 if ( winbind_delete_user( unix_user ) ) {
3655 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3660 /* fall back to 'delete user script' */
3662 pstrcpy(del_script, lp_deluser_script());
3665 all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3666 ret = smbrun(del_script,NULL);
3667 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3672 /*********************************************************************
3673 _samr_delete_dom_user
3674 *********************************************************************/
3676 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3679 SAM_ACCOUNT *sam_pass=NULL;
3682 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3684 /* Find the policy handle. Open a policy on it. */
3685 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3686 return NT_STATUS_INVALID_HANDLE;
3688 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3692 if (!sid_check_is_in_our_domain(&user_sid))
3693 return NT_STATUS_CANNOT_DELETE;
3695 /* check if the user exists before trying to delete */
3696 pdb_init_sam(&sam_pass);
3697 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3698 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3699 sid_string_static(&user_sid)));
3700 pdb_free_sam(&sam_pass);
3701 return NT_STATUS_NO_SUCH_USER;
3704 /* First delete the samba side */
3705 if (!pdb_delete_sam_account(sam_pass)) {
3706 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3707 pdb_free_sam(&sam_pass);
3708 return NT_STATUS_CANNOT_DELETE;
3711 /* Now delete the unix side */
3713 * note: we don't check if the delete really happened
3714 * as the script is not necessary present
3715 * and maybe the sysadmin doesn't want to delete the unix side
3717 smb_delete_user(pdb_get_username(sam_pass));
3720 pdb_free_sam(&sam_pass);
3722 if (!close_policy_hnd(p, &q_u->user_pol))
3723 return NT_STATUS_OBJECT_NAME_INVALID;
3725 return NT_STATUS_OK;
3728 /*********************************************************************
3729 _samr_delete_dom_group
3730 *********************************************************************/
3732 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3737 fstring group_sid_str;
3743 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3745 /* Find the policy handle. Open a policy on it. */
3746 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3747 return NT_STATUS_INVALID_HANDLE;
3749 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3753 sid_copy(&dom_sid, &group_sid);
3754 sid_to_string(group_sid_str, &dom_sid);
3755 sid_split_rid(&dom_sid, &group_rid);
3757 DEBUG(10, ("sid is %s\n", group_sid_str));
3759 /* we check if it's our SID before deleting */
3760 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3761 return NT_STATUS_NO_SUCH_GROUP;
3763 DEBUG(10, ("lookup on Domain SID\n"));
3765 if(!get_domain_group_from_sid(group_sid, &map))
3766 return NT_STATUS_NO_SUCH_GROUP;
3770 /* check if group really exists */
3771 if ( (grp=getgrgid(gid)) == NULL)
3772 return NT_STATUS_NO_SUCH_GROUP;
3774 /* delete mapping first */
3775 if(!pdb_delete_group_mapping_entry(group_sid))
3776 return NT_STATUS_ACCESS_DENIED;
3778 /* we can delete the UNIX group */
3779 smb_delete_group(grp->gr_name);
3781 /* check if the group has been successfully deleted */
3782 if ( (grp=getgrgid(gid)) != NULL)
3783 return NT_STATUS_ACCESS_DENIED;
3786 if (!close_policy_hnd(p, &q_u->group_pol))
3787 return NT_STATUS_OBJECT_NAME_INVALID;
3789 return NT_STATUS_OK;
3792 /*********************************************************************
3793 _samr_delete_dom_alias
3794 *********************************************************************/
3796 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3801 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3803 /* Find the policy handle. Open a policy on it. */
3804 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3805 return NT_STATUS_INVALID_HANDLE;
3807 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3811 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3813 if (!sid_check_is_in_our_domain(&alias_sid))
3814 return NT_STATUS_NO_SUCH_ALIAS;
3816 DEBUG(10, ("lookup on Local SID\n"));
3818 /* Have passdb delete the alias */
3819 if (!pdb_delete_alias(&alias_sid))
3820 return NT_STATUS_ACCESS_DENIED;
3822 if (!close_policy_hnd(p, &q_u->alias_pol))
3823 return NT_STATUS_OBJECT_NAME_INVALID;
3825 return NT_STATUS_OK;
3828 /*********************************************************************
3829 _samr_create_dom_group
3830 *********************************************************************/
3832 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3839 struct samr_info *info;
3843 /* Find the policy handle. Open a policy on it. */
3844 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3845 return NT_STATUS_INVALID_HANDLE;
3847 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3851 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3852 return NT_STATUS_ACCESS_DENIED;
3854 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3856 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3858 /* check if group already exist */
3859 if ((grp=getgrnam(name)) != NULL)
3860 return NT_STATUS_GROUP_EXISTS;
3862 /* we can create the UNIX group */
3863 if (smb_create_group(name, &gid) != 0)
3864 return NT_STATUS_ACCESS_DENIED;
3866 /* check if the group has been successfully created */
3867 if ((grp=getgrgid(gid)) == NULL)
3868 return NT_STATUS_ACCESS_DENIED;
3870 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3872 /* add the group to the mapping table */
3873 sid_copy(&info_sid, get_global_sam_sid());
3874 sid_append_rid(&info_sid, r_u->rid);
3875 sid_to_string(sid_string, &info_sid);
3877 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3878 return NT_STATUS_ACCESS_DENIED;
3880 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3881 return NT_STATUS_NO_MEMORY;
3883 /* get a (unique) handle. open a policy on it. */
3884 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3885 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3887 return NT_STATUS_OK;
3890 /*********************************************************************
3891 _samr_create_dom_alias
3892 *********************************************************************/
3894 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3900 struct samr_info *info;
3905 /* Find the policy handle. Open a policy on it. */
3906 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3907 return NT_STATUS_INVALID_HANDLE;
3909 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3913 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3914 return NT_STATUS_ACCESS_DENIED;
3916 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3918 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3920 /* Have passdb create the alias */
3921 result = pdb_create_alias(name, &r_u->rid);
3923 if (!NT_STATUS_IS_OK(result))
3926 sid_copy(&info_sid, get_global_sam_sid());
3927 sid_append_rid(&info_sid, r_u->rid);
3929 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
3930 return NT_STATUS_ACCESS_DENIED;
3932 /* check if the group has been successfully created */
3933 if ((grp=getgrgid(gid)) == NULL)
3934 return NT_STATUS_ACCESS_DENIED;
3936 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3937 return NT_STATUS_NO_MEMORY;
3939 /* get a (unique) handle. open a policy on it. */
3940 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3941 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3943 return NT_STATUS_OK;
3946 /*********************************************************************
3947 _samr_query_groupinfo
3949 sends the name/comment pair of a domain group
3950 level 1 send also the number of users of that group
3951 *********************************************************************/
3953 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3960 GROUP_INFO_CTR *ctr;
3964 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3965 return NT_STATUS_INVALID_HANDLE;
3967 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
3972 ret = get_domain_group_from_sid(group_sid, &map);
3975 return NT_STATUS_INVALID_HANDLE;
3977 ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
3979 return NT_STATUS_NO_MEMORY;
3981 switch (q_u->switch_level) {
3983 ctr->switch_value1 = 1;
3984 if(!get_memberuids(map.gid, &uids, &num))
3985 return NT_STATUS_NO_SUCH_GROUP;
3987 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
3991 ctr->switch_value1 = 3;
3992 init_samr_group_info3(&ctr->group.info3);
3995 ctr->switch_value1 = 4;
3996 init_samr_group_info4(&ctr->group.info4, map.comment);
3999 return NT_STATUS_INVALID_INFO_CLASS;
4002 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4004 return NT_STATUS_OK;
4007 /*********************************************************************
4010 update a domain group's comment.
4011 *********************************************************************/
4013 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4017 GROUP_INFO_CTR *ctr;
4020 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4021 return NT_STATUS_INVALID_HANDLE;
4023 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4027 if (!get_domain_group_from_sid(group_sid, &map))
4028 return NT_STATUS_NO_SUCH_GROUP;
4032 switch (ctr->switch_value1) {
4034 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4037 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4040 return NT_STATUS_INVALID_INFO_CLASS;
4043 if(!pdb_update_group_mapping_entry(&map)) {
4044 return NT_STATUS_NO_SUCH_GROUP;
4047 return NT_STATUS_OK;
4050 /*********************************************************************
4053 update an alias's comment.
4054 *********************************************************************/
4056 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4059 struct acct_info info;
4060 ALIAS_INFO_CTR *ctr;
4063 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4064 return NT_STATUS_INVALID_HANDLE;
4066 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4072 switch (ctr->switch_value1) {
4074 unistr2_to_ascii(info.acct_desc,
4075 &(ctr->alias.info3.uni_acct_desc),
4076 sizeof(info.acct_desc)-1);
4079 return NT_STATUS_INVALID_INFO_CLASS;
4082 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4083 return NT_STATUS_ACCESS_DENIED;
4086 return NT_STATUS_OK;
4089 /*********************************************************************
4090 _samr_get_dom_pwinfo
4091 *********************************************************************/
4093 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4095 /* Perform access check. Since this rpc does not require a
4096 policy handle it will not be caught by the access checks on
4097 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4099 if (!pipe_access_check(p)) {
4100 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4101 r_u->status = NT_STATUS_ACCESS_DENIED;
4105 /* Actually, returning zeros here works quite well :-). */
4107 return NT_STATUS_OK;
4110 /*********************************************************************
4112 *********************************************************************/
4114 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4119 struct samr_info *info;
4120 SEC_DESC *psd = NULL;
4122 uint32 des_access = q_u->access_mask;
4128 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4129 return NT_STATUS_INVALID_HANDLE;
4131 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4135 /*check if access can be granted as requested by client. */
4136 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4137 se_map_generic(&des_access,&grp_generic_mapping);
4138 if (!NT_STATUS_IS_OK(status =
4139 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4140 des_access, &acc_granted, "_samr_open_group"))) {
4145 /* this should not be hard-coded like this */
4146 if (!sid_equal(&sid, get_global_sam_sid()))
4147 return NT_STATUS_ACCESS_DENIED;
4149 sid_copy(&info_sid, get_global_sam_sid());
4150 sid_append_rid(&info_sid, q_u->rid_group);
4151 sid_to_string(sid_string, &info_sid);
4153 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4154 return NT_STATUS_NO_MEMORY;
4156 info->acc_granted = acc_granted;
4158 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4160 /* check if that group really exists */
4162 ret = get_domain_group_from_sid(info->sid, &map);
4165 return NT_STATUS_NO_SUCH_GROUP;
4167 /* get a (unique) handle. open a policy on it. */
4168 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4169 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4171 return NT_STATUS_OK;
4174 /*********************************************************************
4175 _samr_remove_sid_foreign_domain
4176 *********************************************************************/
4178 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4179 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4180 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4182 DOM_SID delete_sid, alias_sid;
4183 SAM_ACCOUNT *sam_pass=NULL;
4186 BOOL is_user = False;
4188 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4190 sid_copy( &delete_sid, &q_u->sid.sid );
4192 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4193 sid_string_static(&delete_sid)));
4195 /* Find the policy handle. Open a policy on it. */
4197 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4198 return NT_STATUS_INVALID_HANDLE;
4200 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4201 "_samr_remove_sid_foreign_domain");
4203 if (!NT_STATUS_IS_OK(result))
4206 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4207 sid_string_static(&alias_sid)));
4209 /* make sure we can handle this */
4211 if ( sid_check_is_domain(&alias_sid) )
4212 type = SID_NAME_DOM_GRP;
4213 else if ( sid_check_is_builtin(&alias_sid) )
4214 type = SID_NAME_ALIAS;
4216 if ( type == SID_NAME_UNKNOWN ) {
4217 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4218 return NT_STATUS_OK;
4221 /* check if the user exists before trying to delete */
4223 pdb_init_sam(&sam_pass);
4225 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4228 /* maybe it is a group */
4229 if( !pdb_getgrsid(&map, delete_sid) ) {
4230 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4231 sid_string_static(&delete_sid)));
4232 result = NT_STATUS_INVALID_SID;
4237 /* we can only delete a user from a group since we don't have
4238 nested groups anyways. So in the latter case, just say OK */
4241 GROUP_MAP *mappings = NULL;
4245 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4247 /* interate over the groups */
4248 for ( i=0; i<num_groups; i++ ) {
4250 grp2 = getgrgid(mappings[i].gid);
4253 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4257 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4260 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4262 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4263 /* should we fail here ? */
4264 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4265 pdb_get_username(sam_pass), grp2->gr_name ));
4269 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4270 pdb_get_username(sam_pass), grp2->gr_name ));
4273 SAFE_FREE(mappings);
4277 result = NT_STATUS_OK;
4280 pdb_free_sam(&sam_pass);
4285 /*******************************************************************
4287 ********************************************************************/
4289 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4291 struct samr_info *info = NULL;
4293 uint32 min_pass_len,pass_hist,flag;
4294 time_t u_expire, u_min_age;
4295 NTTIME nt_expire, nt_min_age;
4297 time_t u_lock_duration, u_reset_time;
4298 NTTIME nt_lock_duration, nt_reset_time;
4304 uint32 num_users=0, num_groups=0, num_aliases=0;
4306 uint32 account_policy_temp;
4308 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4309 return NT_STATUS_NO_MEMORY;
4313 r_u->status = NT_STATUS_OK;
4315 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4317 /* find the policy handle. open a policy on it. */
4318 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4319 return NT_STATUS_INVALID_HANDLE;
4321 switch (q_u->switch_value) {
4323 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4324 min_pass_len = account_policy_temp;
4326 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4327 pass_hist = account_policy_temp;
4329 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4330 flag = account_policy_temp;
4332 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4333 u_expire = account_policy_temp;
4335 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4336 u_min_age = account_policy_temp;
4338 unix_to_nt_time_abs(&nt_expire, u_expire);
4339 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4341 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4342 flag, nt_expire, nt_min_age);
4346 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4348 if (!NT_STATUS_IS_OK(r_u->status)) {
4349 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4352 num_users=info->disp_info.num_user_account;
4355 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4356 if (NT_STATUS_IS_ERR(r_u->status)) {
4357 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4360 num_groups=info->disp_info.num_group_account;
4363 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4364 init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
4365 num_users, num_groups, num_aliases);
4368 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4369 u_logout = account_policy_temp;
4371 unix_to_nt_time_abs(&nt_logout, u_logout);
4373 init_unk_info3(&ctr->info.inf3, nt_logout);
4376 init_unk_info5(&ctr->info.inf5, global_myname());
4379 init_unk_info6(&ctr->info.inf6);
4382 init_unk_info7(&ctr->info.inf7);
4385 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4386 u_lock_duration = account_policy_temp * 60;
4388 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4389 u_reset_time = account_policy_temp * 60;
4391 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4392 lockout = account_policy_temp;
4394 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4395 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4397 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4400 return NT_STATUS_INVALID_INFO_CLASS;
4403 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4405 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4410 /*******************************************************************
4412 ********************************************************************/
4414 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4416 time_t u_expire, u_min_age;
4418 time_t u_lock_duration, u_reset_time;
4420 r_u->status = NT_STATUS_OK;
4422 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4424 /* find the policy handle. open a policy on it. */
4425 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4426 return NT_STATUS_INVALID_HANDLE;
4428 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4430 switch (q_u->switch_value) {
4432 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4433 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4435 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4436 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4437 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4438 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4439 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4444 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4445 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4454 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
4455 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4457 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4458 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4459 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4462 return NT_STATUS_INVALID_INFO_CLASS;
4465 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4467 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));