2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003,
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
44 typedef struct _disp_info {
46 uint32 num_user_account;
47 SAM_ACCOUNT *disp_user_info;
49 uint32 num_group_account;
50 DOMAIN_GRP *disp_group_info;
54 /* for use by the \PIPE\samr policy */
56 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
79 uint32 *acc_granted, const char *debug)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
83 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84 *acc_granted = des_access;
85 if (geteuid() == sec_initial_uid()) {
86 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
88 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89 status = NT_STATUS_OK;
92 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
99 /*******************************************************************
100 Checks if access to a function can be granted
101 ********************************************************************/
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
105 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
106 debug, acc_granted, acc_required));
107 if ((acc_granted & acc_required) != acc_required) {
108 if (geteuid() == sec_initial_uid()) {
109 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
110 debug, acc_granted, acc_required));
111 DEBUGADD(4,("but overwritten by euid == 0\n"));
114 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
115 debug, acc_granted, acc_required));
116 return NT_STATUS_ACCESS_DENIED;
122 /*******************************************************************
123 Create a samr_info struct.
124 ********************************************************************/
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
128 struct samr_info *info;
133 sid_to_string(sid_str, psid);
135 fstrcpy(sid_str,"(NULL)");
138 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
140 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
144 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
146 sid_copy( &info->sid, psid);
148 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
150 info->mem_ctx = mem_ctx;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
158 static void free_samr_users(struct samr_info *info)
162 if (info->disp_info.user_dbloaded){
163 for (i=0; i<info->disp_info.num_user_account; i++) {
164 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165 /* Not really a free, actually a 'clear' */
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
187 static void free_samr_info(void *ptr)
189 struct samr_info *info=(struct samr_info *) ptr;
192 talloc_destroy(info->mem_ctx);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
214 SAM_ACCOUNT *pwd = NULL;
215 SAM_ACCOUNT *pwd_array = NULL;
216 NTSTATUS nt_status = NT_STATUS_OK;
217 TALLOC_CTX *mem_ctx = info->mem_ctx;
219 DEBUG(10,("load_sampwd_entries\n"));
221 /* if the snapshoot is already loaded, return */
222 if ((info->disp_info.user_dbloaded==True)
223 && (info->acb_mask == acb_mask)
224 && (info->all_machines == all_machines)) {
225 DEBUG(10,("load_sampwd_entries: already in memory\n"));
229 free_samr_users(info);
231 if (!pdb_setsampwent(False)) {
232 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233 return NT_STATUS_ACCESS_DENIED;
236 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
237 && pdb_getsampwent(pwd) == True; pwd=NULL) {
240 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
241 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
247 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
249 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
254 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
257 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258 pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
259 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* Copy the SAM_ACCOUNT into the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
270 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
272 info->disp_info.num_user_account++;
277 /* the snapshoot is in memory, we're ready to enumerate fast */
279 info->acb_mask = acb_mask;
280 info->all_machines = all_machines;
281 info->disp_info.user_dbloaded=True;
283 DEBUG(10,("load_sampwd_entries: done\n"));
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
291 DOMAIN_GRP *grp_array = NULL;
292 uint32 group_entries = 0;
294 TALLOC_CTX *mem_ctx = info->mem_ctx;
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=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
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 = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
721 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(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);
731 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
732 user_sid = pdb_get_user_sid(pwd);
734 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
735 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
736 "the domain sid %s. Failing operation.\n",
738 sid_to_string(user_sid_string, user_sid),
739 sid_to_string(domain_sid_string, domain_sid)));
740 return NT_STATUS_UNSUCCESSFUL;
743 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
744 copy_unistr2(&uni_name[i], &uni_temp_name);
748 *uni_name_pp = uni_name;
752 /*******************************************************************
753 samr_reply_enum_dom_users
754 ********************************************************************/
756 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
757 SAMR_R_ENUM_DOM_USERS *r_u)
759 struct samr_info *info = NULL;
760 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
762 uint32 enum_context=q_u->start_idx;
763 uint32 max_size=q_u->max_size;
765 enum remote_arch_types ra_type = get_remote_arch();
766 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
767 uint32 max_entries = max_sam_entries;
770 r_u->status = NT_STATUS_OK;
772 /* find the policy handle. open a policy on it. */
773 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
774 return NT_STATUS_INVALID_HANDLE;
776 domain_sid = info->sid;
778 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
779 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
780 "_samr_enum_dom_users"))) {
784 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
787 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
790 if (!NT_STATUS_IS_OK(r_u->status))
793 num_account = info->disp_info.num_user_account;
795 if (enum_context > num_account) {
796 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
800 /* verify we won't overflow */
801 if (max_entries > num_account-enum_context) {
802 max_entries = num_account-enum_context;
803 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
806 /* calculate the size and limit on the number of entries we will return */
807 temp_size=max_entries*struct_size;
809 if (temp_size>max_size) {
810 max_entries=MIN((max_size/struct_size),max_entries);;
811 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
815 * Note from JRA. total_entries is not being used here. Currently if there is a
816 * large user base then it looks like NT will enumerate until get_sampwd_entries
817 * returns False due to num_entries being zero. This will cause an access denied
818 * return. I don't think this is right and needs further investigation. Note that
819 * this is also the same in the TNG code (I don't think that has been tested with
820 * a very large user list as MAX_SAM_ENTRIES is set to 600).
822 * I also think that one of the 'num_entries' return parameters is probably
823 * the "max entries" parameter - but in the TNG code they're all currently set to the same
824 * value (again I think this is wrong).
827 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
828 max_entries, enum_context,
829 info->disp_info.disp_user_info,
832 if (!NT_STATUS_IS_OK(r_u->status))
835 if (enum_context+max_entries < num_account)
836 r_u->status = STATUS_MORE_ENTRIES;
838 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
840 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
842 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
847 /*******************************************************************
848 makes a SAM_ENTRY / UNISTR2* structure from a group list.
849 ********************************************************************/
851 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
852 uint32 num_sam_entries, DOMAIN_GRP *grp)
861 if (num_sam_entries == 0)
864 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
866 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
868 if (sam == NULL || uni_name == NULL) {
869 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
873 for (i = 0; i < num_sam_entries; i++) {
875 * JRA. I think this should include the null. TNG does not.
877 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
878 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
882 *uni_name_pp = uni_name;
885 /*******************************************************************
886 Get the group entries - similar to get_sampwd_entries().
887 ******************************************************************/
889 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
890 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
891 uint32 *p_num_entries, uint32 max_entries )
895 uint32 group_entries = 0;
896 uint32 num_entries = 0;
900 /* access checks for the users were performed higher up. become/unbecome_root()
901 needed for some passdb backends to enumerate groups */
904 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
908 num_entries=group_entries-start_idx;
910 /* limit the number of entries */
911 if (num_entries>max_entries) {
912 DEBUG(5,("Limiting to %d entries\n", max_entries));
913 num_entries=max_entries;
916 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
917 if (num_entries!=0 && *d_grp==NULL){
919 return NT_STATUS_NO_MEMORY;
922 for (i=0; i<num_entries; i++) {
923 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
924 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
925 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
926 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
931 *p_num_entries = num_entries;
933 DEBUG(10,("get_group_domain_entries: returning %d entries\n",
939 /*******************************************************************
940 Wrapper for enumerating local groups
941 ******************************************************************/
943 static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
944 const DOM_SID *sid, uint32 start_idx,
945 uint32 *p_num_entries, uint32 max_entries )
947 struct acct_info *info;
952 res = pdb_enum_aliases(sid, start_idx, max_entries,
953 p_num_entries, &info);
957 return NT_STATUS_ACCESS_DENIED;
959 if (*p_num_entries == 0)
962 *d_grp = talloc(ctx, sizeof(DOMAIN_GRP) * (*p_num_entries));
964 if (*d_grp == NULL) {
966 return NT_STATUS_NO_MEMORY;
969 for (i=0; i<*p_num_entries; i++) {
970 fstrcpy((*d_grp)[i].name, info[i].acct_name);
971 fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
972 (*d_grp)[i].rid = info[i].rid;
973 (*d_grp)[i].attr = SID_NAME_ALIAS;
980 /*******************************************************************
981 samr_reply_enum_dom_groups
982 ********************************************************************/
984 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
986 DOMAIN_GRP *grp=NULL;
991 r_u->status = NT_STATUS_OK;
993 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
994 return NT_STATUS_INVALID_HANDLE;
996 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1000 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1002 /* the domain group array is being allocated in the function below */
1003 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))) {
1007 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1009 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1011 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1017 /*******************************************************************
1018 samr_reply_enum_dom_aliases
1019 ********************************************************************/
1021 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1023 DOMAIN_GRP *grp=NULL;
1024 uint32 num_entries = 0;
1030 r_u->status = NT_STATUS_OK;
1032 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1033 return NT_STATUS_INVALID_HANDLE;
1035 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1039 sid_to_string(sid_str, &sid);
1040 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1042 status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1043 &num_entries, MAX_SAM_ENTRIES);
1044 if (!NT_STATUS_IS_OK(status)) return status;
1046 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1050 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1052 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1057 /*******************************************************************
1058 samr_reply_query_dispinfo
1059 ********************************************************************/
1061 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1062 SAMR_R_QUERY_DISPINFO *r_u)
1064 struct samr_info *info = NULL;
1065 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1067 uint32 max_entries=q_u->max_entries;
1068 uint32 enum_context=q_u->start_idx;
1069 uint32 max_size=q_u->max_size;
1071 SAM_DISPINFO_CTR *ctr;
1072 uint32 temp_size=0, total_data_size=0;
1074 uint32 num_account = 0;
1075 enum remote_arch_types ra_type = get_remote_arch();
1076 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1079 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1080 r_u->status = NT_STATUS_OK;
1082 /* find the policy handle. open a policy on it. */
1083 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1084 return NT_STATUS_INVALID_HANDLE;
1086 domain_sid = info->sid;
1089 * calculate how many entries we will return.
1091 * - the number of entries the client asked
1092 * - our limit on that
1093 * - the starting point (enumeration context)
1094 * - the buffer size the client will accept
1098 * We are a lot more like W2K. Instead of reading the SAM
1099 * each time to find the records we need to send back,
1100 * we read it once and link that copy to the sam handle.
1101 * For large user list (over the MAX_SAM_ENTRIES)
1102 * it's a definitive win.
1103 * second point to notice: between enumerations
1104 * our sam is now the same as it's a snapshoot.
1105 * third point: got rid of the static SAM_USER_21 struct
1106 * no more intermediate.
1107 * con: it uses much more memory, as a full copy is stored
1110 * If you want to change it, think twice and think
1111 * of the second point , that's really important.
1116 /* Get what we need from the password database */
1117 switch (q_u->switch_level) {
1119 /* When playing with usrmgr, this is necessary
1120 if you want immediate refresh after editing
1121 a user. I would like to do this after the
1122 setuserinfo2, but we do not have access to
1123 the domain handle in that call, only to the
1124 user handle. Where else does this hurt?
1128 /* We cannot do this here - it kills performace. JRA. */
1129 free_samr_users(info);
1134 /* Level 2 is for all machines, otherwise only 'normal' users */
1135 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1137 if (!NT_STATUS_IS_OK(r_u->status)) {
1138 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1141 num_account = info->disp_info.num_user_account;
1145 r_u->status = load_group_domain_entries(info, &info->sid);
1146 if (!NT_STATUS_IS_OK(r_u->status))
1148 num_account = info->disp_info.num_group_account;
1151 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1152 return NT_STATUS_INVALID_INFO_CLASS;
1155 /* first limit the number of entries we will return */
1156 if(max_entries > max_sam_entries) {
1157 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1158 max_entries = max_sam_entries;
1161 if (enum_context > num_account) {
1162 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1163 return NT_STATUS_NO_MORE_ENTRIES;
1166 /* verify we won't overflow */
1167 if (max_entries > num_account-enum_context) {
1168 max_entries = num_account-enum_context;
1169 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1172 /* calculate the size and limit on the number of entries we will return */
1173 temp_size=max_entries*struct_size;
1175 if (temp_size>max_size) {
1176 max_entries=MIN((max_size/struct_size),max_entries);;
1177 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1180 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1181 return NT_STATUS_NO_MEMORY;
1185 /* Now create reply structure */
1186 switch (q_u->switch_level) {
1189 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1190 return NT_STATUS_NO_MEMORY;
1192 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1193 info->disp_info.disp_user_info, &domain_sid);
1194 if (!NT_STATUS_IS_OK(disp_ret))
1199 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1200 return NT_STATUS_NO_MEMORY;
1202 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1203 info->disp_info.disp_user_info, &domain_sid);
1204 if (!NT_STATUS_IS_OK(disp_ret))
1209 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1210 return NT_STATUS_NO_MEMORY;
1212 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1213 if (!NT_STATUS_IS_OK(disp_ret))
1218 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1219 return NT_STATUS_NO_MEMORY;
1221 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1222 if (!NT_STATUS_IS_OK(disp_ret))
1227 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1228 return NT_STATUS_NO_MEMORY;
1230 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1231 if (!NT_STATUS_IS_OK(disp_ret))
1236 ctr->sam.info = NULL;
1237 return NT_STATUS_INVALID_INFO_CLASS;
1240 /* calculate the total size */
1241 total_data_size=num_account*struct_size;
1243 if (enum_context+max_entries < num_account)
1244 r_u->status = STATUS_MORE_ENTRIES;
1246 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1248 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1254 /*******************************************************************
1255 samr_reply_query_aliasinfo
1256 ********************************************************************/
1258 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1261 struct acct_info info;
1265 r_u->status = NT_STATUS_OK;
1267 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1269 /* find the policy handle. open a policy on it. */
1270 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1271 return NT_STATUS_INVALID_HANDLE;
1272 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1277 ret = pdb_get_aliasinfo(&sid, &info);
1281 return NT_STATUS_NO_SUCH_ALIAS;
1283 switch (q_u->switch_level) {
1286 r_u->ctr.switch_value1 = 1;
1287 init_samr_alias_info1(&r_u->ctr.alias.info1,
1288 info.acct_name, 1, info.acct_desc);
1292 r_u->ctr.switch_value1 = 3;
1293 init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1296 return NT_STATUS_INVALID_INFO_CLASS;
1299 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1305 /*******************************************************************
1306 samr_reply_lookup_ids
1307 ********************************************************************/
1309 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1311 uint32 rid[MAX_SAM_ENTRIES];
1312 int num_rids = q_u->num_sids1;
1314 r_u->status = NT_STATUS_OK;
1316 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1318 if (num_rids > MAX_SAM_ENTRIES) {
1319 num_rids = MAX_SAM_ENTRIES;
1320 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1325 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1327 for (i = 0; i < num_rids && status == 0; i++)
1329 struct sam_passwd *sam_pass;
1333 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1334 q_u->uni_user_name[i].uni_str_len));
1336 /* find the user account */
1338 sam_pass = get_smb21pwd_entry(user_name, 0);
1341 if (sam_pass == NULL)
1343 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1348 rid[i] = sam_pass->user_rid;
1354 rid[0] = BUILTIN_ALIAS_RID_USERS;
1356 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1358 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1364 /*******************************************************************
1366 ********************************************************************/
1368 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1370 uint32 rid[MAX_SAM_ENTRIES];
1372 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1373 enum SID_NAME_USE local_type;
1375 int num_rids = q_u->num_names2;
1380 r_u->status = NT_STATUS_OK;
1382 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1387 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1388 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1392 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 */
1396 if (num_rids > MAX_SAM_ENTRIES) {
1397 num_rids = MAX_SAM_ENTRIES;
1398 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1401 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1403 for (i = 0; i < num_rids; i++) {
1408 r_u->status = NT_STATUS_NONE_MAPPED;
1410 rid [i] = 0xffffffff;
1411 type[i] = SID_NAME_UNKNOWN;
1413 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1416 * we are only looking for a name
1417 * the SID we get back can be outside
1418 * the scope of the pol_sid
1420 * in clear: it prevents to reply to domain\group: yes
1421 * when only builtin\group exists.
1423 * a cleaner code is to add the sid of the domain we're looking in
1424 * to the local_lookup_name function.
1427 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1428 sid_split_rid(&sid, &local_rid);
1430 if (sid_equal(&sid, &pol_sid)) {
1433 /* Windows does not return WKN_GRP here, even
1434 * on lookups in builtin */
1435 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1436 SID_NAME_ALIAS : local_type;
1438 r_u->status = NT_STATUS_OK;
1443 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1445 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1450 /*******************************************************************
1451 _samr_chgpasswd_user
1452 ********************************************************************/
1454 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1459 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1461 r_u->status = NT_STATUS_OK;
1463 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1464 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1466 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1469 * Pass the user through the NT -> unix user mapping
1473 (void)map_username(user_name);
1476 * UNIX username case mangling not required, pass_oem_change
1477 * is case insensitive.
1480 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1481 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1483 init_samr_r_chgpasswd_user(r_u, r_u->status);
1485 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1490 /*******************************************************************
1491 makes a SAMR_R_LOOKUP_RIDS structure.
1492 ********************************************************************/
1494 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1495 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1498 UNIHDR *hdr_name=NULL;
1499 UNISTR2 *uni_name=NULL;
1501 *pp_uni_name = NULL;
1502 *pp_hdr_name = NULL;
1504 if (num_names != 0) {
1505 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1506 if (hdr_name == NULL)
1509 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1510 if (uni_name == NULL)
1514 for (i = 0; i < num_names; i++) {
1515 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1516 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1517 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1520 *pp_uni_name = uni_name;
1521 *pp_hdr_name = hdr_name;
1526 /*******************************************************************
1528 ********************************************************************/
1530 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1532 fstring group_names[MAX_SAM_ENTRIES];
1533 uint32 *group_attrs = NULL;
1534 UNIHDR *hdr_name = NULL;
1535 UNISTR2 *uni_name = NULL;
1537 int num_rids = q_u->num_rids1;
1541 r_u->status = NT_STATUS_OK;
1543 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1545 /* find the policy handle. open a policy on it. */
1546 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1547 return NT_STATUS_INVALID_HANDLE;
1549 if (num_rids > MAX_SAM_ENTRIES) {
1550 num_rids = MAX_SAM_ENTRIES;
1551 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1555 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1556 return NT_STATUS_NO_MEMORY;
1559 r_u->status = NT_STATUS_NONE_MAPPED;
1561 become_root(); /* lookup_sid can require root privs */
1563 for (i = 0; i < num_rids; i++) {
1567 enum SID_NAME_USE type;
1569 group_attrs[i] = SID_NAME_UNKNOWN;
1570 *group_names[i] = '\0';
1572 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1573 sid_copy(&sid, &pol_sid);
1574 sid_append_rid(&sid, q_u->rid[i]);
1576 if (lookup_sid(&sid, domname, tmpname, &type)) {
1577 r_u->status = NT_STATUS_OK;
1578 group_attrs[i] = (uint32)type;
1579 fstrcpy(group_names[i],tmpname);
1580 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1587 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1588 return NT_STATUS_NO_MEMORY;
1590 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1592 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1597 /*******************************************************************
1598 _samr_open_user. Safe - gives out no passwd info.
1599 ********************************************************************/
1601 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1603 SAM_ACCOUNT *sampass=NULL;
1605 POLICY_HND domain_pol = q_u->domain_pol;
1606 POLICY_HND *user_pol = &r_u->user_pol;
1607 struct samr_info *info = NULL;
1608 SEC_DESC *psd = NULL;
1610 uint32 des_access = q_u->access_mask;
1615 r_u->status = NT_STATUS_OK;
1617 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1618 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1619 return NT_STATUS_INVALID_HANDLE;
1621 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1625 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1626 if (!NT_STATUS_IS_OK(nt_status)) {
1630 /* append the user's RID to it */
1631 if (!sid_append_rid(&sid, q_u->user_rid))
1632 return NT_STATUS_NO_SUCH_USER;
1634 /* check if access can be granted as requested by client. */
1635 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1636 se_map_generic(&des_access, &usr_generic_mapping);
1637 if (!NT_STATUS_IS_OK(nt_status =
1638 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1639 des_access, &acc_granted, "_samr_open_user"))) {
1644 ret=pdb_getsampwsid(sampass, &sid);
1647 /* check that the SID exists in our domain. */
1649 return NT_STATUS_NO_SUCH_USER;
1652 pdb_free_sam(&sampass);
1654 /* associate the user's SID and access bits with the new handle. */
1655 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1656 return NT_STATUS_NO_MEMORY;
1657 info->acc_granted = acc_granted;
1659 /* get a (unique) handle. open a policy on it. */
1660 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1661 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1666 /*************************************************************************
1667 get_user_info_10. Safe. Only gives out acb bits.
1668 *************************************************************************/
1670 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1672 SAM_ACCOUNT *smbpass=NULL;
1676 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1678 if (!NT_STATUS_IS_OK(nt_status)) {
1683 ret = pdb_getsampwsid(smbpass, user_sid);
1687 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1688 return NT_STATUS_NO_SUCH_USER;
1691 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1694 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1696 pdb_free_sam(&smbpass);
1698 return NT_STATUS_OK;
1701 /*************************************************************************
1702 get_user_info_12. OK - this is the killer as it gives out password info.
1703 Ensure that this is only allowed on an encrypted connection with a root
1705 *************************************************************************/
1707 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1709 SAM_ACCOUNT *smbpass=NULL;
1713 if (!p->ntlmssp_auth_validated)
1714 return NT_STATUS_ACCESS_DENIED;
1716 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1717 return NT_STATUS_ACCESS_DENIED;
1720 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1723 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1725 if (!NT_STATUS_IS_OK(nt_status)) {
1729 ret = pdb_getsampwsid(smbpass, user_sid);
1732 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1733 pdb_free_sam(&smbpass);
1734 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1737 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1739 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1740 pdb_free_sam(&smbpass);
1741 return NT_STATUS_ACCOUNT_DISABLED;
1745 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1747 pdb_free_sam(&smbpass);
1749 return NT_STATUS_OK;
1752 /*************************************************************************
1754 *************************************************************************/
1756 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1758 SAM_ACCOUNT *sampass=NULL;
1761 pdb_init_sam_talloc(mem_ctx, &sampass);
1764 ret = pdb_getsampwsid(sampass, user_sid);
1768 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1769 return NT_STATUS_NO_SUCH_USER;
1772 samr_clear_sam_passwd(sampass);
1774 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1777 init_sam_user_info20A(id20, sampass);
1779 pdb_free_sam(&sampass);
1781 return NT_STATUS_OK;
1784 /*************************************************************************
1786 *************************************************************************/
1788 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1789 DOM_SID *user_sid, DOM_SID *domain_sid)
1791 SAM_ACCOUNT *sampass=NULL;
1795 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1796 if (!NT_STATUS_IS_OK(nt_status)) {
1801 ret = pdb_getsampwsid(sampass, user_sid);
1805 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1806 return NT_STATUS_NO_SUCH_USER;
1809 samr_clear_sam_passwd(sampass);
1811 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1814 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1816 pdb_free_sam(&sampass);
1818 return NT_STATUS_OK;
1821 /*******************************************************************
1822 _samr_query_userinfo
1823 ********************************************************************/
1825 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1827 SAM_USERINFO_CTR *ctr;
1828 struct samr_info *info = NULL;
1832 r_u->status=NT_STATUS_OK;
1834 /* search for the handle */
1835 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1836 return NT_STATUS_INVALID_HANDLE;
1838 domain_sid = info->sid;
1840 sid_split_rid(&domain_sid, &rid);
1842 if (!sid_check_is_in_our_domain(&info->sid))
1843 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1845 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1847 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1849 return NT_STATUS_NO_MEMORY;
1853 /* ok! user info levels (lots: see MSDEV help), off we go... */
1854 ctr->switch_value = q_u->switch_value;
1856 switch (q_u->switch_value) {
1858 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1859 if (ctr->info.id10 == NULL)
1860 return NT_STATUS_NO_MEMORY;
1862 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1867 /* whoops - got this wrong. i think. or don't understand what's happening. */
1871 info = (void *)&id11;
1873 expire.low = 0xffffffff;
1874 expire.high = 0x7fffffff;
1876 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1881 ZERO_STRUCTP(ctr->info.id11);
1882 init_sam_user_info11(ctr->info.id11, &expire,
1883 "BROOKFIELDS$", /* name */
1884 0x03ef, /* user rid */
1885 0x201, /* group rid */
1886 0x0080); /* acb info */
1893 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1894 if (ctr->info.id12 == NULL)
1895 return NT_STATUS_NO_MEMORY;
1897 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1902 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1903 if (ctr->info.id20 == NULL)
1904 return NT_STATUS_NO_MEMORY;
1905 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1910 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1911 if (ctr->info.id21 == NULL)
1912 return NT_STATUS_NO_MEMORY;
1913 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1914 &info->sid, &domain_sid)))
1919 return NT_STATUS_INVALID_INFO_CLASS;
1922 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1924 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1929 /*******************************************************************
1930 samr_reply_query_usergroups
1931 ********************************************************************/
1933 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1935 SAM_ACCOUNT *sam_pass=NULL;
1937 DOM_GID *gids = NULL;
1943 * from the SID in the request:
1944 * we should send back the list of DOMAIN GROUPS
1945 * the user is a member of
1947 * and only the DOMAIN GROUPS
1948 * no ALIASES !!! neither aliases of the domain
1949 * nor aliases of the builtin SID
1954 r_u->status = NT_STATUS_OK;
1956 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1958 /* find the policy handle. open a policy on it. */
1959 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1960 return NT_STATUS_INVALID_HANDLE;
1962 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1966 if (!sid_check_is_in_our_domain(&sid))
1967 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1969 pdb_init_sam(&sam_pass);
1972 ret = pdb_getsampwsid(sam_pass, &sid);
1976 pdb_free_sam(&sam_pass);
1977 return NT_STATUS_NO_SUCH_USER;
1980 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
1981 pdb_free_sam(&sam_pass);
1982 return NT_STATUS_NO_SUCH_GROUP;
1985 /* construct the response. lkclXXXX: gids are not copied! */
1986 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1988 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1990 pdb_free_sam(&sam_pass);
1995 /*******************************************************************
1996 _samr_query_dom_info
1997 ********************************************************************/
1999 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2001 struct samr_info *info = NULL;
2003 uint32 min_pass_len,pass_hist,flag;
2004 time_t u_expire, u_min_age;
2005 NTTIME nt_expire, nt_min_age;
2007 time_t u_lock_duration, u_reset_time;
2008 NTTIME nt_lock_duration, nt_reset_time;
2014 uint32 account_policy_temp;
2016 uint32 num_users=0, num_groups=0, num_aliases=0;
2018 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2019 return NT_STATUS_NO_MEMORY;
2023 r_u->status = NT_STATUS_OK;
2025 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2027 /* find the policy handle. open a policy on it. */
2028 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2029 return NT_STATUS_INVALID_HANDLE;
2031 switch (q_u->switch_value) {
2034 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2035 min_pass_len = account_policy_temp;
2037 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2038 pass_hist = account_policy_temp;
2040 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2041 flag = account_policy_temp;
2043 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2044 u_expire = account_policy_temp;
2046 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2047 u_min_age = account_policy_temp;
2049 unix_to_nt_time_abs(&nt_expire, u_expire);
2050 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2052 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2053 flag, nt_expire, nt_min_age);
2057 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2059 if (!NT_STATUS_IS_OK(r_u->status)) {
2060 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2063 num_users=info->disp_info.num_user_account;
2066 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2067 if (!NT_STATUS_IS_OK(r_u->status)) {
2068 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2071 num_groups=info->disp_info.num_group_account;
2074 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2075 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2076 num_users, num_groups, num_aliases);
2079 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2080 unix_to_nt_time_abs(&nt_logout, u_logout);
2082 init_unk_info3(&ctr->info.inf3, nt_logout);
2085 init_unk_info5(&ctr->info.inf5, global_myname());
2088 init_unk_info6(&ctr->info.inf6);
2091 init_unk_info7(&ctr->info.inf7);
2094 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2095 u_lock_duration = account_policy_temp * 60;
2097 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2098 u_reset_time = account_policy_temp * 60;
2100 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2101 lockout = account_policy_temp;
2103 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2104 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2106 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2109 return NT_STATUS_INVALID_INFO_CLASS;
2112 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2114 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2119 /*******************************************************************
2121 Create an account, can be either a normal user or a machine.
2122 This funcion will need to be updated for bdc/domain trusts.
2123 ********************************************************************/
2125 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2127 SAM_ACCOUNT *sam_pass=NULL;
2131 POLICY_HND dom_pol = q_u->domain_pol;
2132 UNISTR2 user_account = q_u->uni_name;
2133 uint16 acb_info = q_u->acb_info;
2134 POLICY_HND *user_pol = &r_u->user_pol;
2135 struct samr_info *info = NULL;
2143 /* check this, when giving away 'add computer to domain' privs */
2144 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2146 /* Get the domain SID stored in the domain policy */
2147 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2148 return NT_STATUS_INVALID_HANDLE;
2150 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2154 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2155 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2156 this parameter is not an account type */
2157 return NT_STATUS_INVALID_PARAMETER;
2160 /* find the account: tell the caller if it exists.
2161 lkclXXXX i have *no* idea if this is a problem or not
2162 or even if you are supposed to construct a different
2163 reply if the account already exists...
2166 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2167 strlower_m(account);
2169 pdb_init_sam(&sam_pass);
2172 ret = pdb_getsampwnam(sam_pass, account);
2175 /* this account exists: say so */
2176 pdb_free_sam(&sam_pass);
2177 return NT_STATUS_USER_EXISTS;
2180 pdb_free_sam(&sam_pass);
2183 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2184 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2185 * that only people with write access to the smbpasswd file will be able
2186 * to create a user. JRA.
2190 * add the user in the /etc/passwd file or the unix authority system.
2191 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2192 * a) local_password_change() checks for us if the /etc/passwd account really exists
2193 * b) smb_create_user() would return an error if the account already exists
2194 * and as it could return an error also if it can't create the account, it would be tricky.
2196 * So we go the easy way, only check after if the account exists.
2197 * JFM (2/3/2001), to clear any possible bad understanding (-:
2199 * We now have seperate script paramaters for adding users/machines so we
2200 * now have some sainity-checking to match.
2203 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2206 * we used to have code here that made sure the acb_info flags
2207 * matched with the users named (e.g. an account flags as a machine
2208 * trust account ended in '$'). It has been ifdef'd out for a long
2209 * time, so I replaced it with this comment. --jerry
2212 /* the passdb lookup has failed; check to see if we need to run the
2213 add user/machine script */
2215 pw = Get_Pwnam(account);
2217 /*********************************************************************
2218 * HEADS UP! If we have to create a new user account, we have to get
2219 * a new RID from somewhere. This used to be done by the passdb
2220 * backend. It has been moved into idmap now. Since idmap is now
2221 * wrapped up behind winbind, this means you have to run winbindd if you
2222 * want new accounts to get a new RID when "enable rid algorithm = no".
2223 * Tough. We now have a uniform way of allocating RIDs regardless
2224 * of what ever passdb backend people may use.
2225 * --jerry (2003-07-10)
2226 *********************************************************************/
2230 * we can't check both the ending $ and the acb_info.
2232 * UserManager creates trust accounts (ending in $,
2233 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2236 if (account[strlen(account)-1] == '$')
2237 pstrcpy(add_script, lp_addmachine_script());
2239 pstrcpy(add_script, lp_adduser_script());
2243 all_string_sub(add_script, "%u", account, sizeof(account));
2244 add_ret = smbrun(add_script,NULL);
2245 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2247 else /* no add user script -- ask winbindd to do it */
2249 if ( !winbind_create_user( account, &new_rid ) ) {
2250 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2257 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2259 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2262 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2264 if (!pdb_add_sam_account(sam_pass)) {
2265 pdb_free_sam(&sam_pass);
2266 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2268 return NT_STATUS_ACCESS_DENIED;
2271 /* Get the user's SID */
2272 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2274 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2275 se_map_generic(&des_access, &usr_generic_mapping);
2276 if (!NT_STATUS_IS_OK(nt_status =
2277 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2278 des_access, &acc_granted, "_samr_create_user"))) {
2282 /* associate the user's SID with the new handle. */
2283 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2284 pdb_free_sam(&sam_pass);
2285 return NT_STATUS_NO_MEMORY;
2290 info->acc_granted = acc_granted;
2292 /* get a (unique) handle. open a policy on it. */
2293 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2294 pdb_free_sam(&sam_pass);
2295 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2298 r_u->user_rid=pdb_get_user_rid(sam_pass);
2300 r_u->access_granted = acc_granted;
2302 pdb_free_sam(&sam_pass);
2304 return NT_STATUS_OK;
2307 /*******************************************************************
2308 samr_reply_connect_anon
2309 ********************************************************************/
2311 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2313 struct samr_info *info = NULL;
2314 uint32 des_access = q_u->access_mask;
2318 if (!pipe_access_check(p)) {
2319 DEBUG(3, ("access denied to samr_connect_anon\n"));
2320 r_u->status = NT_STATUS_ACCESS_DENIED;
2324 /* set up the SAMR connect_anon response */
2326 r_u->status = NT_STATUS_OK;
2328 /* associate the user's SID with the new handle. */
2329 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2330 return NT_STATUS_NO_MEMORY;
2332 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2333 was observed from a win98 client trying to enumerate users (when configured
2334 user level access control on shares) --jerry */
2336 se_map_generic( &des_access, &sam_generic_mapping );
2337 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2339 info->status = q_u->unknown_0;
2341 /* get a (unique) handle. open a policy on it. */
2342 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2343 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2348 /*******************************************************************
2350 ********************************************************************/
2352 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2354 struct samr_info *info = NULL;
2355 SEC_DESC *psd = NULL;
2357 uint32 des_access = q_u->access_mask;
2362 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2366 if (!pipe_access_check(p)) {
2367 DEBUG(3, ("access denied to samr_connect\n"));
2368 r_u->status = NT_STATUS_ACCESS_DENIED;
2372 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2373 se_map_generic(&des_access, &sam_generic_mapping);
2374 if (!NT_STATUS_IS_OK(nt_status =
2375 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2376 des_access, &acc_granted, "_samr_connect"))) {
2380 r_u->status = NT_STATUS_OK;
2382 /* associate the user's SID and access granted with the new handle. */
2383 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2384 return NT_STATUS_NO_MEMORY;
2386 info->acc_granted = acc_granted;
2387 info->status = q_u->access_mask;
2389 /* get a (unique) handle. open a policy on it. */
2390 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2391 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2393 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2398 /*******************************************************************
2400 ********************************************************************/
2402 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2404 struct samr_info *info = NULL;
2405 SEC_DESC *psd = NULL;
2407 uint32 des_access = q_u->access_mask;
2412 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2416 if (!pipe_access_check(p)) {
2417 DEBUG(3, ("access denied to samr_connect4\n"));
2418 r_u->status = NT_STATUS_ACCESS_DENIED;
2422 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2423 se_map_generic(&des_access, &sam_generic_mapping);
2424 if (!NT_STATUS_IS_OK(nt_status =
2425 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2426 des_access, &acc_granted, "_samr_connect"))) {
2430 r_u->status = NT_STATUS_OK;
2432 /* associate the user's SID and access granted with the new handle. */
2433 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2434 return NT_STATUS_NO_MEMORY;
2436 info->acc_granted = acc_granted;
2437 info->status = q_u->access_mask;
2439 /* get a (unique) handle. open a policy on it. */
2440 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2441 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2443 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2448 /**********************************************************************
2449 api_samr_lookup_domain
2450 **********************************************************************/
2452 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2454 struct samr_info *info;
2455 fstring domain_name;
2458 r_u->status = NT_STATUS_OK;
2460 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2461 return NT_STATUS_INVALID_HANDLE;
2463 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2464 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2469 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2473 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2474 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2477 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2479 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2484 /******************************************************************
2485 makes a SAMR_R_ENUM_DOMAINS structure.
2486 ********************************************************************/
2488 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2489 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2495 DEBUG(5, ("make_enum_domains\n"));
2498 *pp_uni_name = NULL;
2500 if (num_sam_entries == 0)
2503 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2504 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2506 if (sam == NULL || uni_name == NULL)
2509 for (i = 0; i < num_sam_entries; i++) {
2510 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2511 init_sam_entry(&sam[i], &uni_name[i], 0);
2515 *pp_uni_name = uni_name;
2520 /**********************************************************************
2521 api_samr_enum_domains
2522 **********************************************************************/
2524 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2526 struct samr_info *info;
2527 uint32 num_entries = 2;
2531 r_u->status = NT_STATUS_OK;
2533 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2534 return NT_STATUS_INVALID_HANDLE;
2536 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2540 name = get_global_sam_name();
2542 fstrcpy(dom[0],name);
2544 fstrcpy(dom[1],"Builtin");
2546 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2547 return NT_STATUS_NO_MEMORY;
2549 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2554 /*******************************************************************
2556 ********************************************************************/
2558 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2561 POLICY_HND domain_pol = q_u->dom_pol;
2562 uint32 alias_rid = q_u->rid_alias;
2563 POLICY_HND *alias_pol = &r_u->pol;
2564 struct samr_info *info = NULL;
2565 SEC_DESC *psd = NULL;
2567 uint32 des_access = q_u->access_mask;
2571 r_u->status = NT_STATUS_OK;
2573 /* find the domain policy and get the SID / access bits stored in the domain policy */
2574 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2575 return NT_STATUS_INVALID_HANDLE;
2577 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2581 /* append the alias' RID to it */
2582 if (!sid_append_rid(&sid, alias_rid))
2583 return NT_STATUS_NO_SUCH_USER;
2585 /*check if access can be granted as requested by client. */
2586 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2587 se_map_generic(&des_access,&ali_generic_mapping);
2588 if (!NT_STATUS_IS_OK(status =
2589 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2590 des_access, &acc_granted, "_samr_open_alias"))) {
2595 * we should check if the rid really exist !!!
2599 /* associate the user's SID with the new handle. */
2600 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2601 return NT_STATUS_NO_MEMORY;
2603 info->acc_granted = acc_granted;
2605 /* get a (unique) handle. open a policy on it. */
2606 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2607 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2612 /*******************************************************************
2614 ********************************************************************/
2616 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2618 SAM_ACCOUNT *pwd =NULL;
2623 ret = pdb_getsampwsid(pwd, sid);
2631 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2636 /* FIX ME: check if the value is really changed --metze */
2637 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2642 if(!pdb_update_sam_account(pwd)) {
2652 /*******************************************************************
2654 ********************************************************************/
2656 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2658 SAM_ACCOUNT *pwd = NULL;
2662 if(!pdb_getsampwsid(pwd, sid)) {
2668 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2673 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2677 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2681 if (!pdb_set_pass_changed_now (pwd)) {
2686 if(!pdb_update_sam_account(pwd)) {
2695 /*******************************************************************
2696 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2697 ********************************************************************/
2698 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2703 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2705 DEBUG(2,("Could not get gid for primary group of "
2706 "user %s\n", pdb_get_username(sampass)));
2710 grp = getgrgid(gid);
2713 DEBUG(2,("Could not find primary group %lu for "
2714 "user %s\n", (unsigned long)gid,
2715 pdb_get_username(sampass)));
2719 if (smb_set_primary_group(grp->gr_name,
2720 pdb_get_username(sampass)) != 0) {
2721 DEBUG(2,("Could not set primary group for user %s to "
2723 pdb_get_username(sampass), grp->gr_name));
2731 /*******************************************************************
2733 ********************************************************************/
2735 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2737 SAM_ACCOUNT *pwd = NULL;
2740 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2746 if (!pdb_getsampwsid(pwd, sid)) {
2751 copy_id20_to_sam_passwd(pwd, id20);
2753 /* write the change out */
2754 if(!pdb_update_sam_account(pwd)) {
2763 /*******************************************************************
2765 ********************************************************************/
2767 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2769 SAM_ACCOUNT *pwd = NULL;
2772 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2778 if (!pdb_getsampwsid(pwd, sid)) {
2783 copy_id21_to_sam_passwd(pwd, id21);
2786 * The funny part about the previous two calls is
2787 * that pwd still has the password hashes from the
2788 * passdb entry. These have not been updated from
2789 * id21. I don't know if they need to be set. --jerry
2792 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2793 set_unix_primary_group(pwd);
2795 /* write the change out */
2796 if(!pdb_update_sam_account(pwd)) {
2806 /*******************************************************************
2808 ********************************************************************/
2810 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2812 SAM_ACCOUNT *pwd = NULL;
2813 pstring plaintext_buf;
2818 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2824 if (!pdb_getsampwsid(pwd, sid)) {
2829 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2830 pdb_get_username(pwd)));
2832 acct_ctrl = pdb_get_acct_ctrl(pwd);
2834 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2839 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2844 copy_id23_to_sam_passwd(pwd, id23);
2846 /* if it's a trust account, don't update /etc/passwd */
2847 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2848 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2849 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2850 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2852 /* update the UNIX password */
2853 if (lp_unix_password_sync() ) {
2854 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2856 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2859 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2866 ZERO_STRUCT(plaintext_buf);
2868 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2869 set_unix_primary_group(pwd);
2871 if(!pdb_update_sam_account(pwd)) {
2881 /*******************************************************************
2883 ********************************************************************/
2885 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2887 SAM_ACCOUNT *pwd = NULL;
2889 pstring plaintext_buf;
2894 if (!pdb_getsampwsid(pwd, sid)) {
2899 DEBUG(5, ("Attempting administrator password change for user %s\n",
2900 pdb_get_username(pwd)));
2902 acct_ctrl = pdb_get_acct_ctrl(pwd);
2904 ZERO_STRUCT(plaintext_buf);
2906 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2911 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2916 /* if it's a trust account, don't update /etc/passwd */
2917 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2918 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2919 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2920 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2922 /* update the UNIX password */
2923 if (lp_unix_password_sync()) {
2924 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2926 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2929 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2936 ZERO_STRUCT(plaintext_buf);
2938 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2940 /* update the SAMBA password */
2941 if(!pdb_update_sam_account(pwd)) {
2951 /*******************************************************************
2952 samr_reply_set_userinfo
2953 ********************************************************************/
2955 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2958 POLICY_HND *pol = &q_u->pol;
2959 uint16 switch_value = q_u->switch_value;
2960 SAM_USERINFO_CTR *ctr = q_u->ctr;
2962 uint32 acc_required;
2964 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2966 r_u->status = NT_STATUS_OK;
2968 /* find the policy handle. open a policy on it. */
2969 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2970 return NT_STATUS_INVALID_HANDLE;
2972 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2973 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2977 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2980 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2981 return NT_STATUS_INVALID_INFO_CLASS;
2984 /* ok! user info levels (lots: see MSDEV help), off we go... */
2985 switch (switch_value) {
2987 if (!set_user_info_12(ctr->info.id12, &sid))
2988 return NT_STATUS_ACCESS_DENIED;
2992 if (!p->session_key.length) {
2993 return NT_STATUS_NO_USER_SESSION_KEY;
2995 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
2997 dump_data(100, (char *)ctr->info.id24->pass, 516);
2999 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3000 return NT_STATUS_ACCESS_DENIED;
3006 * Currently we don't really know how to unmarshall
3007 * the level 25 struct, and the password encryption
3008 * is different. This is a placeholder for when we
3009 * do understand it. In the meantime just return INVALID
3010 * info level and W2K SP2 drops down to level 23... JRA.
3013 if (!p->session_key.length) {
3014 return NT_STATUS_NO_USER_SESSION_KEY;
3016 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3018 dump_data(100, (char *)ctr->info.id25->pass, 532);
3020 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3021 return NT_STATUS_ACCESS_DENIED;
3024 return NT_STATUS_INVALID_INFO_CLASS;
3027 if (!p->session_key.length) {
3028 return NT_STATUS_NO_USER_SESSION_KEY;
3030 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3032 dump_data(100, (char *)ctr->info.id23->pass, 516);
3034 if (!set_user_info_23(ctr->info.id23, &sid))
3035 return NT_STATUS_ACCESS_DENIED;
3039 return NT_STATUS_INVALID_INFO_CLASS;
3045 /*******************************************************************
3046 samr_reply_set_userinfo2
3047 ********************************************************************/
3049 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3052 SAM_USERINFO_CTR *ctr = q_u->ctr;
3053 POLICY_HND *pol = &q_u->pol;
3054 uint16 switch_value = q_u->switch_value;
3056 uint32 acc_required;
3058 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3060 r_u->status = NT_STATUS_OK;
3062 /* find the policy handle. open a policy on it. */
3063 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3064 return NT_STATUS_INVALID_HANDLE;
3066 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3067 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3071 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3074 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3075 return NT_STATUS_INVALID_INFO_CLASS;
3078 switch_value=ctr->switch_value;
3080 /* ok! user info levels (lots: see MSDEV help), off we go... */
3081 switch (switch_value) {
3083 if (!set_user_info_21(ctr->info.id21, &sid))
3084 return NT_STATUS_ACCESS_DENIED;
3087 if (!set_user_info_20(ctr->info.id20, &sid))
3088 return NT_STATUS_ACCESS_DENIED;
3091 if (!set_user_info_10(ctr->info.id10, &sid))
3092 return NT_STATUS_ACCESS_DENIED;
3095 /* Used by AS/U JRA. */
3096 if (!set_user_info_12(ctr->info.id12, &sid))
3097 return NT_STATUS_ACCESS_DENIED;
3100 return NT_STATUS_INVALID_INFO_CLASS;
3106 /*********************************************************************
3107 _samr_query_aliasmem
3108 *********************************************************************/
3110 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3112 int num_groups = 0, tmp_num_groups=0;
3113 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3114 struct samr_info *info = NULL;
3120 /* until i see a real useraliases query, we fack one up */
3122 /* I have seen one, JFM 2/12/2001 */
3124 * Explanation of what this call does:
3125 * for all the SID given in the request:
3126 * return a list of alias (local groups)
3127 * that have those SID as members.
3129 * and that's the alias in the domain specified
3130 * in the policy_handle
3132 * if the policy handle is on an incorrect sid
3133 * for example a user's sid
3134 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3137 r_u->status = NT_STATUS_OK;
3139 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3141 /* find the policy handle. open a policy on it. */
3142 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3143 return NT_STATUS_INVALID_HANDLE;
3145 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3146 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3148 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3149 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3150 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3151 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3155 if (!sid_check_is_domain(&info->sid) &&
3156 !sid_check_is_builtin(&info->sid))
3157 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3160 for (i=0; i<q_u->num_sids1; i++) {
3162 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3165 * if there is an error, we just continue as
3166 * it can be an unfound user or group
3168 if (!NT_STATUS_IS_OK(r_u->status)) {
3169 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3173 if (tmp_num_groups==0) {
3174 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3178 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3179 if (new_rids==NULL) {
3180 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3181 return NT_STATUS_NO_MEMORY;
3185 for (j=0; j<tmp_num_groups; j++)
3186 rids[j+num_groups]=tmp_rids[j];
3188 safe_free(tmp_rids);
3190 num_groups+=tmp_num_groups;
3193 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3194 return NT_STATUS_OK;
3197 /*********************************************************************
3198 _samr_query_aliasmem
3199 *********************************************************************/
3201 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3213 /* find the policy handle. open a policy on it. */
3214 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3215 return NT_STATUS_INVALID_HANDLE;
3217 if (!NT_STATUS_IS_OK(r_u->status =
3218 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3222 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3224 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3225 return NT_STATUS_NO_SUCH_ALIAS;
3227 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_sids);
3228 if (num_sids!=0 && sid == NULL) {
3230 return NT_STATUS_NO_MEMORY;
3233 for (i = 0; i < num_sids; i++) {
3234 init_dom_sid2(&sid[i], &sids[i]);
3237 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3241 return NT_STATUS_OK;
3244 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3248 if ((*num) >= groups_max())
3251 for (i=0; i<*num; i++) {
3252 if ((*uids)[i] == uid)
3256 *uids = Realloc(*uids, (*num+1) * sizeof(uid_t));
3261 (*uids)[*num] = uid;
3266 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3270 struct sys_pwent *userlist, *user;
3275 /* We only look at our own sam, so don't care about imported stuff */
3279 if ((grp = getgrgid(gid)) == NULL) {
3284 /* Primary group members */
3286 userlist = getpwent_list();
3288 for (user = userlist; user != NULL; user = user->next) {
3289 if (user->pw_gid != gid)
3291 add_uid_to_array_unique(user->pw_uid, uids, num);
3294 pwent_free(userlist);
3296 /* Secondary group members */
3299 while ((*gr != NULL) && ((*gr)[0] != '\0')) {
3300 struct passwd *pw = getpwnam(*gr);
3305 add_uid_to_array_unique(pw->pw_uid, uids, num);
3315 /*********************************************************************
3316 _samr_query_groupmem
3317 *********************************************************************/
3319 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3321 int final_num_rids, i;
3323 fstring group_sid_str;
3333 /* find the policy handle. open a policy on it. */
3334 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3335 return NT_STATUS_INVALID_HANDLE;
3337 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3341 sid_to_string(group_sid_str, &group_sid);
3342 DEBUG(10, ("sid is %s\n", group_sid_str));
3344 if (!sid_check_is_in_our_domain(&group_sid)) {
3345 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3346 return NT_STATUS_NO_SUCH_GROUP;
3349 DEBUG(10, ("lookup on Domain SID\n"));
3351 if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3352 return NT_STATUS_NO_SUCH_GROUP;
3354 if(!get_memberuids(gid, &uids, &num))
3355 return NT_STATUS_NO_SUCH_GROUP;
3357 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
3358 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
3360 if (num!=0 && (rid==NULL || attr==NULL))
3361 return NT_STATUS_NO_MEMORY;
3365 for (i=0; i<num; i++) {
3368 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3369 DEBUG(1, ("Could not map member uid to SID\n"));
3373 if (!sid_check_is_in_our_domain(&sid)) {
3374 DEBUG(1, ("Inconsistent SAM -- group member uid not "
3375 "in our domain\n"));
3379 sid_peek_rid(&sid, &rid[final_num_rids]);
3381 /* Hmm. In a trace I got the constant 7 here from NT. */
3382 attr[final_num_rids] = SID_NAME_USER;
3384 final_num_rids += 1;
3389 init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3392 return NT_STATUS_OK;
3395 /*********************************************************************
3397 *********************************************************************/
3399 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3404 /* Find the policy handle. Open a policy on it. */
3405 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3406 return NT_STATUS_INVALID_HANDLE;
3408 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3412 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3414 if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
3415 return NT_STATUS_ACCESS_DENIED;
3417 return NT_STATUS_OK;
3420 /*********************************************************************
3422 *********************************************************************/
3424 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3429 /* Find the policy handle. Open a policy on it. */
3430 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3431 return NT_STATUS_INVALID_HANDLE;
3433 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3437 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3438 sid_string_static(&alias_sid)));
3440 if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
3441 return NT_STATUS_ACCESS_DENIED;
3443 return NT_STATUS_OK;
3446 /*********************************************************************
3448 *********************************************************************/
3450 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3454 fstring group_sid_str;
3461 SAM_ACCOUNT *sam_user=NULL;
3465 /* Find the policy handle. Open a policy on it. */
3466 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3467 return NT_STATUS_INVALID_HANDLE;
3469 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3473 sid_to_string(group_sid_str, &group_sid);
3474 DEBUG(10, ("sid is %s\n", group_sid_str));
3476 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3477 return NT_STATUS_NO_SUCH_GROUP;
3479 DEBUG(10, ("lookup on Domain SID\n"));
3481 if(!get_domain_group_from_sid(group_sid, &map))
3482 return NT_STATUS_NO_SUCH_GROUP;
3484 sid_copy(&user_sid, get_global_sam_sid());
3485 sid_append_rid(&user_sid, q_u->rid);
3487 ret = pdb_init_sam(&sam_user);
3488 if (!NT_STATUS_IS_OK(ret))
3491 check = pdb_getsampwsid(sam_user, &user_sid);
3493 if (check != True) {
3494 pdb_free_sam(&sam_user);
3495 return NT_STATUS_NO_SUCH_USER;
3498 /* check a real user exist before we run the script to add a user to a group */
3499 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3500 pdb_free_sam(&sam_user);
3501 return NT_STATUS_NO_SUCH_USER;
3504 pdb_free_sam(&sam_user);
3506 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3507 return NT_STATUS_NO_SUCH_USER;
3510 if ((grp=getgrgid(map.gid)) == NULL) {
3512 return NT_STATUS_NO_SUCH_GROUP;
3515 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3516 fstrcpy(grp_name, grp->gr_name);
3518 /* if the user is already in the group */
3519 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3521 return NT_STATUS_MEMBER_IN_GROUP;
3525 * ok, the group exist, the user exist, the user is not in the group,
3527 * we can (finally) add it to the group !
3530 smb_add_user_group(grp_name, pwd->pw_name);
3532 /* check if the user has been added then ... */
3533 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3535 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3539 return NT_STATUS_OK;
3542 /*********************************************************************
3544 *********************************************************************/
3546 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3550 SAM_ACCOUNT *sam_pass=NULL;
3557 * delete the group member named q_u->rid
3558 * who is a member of the sid associated with the handle
3559 * the rid is a user's rid as the group is a domain group.
3562 /* Find the policy handle. Open a policy on it. */
3563 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3564 return NT_STATUS_INVALID_HANDLE;
3566 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3570 if (!sid_check_is_in_our_domain(&group_sid))
3571 return NT_STATUS_NO_SUCH_GROUP;
3573 sid_copy(&user_sid, get_global_sam_sid());
3574 sid_append_rid(&user_sid, q_u->rid);
3576 if (!get_domain_group_from_sid(group_sid, &map))
3577 return NT_STATUS_NO_SUCH_GROUP;
3579 if ((grp=getgrgid(map.gid)) == NULL)
3580 return NT_STATUS_NO_SUCH_GROUP;
3582 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3583 fstrcpy(grp_name, grp->gr_name);
3585 /* check if the user exists before trying to remove it from the group */
3586 pdb_init_sam(&sam_pass);
3587 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3588 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3589 pdb_free_sam(&sam_pass);
3590 return NT_STATUS_NO_SUCH_USER;
3593 /* if the user is not in the group */
3594 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3595 pdb_free_sam(&sam_pass);
3596 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3599 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3601 /* check if the user has been removed then ... */
3602 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3603 pdb_free_sam(&sam_pass);
3604 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3607 pdb_free_sam(&sam_pass);
3608 return NT_STATUS_OK;
3612 /****************************************************************************
3613 Delete a UNIX user on demand.
3614 ****************************************************************************/
3616 static int smb_delete_user(const char *unix_user)
3621 /* try winbindd first since it is impossible to determine where
3622 a user came from via NSS. Try the delete user script if this fails
3623 meaning the user did not exist in winbindd's list of accounts */
3625 if ( winbind_delete_user( unix_user ) ) {
3626 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3631 /* fall back to 'delete user script' */
3633 pstrcpy(del_script, lp_deluser_script());
3636 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3637 ret = smbrun(del_script,NULL);
3638 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3643 /*********************************************************************
3644 _samr_delete_dom_user
3645 *********************************************************************/
3647 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3650 SAM_ACCOUNT *sam_pass=NULL;
3653 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3655 /* Find the policy handle. Open a policy on it. */
3656 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3657 return NT_STATUS_INVALID_HANDLE;
3659 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3663 if (!sid_check_is_in_our_domain(&user_sid))
3664 return NT_STATUS_CANNOT_DELETE;
3666 /* check if the user exists before trying to delete */
3667 pdb_init_sam(&sam_pass);
3668 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3669 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3670 sid_string_static(&user_sid)));
3671 pdb_free_sam(&sam_pass);
3672 return NT_STATUS_NO_SUCH_USER;
3675 /* delete the unix side */
3677 * note: we don't check if the delete really happened
3678 * as the script is not necessary present
3679 * and maybe the sysadmin doesn't want to delete the unix side
3681 smb_delete_user(pdb_get_username(sam_pass));
3683 /* and delete the samba side */
3684 if (!pdb_delete_sam_account(sam_pass)) {
3685 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3686 pdb_free_sam(&sam_pass);
3687 return NT_STATUS_CANNOT_DELETE;
3690 pdb_free_sam(&sam_pass);
3692 if (!close_policy_hnd(p, &q_u->user_pol))
3693 return NT_STATUS_OBJECT_NAME_INVALID;
3695 return NT_STATUS_OK;
3698 /*********************************************************************
3699 _samr_delete_dom_group
3700 *********************************************************************/
3702 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3707 fstring group_sid_str;
3713 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3715 /* Find the policy handle. Open a policy on it. */
3716 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3717 return NT_STATUS_INVALID_HANDLE;
3719 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3723 sid_copy(&dom_sid, &group_sid);
3724 sid_to_string(group_sid_str, &dom_sid);
3725 sid_split_rid(&dom_sid, &group_rid);
3727 DEBUG(10, ("sid is %s\n", group_sid_str));
3729 /* we check if it's our SID before deleting */
3730 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3731 return NT_STATUS_NO_SUCH_GROUP;
3733 DEBUG(10, ("lookup on Domain SID\n"));
3735 if(!get_domain_group_from_sid(group_sid, &map))
3736 return NT_STATUS_NO_SUCH_GROUP;
3740 /* check if group really exists */
3741 if ( (grp=getgrgid(gid)) == NULL)
3742 return NT_STATUS_NO_SUCH_GROUP;
3744 /* delete mapping first */
3745 if(!pdb_delete_group_mapping_entry(group_sid))
3746 return NT_STATUS_ACCESS_DENIED;
3748 /* we can delete the UNIX group */
3749 smb_delete_group(grp->gr_name);
3751 /* check if the group has been successfully deleted */
3752 if ( (grp=getgrgid(gid)) != NULL)
3753 return NT_STATUS_ACCESS_DENIED;
3756 if (!close_policy_hnd(p, &q_u->group_pol))
3757 return NT_STATUS_OBJECT_NAME_INVALID;
3759 return NT_STATUS_OK;
3762 /*********************************************************************
3763 _samr_delete_dom_alias
3764 *********************************************************************/
3766 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3771 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3773 /* Find the policy handle. Open a policy on it. */
3774 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3775 return NT_STATUS_INVALID_HANDLE;
3777 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3781 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3783 if (!sid_check_is_in_our_domain(&alias_sid))
3784 return NT_STATUS_NO_SUCH_ALIAS;
3786 DEBUG(10, ("lookup on Local SID\n"));
3788 /* Have passdb delete the alias */
3789 if (!pdb_delete_alias(&alias_sid))
3790 return NT_STATUS_ACCESS_DENIED;
3792 if (!close_policy_hnd(p, &q_u->alias_pol))
3793 return NT_STATUS_OBJECT_NAME_INVALID;
3795 return NT_STATUS_OK;
3798 /*********************************************************************
3799 _samr_create_dom_group
3800 *********************************************************************/
3802 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3809 struct samr_info *info;
3813 /* Find the policy handle. Open a policy on it. */
3814 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3815 return NT_STATUS_INVALID_HANDLE;
3817 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3821 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3822 return NT_STATUS_ACCESS_DENIED;
3824 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3826 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3828 /* check if group already exist */
3829 if ((grp=getgrnam(name)) != NULL)
3830 return NT_STATUS_GROUP_EXISTS;
3832 /* we can create the UNIX group */
3833 if (smb_create_group(name, &gid) != 0)
3834 return NT_STATUS_ACCESS_DENIED;
3836 /* check if the group has been successfully created */
3837 if ((grp=getgrgid(gid)) == NULL)
3838 return NT_STATUS_ACCESS_DENIED;
3840 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3842 /* add the group to the mapping table */
3843 sid_copy(&info_sid, get_global_sam_sid());
3844 sid_append_rid(&info_sid, r_u->rid);
3845 sid_to_string(sid_string, &info_sid);
3847 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3848 return NT_STATUS_ACCESS_DENIED;
3850 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3851 return NT_STATUS_NO_MEMORY;
3853 /* get a (unique) handle. open a policy on it. */
3854 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3855 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3857 return NT_STATUS_OK;
3860 /*********************************************************************
3861 _samr_create_dom_alias
3862 *********************************************************************/
3864 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3870 struct samr_info *info;
3875 /* Find the policy handle. Open a policy on it. */
3876 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3877 return NT_STATUS_INVALID_HANDLE;
3879 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3883 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3884 return NT_STATUS_ACCESS_DENIED;
3886 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3888 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3890 /* Have passdb create the alias */
3891 result = pdb_create_alias(name, &r_u->rid);
3893 if (!NT_STATUS_IS_OK(result))
3896 sid_copy(&info_sid, get_global_sam_sid());
3897 sid_append_rid(&info_sid, r_u->rid);
3899 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
3900 return NT_STATUS_ACCESS_DENIED;
3902 /* check if the group has been successfully created */
3903 if ((grp=getgrgid(gid)) == NULL)
3904 return NT_STATUS_ACCESS_DENIED;
3906 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3907 return NT_STATUS_NO_MEMORY;
3909 /* get a (unique) handle. open a policy on it. */
3910 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3911 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3913 return NT_STATUS_OK;
3916 /*********************************************************************
3917 _samr_query_groupinfo
3919 sends the name/comment pair of a domain group
3920 level 1 send also the number of users of that group
3921 *********************************************************************/
3923 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3930 GROUP_INFO_CTR *ctr;
3934 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3935 return NT_STATUS_INVALID_HANDLE;
3937 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
3942 ret = get_domain_group_from_sid(group_sid, &map);
3945 return NT_STATUS_INVALID_HANDLE;
3947 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
3949 return NT_STATUS_NO_MEMORY;
3951 switch (q_u->switch_level) {
3953 ctr->switch_value1 = 1;
3954 if(!get_memberuids(map.gid, &uids, &num))
3955 return NT_STATUS_NO_SUCH_GROUP;
3957 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
3961 ctr->switch_value1 = 3;
3962 init_samr_group_info3(&ctr->group.info3);
3965 ctr->switch_value1 = 4;
3966 init_samr_group_info4(&ctr->group.info4, map.comment);
3969 return NT_STATUS_INVALID_INFO_CLASS;
3972 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
3974 return NT_STATUS_OK;
3977 /*********************************************************************
3980 update a domain group's comment.
3981 *********************************************************************/
3983 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
3987 GROUP_INFO_CTR *ctr;
3990 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3991 return NT_STATUS_INVALID_HANDLE;
3993 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
3997 if (!get_domain_group_from_sid(group_sid, &map))
3998 return NT_STATUS_NO_SUCH_GROUP;
4002 switch (ctr->switch_value1) {
4004 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4007 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4010 return NT_STATUS_INVALID_INFO_CLASS;
4013 if(!pdb_update_group_mapping_entry(&map)) {
4014 return NT_STATUS_NO_SUCH_GROUP;
4017 return NT_STATUS_OK;
4020 /*********************************************************************
4023 update an alias's comment.
4024 *********************************************************************/
4026 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4029 struct acct_info info;
4030 ALIAS_INFO_CTR *ctr;
4033 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4034 return NT_STATUS_INVALID_HANDLE;
4036 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4042 switch (ctr->switch_value1) {
4044 unistr2_to_ascii(info.acct_desc,
4045 &(ctr->alias.info3.uni_acct_desc),
4046 sizeof(info.acct_desc)-1);
4049 return NT_STATUS_INVALID_INFO_CLASS;
4052 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4053 return NT_STATUS_ACCESS_DENIED;
4056 return NT_STATUS_OK;
4059 /*********************************************************************
4060 _samr_get_dom_pwinfo
4061 *********************************************************************/
4063 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4065 /* Perform access check. Since this rpc does not require a
4066 policy handle it will not be caught by the access checks on
4067 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4069 if (!pipe_access_check(p)) {
4070 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4071 r_u->status = NT_STATUS_ACCESS_DENIED;
4075 /* Actually, returning zeros here works quite well :-). */
4077 return NT_STATUS_OK;
4080 /*********************************************************************
4082 *********************************************************************/
4084 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4089 struct samr_info *info;
4090 SEC_DESC *psd = NULL;
4092 uint32 des_access = q_u->access_mask;
4098 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4099 return NT_STATUS_INVALID_HANDLE;
4101 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4105 /*check if access can be granted as requested by client. */
4106 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4107 se_map_generic(&des_access,&grp_generic_mapping);
4108 if (!NT_STATUS_IS_OK(status =
4109 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4110 des_access, &acc_granted, "_samr_open_group"))) {
4115 /* this should not be hard-coded like this */
4116 if (!sid_equal(&sid, get_global_sam_sid()))
4117 return NT_STATUS_ACCESS_DENIED;
4119 sid_copy(&info_sid, get_global_sam_sid());
4120 sid_append_rid(&info_sid, q_u->rid_group);
4121 sid_to_string(sid_string, &info_sid);
4123 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4124 return NT_STATUS_NO_MEMORY;
4126 info->acc_granted = acc_granted;
4128 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4130 /* check if that group really exists */
4132 ret = get_domain_group_from_sid(info->sid, &map);
4135 return NT_STATUS_NO_SUCH_GROUP;
4137 /* get a (unique) handle. open a policy on it. */
4138 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4139 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4141 return NT_STATUS_OK;
4144 /*********************************************************************
4145 _samr_remove_sid_foreign_domain
4146 *********************************************************************/
4148 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4149 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4150 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4152 DOM_SID delete_sid, alias_sid;
4153 SAM_ACCOUNT *sam_pass=NULL;
4156 BOOL is_user = False;
4158 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4160 sid_copy( &delete_sid, &q_u->sid.sid );
4162 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4163 sid_string_static(&delete_sid)));
4165 /* Find the policy handle. Open a policy on it. */
4167 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4168 return NT_STATUS_INVALID_HANDLE;
4170 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4171 "_samr_remove_sid_foreign_domain");
4173 if (!NT_STATUS_IS_OK(result))
4176 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4177 sid_string_static(&alias_sid)));
4179 /* make sure we can handle this */
4181 if ( sid_check_is_domain(&alias_sid) )
4182 type = SID_NAME_DOM_GRP;
4183 else if ( sid_check_is_builtin(&alias_sid) )
4184 type = SID_NAME_ALIAS;
4186 if ( type == SID_NAME_UNKNOWN ) {
4187 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4188 return NT_STATUS_OK;
4191 /* check if the user exists before trying to delete */
4193 pdb_init_sam(&sam_pass);
4195 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4198 /* maybe it is a group */
4199 if( !pdb_getgrsid(&map, delete_sid) ) {
4200 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4201 sid_string_static(&delete_sid)));
4202 result = NT_STATUS_INVALID_SID;
4207 /* we can only delete a user from a group since we don't have
4208 nested groups anyways. So in the latter case, just say OK */
4211 GROUP_MAP *mappings = NULL;
4215 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4217 /* interate over the groups */
4218 for ( i=0; i<num_groups; i++ ) {
4220 grp2 = getgrgid(mappings[i].gid);
4223 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4227 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4230 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4232 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4233 /* should we fail here ? */
4234 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4235 pdb_get_username(sam_pass), grp2->gr_name ));
4239 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4240 pdb_get_username(sam_pass), grp2->gr_name ));
4243 SAFE_FREE(mappings);
4247 result = NT_STATUS_OK;
4250 pdb_free_sam(&sam_pass);
4255 /*******************************************************************
4257 ********************************************************************/
4259 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4261 struct samr_info *info = NULL;
4263 uint32 min_pass_len,pass_hist,flag;
4264 time_t u_expire, u_min_age;
4265 NTTIME nt_expire, nt_min_age;
4267 time_t u_lock_duration, u_reset_time;
4268 NTTIME nt_lock_duration, nt_reset_time;
4274 uint32 num_users=0, num_groups=0, num_aliases=0;
4276 uint32 account_policy_temp;
4278 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4279 return NT_STATUS_NO_MEMORY;
4283 r_u->status = NT_STATUS_OK;
4285 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4287 /* find the policy handle. open a policy on it. */
4288 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4289 return NT_STATUS_INVALID_HANDLE;
4291 switch (q_u->switch_value) {
4293 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4294 min_pass_len = account_policy_temp;
4296 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4297 pass_hist = account_policy_temp;
4299 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4300 flag = account_policy_temp;
4302 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4303 u_expire = account_policy_temp;
4305 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4306 u_min_age = account_policy_temp;
4308 unix_to_nt_time_abs(&nt_expire, u_expire);
4309 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4311 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4312 flag, nt_expire, nt_min_age);
4316 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4318 if (!NT_STATUS_IS_OK(r_u->status)) {
4319 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4322 num_users=info->disp_info.num_user_account;
4325 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4326 if (NT_STATUS_IS_ERR(r_u->status)) {
4327 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4330 num_groups=info->disp_info.num_group_account;
4333 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4334 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4335 num_users, num_groups, num_aliases);
4338 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4339 u_logout = account_policy_temp;
4341 unix_to_nt_time_abs(&nt_logout, u_logout);
4343 init_unk_info3(&ctr->info.inf3, nt_logout);
4346 init_unk_info5(&ctr->info.inf5, global_myname());
4349 init_unk_info6(&ctr->info.inf6);
4352 init_unk_info7(&ctr->info.inf7);
4355 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4356 u_lock_duration = account_policy_temp * 60;
4358 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4359 u_reset_time = account_policy_temp * 60;
4361 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4362 lockout = account_policy_temp;
4364 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4365 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4367 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4370 return NT_STATUS_INVALID_INFO_CLASS;
4373 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4375 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4380 /*******************************************************************
4382 ********************************************************************/
4384 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4386 time_t u_expire, u_min_age;
4388 time_t u_lock_duration, u_reset_time;
4390 r_u->status = NT_STATUS_OK;
4392 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4394 /* find the policy handle. open a policy on it. */
4395 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4396 return NT_STATUS_INVALID_HANDLE;
4398 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4400 switch (q_u->switch_value) {
4402 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4403 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4405 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4406 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4407 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4408 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4409 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4414 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4415 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4424 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
4425 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4427 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4428 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4429 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4432 return NT_STATUS_INVALID_INFO_CLASS;
4435 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4437 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));