2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Anthony Liguori 2002,
11 * Copyright (C) Jim McDonough 2002.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
44 typedef struct _disp_info {
46 uint32 num_user_account;
47 SAM_ACCOUNT *disp_user_info;
49 uint32 num_group_account;
50 DOMAIN_GRP *disp_group_info;
54 /* for use by the \PIPE\samr policy */
56 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
79 uint32 *acc_granted, const char *debug)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
83 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84 *acc_granted = des_access;
85 if (geteuid() == sec_initial_uid()) {
86 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
88 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89 status = NT_STATUS_OK;
92 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
99 /*******************************************************************
100 Checks if access to a function can be granted
101 ********************************************************************/
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
105 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
106 debug, acc_granted, acc_required));
107 if ((acc_granted & acc_required) != acc_required) {
108 if (geteuid() == sec_initial_uid()) {
109 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
110 debug, acc_granted, acc_required));
111 DEBUGADD(4,("but overwritten by euid == 0\n"));
114 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
115 debug, acc_granted, acc_required));
116 return NT_STATUS_ACCESS_DENIED;
122 /*******************************************************************
123 Create a samr_info struct.
124 ********************************************************************/
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
128 struct samr_info *info;
133 sid_to_string(sid_str, psid);
135 fstrcpy(sid_str,"(NULL)");
138 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
140 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
144 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
146 sid_copy( &info->sid, psid);
148 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
150 info->mem_ctx = mem_ctx;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
158 static void free_samr_users(struct samr_info *info)
162 if (info->disp_info.user_dbloaded){
163 for (i=0; i<info->disp_info.num_user_account; i++) {
164 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165 /* Not really a free, actually a 'clear' */
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
187 static void free_samr_info(void *ptr)
189 struct samr_info *info=(struct samr_info *) ptr;
192 talloc_destroy(info->mem_ctx);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
214 SAM_ACCOUNT *pwd = NULL;
215 SAM_ACCOUNT *pwd_array = NULL;
216 NTSTATUS nt_status = NT_STATUS_OK;
217 TALLOC_CTX *mem_ctx = info->mem_ctx;
219 DEBUG(10,("load_sampwd_entries\n"));
221 /* if the snapshoot is already loaded, return */
222 if ((info->disp_info.user_dbloaded==True)
223 && (info->acb_mask == acb_mask)
224 && (info->all_machines == all_machines)) {
225 DEBUG(10,("load_sampwd_entries: already in memory\n"));
229 free_samr_users(info);
231 if (!pdb_setsampwent(False)) {
232 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233 return NT_STATUS_ACCESS_DENIED;
236 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
237 && pdb_getsampwent(pwd) == True; pwd=NULL) {
240 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
241 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
247 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
249 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
254 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
257 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258 pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
259 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* Copy the SAM_ACCOUNT into the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
270 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
272 info->disp_info.num_user_account++;
277 /* the snapshoot is in memory, we're ready to enumerate fast */
279 info->acb_mask = acb_mask;
280 info->all_machines = all_machines;
281 info->disp_info.user_dbloaded=True;
283 DEBUG(10,("load_sampwd_entries: done\n"));
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
291 DOMAIN_GRP *grp_array = NULL;
292 uint32 group_entries = 0;
294 TALLOC_CTX *mem_ctx = info->mem_ctx;
296 DEBUG(10,("load_group_domain_entries\n"));
298 /* if the snapshoot is already loaded, return */
299 if (info->disp_info.group_dbloaded==True) {
300 DEBUG(10,("load_group_domain_entries: already in memory\n"));
307 if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED)) {
308 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
309 return NT_STATUS_NO_MEMORY;
314 info->disp_info.num_group_account=group_entries;
316 grp_array=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
317 if (group_entries!=0 && grp_array==NULL) {
318 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
320 return NT_STATUS_NO_MEMORY;
323 info->disp_info.disp_group_info=grp_array;
325 for (i=0; i<group_entries; i++) {
326 fstrcpy(grp_array[i].name, map[i].nt_name);
327 fstrcpy(grp_array[i].comment, map[i].comment);
328 sid_split_rid(&map[i].sid, &grp_array[i].rid);
329 grp_array[i].attr=SID_NAME_DOM_GRP;
334 /* the snapshoot is in memory, we're ready to enumerate fast */
336 info->disp_info.group_dbloaded=True;
338 DEBUG(10,("load_group_domain_entries: done\n"));
344 /*******************************************************************
346 ********************************************************************/
348 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
350 r_u->status = NT_STATUS_OK;
352 /* close the policy handle */
353 if (!close_policy_hnd(p, &q_u->pol))
354 return NT_STATUS_OBJECT_NAME_INVALID;
356 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
361 /*******************************************************************
362 samr_reply_open_domain
363 ********************************************************************/
365 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
367 struct samr_info *info;
368 SEC_DESC *psd = NULL;
370 uint32 des_access = q_u->flags;
374 r_u->status = NT_STATUS_OK;
376 /* find the connection policy handle. */
377 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
378 return NT_STATUS_INVALID_HANDLE;
380 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
384 /*check if access can be granted as requested by client. */
385 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
386 se_map_generic(&des_access,&dom_generic_mapping);
388 if (!NT_STATUS_IS_OK(status =
389 access_check_samr_object(psd, p->pipe_user.nt_user_token,
390 des_access, &acc_granted, "_samr_open_domain"))) {
394 /* associate the domain SID with the (unique) handle. */
395 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
396 return NT_STATUS_NO_MEMORY;
397 info->acc_granted = acc_granted;
399 /* get a (unique) handle. open a policy on it. */
400 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
401 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
403 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
408 /*******************************************************************
409 _samr_get_usrdom_pwinfo
410 ********************************************************************/
412 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
414 struct samr_info *info = NULL;
416 r_u->status = NT_STATUS_OK;
418 /* find the policy handle. open a policy on it. */
419 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
420 return NT_STATUS_INVALID_HANDLE;
422 if (!sid_check_is_in_our_domain(&info->sid))
423 return NT_STATUS_OBJECT_TYPE_MISMATCH;
425 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
427 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
430 * NT sometimes return NT_STATUS_ACCESS_DENIED
431 * I don't know yet why.
437 /*******************************************************************
439 ********************************************************************/
441 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
443 extern DOM_SID global_sid_World;
452 sid_copy(&adm_sid, &global_sid_Builtin);
453 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
455 sid_copy(&act_sid, &global_sid_Builtin);
456 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
458 /*basic access for every one*/
459 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
460 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
462 /*full access for builtin aliases Administrators and Account Operators*/
463 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
464 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
465 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
467 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
468 return NT_STATUS_NO_MEMORY;
470 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
471 return NT_STATUS_NO_MEMORY;
476 /*******************************************************************
478 ********************************************************************/
480 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
482 extern DOM_SID global_sid_World;
491 sid_copy(&adm_sid, &global_sid_Builtin);
492 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
494 sid_copy(&act_sid, &global_sid_Builtin);
495 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
497 /*basic access for every one*/
498 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
499 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
501 /*full access for builtin aliases Administrators and Account Operators*/
502 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
503 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
504 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
506 /*extended access for the user*/
507 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
508 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
511 return NT_STATUS_NO_MEMORY;
513 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
514 return NT_STATUS_NO_MEMORY;
519 /*******************************************************************
521 ********************************************************************/
523 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
525 extern DOM_SID global_sid_World;
534 sid_copy(&adm_sid, &global_sid_Builtin);
535 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
537 sid_copy(&act_sid, &global_sid_Builtin);
538 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
540 /*basic access for every one*/
541 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
542 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
544 /*full access for builtin aliases Administrators and Account Operators*/
545 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
546 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
547 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
549 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
550 return NT_STATUS_NO_MEMORY;
552 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
553 return NT_STATUS_NO_MEMORY;
558 /*******************************************************************
560 ********************************************************************/
562 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
564 extern DOM_SID global_sid_World;
573 sid_copy(&adm_sid, &global_sid_Builtin);
574 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
576 sid_copy(&act_sid, &global_sid_Builtin);
577 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
579 /*basic access for every one*/
580 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
581 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
583 /*full access for builtin aliases Administrators and Account Operators*/
584 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
585 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
588 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
589 return NT_STATUS_NO_MEMORY;
591 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
592 return NT_STATUS_NO_MEMORY;
597 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
599 struct samr_info *info = NULL;
601 /* find the policy handle. open a policy on it. */
602 if (!find_policy_by_hnd(p, pol, (void **)&info))
609 *acc_granted = info->acc_granted;
613 /*******************************************************************
615 ********************************************************************/
617 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
619 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
620 return NT_STATUS_NOT_IMPLEMENTED;
624 /*******************************************************************
626 ********************************************************************/
628 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
632 SEC_DESC * psd = NULL;
636 r_u->status = NT_STATUS_OK;
639 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
640 return NT_STATUS_INVALID_HANDLE;
644 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
646 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
648 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
649 if (pol_sid.sid_rev_num == 0)
651 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
652 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
654 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
657 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
658 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
660 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
662 /* TODO: Builtin probably needs a different SD with restricted write access*/
663 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
664 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
666 else if (sid_check_is_in_our_domain(&pol_sid) ||
667 sid_check_is_in_builtin(&pol_sid))
669 /* TODO: different SDs have to be generated for aliases groups and users.
670 Currently all three get a default user SD */
671 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
672 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
674 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
676 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
677 return NT_STATUS_NO_MEMORY;
679 if (NT_STATUS_IS_OK(r_u->status))
685 /*******************************************************************
686 makes a SAM_ENTRY / UNISTR2* structure from a user list.
687 ********************************************************************/
689 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
690 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
696 SAM_ACCOUNT *pwd = NULL;
697 UNISTR2 uni_temp_name;
698 const char *temp_name;
699 const DOM_SID *user_sid;
701 fstring user_sid_string;
702 fstring domain_sid_string;
707 if (num_entries == 0)
710 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
712 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
714 if (sam == NULL || uni_name == NULL) {
715 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
716 return NT_STATUS_NO_MEMORY;
719 for (i = 0; i < num_entries; i++) {
720 pwd = &disp_user_info[i+start_idx];
721 temp_name = pdb_get_username(pwd);
722 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
723 user_sid = pdb_get_user_sid(pwd);
725 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
726 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
727 "the domain sid %s. Failing operation.\n",
729 sid_to_string(user_sid_string, user_sid),
730 sid_to_string(domain_sid_string, domain_sid)));
731 return NT_STATUS_UNSUCCESSFUL;
734 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
735 copy_unistr2(&uni_name[i], &uni_temp_name);
739 *uni_name_pp = uni_name;
743 /*******************************************************************
744 samr_reply_enum_dom_users
745 ********************************************************************/
747 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
748 SAMR_R_ENUM_DOM_USERS *r_u)
750 struct samr_info *info = NULL;
751 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
753 uint32 enum_context=q_u->start_idx;
754 uint32 max_size=q_u->max_size;
756 enum remote_arch_types ra_type = get_remote_arch();
757 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
758 uint32 max_entries = max_sam_entries;
761 r_u->status = NT_STATUS_OK;
763 /* find the policy handle. open a policy on it. */
764 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
765 return NT_STATUS_INVALID_HANDLE;
767 domain_sid = info->sid;
769 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
770 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
771 "_samr_enum_dom_users"))) {
775 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
778 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
781 if (!NT_STATUS_IS_OK(r_u->status))
784 num_account = info->disp_info.num_user_account;
786 if (enum_context > num_account) {
787 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
791 /* verify we won't overflow */
792 if (max_entries > num_account-enum_context) {
793 max_entries = num_account-enum_context;
794 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
797 /* calculate the size and limit on the number of entries we will return */
798 temp_size=max_entries*struct_size;
800 if (temp_size>max_size) {
801 max_entries=MIN((max_size/struct_size),max_entries);;
802 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
806 * Note from JRA. total_entries is not being used here. Currently if there is a
807 * large user base then it looks like NT will enumerate until get_sampwd_entries
808 * returns False due to num_entries being zero. This will cause an access denied
809 * return. I don't think this is right and needs further investigation. Note that
810 * this is also the same in the TNG code (I don't think that has been tested with
811 * a very large user list as MAX_SAM_ENTRIES is set to 600).
813 * I also think that one of the 'num_entries' return parameters is probably
814 * the "max entries" parameter - but in the TNG code they're all currently set to the same
815 * value (again I think this is wrong).
818 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
819 max_entries, enum_context,
820 info->disp_info.disp_user_info,
823 if (!NT_STATUS_IS_OK(r_u->status))
826 if (enum_context+max_entries < num_account)
827 r_u->status = STATUS_MORE_ENTRIES;
829 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
831 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
833 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
838 /*******************************************************************
839 makes a SAM_ENTRY / UNISTR2* structure from a group list.
840 ********************************************************************/
842 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
843 uint32 num_sam_entries, DOMAIN_GRP *grp)
852 if (num_sam_entries == 0)
855 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
857 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
859 if (sam == NULL || uni_name == NULL) {
860 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
864 for (i = 0; i < num_sam_entries; i++) {
866 * JRA. I think this should include the null. TNG does not.
868 int len = strlen(grp[i].name)+1;
870 init_sam_entry(&sam[i], len, grp[i].rid);
871 init_unistr2(&uni_name[i], grp[i].name, len);
875 *uni_name_pp = uni_name;
878 /*******************************************************************
879 Get the group entries - similar to get_sampwd_entries().
880 ********************************************************************/
882 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
883 uint32 *p_num_entries, uint32 max_entries)
886 uint32 num_entries = 0;
889 GROUP_MAP *map = NULL;
891 sid_to_string(sid_str, sid);
892 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
896 /* well-known aliases */
897 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
899 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED);
901 if (num_entries != 0) {
902 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
904 return NT_STATUS_NO_MEMORY;
906 for(i=0; i<num_entries && i<max_entries; i++) {
907 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
908 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
914 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
915 struct sys_grent *glist;
916 struct sys_grent *grp;
918 gid_t winbind_gid_low, winbind_gid_high;
919 BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
922 /* we return the UNIX groups here. This seems to be the right */
923 /* thing to do, since NT member servers return their local */
924 /* groups in the same situation. */
926 /* use getgrent_list() to retrieve the list of groups to avoid
927 * problems with getgrent possible infinite loop by internal
928 * libc grent structures overwrites by called functions */
929 grp = glist = getgrent_list();
931 return NT_STATUS_NO_MEMORY;
933 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
936 if(!pdb_getgrgid(&smap, grp->gr_gid))
939 if (smap.sid_name_use!=SID_NAME_ALIAS) {
943 sid_split_rid(&smap.sid, &trid);
945 if (!sid_equal(sid, &smap.sid))
948 /* Don't return winbind groups as they are not local! */
949 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
950 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
954 /* Don't return user private groups... */
956 if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
957 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
961 for( i = 0; i < num_entries; i++)
962 if ( (*d_grp)[i].rid == trid )
965 if ( i < num_entries ) {
966 continue; /* rid was there, dup! */
969 /* JRA - added this for large group db enumeration... */
972 /* skip the requested number of entries.
973 not very efficient, but hey...
979 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
982 return NT_STATUS_NO_MEMORY;
985 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
986 (*d_grp)[num_entries].rid = trid;
988 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
994 *p_num_entries = num_entries;
996 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
998 if (num_entries >= max_entries)
999 return STATUS_MORE_ENTRIES;
1000 return NT_STATUS_OK;
1003 /*******************************************************************
1004 Get the group entries - similar to get_sampwd_entries().
1005 ********************************************************************/
1007 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1008 uint32 *p_num_entries, uint32 max_entries)
1010 GROUP_MAP *map=NULL;
1012 uint32 group_entries = 0;
1013 uint32 num_entries = 0;
1017 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
1019 num_entries=group_entries-start_idx;
1021 /* limit the number of entries */
1022 if (num_entries>max_entries) {
1023 DEBUG(5,("Limiting to %d entries\n", max_entries));
1024 num_entries=max_entries;
1027 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1028 if (num_entries!=0 && *d_grp==NULL){
1030 return NT_STATUS_NO_MEMORY;
1033 for (i=0; i<num_entries; i++) {
1034 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1035 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1036 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1037 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1042 *p_num_entries = num_entries;
1044 return NT_STATUS_OK;
1047 /*******************************************************************
1048 samr_reply_enum_dom_groups
1049 ********************************************************************/
1051 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1053 DOMAIN_GRP *grp=NULL;
1058 r_u->status = NT_STATUS_OK;
1060 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1061 return NT_STATUS_INVALID_HANDLE;
1063 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1067 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1069 /* the domain group array is being allocated in the function below */
1070 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))) {
1074 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1076 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1078 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1084 /*******************************************************************
1085 samr_reply_enum_dom_aliases
1086 ********************************************************************/
1088 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1090 DOMAIN_GRP *grp=NULL;
1091 uint32 num_entries = 0;
1097 r_u->status = NT_STATUS_OK;
1099 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1100 return NT_STATUS_INVALID_HANDLE;
1102 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1106 sid_to_string(sid_str, &sid);
1107 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1109 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1110 &num_entries, MAX_SAM_ENTRIES);
1111 if (NT_STATUS_IS_ERR(status)) return status;
1113 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1117 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1119 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1124 /*******************************************************************
1125 samr_reply_query_dispinfo
1126 ********************************************************************/
1128 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1129 SAMR_R_QUERY_DISPINFO *r_u)
1131 struct samr_info *info = NULL;
1132 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1134 uint32 max_entries=q_u->max_entries;
1135 uint32 enum_context=q_u->start_idx;
1136 uint32 max_size=q_u->max_size;
1138 SAM_DISPINFO_CTR *ctr;
1139 uint32 temp_size=0, total_data_size=0;
1141 uint32 num_account = 0;
1142 enum remote_arch_types ra_type = get_remote_arch();
1143 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1146 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1147 r_u->status = NT_STATUS_OK;
1149 /* find the policy handle. open a policy on it. */
1150 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1151 return NT_STATUS_INVALID_HANDLE;
1153 domain_sid = info->sid;
1156 * calculate how many entries we will return.
1158 * - the number of entries the client asked
1159 * - our limit on that
1160 * - the starting point (enumeration context)
1161 * - the buffer size the client will accept
1165 * We are a lot more like W2K. Instead of reading the SAM
1166 * each time to find the records we need to send back,
1167 * we read it once and link that copy to the sam handle.
1168 * For large user list (over the MAX_SAM_ENTRIES)
1169 * it's a definitive win.
1170 * second point to notice: between enumerations
1171 * our sam is now the same as it's a snapshoot.
1172 * third point: got rid of the static SAM_USER_21 struct
1173 * no more intermediate.
1174 * con: it uses much more memory, as a full copy is stored
1177 * If you want to change it, think twice and think
1178 * of the second point , that's really important.
1183 /* Get what we need from the password database */
1184 switch (q_u->switch_level) {
1186 /* When playing with usrmgr, this is necessary
1187 if you want immediate refresh after editing
1188 a user. I would like to do this after the
1189 setuserinfo2, but we do not have access to
1190 the domain handle in that call, only to the
1191 user handle. Where else does this hurt?
1195 /* We cannot do this here - it kills performace. JRA. */
1196 free_samr_users(info);
1201 /* Level 2 is for all machines, otherwise only 'normal' users */
1202 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1204 if (!NT_STATUS_IS_OK(r_u->status)) {
1205 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1208 num_account = info->disp_info.num_user_account;
1212 r_u->status = load_group_domain_entries(info, &info->sid);
1213 if (!NT_STATUS_IS_OK(r_u->status))
1215 num_account = info->disp_info.num_group_account;
1218 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1219 return NT_STATUS_INVALID_INFO_CLASS;
1222 /* first limit the number of entries we will return */
1223 if(max_entries > max_sam_entries) {
1224 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1225 max_entries = max_sam_entries;
1228 if (enum_context > num_account) {
1229 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1230 return NT_STATUS_NO_MORE_ENTRIES;
1233 /* verify we won't overflow */
1234 if (max_entries > num_account-enum_context) {
1235 max_entries = num_account-enum_context;
1236 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1239 /* calculate the size and limit on the number of entries we will return */
1240 temp_size=max_entries*struct_size;
1242 if (temp_size>max_size) {
1243 max_entries=MIN((max_size/struct_size),max_entries);;
1244 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1247 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1248 return NT_STATUS_NO_MEMORY;
1252 /* Now create reply structure */
1253 switch (q_u->switch_level) {
1256 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1257 return NT_STATUS_NO_MEMORY;
1259 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1260 info->disp_info.disp_user_info, &domain_sid);
1261 if (!NT_STATUS_IS_OK(disp_ret))
1266 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1267 return NT_STATUS_NO_MEMORY;
1269 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1270 info->disp_info.disp_user_info, &domain_sid);
1271 if (!NT_STATUS_IS_OK(disp_ret))
1276 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1277 return NT_STATUS_NO_MEMORY;
1279 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1280 if (!NT_STATUS_IS_OK(disp_ret))
1285 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1286 return NT_STATUS_NO_MEMORY;
1288 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1289 if (!NT_STATUS_IS_OK(disp_ret))
1294 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1295 return NT_STATUS_NO_MEMORY;
1297 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1298 if (!NT_STATUS_IS_OK(disp_ret))
1303 ctr->sam.info = NULL;
1304 return NT_STATUS_INVALID_INFO_CLASS;
1307 /* calculate the total size */
1308 total_data_size=num_account*struct_size;
1310 if (enum_context+max_entries < num_account)
1311 r_u->status = STATUS_MORE_ENTRIES;
1313 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1315 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1321 /*******************************************************************
1322 samr_reply_query_aliasinfo
1323 ********************************************************************/
1325 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1331 r_u->status = NT_STATUS_OK;
1333 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1335 /* find the policy handle. open a policy on it. */
1336 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1337 return NT_STATUS_INVALID_HANDLE;
1338 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1342 if (!sid_check_is_in_our_domain(&sid) &&
1343 !sid_check_is_in_builtin(&sid))
1344 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1346 if (!pdb_getgrsid(&map, sid))
1347 return NT_STATUS_NO_SUCH_ALIAS;
1349 switch (q_u->switch_level) {
1352 r_u->ctr.switch_value1 = 1;
1353 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1357 r_u->ctr.switch_value1 = 3;
1358 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1361 return NT_STATUS_INVALID_INFO_CLASS;
1364 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1370 /*******************************************************************
1371 samr_reply_lookup_ids
1372 ********************************************************************/
1374 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1376 uint32 rid[MAX_SAM_ENTRIES];
1377 int num_rids = q_u->num_sids1;
1379 r_u->status = NT_STATUS_OK;
1381 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1383 if (num_rids > MAX_SAM_ENTRIES) {
1384 num_rids = MAX_SAM_ENTRIES;
1385 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1390 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1392 for (i = 0; i < num_rids && status == 0; i++)
1394 struct sam_passwd *sam_pass;
1398 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1399 q_u->uni_user_name[i].uni_str_len));
1401 /* find the user account */
1403 sam_pass = get_smb21pwd_entry(user_name, 0);
1406 if (sam_pass == NULL)
1408 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1413 rid[i] = sam_pass->user_rid;
1419 rid[0] = BUILTIN_ALIAS_RID_USERS;
1421 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1423 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1429 /*******************************************************************
1431 ********************************************************************/
1433 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1435 uint32 rid[MAX_SAM_ENTRIES];
1437 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1438 enum SID_NAME_USE local_type;
1440 int num_rids = q_u->num_names2;
1445 r_u->status = NT_STATUS_OK;
1447 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1452 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1453 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1457 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 */
1461 if (num_rids > MAX_SAM_ENTRIES) {
1462 num_rids = MAX_SAM_ENTRIES;
1463 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1466 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1468 become_root(); /* local_lookup_name can require root privs */
1470 for (i = 0; i < num_rids; i++) {
1475 r_u->status = NT_STATUS_NONE_MAPPED;
1477 rid [i] = 0xffffffff;
1478 type[i] = SID_NAME_UNKNOWN;
1480 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1483 * we are only looking for a name
1484 * the SID we get back can be outside
1485 * the scope of the pol_sid
1487 * in clear: it prevents to reply to domain\group: yes
1488 * when only builtin\group exists.
1490 * a cleaner code is to add the sid of the domain we're looking in
1491 * to the local_lookup_name function.
1494 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1495 sid_split_rid(&sid, &local_rid);
1497 if (sid_equal(&sid, &pol_sid)) {
1500 r_u->status = NT_STATUS_OK;
1507 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1509 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1514 /*******************************************************************
1515 _samr_chgpasswd_user
1516 ********************************************************************/
1518 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1523 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1525 r_u->status = NT_STATUS_OK;
1527 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1528 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1530 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1533 * Pass the user through the NT -> unix user mapping
1537 (void)map_username(user_name);
1540 * UNIX username case mangling not required, pass_oem_change
1541 * is case insensitive.
1544 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1545 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1547 init_samr_r_chgpasswd_user(r_u, r_u->status);
1549 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1554 /*******************************************************************
1555 makes a SAMR_R_LOOKUP_RIDS structure.
1556 ********************************************************************/
1558 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1559 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1562 UNIHDR *hdr_name=NULL;
1563 UNISTR2 *uni_name=NULL;
1565 *pp_uni_name = NULL;
1566 *pp_hdr_name = NULL;
1568 if (num_names != 0) {
1569 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1570 if (hdr_name == NULL)
1573 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1574 if (uni_name == NULL)
1578 for (i = 0; i < num_names; i++) {
1579 int len = names[i] != NULL ? strlen(names[i]) : 0;
1580 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1581 init_uni_hdr(&hdr_name[i], len);
1582 init_unistr2(&uni_name[i], names[i], len);
1585 *pp_uni_name = uni_name;
1586 *pp_hdr_name = hdr_name;
1591 /*******************************************************************
1593 ********************************************************************/
1595 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1597 fstring group_names[MAX_SAM_ENTRIES];
1598 uint32 *group_attrs = NULL;
1599 UNIHDR *hdr_name = NULL;
1600 UNISTR2 *uni_name = NULL;
1602 int num_rids = q_u->num_rids1;
1606 r_u->status = NT_STATUS_OK;
1608 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1610 /* find the policy handle. open a policy on it. */
1611 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1612 return NT_STATUS_INVALID_HANDLE;
1614 if (num_rids > MAX_SAM_ENTRIES) {
1615 num_rids = MAX_SAM_ENTRIES;
1616 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1620 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1621 return NT_STATUS_NO_MEMORY;
1624 r_u->status = NT_STATUS_NONE_MAPPED;
1626 become_root(); /* lookup_sid can require root privs */
1628 for (i = 0; i < num_rids; i++) {
1632 enum SID_NAME_USE type;
1634 group_attrs[i] = SID_NAME_UNKNOWN;
1635 *group_names[i] = '\0';
1637 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1638 sid_copy(&sid, &pol_sid);
1639 sid_append_rid(&sid, q_u->rid[i]);
1641 if (lookup_sid(&sid, domname, tmpname, &type)) {
1642 r_u->status = NT_STATUS_OK;
1643 group_attrs[i] = (uint32)type;
1644 fstrcpy(group_names[i],tmpname);
1645 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1652 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1653 return NT_STATUS_NO_MEMORY;
1655 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1657 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1662 /*******************************************************************
1663 _api_samr_open_user. Safe - gives out no passwd info.
1664 ********************************************************************/
1666 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1668 SAM_ACCOUNT *sampass=NULL;
1670 POLICY_HND domain_pol = q_u->domain_pol;
1671 POLICY_HND *user_pol = &r_u->user_pol;
1672 struct samr_info *info = NULL;
1673 SEC_DESC *psd = NULL;
1675 uint32 des_access = q_u->access_mask;
1680 r_u->status = NT_STATUS_OK;
1682 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1683 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1684 return NT_STATUS_INVALID_HANDLE;
1686 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1690 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1691 if (!NT_STATUS_IS_OK(nt_status)) {
1695 /* append the user's RID to it */
1696 if (!sid_append_rid(&sid, q_u->user_rid))
1697 return NT_STATUS_NO_SUCH_USER;
1699 /* check if access can be granted as requested by client. */
1700 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1701 se_map_generic(&des_access, &usr_generic_mapping);
1702 if (!NT_STATUS_IS_OK(nt_status =
1703 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1704 des_access, &acc_granted, "_samr_open_user"))) {
1709 ret=pdb_getsampwsid(sampass, &sid);
1712 /* check that the SID exists in our domain. */
1714 return NT_STATUS_NO_SUCH_USER;
1717 pdb_free_sam(&sampass);
1719 /* associate the user's SID and access bits with the new handle. */
1720 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1721 return NT_STATUS_NO_MEMORY;
1722 info->acc_granted = acc_granted;
1724 /* get a (unique) handle. open a policy on it. */
1725 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1726 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1731 /*************************************************************************
1732 get_user_info_10. Safe. Only gives out acb bits.
1733 *************************************************************************/
1735 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1737 SAM_ACCOUNT *smbpass=NULL;
1741 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1743 if (!NT_STATUS_IS_OK(nt_status)) {
1748 ret = pdb_getsampwsid(smbpass, user_sid);
1752 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1753 return NT_STATUS_NO_SUCH_USER;
1756 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1759 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1761 pdb_free_sam(&smbpass);
1763 return NT_STATUS_OK;
1766 /*************************************************************************
1767 get_user_info_12. OK - this is the killer as it gives out password info.
1768 Ensure that this is only allowed on an encrypted connection with a root
1770 *************************************************************************/
1772 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1774 SAM_ACCOUNT *smbpass=NULL;
1778 if (!p->ntlmssp_auth_validated)
1779 return NT_STATUS_ACCESS_DENIED;
1781 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1782 return NT_STATUS_ACCESS_DENIED;
1785 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1788 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1790 if (!NT_STATUS_IS_OK(nt_status)) {
1794 ret = pdb_getsampwsid(smbpass, user_sid);
1797 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1798 pdb_free_sam(&smbpass);
1799 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1802 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1804 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1805 pdb_free_sam(&smbpass);
1806 return NT_STATUS_ACCOUNT_DISABLED;
1810 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1812 pdb_free_sam(&smbpass);
1814 return NT_STATUS_OK;
1817 /*************************************************************************
1819 *************************************************************************/
1821 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1823 SAM_ACCOUNT *sampass=NULL;
1826 pdb_init_sam_talloc(mem_ctx, &sampass);
1829 ret = pdb_getsampwsid(sampass, user_sid);
1833 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1834 return NT_STATUS_NO_SUCH_USER;
1837 samr_clear_sam_passwd(sampass);
1839 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1842 init_sam_user_info20A(id20, sampass);
1844 pdb_free_sam(&sampass);
1846 return NT_STATUS_OK;
1849 /*************************************************************************
1851 *************************************************************************/
1853 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1854 DOM_SID *user_sid, DOM_SID *domain_sid)
1856 SAM_ACCOUNT *sampass=NULL;
1860 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1861 if (!NT_STATUS_IS_OK(nt_status)) {
1866 ret = pdb_getsampwsid(sampass, user_sid);
1870 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1871 return NT_STATUS_NO_SUCH_USER;
1874 samr_clear_sam_passwd(sampass);
1876 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1879 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1881 pdb_free_sam(&sampass);
1883 return NT_STATUS_OK;
1886 /*******************************************************************
1887 _samr_query_userinfo
1888 ********************************************************************/
1890 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1892 SAM_USERINFO_CTR *ctr;
1893 struct samr_info *info = NULL;
1897 r_u->status=NT_STATUS_OK;
1899 /* search for the handle */
1900 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1901 return NT_STATUS_INVALID_HANDLE;
1903 domain_sid = info->sid;
1905 sid_split_rid(&domain_sid, &rid);
1907 if (!sid_check_is_in_our_domain(&info->sid))
1908 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1910 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1912 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1914 return NT_STATUS_NO_MEMORY;
1918 /* ok! user info levels (lots: see MSDEV help), off we go... */
1919 ctr->switch_value = q_u->switch_value;
1921 switch (q_u->switch_value) {
1923 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1924 if (ctr->info.id10 == NULL)
1925 return NT_STATUS_NO_MEMORY;
1927 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1932 /* whoops - got this wrong. i think. or don't understand what's happening. */
1936 info = (void *)&id11;
1938 expire.low = 0xffffffff;
1939 expire.high = 0x7fffffff;
1941 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1946 ZERO_STRUCTP(ctr->info.id11);
1947 init_sam_user_info11(ctr->info.id11, &expire,
1948 "BROOKFIELDS$", /* name */
1949 0x03ef, /* user rid */
1950 0x201, /* group rid */
1951 0x0080); /* acb info */
1958 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1959 if (ctr->info.id12 == NULL)
1960 return NT_STATUS_NO_MEMORY;
1962 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1967 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1968 if (ctr->info.id20 == NULL)
1969 return NT_STATUS_NO_MEMORY;
1970 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1975 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1976 if (ctr->info.id21 == NULL)
1977 return NT_STATUS_NO_MEMORY;
1978 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1979 &info->sid, &domain_sid)))
1984 return NT_STATUS_INVALID_INFO_CLASS;
1987 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1989 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1994 /*******************************************************************
1995 samr_reply_query_usergroups
1996 ********************************************************************/
1998 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
2000 SAM_ACCOUNT *sam_pass=NULL;
2002 DOM_GID *gids = NULL;
2008 * from the SID in the request:
2009 * we should send back the list of DOMAIN GROUPS
2010 * the user is a member of
2012 * and only the DOMAIN GROUPS
2013 * no ALIASES !!! neither aliases of the domain
2014 * nor aliases of the builtin SID
2019 r_u->status = NT_STATUS_OK;
2021 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2023 /* find the policy handle. open a policy on it. */
2024 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2025 return NT_STATUS_INVALID_HANDLE;
2027 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2031 if (!sid_check_is_in_our_domain(&sid))
2032 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2034 pdb_init_sam(&sam_pass);
2037 ret = pdb_getsampwsid(sam_pass, &sid);
2041 pdb_free_sam(&sam_pass);
2042 return NT_STATUS_NO_SUCH_USER;
2045 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2046 pdb_free_sam(&sam_pass);
2047 return NT_STATUS_NO_SUCH_GROUP;
2050 /* construct the response. lkclXXXX: gids are not copied! */
2051 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2053 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2055 pdb_free_sam(&sam_pass);
2060 /*******************************************************************
2061 _samr_query_dom_info
2062 ********************************************************************/
2064 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2066 struct samr_info *info = NULL;
2068 uint32 min_pass_len,pass_hist,flag;
2069 time_t u_expire, u_min_age;
2070 NTTIME nt_expire, nt_min_age;
2072 time_t u_lock_duration, u_reset_time;
2073 NTTIME nt_lock_duration, nt_reset_time;
2079 uint32 account_policy_temp;
2081 uint32 num_users=0, num_groups=0, num_aliases=0;
2083 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2084 return NT_STATUS_NO_MEMORY;
2088 r_u->status = NT_STATUS_OK;
2090 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2092 /* find the policy handle. open a policy on it. */
2093 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2094 return NT_STATUS_INVALID_HANDLE;
2096 switch (q_u->switch_value) {
2099 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2100 min_pass_len = account_policy_temp;
2102 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2103 pass_hist = account_policy_temp;
2105 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2106 flag = account_policy_temp;
2108 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2109 u_expire = account_policy_temp;
2111 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2112 u_min_age = account_policy_temp;
2114 unix_to_nt_time_abs(&nt_expire, u_expire);
2115 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2117 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2118 flag, nt_expire, nt_min_age);
2122 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2124 if (!NT_STATUS_IS_OK(r_u->status)) {
2125 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2128 num_users=info->disp_info.num_user_account;
2131 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2132 if (!NT_STATUS_IS_OK(r_u->status)) {
2133 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2136 num_groups=info->disp_info.num_group_account;
2139 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2140 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2141 num_users, num_groups, num_aliases);
2144 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
2145 unix_to_nt_time_abs(&nt_logout, u_logout);
2147 init_unk_info3(&ctr->info.inf3, nt_logout);
2150 init_unk_info5(&ctr->info.inf5, global_myname());
2153 init_unk_info6(&ctr->info.inf6);
2156 init_unk_info7(&ctr->info.inf7);
2159 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2160 u_lock_duration = account_policy_temp;
2162 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2163 u_reset_time = account_policy_temp;
2165 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2166 lockout = account_policy_temp;
2168 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2169 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2171 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2174 return NT_STATUS_INVALID_INFO_CLASS;
2177 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2179 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2184 /*******************************************************************
2185 _api_samr_create_user
2186 Create an account, can be either a normal user or a machine.
2187 This funcion will need to be updated for bdc/domain trusts.
2188 ********************************************************************/
2190 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2192 SAM_ACCOUNT *sam_pass=NULL;
2196 POLICY_HND dom_pol = q_u->domain_pol;
2197 UNISTR2 user_account = q_u->uni_name;
2198 uint16 acb_info = q_u->acb_info;
2199 POLICY_HND *user_pol = &r_u->user_pol;
2200 struct samr_info *info = NULL;
2208 /* check this, when giving away 'add computer to domain' privs */
2209 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2211 /* Get the domain SID stored in the domain policy */
2212 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2213 return NT_STATUS_INVALID_HANDLE;
2215 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2219 /* find the account: tell the caller if it exists.
2220 lkclXXXX i have *no* idea if this is a problem or not
2221 or even if you are supposed to construct a different
2222 reply if the account already exists...
2225 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2226 strlower_m(account);
2228 pdb_init_sam(&sam_pass);
2231 ret = pdb_getsampwnam(sam_pass, account);
2234 /* this account exists: say so */
2235 pdb_free_sam(&sam_pass);
2236 return NT_STATUS_USER_EXISTS;
2239 pdb_free_sam(&sam_pass);
2242 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2243 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2244 * that only people with write access to the smbpasswd file will be able
2245 * to create a user. JRA.
2249 * add the user in the /etc/passwd file or the unix authority system.
2250 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2251 * a) local_password_change() checks for us if the /etc/passwd account really exists
2252 * b) smb_create_user() would return an error if the account already exists
2253 * and as it could return an error also if it can't create the account, it would be tricky.
2255 * So we go the easy way, only check after if the account exists.
2256 * JFM (2/3/2001), to clear any possible bad understanding (-:
2258 * We now have seperate script paramaters for adding users/machines so we
2259 * now have some sainity-checking to match.
2262 DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2265 * we used to have code here that made sure the acb_info flags
2266 * matched with the users named (e.g. an account flags as a machine
2267 * trust account ended in '$'). It has been ifdef'd out for a long
2268 * time, so I replaced it with this comment. --jerry
2271 /* the passdb lookup has failed; check to see if we need to run the
2272 add user/machine script */
2274 pw = Get_Pwnam(account);
2276 /*********************************************************************
2277 * HEADS UP! If we have to create a new user account, we have to get
2278 * a new RID from somewhere. This used to be done by the passdb
2279 * backend. It has been moved into idmap now. Since idmap is now
2280 * wrapped up behind winbind, this means you have to run winbindd if you
2281 * want new accounts to get a new RID when "enable rid algorithm = no".
2282 * Tough. We now have a uniform way of allocating RIDs regardless
2283 * of what ever passdb backend people may use.
2284 * --jerry (2003-07-10)
2285 *********************************************************************/
2289 * we can't check both the ending $ and the acb_info.
2291 * UserManager creates trust accounts (ending in $,
2292 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2295 if (account[strlen(account)-1] == '$')
2296 pstrcpy(add_script, lp_addmachine_script());
2298 pstrcpy(add_script, lp_adduser_script());
2302 all_string_sub(add_script, "%u", account, sizeof(account));
2303 add_ret = smbrun(add_script,NULL);
2304 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2306 else /* no add user script -- ask winbindd to do it */
2308 if ( !winbind_create_user( account, &new_rid ) ) {
2309 DEBUG(3,("_api_samr_create_user: winbind_create_user(%s) failed\n",
2316 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2318 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2321 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2323 if (!pdb_add_sam_account(sam_pass)) {
2324 pdb_free_sam(&sam_pass);
2325 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2327 return NT_STATUS_ACCESS_DENIED;
2330 /* Get the user's SID */
2331 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2333 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2334 se_map_generic(&des_access, &usr_generic_mapping);
2335 if (!NT_STATUS_IS_OK(nt_status =
2336 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2337 des_access, &acc_granted, "_samr_create_user"))) {
2341 /* associate the user's SID with the new handle. */
2342 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2343 pdb_free_sam(&sam_pass);
2344 return NT_STATUS_NO_MEMORY;
2349 info->acc_granted = acc_granted;
2351 /* get a (unique) handle. open a policy on it. */
2352 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2353 pdb_free_sam(&sam_pass);
2354 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2357 r_u->user_rid=pdb_get_user_rid(sam_pass);
2359 r_u->access_granted = acc_granted;
2361 pdb_free_sam(&sam_pass);
2363 return NT_STATUS_OK;
2366 /*******************************************************************
2367 samr_reply_connect_anon
2368 ********************************************************************/
2370 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2372 struct samr_info *info = NULL;
2376 if (!pipe_access_check(p)) {
2377 DEBUG(3, ("access denied to samr_connect_anon\n"));
2378 r_u->status = NT_STATUS_ACCESS_DENIED;
2382 /* set up the SAMR connect_anon response */
2384 r_u->status = NT_STATUS_OK;
2386 /* associate the user's SID with the new handle. */
2387 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2388 return NT_STATUS_NO_MEMORY;
2390 info->status = q_u->unknown_0;
2392 /* get a (unique) handle. open a policy on it. */
2393 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2394 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2399 /*******************************************************************
2401 ********************************************************************/
2403 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2405 struct samr_info *info = NULL;
2406 SEC_DESC *psd = NULL;
2408 uint32 des_access = q_u->access_mask;
2413 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2417 if (!pipe_access_check(p)) {
2418 DEBUG(3, ("access denied to samr_connect\n"));
2419 r_u->status = NT_STATUS_ACCESS_DENIED;
2423 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2424 se_map_generic(&des_access, &sam_generic_mapping);
2425 if (!NT_STATUS_IS_OK(nt_status =
2426 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2427 des_access, &acc_granted, "_samr_connect"))) {
2431 r_u->status = NT_STATUS_OK;
2433 /* associate the user's SID and access granted with the new handle. */
2434 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2435 return NT_STATUS_NO_MEMORY;
2437 info->acc_granted = acc_granted;
2438 info->status = q_u->access_mask;
2440 /* get a (unique) handle. open a policy on it. */
2441 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2442 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2444 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2449 /*******************************************************************
2451 ********************************************************************/
2453 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2455 struct samr_info *info = NULL;
2456 SEC_DESC *psd = NULL;
2458 uint32 des_access = q_u->access_mask;
2463 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2467 if (!pipe_access_check(p)) {
2468 DEBUG(3, ("access denied to samr_connect4\n"));
2469 r_u->status = NT_STATUS_ACCESS_DENIED;
2473 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2474 se_map_generic(&des_access, &sam_generic_mapping);
2475 if (!NT_STATUS_IS_OK(nt_status =
2476 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2477 des_access, &acc_granted, "_samr_connect"))) {
2481 r_u->status = NT_STATUS_OK;
2483 /* associate the user's SID and access granted with the new handle. */
2484 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2485 return NT_STATUS_NO_MEMORY;
2487 info->acc_granted = acc_granted;
2488 info->status = q_u->access_mask;
2490 /* get a (unique) handle. open a policy on it. */
2491 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2492 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2494 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2499 /**********************************************************************
2500 api_samr_lookup_domain
2501 **********************************************************************/
2503 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2505 struct samr_info *info;
2506 fstring domain_name;
2509 r_u->status = NT_STATUS_OK;
2511 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2512 return NT_STATUS_INVALID_HANDLE;
2514 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2518 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2522 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2523 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2526 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2528 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2533 /******************************************************************
2534 makes a SAMR_R_ENUM_DOMAINS structure.
2535 ********************************************************************/
2537 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2538 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2544 DEBUG(5, ("make_enum_domains\n"));
2547 *pp_uni_name = NULL;
2549 if (num_sam_entries == 0)
2552 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2553 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2555 if (sam == NULL || uni_name == NULL)
2558 for (i = 0; i < num_sam_entries; i++) {
2559 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2561 init_sam_entry(&sam[i], len, 0);
2562 init_unistr2(&uni_name[i], doms[i], len);
2566 *pp_uni_name = uni_name;
2571 /**********************************************************************
2572 api_samr_enum_domains
2573 **********************************************************************/
2575 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2577 struct samr_info *info;
2578 uint32 num_entries = 2;
2582 r_u->status = NT_STATUS_OK;
2584 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2585 return NT_STATUS_INVALID_HANDLE;
2587 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2591 name = get_global_sam_name();
2593 fstrcpy(dom[0],name);
2595 fstrcpy(dom[1],"Builtin");
2597 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2598 return NT_STATUS_NO_MEMORY;
2600 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2605 /*******************************************************************
2607 ********************************************************************/
2609 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2612 POLICY_HND domain_pol = q_u->dom_pol;
2613 uint32 alias_rid = q_u->rid_alias;
2614 POLICY_HND *alias_pol = &r_u->pol;
2615 struct samr_info *info = NULL;
2616 SEC_DESC *psd = NULL;
2618 uint32 des_access = q_u->access_mask;
2622 r_u->status = NT_STATUS_OK;
2624 /* find the domain policy and get the SID / access bits stored in the domain policy */
2625 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2626 return NT_STATUS_INVALID_HANDLE;
2628 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2632 /* append the alias' RID to it */
2633 if (!sid_append_rid(&sid, alias_rid))
2634 return NT_STATUS_NO_SUCH_USER;
2636 /*check if access can be granted as requested by client. */
2637 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2638 se_map_generic(&des_access,&ali_generic_mapping);
2639 if (!NT_STATUS_IS_OK(status =
2640 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2641 des_access, &acc_granted, "_samr_open_alias"))) {
2646 * we should check if the rid really exist !!!
2650 /* associate the user's SID with the new handle. */
2651 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2652 return NT_STATUS_NO_MEMORY;
2654 info->acc_granted = acc_granted;
2656 /* get a (unique) handle. open a policy on it. */
2657 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2658 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2663 /*******************************************************************
2665 ********************************************************************/
2667 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2669 SAM_ACCOUNT *pwd =NULL;
2674 ret = pdb_getsampwsid(pwd, sid);
2682 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2687 /* FIX ME: check if the value is really changed --metze */
2688 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2693 if(!pdb_update_sam_account(pwd)) {
2703 /*******************************************************************
2705 ********************************************************************/
2707 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2709 SAM_ACCOUNT *pwd = NULL;
2713 if(!pdb_getsampwsid(pwd, sid)) {
2719 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2724 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2728 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2732 if (!pdb_set_pass_changed_now (pwd)) {
2737 if(!pdb_update_sam_account(pwd)) {
2746 /*******************************************************************
2747 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2748 ********************************************************************/
2749 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2754 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2756 DEBUG(2,("Could not get gid for primary group of "
2757 "user %s\n", pdb_get_username(sampass)));
2761 grp = getgrgid(gid);
2764 DEBUG(2,("Could not find primary group %d for "
2765 "user %s\n", gid, pdb_get_username(sampass)));
2769 if (smb_set_primary_group(grp->gr_name,
2770 pdb_get_username(sampass)) != 0) {
2771 DEBUG(2,("Could not set primary group for user %s to "
2773 pdb_get_username(sampass), grp->gr_name));
2781 /*******************************************************************
2783 ********************************************************************/
2785 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2787 SAM_ACCOUNT *pwd = NULL;
2790 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2796 if (!pdb_getsampwsid(pwd, sid)) {
2801 copy_id21_to_sam_passwd(pwd, id21);
2804 * The funny part about the previous two calls is
2805 * that pwd still has the password hashes from the
2806 * passdb entry. These have not been updated from
2807 * id21. I don't know if they need to be set. --jerry
2810 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2811 set_unix_primary_group(pwd);
2813 /* write the change out */
2814 if(!pdb_update_sam_account(pwd)) {
2824 /*******************************************************************
2826 ********************************************************************/
2828 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2830 SAM_ACCOUNT *pwd = NULL;
2831 pstring plaintext_buf;
2836 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2842 if (!pdb_getsampwsid(pwd, sid)) {
2847 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2848 pdb_get_username(pwd)));
2850 acct_ctrl = pdb_get_acct_ctrl(pwd);
2852 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2857 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2862 copy_id23_to_sam_passwd(pwd, id23);
2864 /* if it's a trust account, don't update /etc/passwd */
2865 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2866 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2867 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2868 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2870 /* update the UNIX password */
2871 if (lp_unix_password_sync() )
2872 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2878 ZERO_STRUCT(plaintext_buf);
2880 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2881 set_unix_primary_group(pwd);
2883 if(!pdb_update_sam_account(pwd)) {
2893 /*******************************************************************
2895 ********************************************************************/
2897 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2899 SAM_ACCOUNT *pwd = NULL;
2901 pstring plaintext_buf;
2906 if (!pdb_getsampwsid(pwd, sid)) {
2911 DEBUG(5, ("Attempting administrator password change for user %s\n",
2912 pdb_get_username(pwd)));
2914 acct_ctrl = pdb_get_acct_ctrl(pwd);
2916 ZERO_STRUCT(plaintext_buf);
2918 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2923 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2928 /* if it's a trust account, don't update /etc/passwd */
2929 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2930 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2931 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2932 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2934 /* update the UNIX password */
2935 if (lp_unix_password_sync()) {
2936 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2943 ZERO_STRUCT(plaintext_buf);
2945 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2947 /* update the SAMBA password */
2948 if(!pdb_update_sam_account(pwd)) {
2958 /*******************************************************************
2959 samr_reply_set_userinfo
2960 ********************************************************************/
2962 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2965 POLICY_HND *pol = &q_u->pol;
2966 uint16 switch_value = q_u->switch_value;
2967 SAM_USERINFO_CTR *ctr = q_u->ctr;
2969 uint32 acc_required;
2971 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2973 r_u->status = NT_STATUS_OK;
2975 /* find the policy handle. open a policy on it. */
2976 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2977 return NT_STATUS_INVALID_HANDLE;
2979 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2980 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2984 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2987 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2988 return NT_STATUS_INVALID_INFO_CLASS;
2991 /* ok! user info levels (lots: see MSDEV help), off we go... */
2992 switch (switch_value) {
2994 if (!set_user_info_12(ctr->info.id12, &sid))
2995 return NT_STATUS_ACCESS_DENIED;
2999 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
3001 dump_data(100, (char *)ctr->info.id24->pass, 516);
3003 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3004 return NT_STATUS_ACCESS_DENIED;
3010 * Currently we don't really know how to unmarshall
3011 * the level 25 struct, and the password encryption
3012 * is different. This is a placeholder for when we
3013 * do understand it. In the meantime just return INVALID
3014 * info level and W2K SP2 drops down to level 23... JRA.
3017 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3019 dump_data(100, (char *)ctr->info.id25->pass, 532);
3021 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3022 return NT_STATUS_ACCESS_DENIED;
3025 return NT_STATUS_INVALID_INFO_CLASS;
3028 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3030 dump_data(100, (char *)ctr->info.id23->pass, 516);
3032 if (!set_user_info_23(ctr->info.id23, &sid))
3033 return NT_STATUS_ACCESS_DENIED;
3037 return NT_STATUS_INVALID_INFO_CLASS;
3043 /*******************************************************************
3044 samr_reply_set_userinfo2
3045 ********************************************************************/
3047 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3050 SAM_USERINFO_CTR *ctr = q_u->ctr;
3051 POLICY_HND *pol = &q_u->pol;
3052 uint16 switch_value = q_u->switch_value;
3054 uint32 acc_required;
3056 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3058 r_u->status = NT_STATUS_OK;
3060 /* find the policy handle. open a policy on it. */
3061 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3062 return NT_STATUS_INVALID_HANDLE;
3064 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3065 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3069 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3072 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3073 return NT_STATUS_INVALID_INFO_CLASS;
3076 switch_value=ctr->switch_value;
3078 /* ok! user info levels (lots: see MSDEV help), off we go... */
3079 switch (switch_value) {
3081 if (!set_user_info_21(ctr->info.id21, &sid))
3082 return NT_STATUS_ACCESS_DENIED;
3085 if (!set_user_info_10(ctr->info.id10, &sid))
3086 return NT_STATUS_ACCESS_DENIED;
3089 /* Used by AS/U JRA. */
3090 if (!set_user_info_12(ctr->info.id12, &sid))
3091 return NT_STATUS_ACCESS_DENIED;
3094 return NT_STATUS_INVALID_INFO_CLASS;
3100 /*********************************************************************
3101 _samr_query_aliasmem
3102 *********************************************************************/
3104 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3106 int num_groups = 0, tmp_num_groups=0;
3107 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3108 struct samr_info *info = NULL;
3114 /* until i see a real useraliases query, we fack one up */
3116 /* I have seen one, JFM 2/12/2001 */
3118 * Explanation of what this call does:
3119 * for all the SID given in the request:
3120 * return a list of alias (local groups)
3121 * that have those SID as members.
3123 * and that's the alias in the domain specified
3124 * in the policy_handle
3126 * if the policy handle is on an incorrect sid
3127 * for example a user's sid
3128 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3131 r_u->status = NT_STATUS_OK;
3133 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3135 /* find the policy handle. open a policy on it. */
3136 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3137 return NT_STATUS_INVALID_HANDLE;
3139 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3140 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3142 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3143 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3144 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3145 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3149 if (!sid_check_is_domain(&info->sid) &&
3150 !sid_check_is_builtin(&info->sid))
3151 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3154 for (i=0; i<q_u->num_sids1; i++) {
3156 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3159 * if there is an error, we just continue as
3160 * it can be an unfound user or group
3162 if (!NT_STATUS_IS_OK(r_u->status)) {
3163 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3167 if (tmp_num_groups==0) {
3168 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3172 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3173 if (new_rids==NULL) {
3174 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3175 return NT_STATUS_NO_MEMORY;
3179 for (j=0; j<tmp_num_groups; j++)
3180 rids[j+num_groups]=tmp_rids[j];
3182 safe_free(tmp_rids);
3184 num_groups+=tmp_num_groups;
3187 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3188 return NT_STATUS_OK;
3191 /*********************************************************************
3192 _samr_query_aliasmem
3193 *********************************************************************/
3195 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3207 fstring alias_sid_str;
3210 SAM_ACCOUNT *sam_user = NULL;
3214 /* find the policy handle. open a policy on it. */
3215 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3216 return NT_STATUS_INVALID_HANDLE;
3218 if (!NT_STATUS_IS_OK(r_u->status =
3219 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3223 sid_copy(&als_sid, &alias_sid);
3224 sid_to_string(alias_sid_str, &alias_sid);
3225 sid_split_rid(&alias_sid, &alias_rid);
3227 DEBUG(10, ("sid is %s\n", alias_sid_str));
3229 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3230 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3231 if(!get_builtin_group_from_sid(als_sid, &map))
3232 return NT_STATUS_NO_SUCH_ALIAS;
3234 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3235 DEBUG(10, ("lookup on Server SID\n"));
3236 if(!get_local_group_from_sid(als_sid, &map))
3237 return NT_STATUS_NO_SUCH_ALIAS;
3241 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3242 return NT_STATUS_NO_SUCH_ALIAS;
3244 DEBUG(10, ("sid is %s\n", alias_sid_str));
3245 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3246 if (num_uids!=0 && sid == NULL)
3247 return NT_STATUS_NO_MEMORY;
3249 for (i = 0; i < num_uids; i++) {
3250 struct passwd *pass;
3253 sid_copy(&temp_sid, get_global_sam_sid());
3255 pass = getpwuid_alloc(uid[i]);
3256 if (!pass) continue;
3258 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3264 check = pdb_getsampwnam(sam_user, pass->pw_name);
3267 if (check != True) {
3268 pdb_free_sam(&sam_user);
3273 rid = pdb_get_user_rid(sam_user);
3275 pdb_free_sam(&sam_user);
3280 pdb_free_sam(&sam_user);
3283 sid_append_rid(&temp_sid, rid);
3285 init_dom_sid2(&sid[i], &temp_sid);
3288 DEBUG(10, ("sid is %s\n", alias_sid_str));
3289 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3291 return NT_STATUS_OK;
3294 /*********************************************************************
3295 _samr_query_groupmem
3296 *********************************************************************/
3298 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3304 fstring group_sid_str;
3312 SAM_ACCOUNT *sam_user = NULL;
3316 /* find the policy handle. open a policy on it. */
3317 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3318 return NT_STATUS_INVALID_HANDLE;
3320 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3324 /* todo: change to use sid_compare_front */
3326 sid_split_rid(&group_sid, &group_rid);
3327 sid_to_string(group_sid_str, &group_sid);
3328 DEBUG(10, ("sid is %s\n", group_sid_str));
3330 /* can we get a query for an SID outside our domain ? */
3331 if (!sid_equal(&group_sid, get_global_sam_sid()))
3332 return NT_STATUS_NO_SUCH_GROUP;
3334 sid_append_rid(&group_sid, group_rid);
3335 DEBUG(10, ("lookup on Domain SID\n"));
3337 if(!get_domain_group_from_sid(group_sid, &map))
3338 return NT_STATUS_NO_SUCH_GROUP;
3340 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3341 return NT_STATUS_NO_SUCH_GROUP;
3343 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3344 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3346 if (num_uids!=0 && (rid==NULL || attr==NULL))
3347 return NT_STATUS_NO_MEMORY;
3349 for (i=0; i<num_uids; i++) {
3350 struct passwd *pass;
3353 pass = getpwuid_alloc(uid[i]);
3354 if (!pass) continue;
3356 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3362 check = pdb_getsampwnam(sam_user, pass->pw_name);
3365 if (check != True) {
3366 pdb_free_sam(&sam_user);
3371 urid = pdb_get_user_rid(sam_user);
3373 pdb_free_sam(&sam_user);
3378 pdb_free_sam(&sam_user);
3382 attr[i] = SID_NAME_USER;
3385 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3387 return NT_STATUS_OK;
3390 /*********************************************************************
3392 *********************************************************************/
3394 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3397 fstring alias_sid_str;
3404 SAM_ACCOUNT *sam_user = NULL;
3408 /* Find the policy handle. Open a policy on it. */
3409 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3410 return NT_STATUS_INVALID_HANDLE;
3412 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3416 sid_to_string(alias_sid_str, &alias_sid);
3417 DEBUG(10, ("sid is %s\n", alias_sid_str));
3419 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3420 DEBUG(10, ("adding member on Server SID\n"));
3421 if(!get_local_group_from_sid(alias_sid, &map))
3422 return NT_STATUS_NO_SUCH_ALIAS;
3425 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3426 DEBUG(10, ("adding member on BUILTIN SID\n"));
3427 if( !get_local_group_from_sid(alias_sid, &map))
3428 return NT_STATUS_NO_SUCH_ALIAS;
3431 return NT_STATUS_NO_SUCH_ALIAS;
3434 ret = pdb_init_sam(&sam_user);
3435 if (!NT_STATUS_IS_OK(ret))
3438 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3440 if (check != True) {
3441 pdb_free_sam(&sam_user);
3442 return NT_STATUS_NO_SUCH_USER;
3445 /* check a real user exist before we run the script to add a user to a group */
3446 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3447 pdb_free_sam(&sam_user);
3448 return NT_STATUS_NO_SUCH_USER;
3451 pdb_free_sam(&sam_user);
3453 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3454 return NT_STATUS_NO_SUCH_USER;
3457 if ((grp=getgrgid(map.gid)) == NULL) {
3459 return NT_STATUS_NO_SUCH_ALIAS;
3462 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3463 fstrcpy(grp_name, grp->gr_name);
3465 /* if the user is already in the group */
3466 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3468 return NT_STATUS_MEMBER_IN_ALIAS;
3472 * ok, the group exist, the user exist, the user is not in the group,
3473 * we can (finally) add it to the group !
3475 smb_add_user_group(grp_name, pwd->pw_name);
3477 /* check if the user has been added then ... */
3478 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3480 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3484 return NT_STATUS_OK;
3487 /*********************************************************************
3489 *********************************************************************/
3491 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3494 fstring alias_sid_str;
3498 SAM_ACCOUNT *sam_pass=NULL;
3501 /* Find the policy handle. Open a policy on it. */
3502 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3503 return NT_STATUS_INVALID_HANDLE;
3505 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3509 sid_to_string(alias_sid_str, &alias_sid);
3510 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3512 if (!sid_check_is_in_our_domain(&alias_sid) &&
3513 !sid_check_is_in_builtin(&alias_sid)) {
3514 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3515 return NT_STATUS_NO_SUCH_ALIAS;
3518 if( !get_local_group_from_sid(alias_sid, &map))
3519 return NT_STATUS_NO_SUCH_ALIAS;
3521 if ((grp=getgrgid(map.gid)) == NULL)
3522 return NT_STATUS_NO_SUCH_ALIAS;
3524 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3525 fstrcpy(grp_name, grp->gr_name);
3527 /* check if the user exists before trying to remove it from the group */
3528 pdb_init_sam(&sam_pass);
3529 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3530 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3531 pdb_free_sam(&sam_pass);
3532 return NT_STATUS_NO_SUCH_USER;
3535 /* if the user is not in the group */
3536 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3537 pdb_free_sam(&sam_pass);
3538 return NT_STATUS_MEMBER_IN_ALIAS;
3541 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3543 /* check if the user has been removed then ... */
3544 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3545 pdb_free_sam(&sam_pass);
3546 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3549 pdb_free_sam(&sam_pass);
3550 return NT_STATUS_OK;
3553 /*********************************************************************
3555 *********************************************************************/
3557 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3561 fstring group_sid_str;
3568 SAM_ACCOUNT *sam_user=NULL;
3572 /* Find the policy handle. Open a policy on it. */
3573 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3574 return NT_STATUS_INVALID_HANDLE;
3576 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3580 sid_to_string(group_sid_str, &group_sid);
3581 DEBUG(10, ("sid is %s\n", group_sid_str));
3583 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3584 return NT_STATUS_NO_SUCH_GROUP;
3586 DEBUG(10, ("lookup on Domain SID\n"));
3588 if(!get_domain_group_from_sid(group_sid, &map))
3589 return NT_STATUS_NO_SUCH_GROUP;
3591 sid_copy(&user_sid, get_global_sam_sid());
3592 sid_append_rid(&user_sid, q_u->rid);
3594 ret = pdb_init_sam(&sam_user);
3595 if (!NT_STATUS_IS_OK(ret))
3598 check = pdb_getsampwsid(sam_user, &user_sid);
3600 if (check != True) {
3601 pdb_free_sam(&sam_user);
3602 return NT_STATUS_NO_SUCH_USER;
3605 /* check a real user exist before we run the script to add a user to a group */
3606 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3607 pdb_free_sam(&sam_user);
3608 return NT_STATUS_NO_SUCH_USER;
3611 pdb_free_sam(&sam_user);
3613 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3614 return NT_STATUS_NO_SUCH_USER;
3617 if ((grp=getgrgid(map.gid)) == NULL) {
3619 return NT_STATUS_NO_SUCH_GROUP;
3622 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3623 fstrcpy(grp_name, grp->gr_name);
3625 /* if the user is already in the group */
3626 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3628 return NT_STATUS_MEMBER_IN_GROUP;
3632 * ok, the group exist, the user exist, the user is not in the group,
3634 * we can (finally) add it to the group !
3637 smb_add_user_group(grp_name, pwd->pw_name);
3639 /* check if the user has been added then ... */
3640 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3642 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3646 return NT_STATUS_OK;
3649 /*********************************************************************
3651 *********************************************************************/
3653 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3657 SAM_ACCOUNT *sam_pass=NULL;
3664 * delete the group member named q_u->rid
3665 * who is a member of the sid associated with the handle
3666 * the rid is a user's rid as the group is a domain group.
3669 /* Find the policy handle. Open a policy on it. */
3670 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3671 return NT_STATUS_INVALID_HANDLE;
3673 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3677 if (!sid_check_is_in_our_domain(&group_sid))
3678 return NT_STATUS_NO_SUCH_GROUP;
3680 sid_copy(&user_sid, get_global_sam_sid());
3681 sid_append_rid(&user_sid, q_u->rid);
3683 if (!get_domain_group_from_sid(group_sid, &map))
3684 return NT_STATUS_NO_SUCH_GROUP;
3686 if ((grp=getgrgid(map.gid)) == NULL)
3687 return NT_STATUS_NO_SUCH_GROUP;
3689 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3690 fstrcpy(grp_name, grp->gr_name);
3692 /* check if the user exists before trying to remove it from the group */
3693 pdb_init_sam(&sam_pass);
3694 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3695 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3696 pdb_free_sam(&sam_pass);
3697 return NT_STATUS_NO_SUCH_USER;
3700 /* if the user is not in the group */
3701 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3702 pdb_free_sam(&sam_pass);
3703 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3706 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3708 /* check if the user has been removed then ... */
3709 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3710 pdb_free_sam(&sam_pass);
3711 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3714 pdb_free_sam(&sam_pass);
3715 return NT_STATUS_OK;
3719 /****************************************************************************
3720 Delete a UNIX user on demand.
3721 ****************************************************************************/
3723 static int smb_delete_user(const char *unix_user)
3728 /* try winbindd first since it is impossible to determine where
3729 a user came from via NSS. Try the delete user script if this fails
3730 meaning the user did not exist in winbindd's list of accounts */
3732 if ( winbind_delete_user( unix_user ) ) {
3733 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3738 /* fall back to 'delete user script' */
3740 pstrcpy(del_script, lp_deluser_script());
3743 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3744 ret = smbrun(del_script,NULL);
3745 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3750 /*********************************************************************
3751 _samr_delete_dom_user
3752 *********************************************************************/
3754 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3757 SAM_ACCOUNT *sam_pass=NULL;
3760 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3762 /* Find the policy handle. Open a policy on it. */
3763 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3764 return NT_STATUS_INVALID_HANDLE;
3766 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3770 if (!sid_check_is_in_our_domain(&user_sid))
3771 return NT_STATUS_CANNOT_DELETE;
3773 /* check if the user exists before trying to delete */
3774 pdb_init_sam(&sam_pass);
3775 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3776 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3777 pdb_free_sam(&sam_pass);
3778 return NT_STATUS_NO_SUCH_USER;
3781 /* delete the unix side */
3783 * note: we don't check if the delete really happened
3784 * as the script is not necessary present
3785 * and maybe the sysadmin doesn't want to delete the unix side
3787 smb_delete_user(pdb_get_username(sam_pass));
3789 /* and delete the samba side */
3790 if (!pdb_delete_sam_account(sam_pass)) {
3791 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3792 pdb_free_sam(&sam_pass);
3793 return NT_STATUS_CANNOT_DELETE;
3796 pdb_free_sam(&sam_pass);
3798 if (!close_policy_hnd(p, &q_u->user_pol))
3799 return NT_STATUS_OBJECT_NAME_INVALID;
3801 return NT_STATUS_OK;
3804 /*********************************************************************
3805 _samr_delete_dom_group
3806 *********************************************************************/
3808 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3813 fstring group_sid_str;
3819 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3821 /* Find the policy handle. Open a policy on it. */
3822 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3823 return NT_STATUS_INVALID_HANDLE;
3825 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3829 sid_copy(&dom_sid, &group_sid);
3830 sid_to_string(group_sid_str, &dom_sid);
3831 sid_split_rid(&dom_sid, &group_rid);
3833 DEBUG(10, ("sid is %s\n", group_sid_str));
3835 /* we check if it's our SID before deleting */
3836 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3837 return NT_STATUS_NO_SUCH_GROUP;
3839 DEBUG(10, ("lookup on Domain SID\n"));
3841 if(!get_domain_group_from_sid(group_sid, &map))
3842 return NT_STATUS_NO_SUCH_GROUP;
3846 /* check if group really exists */
3847 if ( (grp=getgrgid(gid)) == NULL)
3848 return NT_STATUS_NO_SUCH_GROUP;
3850 /* we can delete the UNIX group */
3851 smb_delete_group(grp->gr_name);
3853 /* check if the group has been successfully deleted */
3854 if ( (grp=getgrgid(gid)) != NULL)
3855 return NT_STATUS_ACCESS_DENIED;
3857 if(!pdb_delete_group_mapping_entry(group_sid))
3858 return NT_STATUS_ACCESS_DENIED;
3860 if (!close_policy_hnd(p, &q_u->group_pol))
3861 return NT_STATUS_OBJECT_NAME_INVALID;
3863 return NT_STATUS_OK;
3866 /*********************************************************************
3867 _samr_delete_dom_alias
3868 *********************************************************************/
3870 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3875 fstring alias_sid_str;
3881 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3883 /* Find the policy handle. Open a policy on it. */
3884 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3885 return NT_STATUS_INVALID_HANDLE;
3887 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3891 sid_copy(&dom_sid, &alias_sid);
3892 sid_to_string(alias_sid_str, &dom_sid);
3893 sid_split_rid(&dom_sid, &alias_rid);
3895 DEBUG(10, ("sid is %s\n", alias_sid_str));
3897 /* we check if it's our SID before deleting */
3898 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3899 return NT_STATUS_NO_SUCH_ALIAS;
3901 DEBUG(10, ("lookup on Local SID\n"));
3903 if(!get_local_group_from_sid(alias_sid, &map))
3904 return NT_STATUS_NO_SUCH_ALIAS;
3908 /* check if group really exists */
3909 if ( (grp=getgrgid(gid)) == NULL)
3910 return NT_STATUS_NO_SUCH_ALIAS;
3912 /* we can delete the UNIX group */
3913 smb_delete_group(grp->gr_name);
3915 /* check if the group has been successfully deleted */
3916 if ( (grp=getgrgid(gid)) != NULL)
3917 return NT_STATUS_ACCESS_DENIED;
3919 /* don't check if we removed it as it could be an un-mapped group */
3920 pdb_delete_group_mapping_entry(alias_sid);
3922 if (!close_policy_hnd(p, &q_u->alias_pol))
3923 return NT_STATUS_OBJECT_NAME_INVALID;
3925 return NT_STATUS_OK;
3928 /*********************************************************************
3929 _samr_create_dom_group
3930 *********************************************************************/
3932 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3939 struct samr_info *info;
3943 /* Find the policy handle. Open a policy on it. */
3944 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3945 return NT_STATUS_INVALID_HANDLE;
3947 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3951 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3952 return NT_STATUS_ACCESS_DENIED;
3954 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3956 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3958 /* check if group already exist */
3959 if ((grp=getgrnam(name)) != NULL)
3960 return NT_STATUS_GROUP_EXISTS;
3962 /* we can create the UNIX group */
3963 if (smb_create_group(name, &gid) != 0)
3964 return NT_STATUS_ACCESS_DENIED;
3966 /* check if the group has been successfully created */
3967 if ((grp=getgrgid(gid)) == NULL)
3968 return NT_STATUS_ACCESS_DENIED;
3970 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3972 /* add the group to the mapping table */
3973 sid_copy(&info_sid, get_global_sam_sid());
3974 sid_append_rid(&info_sid, r_u->rid);
3975 sid_to_string(sid_string, &info_sid);
3977 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3978 return NT_STATUS_ACCESS_DENIED;
3980 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3981 return NT_STATUS_NO_MEMORY;
3983 /* get a (unique) handle. open a policy on it. */
3984 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3985 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3987 return NT_STATUS_OK;
3990 /*********************************************************************
3991 _samr_create_dom_alias
3992 *********************************************************************/
3994 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4001 struct samr_info *info;
4005 /* Find the policy handle. Open a policy on it. */
4006 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4007 return NT_STATUS_INVALID_HANDLE;
4009 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4013 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4014 return NT_STATUS_ACCESS_DENIED;
4016 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4018 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4020 /* check if group already exists */
4021 if ( (grp=getgrnam(name)) != NULL)
4022 return NT_STATUS_GROUP_EXISTS;
4024 /* we can create the UNIX group */
4025 if (smb_create_group(name, &gid) != 0)
4026 return NT_STATUS_ACCESS_DENIED;
4028 /* check if the group has been successfully created */
4029 if ((grp=getgrgid(gid)) == NULL)
4030 return NT_STATUS_ACCESS_DENIED;
4032 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4034 sid_copy(&info_sid, get_global_sam_sid());
4035 sid_append_rid(&info_sid, r_u->rid);
4036 sid_to_string(sid_string, &info_sid);
4038 /* add the group to the mapping table */
4039 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
4040 return NT_STATUS_ACCESS_DENIED;
4042 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4043 return NT_STATUS_NO_MEMORY;
4045 /* get a (unique) handle. open a policy on it. */
4046 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4047 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4049 return NT_STATUS_OK;
4052 /*********************************************************************
4053 _samr_query_groupinfo
4055 sends the name/comment pair of a domain group
4056 level 1 send also the number of users of that group
4057 *********************************************************************/
4059 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4065 GROUP_INFO_CTR *ctr;
4068 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4069 return NT_STATUS_INVALID_HANDLE;
4071 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4075 if (!get_domain_group_from_sid(group_sid, &map))
4076 return NT_STATUS_INVALID_HANDLE;
4078 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4080 return NT_STATUS_NO_MEMORY;
4082 switch (q_u->switch_level) {
4084 ctr->switch_value1 = 1;
4085 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4086 return NT_STATUS_NO_SUCH_GROUP;
4087 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4091 ctr->switch_value1 = 3;
4092 init_samr_group_info3(&ctr->group.info3);
4095 ctr->switch_value1 = 4;
4096 init_samr_group_info4(&ctr->group.info4, map.comment);
4099 return NT_STATUS_INVALID_INFO_CLASS;
4102 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4104 return NT_STATUS_OK;
4107 /*********************************************************************
4110 update a domain group's comment.
4111 *********************************************************************/
4113 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4117 GROUP_INFO_CTR *ctr;
4120 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4121 return NT_STATUS_INVALID_HANDLE;
4123 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4127 if (!get_domain_group_from_sid(group_sid, &map))
4128 return NT_STATUS_NO_SUCH_GROUP;
4132 switch (ctr->switch_value1) {
4134 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4137 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4140 return NT_STATUS_INVALID_INFO_CLASS;
4143 if(!pdb_update_group_mapping_entry(&map)) {
4144 return NT_STATUS_NO_SUCH_GROUP;
4147 return NT_STATUS_OK;
4150 /*********************************************************************
4153 update an alias's comment.
4154 *********************************************************************/
4156 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4160 ALIAS_INFO_CTR *ctr;
4163 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4164 return NT_STATUS_INVALID_HANDLE;
4166 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4170 if (!get_local_group_from_sid(group_sid, &map))
4171 return NT_STATUS_NO_SUCH_GROUP;
4175 switch (ctr->switch_value1) {
4177 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4180 return NT_STATUS_INVALID_INFO_CLASS;
4183 if(!pdb_update_group_mapping_entry(&map)) {
4184 return NT_STATUS_NO_SUCH_GROUP;
4187 return NT_STATUS_OK;
4190 /*********************************************************************
4191 _samr_get_dom_pwinfo
4192 *********************************************************************/
4194 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4196 /* Perform access check. Since this rpc does not require a
4197 policy handle it will not be caught by the access checks on
4198 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4200 if (!pipe_access_check(p)) {
4201 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4202 r_u->status = NT_STATUS_ACCESS_DENIED;
4206 /* Actually, returning zeros here works quite well :-). */
4208 return NT_STATUS_OK;
4211 /*********************************************************************
4213 *********************************************************************/
4215 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4220 struct samr_info *info;
4221 SEC_DESC *psd = NULL;
4228 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4229 return NT_STATUS_INVALID_HANDLE;
4231 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4235 /*check if access can be granted as requested by client. */
4236 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4237 se_map_generic(&des_access,&grp_generic_mapping);
4238 if (!NT_STATUS_IS_OK(status =
4239 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4240 des_access, &acc_granted, "_samr_open_group"))) {
4245 /* this should not be hard-coded like this */
4246 if (!sid_equal(&sid, get_global_sam_sid()))
4247 return NT_STATUS_ACCESS_DENIED;
4249 sid_copy(&info_sid, get_global_sam_sid());
4250 sid_append_rid(&info_sid, q_u->rid_group);
4251 sid_to_string(sid_string, &info_sid);
4253 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4254 return NT_STATUS_NO_MEMORY;
4256 info->acc_granted = acc_granted;
4258 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4260 /* check if that group really exists */
4261 if (!get_domain_group_from_sid(info->sid, &map))
4262 return NT_STATUS_NO_SUCH_GROUP;
4264 /* get a (unique) handle. open a policy on it. */
4265 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4266 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4268 return NT_STATUS_OK;
4271 /*********************************************************************
4273 *********************************************************************/
4275 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4277 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4278 return NT_STATUS_NOT_IMPLEMENTED;
4281 /*******************************************************************
4283 ********************************************************************/
4285 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4287 struct samr_info *info = NULL;
4289 uint32 min_pass_len,pass_hist,flag;
4290 time_t u_expire, u_min_age;
4291 NTTIME nt_expire, nt_min_age;
4293 time_t u_lock_duration, u_reset_time;
4294 NTTIME nt_lock_duration, nt_reset_time;
4300 uint32 num_users=0, num_groups=0, num_aliases=0;
4302 uint32 account_policy_temp;
4304 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4305 return NT_STATUS_NO_MEMORY;
4309 r_u->status = NT_STATUS_OK;
4311 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4313 /* find the policy handle. open a policy on it. */
4314 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4315 return NT_STATUS_INVALID_HANDLE;
4317 switch (q_u->switch_value) {
4319 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4320 min_pass_len = account_policy_temp;
4322 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4323 pass_hist = account_policy_temp;
4325 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4326 flag = account_policy_temp;
4328 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4329 u_expire = account_policy_temp;
4331 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4332 u_min_age = account_policy_temp;
4334 unix_to_nt_time_abs(&nt_expire, u_expire);
4335 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4337 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4338 flag, nt_expire, nt_min_age);
4342 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4344 if (!NT_STATUS_IS_OK(r_u->status)) {
4345 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4348 num_users=info->disp_info.num_user_account;
4351 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4352 if (NT_STATUS_IS_ERR(r_u->status)) {
4353 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4356 num_groups=info->disp_info.num_group_account;
4359 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4360 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4361 num_users, num_groups, num_aliases);
4364 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4365 u_logout = account_policy_temp;
4367 unix_to_nt_time_abs(&nt_logout, u_logout);
4369 init_unk_info3(&ctr->info.inf3, nt_logout);
4372 init_unk_info5(&ctr->info.inf5, global_myname());
4375 init_unk_info6(&ctr->info.inf6);
4378 init_unk_info7(&ctr->info.inf7);
4381 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4382 u_lock_duration = account_policy_temp;
4384 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4385 u_reset_time = account_policy_temp;
4387 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4388 lockout = account_policy_temp;
4390 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4391 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4393 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4396 return NT_STATUS_INVALID_INFO_CLASS;
4399 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4401 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4406 /*******************************************************************
4408 ********************************************************************/
4410 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4412 time_t u_expire, u_min_age;
4414 time_t u_lock_duration, u_reset_time;
4416 r_u->status = NT_STATUS_OK;
4418 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4420 /* find the policy handle. open a policy on it. */
4421 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4422 return NT_STATUS_INVALID_HANDLE;
4424 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4426 switch (q_u->switch_value) {
4428 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4429 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4431 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4432 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4433 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4434 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4435 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4440 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4441 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4450 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4451 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4453 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4454 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4455 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4458 return NT_STATUS_INVALID_INFO_CLASS;
4461 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4463 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));