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);
733 * usrmgr expects a non-NULL terminated string with
734 * trust relationships
736 if (pdb_get_acct_ctrl(pwd) & ACB_DOMTRUST) {
737 init_unistr2(&uni_temp_name, temp_name, UNI_FLAGS_NONE);
739 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
742 user_sid = pdb_get_user_sid(pwd);
744 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
745 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
746 "the domain sid %s. Failing operation.\n",
748 sid_to_string(user_sid_string, user_sid),
749 sid_to_string(domain_sid_string, domain_sid)));
750 return NT_STATUS_UNSUCCESSFUL;
753 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
754 copy_unistr2(&uni_name[i], &uni_temp_name);
758 *uni_name_pp = uni_name;
762 /*******************************************************************
763 samr_reply_enum_dom_users
764 ********************************************************************/
766 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
767 SAMR_R_ENUM_DOM_USERS *r_u)
769 struct samr_info *info = NULL;
770 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
772 uint32 enum_context=q_u->start_idx;
773 uint32 max_size=q_u->max_size;
775 enum remote_arch_types ra_type = get_remote_arch();
776 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
777 uint32 max_entries = max_sam_entries;
780 r_u->status = NT_STATUS_OK;
782 /* find the policy handle. open a policy on it. */
783 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
784 return NT_STATUS_INVALID_HANDLE;
786 domain_sid = info->sid;
788 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
789 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
790 "_samr_enum_dom_users"))) {
794 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
797 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
800 if (!NT_STATUS_IS_OK(r_u->status))
803 num_account = info->disp_info.num_user_account;
805 if (enum_context > num_account) {
806 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
810 /* verify we won't overflow */
811 if (max_entries > num_account-enum_context) {
812 max_entries = num_account-enum_context;
813 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
816 /* calculate the size and limit on the number of entries we will return */
817 temp_size=max_entries*struct_size;
819 if (temp_size>max_size) {
820 max_entries=MIN((max_size/struct_size),max_entries);;
821 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
825 * Note from JRA. total_entries is not being used here. Currently if there is a
826 * large user base then it looks like NT will enumerate until get_sampwd_entries
827 * returns False due to num_entries being zero. This will cause an access denied
828 * return. I don't think this is right and needs further investigation. Note that
829 * this is also the same in the TNG code (I don't think that has been tested with
830 * a very large user list as MAX_SAM_ENTRIES is set to 600).
832 * I also think that one of the 'num_entries' return parameters is probably
833 * the "max entries" parameter - but in the TNG code they're all currently set to the same
834 * value (again I think this is wrong).
837 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
838 max_entries, enum_context,
839 info->disp_info.disp_user_info,
842 if (!NT_STATUS_IS_OK(r_u->status))
845 if (enum_context+max_entries < num_account)
846 r_u->status = STATUS_MORE_ENTRIES;
848 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
850 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
852 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
857 /*******************************************************************
858 makes a SAM_ENTRY / UNISTR2* structure from a group list.
859 ********************************************************************/
861 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
862 uint32 num_sam_entries, DOMAIN_GRP *grp)
871 if (num_sam_entries == 0)
874 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
876 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
878 if (sam == NULL || uni_name == NULL) {
879 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
883 for (i = 0; i < num_sam_entries; i++) {
885 * JRA. I think this should include the null. TNG does not.
887 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
888 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
892 *uni_name_pp = uni_name;
895 /*******************************************************************
896 Get the group entries - similar to get_sampwd_entries().
897 ******************************************************************/
899 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
900 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
901 uint32 *p_num_entries, uint32 max_entries )
905 uint32 group_entries = 0;
906 uint32 num_entries = 0;
910 /* access checks for the users were performed higher up. become/unbecome_root()
911 needed for some passdb backends to enumerate groups */
914 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
918 num_entries=group_entries-start_idx;
920 /* limit the number of entries */
921 if (num_entries>max_entries) {
922 DEBUG(5,("Limiting to %d entries\n", max_entries));
923 num_entries=max_entries;
926 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
927 if (num_entries!=0 && *d_grp==NULL){
929 return NT_STATUS_NO_MEMORY;
932 for (i=0; i<num_entries; i++) {
933 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
934 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
935 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
936 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
941 *p_num_entries = num_entries;
943 DEBUG(10,("get_group_domain_entries: returning %d entries\n",
949 /*******************************************************************
950 Wrapper for enumerating local groups
951 ******************************************************************/
953 static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
954 const DOM_SID *sid, uint32 start_idx,
955 uint32 *p_num_entries, uint32 max_entries )
957 struct acct_info *info;
962 res = pdb_enum_aliases(sid, start_idx, max_entries,
963 p_num_entries, &info);
967 return NT_STATUS_ACCESS_DENIED;
969 if (*p_num_entries == 0)
972 *d_grp = talloc(ctx, sizeof(DOMAIN_GRP) * (*p_num_entries));
974 if (*d_grp == NULL) {
976 return NT_STATUS_NO_MEMORY;
979 for (i=0; i<*p_num_entries; i++) {
980 fstrcpy((*d_grp)[i].name, info[i].acct_name);
981 fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
982 (*d_grp)[i].rid = info[i].rid;
983 (*d_grp)[i].attr = SID_NAME_ALIAS;
990 /*******************************************************************
991 samr_reply_enum_dom_groups
992 ********************************************************************/
994 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
996 DOMAIN_GRP *grp=NULL;
1001 r_u->status = NT_STATUS_OK;
1003 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1004 return NT_STATUS_INVALID_HANDLE;
1006 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1010 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1012 /* the domain group array is being allocated in the function below */
1013 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))) {
1017 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1019 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1021 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1027 /*******************************************************************
1028 samr_reply_enum_dom_aliases
1029 ********************************************************************/
1031 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1033 DOMAIN_GRP *grp=NULL;
1034 uint32 num_entries = 0;
1040 r_u->status = NT_STATUS_OK;
1042 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1043 return NT_STATUS_INVALID_HANDLE;
1045 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1049 sid_to_string(sid_str, &sid);
1050 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1052 status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1053 &num_entries, MAX_SAM_ENTRIES);
1054 if (!NT_STATUS_IS_OK(status)) return status;
1056 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1060 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1062 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1067 /*******************************************************************
1068 samr_reply_query_dispinfo
1069 ********************************************************************/
1071 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1072 SAMR_R_QUERY_DISPINFO *r_u)
1074 struct samr_info *info = NULL;
1075 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1077 uint32 max_entries=q_u->max_entries;
1078 uint32 enum_context=q_u->start_idx;
1079 uint32 max_size=q_u->max_size;
1081 SAM_DISPINFO_CTR *ctr;
1082 uint32 temp_size=0, total_data_size=0;
1084 uint32 num_account = 0;
1085 enum remote_arch_types ra_type = get_remote_arch();
1086 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1089 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1090 r_u->status = NT_STATUS_OK;
1092 /* find the policy handle. open a policy on it. */
1093 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1094 return NT_STATUS_INVALID_HANDLE;
1096 domain_sid = info->sid;
1099 * calculate how many entries we will return.
1101 * - the number of entries the client asked
1102 * - our limit on that
1103 * - the starting point (enumeration context)
1104 * - the buffer size the client will accept
1108 * We are a lot more like W2K. Instead of reading the SAM
1109 * each time to find the records we need to send back,
1110 * we read it once and link that copy to the sam handle.
1111 * For large user list (over the MAX_SAM_ENTRIES)
1112 * it's a definitive win.
1113 * second point to notice: between enumerations
1114 * our sam is now the same as it's a snapshoot.
1115 * third point: got rid of the static SAM_USER_21 struct
1116 * no more intermediate.
1117 * con: it uses much more memory, as a full copy is stored
1120 * If you want to change it, think twice and think
1121 * of the second point , that's really important.
1126 /* Get what we need from the password database */
1127 switch (q_u->switch_level) {
1129 /* When playing with usrmgr, this is necessary
1130 if you want immediate refresh after editing
1131 a user. I would like to do this after the
1132 setuserinfo2, but we do not have access to
1133 the domain handle in that call, only to the
1134 user handle. Where else does this hurt?
1138 /* We cannot do this here - it kills performace. JRA. */
1139 free_samr_users(info);
1144 /* Level 2 is for all machines, otherwise only 'normal' users */
1145 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1147 if (!NT_STATUS_IS_OK(r_u->status)) {
1148 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1151 num_account = info->disp_info.num_user_account;
1155 r_u->status = load_group_domain_entries(info, &info->sid);
1156 if (!NT_STATUS_IS_OK(r_u->status))
1158 num_account = info->disp_info.num_group_account;
1161 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1162 return NT_STATUS_INVALID_INFO_CLASS;
1165 /* first limit the number of entries we will return */
1166 if(max_entries > max_sam_entries) {
1167 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1168 max_entries = max_sam_entries;
1171 if (enum_context > num_account) {
1172 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1173 return NT_STATUS_NO_MORE_ENTRIES;
1176 /* verify we won't overflow */
1177 if (max_entries > num_account-enum_context) {
1178 max_entries = num_account-enum_context;
1179 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1182 /* calculate the size and limit on the number of entries we will return */
1183 temp_size=max_entries*struct_size;
1185 if (temp_size>max_size) {
1186 max_entries=MIN((max_size/struct_size),max_entries);;
1187 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1190 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1191 return NT_STATUS_NO_MEMORY;
1195 /* Now create reply structure */
1196 switch (q_u->switch_level) {
1199 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1200 return NT_STATUS_NO_MEMORY;
1202 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, 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.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1210 return NT_STATUS_NO_MEMORY;
1212 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1213 info->disp_info.disp_user_info, &domain_sid);
1214 if (!NT_STATUS_IS_OK(disp_ret))
1219 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1220 return NT_STATUS_NO_MEMORY;
1222 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1223 if (!NT_STATUS_IS_OK(disp_ret))
1228 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1229 return NT_STATUS_NO_MEMORY;
1231 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1232 if (!NT_STATUS_IS_OK(disp_ret))
1237 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1238 return NT_STATUS_NO_MEMORY;
1240 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1241 if (!NT_STATUS_IS_OK(disp_ret))
1246 ctr->sam.info = NULL;
1247 return NT_STATUS_INVALID_INFO_CLASS;
1250 /* calculate the total size */
1251 total_data_size=num_account*struct_size;
1253 if (enum_context+max_entries < num_account)
1254 r_u->status = STATUS_MORE_ENTRIES;
1256 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1258 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1264 /*******************************************************************
1265 samr_reply_query_aliasinfo
1266 ********************************************************************/
1268 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1271 struct acct_info info;
1275 r_u->status = NT_STATUS_OK;
1277 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1279 /* find the policy handle. open a policy on it. */
1280 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1281 return NT_STATUS_INVALID_HANDLE;
1282 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1287 ret = pdb_get_aliasinfo(&sid, &info);
1291 return NT_STATUS_NO_SUCH_ALIAS;
1293 switch (q_u->switch_level) {
1296 r_u->ctr.switch_value1 = 1;
1297 init_samr_alias_info1(&r_u->ctr.alias.info1,
1298 info.acct_name, 1, info.acct_desc);
1302 r_u->ctr.switch_value1 = 3;
1303 init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1306 return NT_STATUS_INVALID_INFO_CLASS;
1309 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1315 /*******************************************************************
1316 samr_reply_lookup_ids
1317 ********************************************************************/
1319 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1321 uint32 rid[MAX_SAM_ENTRIES];
1322 int num_rids = q_u->num_sids1;
1324 r_u->status = NT_STATUS_OK;
1326 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1328 if (num_rids > MAX_SAM_ENTRIES) {
1329 num_rids = MAX_SAM_ENTRIES;
1330 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1335 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1337 for (i = 0; i < num_rids && status == 0; i++)
1339 struct sam_passwd *sam_pass;
1343 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1344 q_u->uni_user_name[i].uni_str_len));
1346 /* find the user account */
1348 sam_pass = get_smb21pwd_entry(user_name, 0);
1351 if (sam_pass == NULL)
1353 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1358 rid[i] = sam_pass->user_rid;
1364 rid[0] = BUILTIN_ALIAS_RID_USERS;
1366 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1368 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1374 /*******************************************************************
1376 ********************************************************************/
1378 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1380 uint32 rid[MAX_SAM_ENTRIES];
1382 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1383 enum SID_NAME_USE local_type;
1385 int num_rids = q_u->num_names2;
1390 r_u->status = NT_STATUS_OK;
1392 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1397 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1398 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1402 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 */
1406 if (num_rids > MAX_SAM_ENTRIES) {
1407 num_rids = MAX_SAM_ENTRIES;
1408 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1411 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1413 for (i = 0; i < num_rids; i++) {
1418 r_u->status = NT_STATUS_NONE_MAPPED;
1420 rid [i] = 0xffffffff;
1421 type[i] = SID_NAME_UNKNOWN;
1423 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1426 * we are only looking for a name
1427 * the SID we get back can be outside
1428 * the scope of the pol_sid
1430 * in clear: it prevents to reply to domain\group: yes
1431 * when only builtin\group exists.
1433 * a cleaner code is to add the sid of the domain we're looking in
1434 * to the local_lookup_name function.
1437 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1438 sid_split_rid(&sid, &local_rid);
1440 if (sid_equal(&sid, &pol_sid)) {
1443 /* Windows does not return WKN_GRP here, even
1444 * on lookups in builtin */
1445 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1446 SID_NAME_ALIAS : local_type;
1448 r_u->status = NT_STATUS_OK;
1453 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1455 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1460 /*******************************************************************
1461 _samr_chgpasswd_user
1462 ********************************************************************/
1464 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1469 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1471 r_u->status = NT_STATUS_OK;
1473 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1474 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1476 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1479 * Pass the user through the NT -> unix user mapping
1483 (void)map_username(user_name);
1486 * UNIX username case mangling not required, pass_oem_change
1487 * is case insensitive.
1490 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1491 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1493 init_samr_r_chgpasswd_user(r_u, r_u->status);
1495 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1500 /*******************************************************************
1501 makes a SAMR_R_LOOKUP_RIDS structure.
1502 ********************************************************************/
1504 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1505 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1508 UNIHDR *hdr_name=NULL;
1509 UNISTR2 *uni_name=NULL;
1511 *pp_uni_name = NULL;
1512 *pp_hdr_name = NULL;
1514 if (num_names != 0) {
1515 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1516 if (hdr_name == NULL)
1519 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1520 if (uni_name == NULL)
1524 for (i = 0; i < num_names; i++) {
1525 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1526 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1527 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1530 *pp_uni_name = uni_name;
1531 *pp_hdr_name = hdr_name;
1536 /*******************************************************************
1538 ********************************************************************/
1540 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1542 fstring group_names[MAX_SAM_ENTRIES];
1543 uint32 *group_attrs = NULL;
1544 UNIHDR *hdr_name = NULL;
1545 UNISTR2 *uni_name = NULL;
1547 int num_rids = q_u->num_rids1;
1551 r_u->status = NT_STATUS_OK;
1553 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1555 /* find the policy handle. open a policy on it. */
1556 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1557 return NT_STATUS_INVALID_HANDLE;
1559 if (num_rids > MAX_SAM_ENTRIES) {
1560 num_rids = MAX_SAM_ENTRIES;
1561 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1565 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1566 return NT_STATUS_NO_MEMORY;
1569 r_u->status = NT_STATUS_NONE_MAPPED;
1571 become_root(); /* lookup_sid can require root privs */
1573 for (i = 0; i < num_rids; i++) {
1577 enum SID_NAME_USE type;
1579 group_attrs[i] = SID_NAME_UNKNOWN;
1580 *group_names[i] = '\0';
1582 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1583 sid_copy(&sid, &pol_sid);
1584 sid_append_rid(&sid, q_u->rid[i]);
1586 if (lookup_sid(&sid, domname, tmpname, &type)) {
1587 r_u->status = NT_STATUS_OK;
1588 group_attrs[i] = (uint32)type;
1589 fstrcpy(group_names[i],tmpname);
1590 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1597 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1598 return NT_STATUS_NO_MEMORY;
1600 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1602 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1607 /*******************************************************************
1608 _samr_open_user. Safe - gives out no passwd info.
1609 ********************************************************************/
1611 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1613 SAM_ACCOUNT *sampass=NULL;
1615 POLICY_HND domain_pol = q_u->domain_pol;
1616 POLICY_HND *user_pol = &r_u->user_pol;
1617 struct samr_info *info = NULL;
1618 SEC_DESC *psd = NULL;
1620 uint32 des_access = q_u->access_mask;
1625 r_u->status = NT_STATUS_OK;
1627 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1628 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1629 return NT_STATUS_INVALID_HANDLE;
1631 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1635 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1636 if (!NT_STATUS_IS_OK(nt_status)) {
1640 /* append the user's RID to it */
1641 if (!sid_append_rid(&sid, q_u->user_rid))
1642 return NT_STATUS_NO_SUCH_USER;
1644 /* check if access can be granted as requested by client. */
1645 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1646 se_map_generic(&des_access, &usr_generic_mapping);
1647 if (!NT_STATUS_IS_OK(nt_status =
1648 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1649 des_access, &acc_granted, "_samr_open_user"))) {
1654 ret=pdb_getsampwsid(sampass, &sid);
1657 /* check that the SID exists in our domain. */
1659 return NT_STATUS_NO_SUCH_USER;
1662 pdb_free_sam(&sampass);
1664 /* associate the user's SID and access bits with the new handle. */
1665 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1666 return NT_STATUS_NO_MEMORY;
1667 info->acc_granted = acc_granted;
1669 /* get a (unique) handle. open a policy on it. */
1670 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1671 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1676 /*************************************************************************
1677 get_user_info_10. Safe. Only gives out acb bits.
1678 *************************************************************************/
1680 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1682 SAM_ACCOUNT *smbpass=NULL;
1686 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1688 if (!NT_STATUS_IS_OK(nt_status)) {
1693 ret = pdb_getsampwsid(smbpass, user_sid);
1697 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1698 return NT_STATUS_NO_SUCH_USER;
1701 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1704 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1706 pdb_free_sam(&smbpass);
1708 return NT_STATUS_OK;
1711 /*************************************************************************
1712 get_user_info_12. OK - this is the killer as it gives out password info.
1713 Ensure that this is only allowed on an encrypted connection with a root
1715 *************************************************************************/
1717 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1719 SAM_ACCOUNT *smbpass=NULL;
1723 if (!p->ntlmssp_auth_validated)
1724 return NT_STATUS_ACCESS_DENIED;
1726 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1727 return NT_STATUS_ACCESS_DENIED;
1730 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1733 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1735 if (!NT_STATUS_IS_OK(nt_status)) {
1739 ret = pdb_getsampwsid(smbpass, user_sid);
1742 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1743 pdb_free_sam(&smbpass);
1744 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1747 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1749 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1750 pdb_free_sam(&smbpass);
1751 return NT_STATUS_ACCOUNT_DISABLED;
1755 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1757 pdb_free_sam(&smbpass);
1759 return NT_STATUS_OK;
1762 /*************************************************************************
1764 *************************************************************************/
1766 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1768 SAM_ACCOUNT *sampass=NULL;
1771 pdb_init_sam_talloc(mem_ctx, &sampass);
1774 ret = pdb_getsampwsid(sampass, user_sid);
1778 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1779 return NT_STATUS_NO_SUCH_USER;
1782 samr_clear_sam_passwd(sampass);
1784 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1787 init_sam_user_info20A(id20, sampass);
1789 pdb_free_sam(&sampass);
1791 return NT_STATUS_OK;
1794 /*************************************************************************
1796 *************************************************************************/
1798 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1799 DOM_SID *user_sid, DOM_SID *domain_sid)
1801 SAM_ACCOUNT *sampass=NULL;
1805 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1806 if (!NT_STATUS_IS_OK(nt_status)) {
1811 ret = pdb_getsampwsid(sampass, user_sid);
1815 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1816 return NT_STATUS_NO_SUCH_USER;
1819 samr_clear_sam_passwd(sampass);
1821 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1824 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1826 pdb_free_sam(&sampass);
1828 return NT_STATUS_OK;
1831 /*******************************************************************
1832 _samr_query_userinfo
1833 ********************************************************************/
1835 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1837 SAM_USERINFO_CTR *ctr;
1838 struct samr_info *info = NULL;
1842 r_u->status=NT_STATUS_OK;
1844 /* search for the handle */
1845 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1846 return NT_STATUS_INVALID_HANDLE;
1848 domain_sid = info->sid;
1850 sid_split_rid(&domain_sid, &rid);
1852 if (!sid_check_is_in_our_domain(&info->sid))
1853 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1855 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1857 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1859 return NT_STATUS_NO_MEMORY;
1863 /* ok! user info levels (lots: see MSDEV help), off we go... */
1864 ctr->switch_value = q_u->switch_value;
1866 switch (q_u->switch_value) {
1868 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1869 if (ctr->info.id10 == NULL)
1870 return NT_STATUS_NO_MEMORY;
1872 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1877 /* whoops - got this wrong. i think. or don't understand what's happening. */
1881 info = (void *)&id11;
1883 expire.low = 0xffffffff;
1884 expire.high = 0x7fffffff;
1886 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1891 ZERO_STRUCTP(ctr->info.id11);
1892 init_sam_user_info11(ctr->info.id11, &expire,
1893 "BROOKFIELDS$", /* name */
1894 0x03ef, /* user rid */
1895 0x201, /* group rid */
1896 0x0080); /* acb info */
1903 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1904 if (ctr->info.id12 == NULL)
1905 return NT_STATUS_NO_MEMORY;
1907 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1912 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1913 if (ctr->info.id20 == NULL)
1914 return NT_STATUS_NO_MEMORY;
1915 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1920 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1921 if (ctr->info.id21 == NULL)
1922 return NT_STATUS_NO_MEMORY;
1923 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1924 &info->sid, &domain_sid)))
1929 return NT_STATUS_INVALID_INFO_CLASS;
1932 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1934 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1939 /*******************************************************************
1940 samr_reply_query_usergroups
1941 ********************************************************************/
1943 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1945 SAM_ACCOUNT *sam_pass=NULL;
1947 DOM_GID *gids = NULL;
1953 * from the SID in the request:
1954 * we should send back the list of DOMAIN GROUPS
1955 * the user is a member of
1957 * and only the DOMAIN GROUPS
1958 * no ALIASES !!! neither aliases of the domain
1959 * nor aliases of the builtin SID
1964 r_u->status = NT_STATUS_OK;
1966 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1968 /* find the policy handle. open a policy on it. */
1969 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1970 return NT_STATUS_INVALID_HANDLE;
1972 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1976 if (!sid_check_is_in_our_domain(&sid))
1977 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1979 pdb_init_sam(&sam_pass);
1982 ret = pdb_getsampwsid(sam_pass, &sid);
1986 pdb_free_sam(&sam_pass);
1987 return NT_STATUS_NO_SUCH_USER;
1990 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
1991 pdb_free_sam(&sam_pass);
1992 return NT_STATUS_NO_SUCH_GROUP;
1995 /* construct the response. lkclXXXX: gids are not copied! */
1996 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1998 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2000 pdb_free_sam(&sam_pass);
2005 /*******************************************************************
2006 _samr_query_dom_info
2007 ********************************************************************/
2009 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2011 struct samr_info *info = NULL;
2013 uint32 min_pass_len,pass_hist,flag;
2014 time_t u_expire, u_min_age;
2015 NTTIME nt_expire, nt_min_age;
2017 time_t u_lock_duration, u_reset_time;
2018 NTTIME nt_lock_duration, nt_reset_time;
2024 uint32 account_policy_temp;
2026 uint32 num_users=0, num_groups=0, num_aliases=0;
2028 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2029 return NT_STATUS_NO_MEMORY;
2033 r_u->status = NT_STATUS_OK;
2035 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2037 /* find the policy handle. open a policy on it. */
2038 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2039 return NT_STATUS_INVALID_HANDLE;
2041 switch (q_u->switch_value) {
2044 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2045 min_pass_len = account_policy_temp;
2047 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2048 pass_hist = account_policy_temp;
2050 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2051 flag = account_policy_temp;
2053 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2054 u_expire = account_policy_temp;
2056 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2057 u_min_age = account_policy_temp;
2059 unix_to_nt_time_abs(&nt_expire, u_expire);
2060 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2062 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2063 flag, nt_expire, nt_min_age);
2067 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2069 if (!NT_STATUS_IS_OK(r_u->status)) {
2070 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2073 num_users=info->disp_info.num_user_account;
2076 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2077 if (!NT_STATUS_IS_OK(r_u->status)) {
2078 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2081 num_groups=info->disp_info.num_group_account;
2084 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2085 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2086 num_users, num_groups, num_aliases);
2089 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2090 unix_to_nt_time_abs(&nt_logout, u_logout);
2092 init_unk_info3(&ctr->info.inf3, nt_logout);
2095 init_unk_info5(&ctr->info.inf5, global_myname());
2098 init_unk_info6(&ctr->info.inf6);
2101 init_unk_info7(&ctr->info.inf7);
2104 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2105 u_lock_duration = account_policy_temp * 60;
2107 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2108 u_reset_time = account_policy_temp * 60;
2110 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2111 lockout = account_policy_temp;
2113 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2114 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2116 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2119 return NT_STATUS_INVALID_INFO_CLASS;
2122 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2124 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2129 /*******************************************************************
2131 Create an account, can be either a normal user or a machine.
2132 This funcion will need to be updated for bdc/domain trusts.
2133 ********************************************************************/
2135 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2137 SAM_ACCOUNT *sam_pass=NULL;
2141 POLICY_HND dom_pol = q_u->domain_pol;
2142 UNISTR2 user_account = q_u->uni_name;
2143 uint16 acb_info = q_u->acb_info;
2144 POLICY_HND *user_pol = &r_u->user_pol;
2145 struct samr_info *info = NULL;
2153 /* check this, when giving away 'add computer to domain' privs */
2154 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2156 /* Get the domain SID stored in the domain policy */
2157 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2158 return NT_STATUS_INVALID_HANDLE;
2160 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2164 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2165 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2166 this parameter is not an account type */
2167 return NT_STATUS_INVALID_PARAMETER;
2170 /* find the account: tell the caller if it exists.
2171 lkclXXXX i have *no* idea if this is a problem or not
2172 or even if you are supposed to construct a different
2173 reply if the account already exists...
2176 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2177 strlower_m(account);
2179 pdb_init_sam(&sam_pass);
2182 ret = pdb_getsampwnam(sam_pass, account);
2185 /* this account exists: say so */
2186 pdb_free_sam(&sam_pass);
2187 return NT_STATUS_USER_EXISTS;
2190 pdb_free_sam(&sam_pass);
2193 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2194 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2195 * that only people with write access to the smbpasswd file will be able
2196 * to create a user. JRA.
2200 * add the user in the /etc/passwd file or the unix authority system.
2201 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2202 * a) local_password_change() checks for us if the /etc/passwd account really exists
2203 * b) smb_create_user() would return an error if the account already exists
2204 * and as it could return an error also if it can't create the account, it would be tricky.
2206 * So we go the easy way, only check after if the account exists.
2207 * JFM (2/3/2001), to clear any possible bad understanding (-:
2209 * We now have seperate script paramaters for adding users/machines so we
2210 * now have some sainity-checking to match.
2213 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2216 * we used to have code here that made sure the acb_info flags
2217 * matched with the users named (e.g. an account flags as a machine
2218 * trust account ended in '$'). It has been ifdef'd out for a long
2219 * time, so I replaced it with this comment. --jerry
2222 /* the passdb lookup has failed; check to see if we need to run the
2223 add user/machine script */
2225 pw = Get_Pwnam(account);
2227 /*********************************************************************
2228 * HEADS UP! If we have to create a new user account, we have to get
2229 * a new RID from somewhere. This used to be done by the passdb
2230 * backend. It has been moved into idmap now. Since idmap is now
2231 * wrapped up behind winbind, this means you have to run winbindd if you
2232 * want new accounts to get a new RID when "enable rid algorithm = no".
2233 * Tough. We now have a uniform way of allocating RIDs regardless
2234 * of what ever passdb backend people may use.
2235 * --jerry (2003-07-10)
2236 *********************************************************************/
2240 * we can't check both the ending $ and the acb_info.
2242 * UserManager creates trust accounts (ending in $,
2243 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2246 if (account[strlen(account)-1] == '$')
2247 pstrcpy(add_script, lp_addmachine_script());
2249 pstrcpy(add_script, lp_adduser_script());
2253 all_string_sub(add_script, "%u", account, sizeof(add_script));
2254 add_ret = smbrun(add_script,NULL);
2255 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2257 else /* no add user script -- ask winbindd to do it */
2259 if ( !winbind_create_user( account, &new_rid ) ) {
2260 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2267 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2269 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2272 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2274 if (!pdb_add_sam_account(sam_pass)) {
2275 pdb_free_sam(&sam_pass);
2276 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2278 return NT_STATUS_ACCESS_DENIED;
2281 /* Get the user's SID */
2282 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2284 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2285 se_map_generic(&des_access, &usr_generic_mapping);
2286 if (!NT_STATUS_IS_OK(nt_status =
2287 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2288 des_access, &acc_granted, "_samr_create_user"))) {
2292 /* associate the user's SID with the new handle. */
2293 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2294 pdb_free_sam(&sam_pass);
2295 return NT_STATUS_NO_MEMORY;
2300 info->acc_granted = acc_granted;
2302 /* get a (unique) handle. open a policy on it. */
2303 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2304 pdb_free_sam(&sam_pass);
2305 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2308 r_u->user_rid=pdb_get_user_rid(sam_pass);
2310 r_u->access_granted = acc_granted;
2312 pdb_free_sam(&sam_pass);
2314 return NT_STATUS_OK;
2317 /*******************************************************************
2318 samr_reply_connect_anon
2319 ********************************************************************/
2321 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2323 struct samr_info *info = NULL;
2324 uint32 des_access = q_u->access_mask;
2328 if (!pipe_access_check(p)) {
2329 DEBUG(3, ("access denied to samr_connect_anon\n"));
2330 r_u->status = NT_STATUS_ACCESS_DENIED;
2334 /* set up the SAMR connect_anon response */
2336 r_u->status = NT_STATUS_OK;
2338 /* associate the user's SID with the new handle. */
2339 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2340 return NT_STATUS_NO_MEMORY;
2342 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2343 was observed from a win98 client trying to enumerate users (when configured
2344 user level access control on shares) --jerry */
2346 se_map_generic( &des_access, &sam_generic_mapping );
2347 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2349 info->status = q_u->unknown_0;
2351 /* get a (unique) handle. open a policy on it. */
2352 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2353 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2358 /*******************************************************************
2360 ********************************************************************/
2362 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2364 struct samr_info *info = NULL;
2365 SEC_DESC *psd = NULL;
2367 uint32 des_access = q_u->access_mask;
2372 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2376 if (!pipe_access_check(p)) {
2377 DEBUG(3, ("access denied to samr_connect\n"));
2378 r_u->status = NT_STATUS_ACCESS_DENIED;
2382 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2383 se_map_generic(&des_access, &sam_generic_mapping);
2384 if (!NT_STATUS_IS_OK(nt_status =
2385 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2386 des_access, &acc_granted, "_samr_connect"))) {
2390 r_u->status = NT_STATUS_OK;
2392 /* associate the user's SID and access granted with the new handle. */
2393 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2394 return NT_STATUS_NO_MEMORY;
2396 info->acc_granted = acc_granted;
2397 info->status = q_u->access_mask;
2399 /* get a (unique) handle. open a policy on it. */
2400 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2401 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2403 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2408 /*******************************************************************
2410 ********************************************************************/
2412 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2414 struct samr_info *info = NULL;
2415 SEC_DESC *psd = NULL;
2417 uint32 des_access = q_u->access_mask;
2422 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2426 if (!pipe_access_check(p)) {
2427 DEBUG(3, ("access denied to samr_connect4\n"));
2428 r_u->status = NT_STATUS_ACCESS_DENIED;
2432 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2433 se_map_generic(&des_access, &sam_generic_mapping);
2434 if (!NT_STATUS_IS_OK(nt_status =
2435 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2436 des_access, &acc_granted, "_samr_connect"))) {
2440 r_u->status = NT_STATUS_OK;
2442 /* associate the user's SID and access granted with the new handle. */
2443 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2444 return NT_STATUS_NO_MEMORY;
2446 info->acc_granted = acc_granted;
2447 info->status = q_u->access_mask;
2449 /* get a (unique) handle. open a policy on it. */
2450 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2451 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2453 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2458 /**********************************************************************
2459 api_samr_lookup_domain
2460 **********************************************************************/
2462 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2464 struct samr_info *info;
2465 fstring domain_name;
2468 r_u->status = NT_STATUS_OK;
2470 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2471 return NT_STATUS_INVALID_HANDLE;
2473 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2474 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2479 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2483 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2484 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2487 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2489 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2494 /******************************************************************
2495 makes a SAMR_R_ENUM_DOMAINS structure.
2496 ********************************************************************/
2498 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2499 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2505 DEBUG(5, ("make_enum_domains\n"));
2508 *pp_uni_name = NULL;
2510 if (num_sam_entries == 0)
2513 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2514 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2516 if (sam == NULL || uni_name == NULL)
2519 for (i = 0; i < num_sam_entries; i++) {
2520 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2521 init_sam_entry(&sam[i], &uni_name[i], 0);
2525 *pp_uni_name = uni_name;
2530 /**********************************************************************
2531 api_samr_enum_domains
2532 **********************************************************************/
2534 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2536 struct samr_info *info;
2537 uint32 num_entries = 2;
2541 r_u->status = NT_STATUS_OK;
2543 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2544 return NT_STATUS_INVALID_HANDLE;
2546 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2550 name = get_global_sam_name();
2552 fstrcpy(dom[0],name);
2554 fstrcpy(dom[1],"Builtin");
2556 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2557 return NT_STATUS_NO_MEMORY;
2559 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2564 /*******************************************************************
2566 ********************************************************************/
2568 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2571 POLICY_HND domain_pol = q_u->dom_pol;
2572 uint32 alias_rid = q_u->rid_alias;
2573 POLICY_HND *alias_pol = &r_u->pol;
2574 struct samr_info *info = NULL;
2575 SEC_DESC *psd = NULL;
2577 uint32 des_access = q_u->access_mask;
2581 r_u->status = NT_STATUS_OK;
2583 /* find the domain policy and get the SID / access bits stored in the domain policy */
2584 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2585 return NT_STATUS_INVALID_HANDLE;
2587 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2591 /* append the alias' RID to it */
2592 if (!sid_append_rid(&sid, alias_rid))
2593 return NT_STATUS_NO_SUCH_USER;
2595 /*check if access can be granted as requested by client. */
2596 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2597 se_map_generic(&des_access,&ali_generic_mapping);
2598 if (!NT_STATUS_IS_OK(status =
2599 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2600 des_access, &acc_granted, "_samr_open_alias"))) {
2605 * we should check if the rid really exist !!!
2609 /* associate the user's SID with the new handle. */
2610 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2611 return NT_STATUS_NO_MEMORY;
2613 info->acc_granted = acc_granted;
2615 /* get a (unique) handle. open a policy on it. */
2616 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2617 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2622 /*******************************************************************
2624 ********************************************************************/
2626 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2628 SAM_ACCOUNT *pwd =NULL;
2633 ret = pdb_getsampwsid(pwd, sid);
2641 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2646 /* FIX ME: check if the value is really changed --metze */
2647 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2652 if(!pdb_update_sam_account(pwd)) {
2662 /*******************************************************************
2664 ********************************************************************/
2666 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2668 SAM_ACCOUNT *pwd = NULL;
2672 if(!pdb_getsampwsid(pwd, sid)) {
2678 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2683 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2687 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2691 if (!pdb_set_pass_changed_now (pwd)) {
2696 if(!pdb_update_sam_account(pwd)) {
2705 /*******************************************************************
2706 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2707 ********************************************************************/
2708 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2713 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2715 DEBUG(2,("Could not get gid for primary group of "
2716 "user %s\n", pdb_get_username(sampass)));
2720 grp = getgrgid(gid);
2723 DEBUG(2,("Could not find primary group %lu for "
2724 "user %s\n", (unsigned long)gid,
2725 pdb_get_username(sampass)));
2729 if (smb_set_primary_group(grp->gr_name,
2730 pdb_get_username(sampass)) != 0) {
2731 DEBUG(2,("Could not set primary group for user %s to "
2733 pdb_get_username(sampass), grp->gr_name));
2741 /*******************************************************************
2743 ********************************************************************/
2745 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2747 SAM_ACCOUNT *pwd = NULL;
2750 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2756 if (!pdb_getsampwsid(pwd, sid)) {
2761 copy_id20_to_sam_passwd(pwd, id20);
2763 /* write the change out */
2764 if(!pdb_update_sam_account(pwd)) {
2773 /*******************************************************************
2775 ********************************************************************/
2777 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2779 SAM_ACCOUNT *pwd = NULL;
2782 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2788 if (!pdb_getsampwsid(pwd, sid)) {
2793 copy_id21_to_sam_passwd(pwd, id21);
2796 * The funny part about the previous two calls is
2797 * that pwd still has the password hashes from the
2798 * passdb entry. These have not been updated from
2799 * id21. I don't know if they need to be set. --jerry
2802 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2803 set_unix_primary_group(pwd);
2805 /* write the change out */
2806 if(!pdb_update_sam_account(pwd)) {
2816 /*******************************************************************
2818 ********************************************************************/
2820 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2822 SAM_ACCOUNT *pwd = NULL;
2823 pstring plaintext_buf;
2828 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2834 if (!pdb_getsampwsid(pwd, sid)) {
2839 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2840 pdb_get_username(pwd)));
2842 acct_ctrl = pdb_get_acct_ctrl(pwd);
2844 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2849 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2854 copy_id23_to_sam_passwd(pwd, id23);
2856 /* if it's a trust account, don't update /etc/passwd */
2857 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2858 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2859 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2860 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2862 /* update the UNIX password */
2863 if (lp_unix_password_sync() ) {
2864 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2866 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2869 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2876 ZERO_STRUCT(plaintext_buf);
2878 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2879 set_unix_primary_group(pwd);
2881 if(!pdb_update_sam_account(pwd)) {
2891 /*******************************************************************
2893 ********************************************************************/
2895 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2897 SAM_ACCOUNT *pwd = NULL;
2899 pstring plaintext_buf;
2904 if (!pdb_getsampwsid(pwd, sid)) {
2909 DEBUG(5, ("Attempting administrator password change for user %s\n",
2910 pdb_get_username(pwd)));
2912 acct_ctrl = pdb_get_acct_ctrl(pwd);
2914 ZERO_STRUCT(plaintext_buf);
2916 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2921 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2926 /* if it's a trust account, don't update /etc/passwd */
2927 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2928 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2929 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2930 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2932 /* update the UNIX password */
2933 if (lp_unix_password_sync()) {
2934 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2936 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2939 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2946 ZERO_STRUCT(plaintext_buf);
2948 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2950 /* update the SAMBA password */
2951 if(!pdb_update_sam_account(pwd)) {
2961 /*******************************************************************
2962 samr_reply_set_userinfo
2963 ********************************************************************/
2965 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2968 POLICY_HND *pol = &q_u->pol;
2969 uint16 switch_value = q_u->switch_value;
2970 SAM_USERINFO_CTR *ctr = q_u->ctr;
2972 uint32 acc_required;
2974 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2976 r_u->status = NT_STATUS_OK;
2978 /* find the policy handle. open a policy on it. */
2979 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2980 return NT_STATUS_INVALID_HANDLE;
2982 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2983 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2987 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2990 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2991 return NT_STATUS_INVALID_INFO_CLASS;
2994 /* ok! user info levels (lots: see MSDEV help), off we go... */
2995 switch (switch_value) {
2997 if (!set_user_info_12(ctr->info.id12, &sid))
2998 return NT_STATUS_ACCESS_DENIED;
3002 if (!p->session_key.length) {
3003 return NT_STATUS_NO_USER_SESSION_KEY;
3005 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3007 dump_data(100, (char *)ctr->info.id24->pass, 516);
3009 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3010 return NT_STATUS_ACCESS_DENIED;
3016 * Currently we don't really know how to unmarshall
3017 * the level 25 struct, and the password encryption
3018 * is different. This is a placeholder for when we
3019 * do understand it. In the meantime just return INVALID
3020 * info level and W2K SP2 drops down to level 23... JRA.
3023 if (!p->session_key.length) {
3024 return NT_STATUS_NO_USER_SESSION_KEY;
3026 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3028 dump_data(100, (char *)ctr->info.id25->pass, 532);
3030 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3031 return NT_STATUS_ACCESS_DENIED;
3034 return NT_STATUS_INVALID_INFO_CLASS;
3037 if (!p->session_key.length) {
3038 return NT_STATUS_NO_USER_SESSION_KEY;
3040 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3042 dump_data(100, (char *)ctr->info.id23->pass, 516);
3044 if (!set_user_info_23(ctr->info.id23, &sid))
3045 return NT_STATUS_ACCESS_DENIED;
3049 return NT_STATUS_INVALID_INFO_CLASS;
3055 /*******************************************************************
3056 samr_reply_set_userinfo2
3057 ********************************************************************/
3059 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3062 SAM_USERINFO_CTR *ctr = q_u->ctr;
3063 POLICY_HND *pol = &q_u->pol;
3064 uint16 switch_value = q_u->switch_value;
3066 uint32 acc_required;
3068 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3070 r_u->status = NT_STATUS_OK;
3072 /* find the policy handle. open a policy on it. */
3073 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3074 return NT_STATUS_INVALID_HANDLE;
3076 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3077 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3081 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3084 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3085 return NT_STATUS_INVALID_INFO_CLASS;
3088 switch_value=ctr->switch_value;
3090 /* ok! user info levels (lots: see MSDEV help), off we go... */
3091 switch (switch_value) {
3093 if (!set_user_info_21(ctr->info.id21, &sid))
3094 return NT_STATUS_ACCESS_DENIED;
3097 if (!set_user_info_20(ctr->info.id20, &sid))
3098 return NT_STATUS_ACCESS_DENIED;
3101 if (!set_user_info_10(ctr->info.id10, &sid))
3102 return NT_STATUS_ACCESS_DENIED;
3105 /* Used by AS/U JRA. */
3106 if (!set_user_info_12(ctr->info.id12, &sid))
3107 return NT_STATUS_ACCESS_DENIED;
3110 return NT_STATUS_INVALID_INFO_CLASS;
3116 /*********************************************************************
3117 _samr_query_aliasmem
3118 *********************************************************************/
3120 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3122 int num_groups = 0, tmp_num_groups=0;
3123 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3124 struct samr_info *info = NULL;
3130 /* until i see a real useraliases query, we fack one up */
3132 /* I have seen one, JFM 2/12/2001 */
3134 * Explanation of what this call does:
3135 * for all the SID given in the request:
3136 * return a list of alias (local groups)
3137 * that have those SID as members.
3139 * and that's the alias in the domain specified
3140 * in the policy_handle
3142 * if the policy handle is on an incorrect sid
3143 * for example a user's sid
3144 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3147 r_u->status = NT_STATUS_OK;
3149 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3151 /* find the policy handle. open a policy on it. */
3152 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3153 return NT_STATUS_INVALID_HANDLE;
3155 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3156 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3158 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3159 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3160 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3161 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3165 if (!sid_check_is_domain(&info->sid) &&
3166 !sid_check_is_builtin(&info->sid))
3167 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3170 for (i=0; i<q_u->num_sids1; i++) {
3172 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3175 * if there is an error, we just continue as
3176 * it can be an unfound user or group
3178 if (!NT_STATUS_IS_OK(r_u->status)) {
3179 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3183 if (tmp_num_groups==0) {
3184 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3188 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3189 if (new_rids==NULL) {
3190 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3191 return NT_STATUS_NO_MEMORY;
3195 for (j=0; j<tmp_num_groups; j++)
3196 rids[j+num_groups]=tmp_rids[j];
3198 safe_free(tmp_rids);
3200 num_groups+=tmp_num_groups;
3203 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3204 return NT_STATUS_OK;
3207 /*********************************************************************
3208 _samr_query_aliasmem
3209 *********************************************************************/
3211 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3223 /* find the policy handle. open a policy on it. */
3224 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3225 return NT_STATUS_INVALID_HANDLE;
3227 if (!NT_STATUS_IS_OK(r_u->status =
3228 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3232 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3234 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3235 return NT_STATUS_NO_SUCH_ALIAS;
3237 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_sids);
3238 if (num_sids!=0 && sid == NULL) {
3240 return NT_STATUS_NO_MEMORY;
3243 for (i = 0; i < num_sids; i++) {
3244 init_dom_sid2(&sid[i], &sids[i]);
3247 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3251 return NT_STATUS_OK;
3254 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3258 for (i=0; i<*num; i++) {
3259 if ((*uids)[i] == uid)
3263 *uids = Realloc(*uids, (*num+1) * sizeof(uid_t));
3268 (*uids)[*num] = uid;
3273 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3277 struct sys_pwent *userlist, *user;
3282 /* We only look at our own sam, so don't care about imported stuff */
3286 if ((grp = getgrgid(gid)) == NULL) {
3291 /* Primary group members */
3293 userlist = getpwent_list();
3295 for (user = userlist; user != NULL; user = user->next) {
3296 if (user->pw_gid != gid)
3298 add_uid_to_array_unique(user->pw_uid, uids, num);
3301 pwent_free(userlist);
3303 /* Secondary group members */
3305 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3306 struct passwd *pw = getpwnam(*gr);
3310 add_uid_to_array_unique(pw->pw_uid, uids, num);
3318 /*********************************************************************
3319 _samr_query_groupmem
3320 *********************************************************************/
3322 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3324 int final_num_rids, i;
3326 fstring group_sid_str;
3336 /* find the policy handle. open a policy on it. */
3337 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3338 return NT_STATUS_INVALID_HANDLE;
3340 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3344 sid_to_string(group_sid_str, &group_sid);
3345 DEBUG(10, ("sid is %s\n", group_sid_str));
3347 if (!sid_check_is_in_our_domain(&group_sid)) {
3348 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3349 return NT_STATUS_NO_SUCH_GROUP;
3352 DEBUG(10, ("lookup on Domain SID\n"));
3354 if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3355 return NT_STATUS_NO_SUCH_GROUP;
3357 if(!get_memberuids(gid, &uids, &num))
3358 return NT_STATUS_NO_SUCH_GROUP;
3360 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
3361 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
3363 if (num!=0 && (rid==NULL || attr==NULL))
3364 return NT_STATUS_NO_MEMORY;
3368 for (i=0; i<num; i++) {
3371 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3372 DEBUG(1, ("Could not map member uid to SID\n"));
3376 if (!sid_check_is_in_our_domain(&sid)) {
3377 DEBUG(1, ("Inconsistent SAM -- group member uid not "
3378 "in our domain\n"));
3382 sid_peek_rid(&sid, &rid[final_num_rids]);
3384 /* Hmm. In a trace I got the constant 7 here from NT. */
3385 attr[final_num_rids] = SID_NAME_USER;
3387 final_num_rids += 1;
3392 init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3395 return NT_STATUS_OK;
3398 /*********************************************************************
3400 *********************************************************************/
3402 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3407 /* Find the policy handle. Open a policy on it. */
3408 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3409 return NT_STATUS_INVALID_HANDLE;
3411 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3415 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3417 if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
3418 return NT_STATUS_ACCESS_DENIED;
3420 return NT_STATUS_OK;
3423 /*********************************************************************
3425 *********************************************************************/
3427 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3432 /* Find the policy handle. Open a policy on it. */
3433 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3434 return NT_STATUS_INVALID_HANDLE;
3436 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3440 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3441 sid_string_static(&alias_sid)));
3443 if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
3444 return NT_STATUS_ACCESS_DENIED;
3446 return NT_STATUS_OK;
3449 /*********************************************************************
3451 *********************************************************************/
3453 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3457 fstring group_sid_str;
3464 SAM_ACCOUNT *sam_user=NULL;
3468 /* Find the policy handle. Open a policy on it. */
3469 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3470 return NT_STATUS_INVALID_HANDLE;
3472 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3476 sid_to_string(group_sid_str, &group_sid);
3477 DEBUG(10, ("sid is %s\n", group_sid_str));
3479 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3480 return NT_STATUS_NO_SUCH_GROUP;
3482 DEBUG(10, ("lookup on Domain SID\n"));
3484 if(!get_domain_group_from_sid(group_sid, &map))
3485 return NT_STATUS_NO_SUCH_GROUP;
3487 sid_copy(&user_sid, get_global_sam_sid());
3488 sid_append_rid(&user_sid, q_u->rid);
3490 ret = pdb_init_sam(&sam_user);
3491 if (!NT_STATUS_IS_OK(ret))
3494 check = pdb_getsampwsid(sam_user, &user_sid);
3496 if (check != True) {
3497 pdb_free_sam(&sam_user);
3498 return NT_STATUS_NO_SUCH_USER;
3501 /* check a real user exist before we run the script to add a user to a group */
3502 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3503 pdb_free_sam(&sam_user);
3504 return NT_STATUS_NO_SUCH_USER;
3507 pdb_free_sam(&sam_user);
3509 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3510 return NT_STATUS_NO_SUCH_USER;
3513 if ((grp=getgrgid(map.gid)) == NULL) {
3515 return NT_STATUS_NO_SUCH_GROUP;
3518 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3519 fstrcpy(grp_name, grp->gr_name);
3521 /* if the user is already in the group */
3522 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3524 return NT_STATUS_MEMBER_IN_GROUP;
3528 * ok, the group exist, the user exist, the user is not in the group,
3530 * we can (finally) add it to the group !
3533 smb_add_user_group(grp_name, pwd->pw_name);
3535 /* check if the user has been added then ... */
3536 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3538 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3542 return NT_STATUS_OK;
3545 /*********************************************************************
3547 *********************************************************************/
3549 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3553 SAM_ACCOUNT *sam_pass=NULL;
3560 * delete the group member named q_u->rid
3561 * who is a member of the sid associated with the handle
3562 * the rid is a user's rid as the group is a domain group.
3565 /* Find the policy handle. Open a policy on it. */
3566 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3567 return NT_STATUS_INVALID_HANDLE;
3569 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3573 if (!sid_check_is_in_our_domain(&group_sid))
3574 return NT_STATUS_NO_SUCH_GROUP;
3576 sid_copy(&user_sid, get_global_sam_sid());
3577 sid_append_rid(&user_sid, q_u->rid);
3579 if (!get_domain_group_from_sid(group_sid, &map))
3580 return NT_STATUS_NO_SUCH_GROUP;
3582 if ((grp=getgrgid(map.gid)) == NULL)
3583 return NT_STATUS_NO_SUCH_GROUP;
3585 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3586 fstrcpy(grp_name, grp->gr_name);
3588 /* check if the user exists before trying to remove it from the group */
3589 pdb_init_sam(&sam_pass);
3590 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3591 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3592 pdb_free_sam(&sam_pass);
3593 return NT_STATUS_NO_SUCH_USER;
3596 /* if the user is not in the group */
3597 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3598 pdb_free_sam(&sam_pass);
3599 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3602 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3604 /* check if the user has been removed then ... */
3605 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3606 pdb_free_sam(&sam_pass);
3607 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3610 pdb_free_sam(&sam_pass);
3611 return NT_STATUS_OK;
3615 /****************************************************************************
3616 Delete a UNIX user on demand.
3617 ****************************************************************************/
3619 static int smb_delete_user(const char *unix_user)
3624 /* try winbindd first since it is impossible to determine where
3625 a user came from via NSS. Try the delete user script if this fails
3626 meaning the user did not exist in winbindd's list of accounts */
3628 if ( winbind_delete_user( unix_user ) ) {
3629 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3634 /* fall back to 'delete user script' */
3636 pstrcpy(del_script, lp_deluser_script());
3639 all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3640 ret = smbrun(del_script,NULL);
3641 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3646 /*********************************************************************
3647 _samr_delete_dom_user
3648 *********************************************************************/
3650 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3653 SAM_ACCOUNT *sam_pass=NULL;
3656 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3658 /* Find the policy handle. Open a policy on it. */
3659 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3660 return NT_STATUS_INVALID_HANDLE;
3662 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3666 if (!sid_check_is_in_our_domain(&user_sid))
3667 return NT_STATUS_CANNOT_DELETE;
3669 /* check if the user exists before trying to delete */
3670 pdb_init_sam(&sam_pass);
3671 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3672 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3673 sid_string_static(&user_sid)));
3674 pdb_free_sam(&sam_pass);
3675 return NT_STATUS_NO_SUCH_USER;
3678 /* delete the unix side */
3680 * note: we don't check if the delete really happened
3681 * as the script is not necessary present
3682 * and maybe the sysadmin doesn't want to delete the unix side
3684 smb_delete_user(pdb_get_username(sam_pass));
3686 /* and delete the samba side */
3687 if (!pdb_delete_sam_account(sam_pass)) {
3688 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3689 pdb_free_sam(&sam_pass);
3690 return NT_STATUS_CANNOT_DELETE;
3693 pdb_free_sam(&sam_pass);
3695 if (!close_policy_hnd(p, &q_u->user_pol))
3696 return NT_STATUS_OBJECT_NAME_INVALID;
3698 return NT_STATUS_OK;
3701 /*********************************************************************
3702 _samr_delete_dom_group
3703 *********************************************************************/
3705 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3710 fstring group_sid_str;
3716 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3718 /* Find the policy handle. Open a policy on it. */
3719 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3720 return NT_STATUS_INVALID_HANDLE;
3722 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3726 sid_copy(&dom_sid, &group_sid);
3727 sid_to_string(group_sid_str, &dom_sid);
3728 sid_split_rid(&dom_sid, &group_rid);
3730 DEBUG(10, ("sid is %s\n", group_sid_str));
3732 /* we check if it's our SID before deleting */
3733 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3734 return NT_STATUS_NO_SUCH_GROUP;
3736 DEBUG(10, ("lookup on Domain SID\n"));
3738 if(!get_domain_group_from_sid(group_sid, &map))
3739 return NT_STATUS_NO_SUCH_GROUP;
3743 /* check if group really exists */
3744 if ( (grp=getgrgid(gid)) == NULL)
3745 return NT_STATUS_NO_SUCH_GROUP;
3747 /* delete mapping first */
3748 if(!pdb_delete_group_mapping_entry(group_sid))
3749 return NT_STATUS_ACCESS_DENIED;
3751 /* we can delete the UNIX group */
3752 smb_delete_group(grp->gr_name);
3754 /* check if the group has been successfully deleted */
3755 if ( (grp=getgrgid(gid)) != NULL)
3756 return NT_STATUS_ACCESS_DENIED;
3759 if (!close_policy_hnd(p, &q_u->group_pol))
3760 return NT_STATUS_OBJECT_NAME_INVALID;
3762 return NT_STATUS_OK;
3765 /*********************************************************************
3766 _samr_delete_dom_alias
3767 *********************************************************************/
3769 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3774 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3776 /* Find the policy handle. Open a policy on it. */
3777 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3778 return NT_STATUS_INVALID_HANDLE;
3780 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3784 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3786 if (!sid_check_is_in_our_domain(&alias_sid))
3787 return NT_STATUS_NO_SUCH_ALIAS;
3789 DEBUG(10, ("lookup on Local SID\n"));
3791 /* Have passdb delete the alias */
3792 if (!pdb_delete_alias(&alias_sid))
3793 return NT_STATUS_ACCESS_DENIED;
3795 if (!close_policy_hnd(p, &q_u->alias_pol))
3796 return NT_STATUS_OBJECT_NAME_INVALID;
3798 return NT_STATUS_OK;
3801 /*********************************************************************
3802 _samr_create_dom_group
3803 *********************************************************************/
3805 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3812 struct samr_info *info;
3816 /* Find the policy handle. Open a policy on it. */
3817 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3818 return NT_STATUS_INVALID_HANDLE;
3820 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3824 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3825 return NT_STATUS_ACCESS_DENIED;
3827 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3829 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3831 /* check if group already exist */
3832 if ((grp=getgrnam(name)) != NULL)
3833 return NT_STATUS_GROUP_EXISTS;
3835 /* we can create the UNIX group */
3836 if (smb_create_group(name, &gid) != 0)
3837 return NT_STATUS_ACCESS_DENIED;
3839 /* check if the group has been successfully created */
3840 if ((grp=getgrgid(gid)) == NULL)
3841 return NT_STATUS_ACCESS_DENIED;
3843 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3845 /* add the group to the mapping table */
3846 sid_copy(&info_sid, get_global_sam_sid());
3847 sid_append_rid(&info_sid, r_u->rid);
3848 sid_to_string(sid_string, &info_sid);
3850 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3851 return NT_STATUS_ACCESS_DENIED;
3853 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3854 return NT_STATUS_NO_MEMORY;
3856 /* get a (unique) handle. open a policy on it. */
3857 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3858 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3860 return NT_STATUS_OK;
3863 /*********************************************************************
3864 _samr_create_dom_alias
3865 *********************************************************************/
3867 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3873 struct samr_info *info;
3878 /* Find the policy handle. Open a policy on it. */
3879 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3880 return NT_STATUS_INVALID_HANDLE;
3882 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3886 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3887 return NT_STATUS_ACCESS_DENIED;
3889 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3891 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3893 /* Have passdb create the alias */
3894 result = pdb_create_alias(name, &r_u->rid);
3896 if (!NT_STATUS_IS_OK(result))
3899 sid_copy(&info_sid, get_global_sam_sid());
3900 sid_append_rid(&info_sid, r_u->rid);
3902 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
3903 return NT_STATUS_ACCESS_DENIED;
3905 /* check if the group has been successfully created */
3906 if ((grp=getgrgid(gid)) == NULL)
3907 return NT_STATUS_ACCESS_DENIED;
3909 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3910 return NT_STATUS_NO_MEMORY;
3912 /* get a (unique) handle. open a policy on it. */
3913 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3914 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3916 return NT_STATUS_OK;
3919 /*********************************************************************
3920 _samr_query_groupinfo
3922 sends the name/comment pair of a domain group
3923 level 1 send also the number of users of that group
3924 *********************************************************************/
3926 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3933 GROUP_INFO_CTR *ctr;
3937 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3938 return NT_STATUS_INVALID_HANDLE;
3940 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
3945 ret = get_domain_group_from_sid(group_sid, &map);
3948 return NT_STATUS_INVALID_HANDLE;
3950 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
3952 return NT_STATUS_NO_MEMORY;
3954 switch (q_u->switch_level) {
3956 ctr->switch_value1 = 1;
3957 if(!get_memberuids(map.gid, &uids, &num))
3958 return NT_STATUS_NO_SUCH_GROUP;
3960 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
3964 ctr->switch_value1 = 3;
3965 init_samr_group_info3(&ctr->group.info3);
3968 ctr->switch_value1 = 4;
3969 init_samr_group_info4(&ctr->group.info4, map.comment);
3972 return NT_STATUS_INVALID_INFO_CLASS;
3975 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
3977 return NT_STATUS_OK;
3980 /*********************************************************************
3983 update a domain group's comment.
3984 *********************************************************************/
3986 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
3990 GROUP_INFO_CTR *ctr;
3993 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3994 return NT_STATUS_INVALID_HANDLE;
3996 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4000 if (!get_domain_group_from_sid(group_sid, &map))
4001 return NT_STATUS_NO_SUCH_GROUP;
4005 switch (ctr->switch_value1) {
4007 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4010 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4013 return NT_STATUS_INVALID_INFO_CLASS;
4016 if(!pdb_update_group_mapping_entry(&map)) {
4017 return NT_STATUS_NO_SUCH_GROUP;
4020 return NT_STATUS_OK;
4023 /*********************************************************************
4026 update an alias's comment.
4027 *********************************************************************/
4029 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4032 struct acct_info info;
4033 ALIAS_INFO_CTR *ctr;
4036 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4037 return NT_STATUS_INVALID_HANDLE;
4039 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4045 switch (ctr->switch_value1) {
4047 unistr2_to_ascii(info.acct_desc,
4048 &(ctr->alias.info3.uni_acct_desc),
4049 sizeof(info.acct_desc)-1);
4052 return NT_STATUS_INVALID_INFO_CLASS;
4055 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4056 return NT_STATUS_ACCESS_DENIED;
4059 return NT_STATUS_OK;
4062 /*********************************************************************
4063 _samr_get_dom_pwinfo
4064 *********************************************************************/
4066 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4068 /* Perform access check. Since this rpc does not require a
4069 policy handle it will not be caught by the access checks on
4070 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4072 if (!pipe_access_check(p)) {
4073 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4074 r_u->status = NT_STATUS_ACCESS_DENIED;
4078 /* Actually, returning zeros here works quite well :-). */
4080 return NT_STATUS_OK;
4083 /*********************************************************************
4085 *********************************************************************/
4087 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4092 struct samr_info *info;
4093 SEC_DESC *psd = NULL;
4095 uint32 des_access = q_u->access_mask;
4101 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4102 return NT_STATUS_INVALID_HANDLE;
4104 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4108 /*check if access can be granted as requested by client. */
4109 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4110 se_map_generic(&des_access,&grp_generic_mapping);
4111 if (!NT_STATUS_IS_OK(status =
4112 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4113 des_access, &acc_granted, "_samr_open_group"))) {
4118 /* this should not be hard-coded like this */
4119 if (!sid_equal(&sid, get_global_sam_sid()))
4120 return NT_STATUS_ACCESS_DENIED;
4122 sid_copy(&info_sid, get_global_sam_sid());
4123 sid_append_rid(&info_sid, q_u->rid_group);
4124 sid_to_string(sid_string, &info_sid);
4126 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4127 return NT_STATUS_NO_MEMORY;
4129 info->acc_granted = acc_granted;
4131 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4133 /* check if that group really exists */
4135 ret = get_domain_group_from_sid(info->sid, &map);
4138 return NT_STATUS_NO_SUCH_GROUP;
4140 /* get a (unique) handle. open a policy on it. */
4141 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4142 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4144 return NT_STATUS_OK;
4147 /*********************************************************************
4148 _samr_remove_sid_foreign_domain
4149 *********************************************************************/
4151 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4152 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4153 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4155 DOM_SID delete_sid, alias_sid;
4156 SAM_ACCOUNT *sam_pass=NULL;
4159 BOOL is_user = False;
4161 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4163 sid_copy( &delete_sid, &q_u->sid.sid );
4165 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4166 sid_string_static(&delete_sid)));
4168 /* Find the policy handle. Open a policy on it. */
4170 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4171 return NT_STATUS_INVALID_HANDLE;
4173 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4174 "_samr_remove_sid_foreign_domain");
4176 if (!NT_STATUS_IS_OK(result))
4179 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4180 sid_string_static(&alias_sid)));
4182 /* make sure we can handle this */
4184 if ( sid_check_is_domain(&alias_sid) )
4185 type = SID_NAME_DOM_GRP;
4186 else if ( sid_check_is_builtin(&alias_sid) )
4187 type = SID_NAME_ALIAS;
4189 if ( type == SID_NAME_UNKNOWN ) {
4190 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4191 return NT_STATUS_OK;
4194 /* check if the user exists before trying to delete */
4196 pdb_init_sam(&sam_pass);
4198 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4201 /* maybe it is a group */
4202 if( !pdb_getgrsid(&map, delete_sid) ) {
4203 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4204 sid_string_static(&delete_sid)));
4205 result = NT_STATUS_INVALID_SID;
4210 /* we can only delete a user from a group since we don't have
4211 nested groups anyways. So in the latter case, just say OK */
4214 GROUP_MAP *mappings = NULL;
4218 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4220 /* interate over the groups */
4221 for ( i=0; i<num_groups; i++ ) {
4223 grp2 = getgrgid(mappings[i].gid);
4226 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4230 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4233 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4235 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4236 /* should we fail here ? */
4237 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4238 pdb_get_username(sam_pass), grp2->gr_name ));
4242 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4243 pdb_get_username(sam_pass), grp2->gr_name ));
4246 SAFE_FREE(mappings);
4250 result = NT_STATUS_OK;
4253 pdb_free_sam(&sam_pass);
4258 /*******************************************************************
4260 ********************************************************************/
4262 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4264 struct samr_info *info = NULL;
4266 uint32 min_pass_len,pass_hist,flag;
4267 time_t u_expire, u_min_age;
4268 NTTIME nt_expire, nt_min_age;
4270 time_t u_lock_duration, u_reset_time;
4271 NTTIME nt_lock_duration, nt_reset_time;
4277 uint32 num_users=0, num_groups=0, num_aliases=0;
4279 uint32 account_policy_temp;
4281 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4282 return NT_STATUS_NO_MEMORY;
4286 r_u->status = NT_STATUS_OK;
4288 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4290 /* find the policy handle. open a policy on it. */
4291 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4292 return NT_STATUS_INVALID_HANDLE;
4294 switch (q_u->switch_value) {
4296 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4297 min_pass_len = account_policy_temp;
4299 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4300 pass_hist = account_policy_temp;
4302 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4303 flag = account_policy_temp;
4305 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4306 u_expire = account_policy_temp;
4308 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4309 u_min_age = account_policy_temp;
4311 unix_to_nt_time_abs(&nt_expire, u_expire);
4312 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4314 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4315 flag, nt_expire, nt_min_age);
4319 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4321 if (!NT_STATUS_IS_OK(r_u->status)) {
4322 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4325 num_users=info->disp_info.num_user_account;
4328 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4329 if (NT_STATUS_IS_ERR(r_u->status)) {
4330 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4333 num_groups=info->disp_info.num_group_account;
4336 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4337 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4338 num_users, num_groups, num_aliases);
4341 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4342 u_logout = account_policy_temp;
4344 unix_to_nt_time_abs(&nt_logout, u_logout);
4346 init_unk_info3(&ctr->info.inf3, nt_logout);
4349 init_unk_info5(&ctr->info.inf5, global_myname());
4352 init_unk_info6(&ctr->info.inf6);
4355 init_unk_info7(&ctr->info.inf7);
4358 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4359 u_lock_duration = account_policy_temp * 60;
4361 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4362 u_reset_time = account_policy_temp * 60;
4364 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4365 lockout = account_policy_temp;
4367 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4368 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4370 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4373 return NT_STATUS_INVALID_INFO_CLASS;
4376 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4378 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4383 /*******************************************************************
4385 ********************************************************************/
4387 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4389 time_t u_expire, u_min_age;
4391 time_t u_lock_duration, u_reset_time;
4393 r_u->status = NT_STATUS_OK;
4395 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4397 /* find the policy handle. open a policy on it. */
4398 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4399 return NT_STATUS_INVALID_HANDLE;
4401 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4403 switch (q_u->switch_value) {
4405 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4406 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4408 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4409 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4410 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4411 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4412 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4417 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4418 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4427 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
4428 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4430 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4431 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4432 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4435 return NT_STATUS_INVALID_INFO_CLASS;
4438 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4440 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));