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 %l 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 %lu for "
2765 "user %s\n", (unsigned long)gid,
2766 pdb_get_username(sampass)));
2770 if (smb_set_primary_group(grp->gr_name,
2771 pdb_get_username(sampass)) != 0) {
2772 DEBUG(2,("Could not set primary group for user %s to "
2774 pdb_get_username(sampass), grp->gr_name));
2782 /*******************************************************************
2784 ********************************************************************/
2786 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2788 SAM_ACCOUNT *pwd = NULL;
2791 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2797 if (!pdb_getsampwsid(pwd, sid)) {
2802 copy_id21_to_sam_passwd(pwd, id21);
2805 * The funny part about the previous two calls is
2806 * that pwd still has the password hashes from the
2807 * passdb entry. These have not been updated from
2808 * id21. I don't know if they need to be set. --jerry
2811 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2812 set_unix_primary_group(pwd);
2814 /* write the change out */
2815 if(!pdb_update_sam_account(pwd)) {
2825 /*******************************************************************
2827 ********************************************************************/
2829 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2831 SAM_ACCOUNT *pwd = NULL;
2832 pstring plaintext_buf;
2837 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2843 if (!pdb_getsampwsid(pwd, sid)) {
2848 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2849 pdb_get_username(pwd)));
2851 acct_ctrl = pdb_get_acct_ctrl(pwd);
2853 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2858 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2863 copy_id23_to_sam_passwd(pwd, id23);
2865 /* if it's a trust account, don't update /etc/passwd */
2866 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2867 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2868 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2869 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2871 /* update the UNIX password */
2872 if (lp_unix_password_sync() )
2873 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2879 ZERO_STRUCT(plaintext_buf);
2881 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2882 set_unix_primary_group(pwd);
2884 if(!pdb_update_sam_account(pwd)) {
2894 /*******************************************************************
2896 ********************************************************************/
2898 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2900 SAM_ACCOUNT *pwd = NULL;
2902 pstring plaintext_buf;
2907 if (!pdb_getsampwsid(pwd, sid)) {
2912 DEBUG(5, ("Attempting administrator password change for user %s\n",
2913 pdb_get_username(pwd)));
2915 acct_ctrl = pdb_get_acct_ctrl(pwd);
2917 ZERO_STRUCT(plaintext_buf);
2919 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2924 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2929 /* if it's a trust account, don't update /etc/passwd */
2930 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2931 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2932 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2933 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2935 /* update the UNIX password */
2936 if (lp_unix_password_sync()) {
2937 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2944 ZERO_STRUCT(plaintext_buf);
2946 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2948 /* update the SAMBA password */
2949 if(!pdb_update_sam_account(pwd)) {
2959 /*******************************************************************
2960 samr_reply_set_userinfo
2961 ********************************************************************/
2963 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2966 POLICY_HND *pol = &q_u->pol;
2967 uint16 switch_value = q_u->switch_value;
2968 SAM_USERINFO_CTR *ctr = q_u->ctr;
2970 uint32 acc_required;
2972 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2974 r_u->status = NT_STATUS_OK;
2976 /* find the policy handle. open a policy on it. */
2977 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2978 return NT_STATUS_INVALID_HANDLE;
2980 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2981 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2985 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2988 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2989 return NT_STATUS_INVALID_INFO_CLASS;
2992 /* ok! user info levels (lots: see MSDEV help), off we go... */
2993 switch (switch_value) {
2995 if (!set_user_info_12(ctr->info.id12, &sid))
2996 return NT_STATUS_ACCESS_DENIED;
3000 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
3002 dump_data(100, (char *)ctr->info.id24->pass, 516);
3004 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3005 return NT_STATUS_ACCESS_DENIED;
3011 * Currently we don't really know how to unmarshall
3012 * the level 25 struct, and the password encryption
3013 * is different. This is a placeholder for when we
3014 * do understand it. In the meantime just return INVALID
3015 * info level and W2K SP2 drops down to level 23... JRA.
3018 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3020 dump_data(100, (char *)ctr->info.id25->pass, 532);
3022 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3023 return NT_STATUS_ACCESS_DENIED;
3026 return NT_STATUS_INVALID_INFO_CLASS;
3029 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3031 dump_data(100, (char *)ctr->info.id23->pass, 516);
3033 if (!set_user_info_23(ctr->info.id23, &sid))
3034 return NT_STATUS_ACCESS_DENIED;
3038 return NT_STATUS_INVALID_INFO_CLASS;
3044 /*******************************************************************
3045 samr_reply_set_userinfo2
3046 ********************************************************************/
3048 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3051 SAM_USERINFO_CTR *ctr = q_u->ctr;
3052 POLICY_HND *pol = &q_u->pol;
3053 uint16 switch_value = q_u->switch_value;
3055 uint32 acc_required;
3057 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3059 r_u->status = NT_STATUS_OK;
3061 /* find the policy handle. open a policy on it. */
3062 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3063 return NT_STATUS_INVALID_HANDLE;
3065 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3066 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3070 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3073 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3074 return NT_STATUS_INVALID_INFO_CLASS;
3077 switch_value=ctr->switch_value;
3079 /* ok! user info levels (lots: see MSDEV help), off we go... */
3080 switch (switch_value) {
3082 if (!set_user_info_21(ctr->info.id21, &sid))
3083 return NT_STATUS_ACCESS_DENIED;
3086 if (!set_user_info_10(ctr->info.id10, &sid))
3087 return NT_STATUS_ACCESS_DENIED;
3090 /* Used by AS/U JRA. */
3091 if (!set_user_info_12(ctr->info.id12, &sid))
3092 return NT_STATUS_ACCESS_DENIED;
3095 return NT_STATUS_INVALID_INFO_CLASS;
3101 /*********************************************************************
3102 _samr_query_aliasmem
3103 *********************************************************************/
3105 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3107 int num_groups = 0, tmp_num_groups=0;
3108 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3109 struct samr_info *info = NULL;
3115 /* until i see a real useraliases query, we fack one up */
3117 /* I have seen one, JFM 2/12/2001 */
3119 * Explanation of what this call does:
3120 * for all the SID given in the request:
3121 * return a list of alias (local groups)
3122 * that have those SID as members.
3124 * and that's the alias in the domain specified
3125 * in the policy_handle
3127 * if the policy handle is on an incorrect sid
3128 * for example a user's sid
3129 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3132 r_u->status = NT_STATUS_OK;
3134 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3136 /* find the policy handle. open a policy on it. */
3137 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3138 return NT_STATUS_INVALID_HANDLE;
3140 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3141 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3143 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3144 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3145 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3146 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3150 if (!sid_check_is_domain(&info->sid) &&
3151 !sid_check_is_builtin(&info->sid))
3152 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3155 for (i=0; i<q_u->num_sids1; i++) {
3157 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3160 * if there is an error, we just continue as
3161 * it can be an unfound user or group
3163 if (!NT_STATUS_IS_OK(r_u->status)) {
3164 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3168 if (tmp_num_groups==0) {
3169 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3173 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3174 if (new_rids==NULL) {
3175 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3176 return NT_STATUS_NO_MEMORY;
3180 for (j=0; j<tmp_num_groups; j++)
3181 rids[j+num_groups]=tmp_rids[j];
3183 safe_free(tmp_rids);
3185 num_groups+=tmp_num_groups;
3188 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3189 return NT_STATUS_OK;
3192 /*********************************************************************
3193 _samr_query_aliasmem
3194 *********************************************************************/
3196 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3208 fstring alias_sid_str;
3211 SAM_ACCOUNT *sam_user = NULL;
3215 /* find the policy handle. open a policy on it. */
3216 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3217 return NT_STATUS_INVALID_HANDLE;
3219 if (!NT_STATUS_IS_OK(r_u->status =
3220 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3224 sid_copy(&als_sid, &alias_sid);
3225 sid_to_string(alias_sid_str, &alias_sid);
3226 sid_split_rid(&alias_sid, &alias_rid);
3228 DEBUG(10, ("sid is %s\n", alias_sid_str));
3230 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3231 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3232 if(!get_builtin_group_from_sid(als_sid, &map))
3233 return NT_STATUS_NO_SUCH_ALIAS;
3235 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3236 DEBUG(10, ("lookup on Server SID\n"));
3237 if(!get_local_group_from_sid(als_sid, &map))
3238 return NT_STATUS_NO_SUCH_ALIAS;
3242 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3243 return NT_STATUS_NO_SUCH_ALIAS;
3245 DEBUG(10, ("sid is %s\n", alias_sid_str));
3246 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3247 if (num_uids!=0 && sid == NULL)
3248 return NT_STATUS_NO_MEMORY;
3250 for (i = 0; i < num_uids; i++) {
3251 struct passwd *pass;
3254 sid_copy(&temp_sid, get_global_sam_sid());
3256 pass = getpwuid_alloc(uid[i]);
3257 if (!pass) continue;
3259 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3265 check = pdb_getsampwnam(sam_user, pass->pw_name);
3268 if (check != True) {
3269 pdb_free_sam(&sam_user);
3274 rid = pdb_get_user_rid(sam_user);
3276 pdb_free_sam(&sam_user);
3281 pdb_free_sam(&sam_user);
3284 sid_append_rid(&temp_sid, rid);
3286 init_dom_sid2(&sid[i], &temp_sid);
3289 DEBUG(10, ("sid is %s\n", alias_sid_str));
3290 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3292 return NT_STATUS_OK;
3295 /*********************************************************************
3296 _samr_query_groupmem
3297 *********************************************************************/
3299 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3305 fstring group_sid_str;
3313 SAM_ACCOUNT *sam_user = NULL;
3317 /* find the policy handle. open a policy on it. */
3318 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3319 return NT_STATUS_INVALID_HANDLE;
3321 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3325 /* todo: change to use sid_compare_front */
3327 sid_split_rid(&group_sid, &group_rid);
3328 sid_to_string(group_sid_str, &group_sid);
3329 DEBUG(10, ("sid is %s\n", group_sid_str));
3331 /* can we get a query for an SID outside our domain ? */
3332 if (!sid_equal(&group_sid, get_global_sam_sid()))
3333 return NT_STATUS_NO_SUCH_GROUP;
3335 sid_append_rid(&group_sid, group_rid);
3336 DEBUG(10, ("lookup on Domain SID\n"));
3338 if(!get_domain_group_from_sid(group_sid, &map))
3339 return NT_STATUS_NO_SUCH_GROUP;
3341 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3342 return NT_STATUS_NO_SUCH_GROUP;
3344 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3345 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3347 if (num_uids!=0 && (rid==NULL || attr==NULL))
3348 return NT_STATUS_NO_MEMORY;
3350 for (i=0; i<num_uids; i++) {
3351 struct passwd *pass;
3354 pass = getpwuid_alloc(uid[i]);
3355 if (!pass) continue;
3357 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3363 check = pdb_getsampwnam(sam_user, pass->pw_name);
3366 if (check != True) {
3367 pdb_free_sam(&sam_user);
3372 urid = pdb_get_user_rid(sam_user);
3374 pdb_free_sam(&sam_user);
3379 pdb_free_sam(&sam_user);
3383 attr[i] = SID_NAME_USER;
3386 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3388 return NT_STATUS_OK;
3391 /*********************************************************************
3393 *********************************************************************/
3395 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3398 fstring alias_sid_str;
3405 SAM_ACCOUNT *sam_user = NULL;
3409 /* Find the policy handle. Open a policy on it. */
3410 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3411 return NT_STATUS_INVALID_HANDLE;
3413 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3417 sid_to_string(alias_sid_str, &alias_sid);
3418 DEBUG(10, ("sid is %s\n", alias_sid_str));
3420 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3421 DEBUG(10, ("adding member on Server SID\n"));
3422 if(!get_local_group_from_sid(alias_sid, &map))
3423 return NT_STATUS_NO_SUCH_ALIAS;
3426 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3427 DEBUG(10, ("adding member on BUILTIN SID\n"));
3428 if( !get_local_group_from_sid(alias_sid, &map))
3429 return NT_STATUS_NO_SUCH_ALIAS;
3432 return NT_STATUS_NO_SUCH_ALIAS;
3435 ret = pdb_init_sam(&sam_user);
3436 if (!NT_STATUS_IS_OK(ret))
3439 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3441 if (check != True) {
3442 pdb_free_sam(&sam_user);
3443 return NT_STATUS_NO_SUCH_USER;
3446 /* check a real user exist before we run the script to add a user to a group */
3447 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3448 pdb_free_sam(&sam_user);
3449 return NT_STATUS_NO_SUCH_USER;
3452 pdb_free_sam(&sam_user);
3454 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3455 return NT_STATUS_NO_SUCH_USER;
3458 if ((grp=getgrgid(map.gid)) == NULL) {
3460 return NT_STATUS_NO_SUCH_ALIAS;
3463 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3464 fstrcpy(grp_name, grp->gr_name);
3466 /* if the user is already in the group */
3467 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3469 return NT_STATUS_MEMBER_IN_ALIAS;
3473 * ok, the group exist, the user exist, the user is not in the group,
3474 * we can (finally) add it to the group !
3476 smb_add_user_group(grp_name, pwd->pw_name);
3478 /* check if the user has been added then ... */
3479 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3481 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3485 return NT_STATUS_OK;
3488 /*********************************************************************
3490 *********************************************************************/
3492 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3495 fstring alias_sid_str;
3499 SAM_ACCOUNT *sam_pass=NULL;
3502 /* Find the policy handle. Open a policy on it. */
3503 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3504 return NT_STATUS_INVALID_HANDLE;
3506 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3510 sid_to_string(alias_sid_str, &alias_sid);
3511 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3513 if (!sid_check_is_in_our_domain(&alias_sid) &&
3514 !sid_check_is_in_builtin(&alias_sid)) {
3515 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3516 return NT_STATUS_NO_SUCH_ALIAS;
3519 if( !get_local_group_from_sid(alias_sid, &map))
3520 return NT_STATUS_NO_SUCH_ALIAS;
3522 if ((grp=getgrgid(map.gid)) == NULL)
3523 return NT_STATUS_NO_SUCH_ALIAS;
3525 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3526 fstrcpy(grp_name, grp->gr_name);
3528 /* check if the user exists before trying to remove it from the group */
3529 pdb_init_sam(&sam_pass);
3530 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3531 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3532 pdb_free_sam(&sam_pass);
3533 return NT_STATUS_NO_SUCH_USER;
3536 /* if the user is not in the group */
3537 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3538 pdb_free_sam(&sam_pass);
3539 return NT_STATUS_MEMBER_IN_ALIAS;
3542 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3544 /* check if the user has been removed then ... */
3545 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3546 pdb_free_sam(&sam_pass);
3547 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3550 pdb_free_sam(&sam_pass);
3551 return NT_STATUS_OK;
3554 /*********************************************************************
3556 *********************************************************************/
3558 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3562 fstring group_sid_str;
3569 SAM_ACCOUNT *sam_user=NULL;
3573 /* Find the policy handle. Open a policy on it. */
3574 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3575 return NT_STATUS_INVALID_HANDLE;
3577 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3581 sid_to_string(group_sid_str, &group_sid);
3582 DEBUG(10, ("sid is %s\n", group_sid_str));
3584 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3585 return NT_STATUS_NO_SUCH_GROUP;
3587 DEBUG(10, ("lookup on Domain SID\n"));
3589 if(!get_domain_group_from_sid(group_sid, &map))
3590 return NT_STATUS_NO_SUCH_GROUP;
3592 sid_copy(&user_sid, get_global_sam_sid());
3593 sid_append_rid(&user_sid, q_u->rid);
3595 ret = pdb_init_sam(&sam_user);
3596 if (!NT_STATUS_IS_OK(ret))
3599 check = pdb_getsampwsid(sam_user, &user_sid);
3601 if (check != True) {
3602 pdb_free_sam(&sam_user);
3603 return NT_STATUS_NO_SUCH_USER;
3606 /* check a real user exist before we run the script to add a user to a group */
3607 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3608 pdb_free_sam(&sam_user);
3609 return NT_STATUS_NO_SUCH_USER;
3612 pdb_free_sam(&sam_user);
3614 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3615 return NT_STATUS_NO_SUCH_USER;
3618 if ((grp=getgrgid(map.gid)) == NULL) {
3620 return NT_STATUS_NO_SUCH_GROUP;
3623 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3624 fstrcpy(grp_name, grp->gr_name);
3626 /* if the user is already in the group */
3627 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3629 return NT_STATUS_MEMBER_IN_GROUP;
3633 * ok, the group exist, the user exist, the user is not in the group,
3635 * we can (finally) add it to the group !
3638 smb_add_user_group(grp_name, pwd->pw_name);
3640 /* check if the user has been added then ... */
3641 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3643 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3647 return NT_STATUS_OK;
3650 /*********************************************************************
3652 *********************************************************************/
3654 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3658 SAM_ACCOUNT *sam_pass=NULL;
3665 * delete the group member named q_u->rid
3666 * who is a member of the sid associated with the handle
3667 * the rid is a user's rid as the group is a domain group.
3670 /* Find the policy handle. Open a policy on it. */
3671 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3672 return NT_STATUS_INVALID_HANDLE;
3674 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3678 if (!sid_check_is_in_our_domain(&group_sid))
3679 return NT_STATUS_NO_SUCH_GROUP;
3681 sid_copy(&user_sid, get_global_sam_sid());
3682 sid_append_rid(&user_sid, q_u->rid);
3684 if (!get_domain_group_from_sid(group_sid, &map))
3685 return NT_STATUS_NO_SUCH_GROUP;
3687 if ((grp=getgrgid(map.gid)) == NULL)
3688 return NT_STATUS_NO_SUCH_GROUP;
3690 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3691 fstrcpy(grp_name, grp->gr_name);
3693 /* check if the user exists before trying to remove it from the group */
3694 pdb_init_sam(&sam_pass);
3695 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3696 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3697 pdb_free_sam(&sam_pass);
3698 return NT_STATUS_NO_SUCH_USER;
3701 /* if the user is not in the group */
3702 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3703 pdb_free_sam(&sam_pass);
3704 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3707 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3709 /* check if the user has been removed then ... */
3710 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3711 pdb_free_sam(&sam_pass);
3712 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3715 pdb_free_sam(&sam_pass);
3716 return NT_STATUS_OK;
3720 /****************************************************************************
3721 Delete a UNIX user on demand.
3722 ****************************************************************************/
3724 static int smb_delete_user(const char *unix_user)
3729 /* try winbindd first since it is impossible to determine where
3730 a user came from via NSS. Try the delete user script if this fails
3731 meaning the user did not exist in winbindd's list of accounts */
3733 if ( winbind_delete_user( unix_user ) ) {
3734 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3739 /* fall back to 'delete user script' */
3741 pstrcpy(del_script, lp_deluser_script());
3744 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3745 ret = smbrun(del_script,NULL);
3746 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3751 /*********************************************************************
3752 _samr_delete_dom_user
3753 *********************************************************************/
3755 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3758 SAM_ACCOUNT *sam_pass=NULL;
3761 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3763 /* Find the policy handle. Open a policy on it. */
3764 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3765 return NT_STATUS_INVALID_HANDLE;
3767 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3771 if (!sid_check_is_in_our_domain(&user_sid))
3772 return NT_STATUS_CANNOT_DELETE;
3774 /* check if the user exists before trying to delete */
3775 pdb_init_sam(&sam_pass);
3776 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3777 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3778 pdb_free_sam(&sam_pass);
3779 return NT_STATUS_NO_SUCH_USER;
3782 /* delete the unix side */
3784 * note: we don't check if the delete really happened
3785 * as the script is not necessary present
3786 * and maybe the sysadmin doesn't want to delete the unix side
3788 smb_delete_user(pdb_get_username(sam_pass));
3790 /* and delete the samba side */
3791 if (!pdb_delete_sam_account(sam_pass)) {
3792 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3793 pdb_free_sam(&sam_pass);
3794 return NT_STATUS_CANNOT_DELETE;
3797 pdb_free_sam(&sam_pass);
3799 if (!close_policy_hnd(p, &q_u->user_pol))
3800 return NT_STATUS_OBJECT_NAME_INVALID;
3802 return NT_STATUS_OK;
3805 /*********************************************************************
3806 _samr_delete_dom_group
3807 *********************************************************************/
3809 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3814 fstring group_sid_str;
3820 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3822 /* Find the policy handle. Open a policy on it. */
3823 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3824 return NT_STATUS_INVALID_HANDLE;
3826 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3830 sid_copy(&dom_sid, &group_sid);
3831 sid_to_string(group_sid_str, &dom_sid);
3832 sid_split_rid(&dom_sid, &group_rid);
3834 DEBUG(10, ("sid is %s\n", group_sid_str));
3836 /* we check if it's our SID before deleting */
3837 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3838 return NT_STATUS_NO_SUCH_GROUP;
3840 DEBUG(10, ("lookup on Domain SID\n"));
3842 if(!get_domain_group_from_sid(group_sid, &map))
3843 return NT_STATUS_NO_SUCH_GROUP;
3847 /* check if group really exists */
3848 if ( (grp=getgrgid(gid)) == NULL)
3849 return NT_STATUS_NO_SUCH_GROUP;
3851 /* we can delete the UNIX group */
3852 smb_delete_group(grp->gr_name);
3854 /* check if the group has been successfully deleted */
3855 if ( (grp=getgrgid(gid)) != NULL)
3856 return NT_STATUS_ACCESS_DENIED;
3858 if(!pdb_delete_group_mapping_entry(group_sid))
3859 return NT_STATUS_ACCESS_DENIED;
3861 if (!close_policy_hnd(p, &q_u->group_pol))
3862 return NT_STATUS_OBJECT_NAME_INVALID;
3864 return NT_STATUS_OK;
3867 /*********************************************************************
3868 _samr_delete_dom_alias
3869 *********************************************************************/
3871 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3876 fstring alias_sid_str;
3882 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3884 /* Find the policy handle. Open a policy on it. */
3885 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3886 return NT_STATUS_INVALID_HANDLE;
3888 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3892 sid_copy(&dom_sid, &alias_sid);
3893 sid_to_string(alias_sid_str, &dom_sid);
3894 sid_split_rid(&dom_sid, &alias_rid);
3896 DEBUG(10, ("sid is %s\n", alias_sid_str));
3898 /* we check if it's our SID before deleting */
3899 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3900 return NT_STATUS_NO_SUCH_ALIAS;
3902 DEBUG(10, ("lookup on Local SID\n"));
3904 if(!get_local_group_from_sid(alias_sid, &map))
3905 return NT_STATUS_NO_SUCH_ALIAS;
3909 /* check if group really exists */
3910 if ( (grp=getgrgid(gid)) == NULL)
3911 return NT_STATUS_NO_SUCH_ALIAS;
3913 /* we can delete the UNIX group */
3914 smb_delete_group(grp->gr_name);
3916 /* check if the group has been successfully deleted */
3917 if ( (grp=getgrgid(gid)) != NULL)
3918 return NT_STATUS_ACCESS_DENIED;
3920 /* don't check if we removed it as it could be an un-mapped group */
3921 pdb_delete_group_mapping_entry(alias_sid);
3923 if (!close_policy_hnd(p, &q_u->alias_pol))
3924 return NT_STATUS_OBJECT_NAME_INVALID;
3926 return NT_STATUS_OK;
3929 /*********************************************************************
3930 _samr_create_dom_group
3931 *********************************************************************/
3933 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3940 struct samr_info *info;
3944 /* Find the policy handle. Open a policy on it. */
3945 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3946 return NT_STATUS_INVALID_HANDLE;
3948 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3952 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3953 return NT_STATUS_ACCESS_DENIED;
3955 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3957 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3959 /* check if group already exist */
3960 if ((grp=getgrnam(name)) != NULL)
3961 return NT_STATUS_GROUP_EXISTS;
3963 /* we can create the UNIX group */
3964 if (smb_create_group(name, &gid) != 0)
3965 return NT_STATUS_ACCESS_DENIED;
3967 /* check if the group has been successfully created */
3968 if ((grp=getgrgid(gid)) == NULL)
3969 return NT_STATUS_ACCESS_DENIED;
3971 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3973 /* add the group to the mapping table */
3974 sid_copy(&info_sid, get_global_sam_sid());
3975 sid_append_rid(&info_sid, r_u->rid);
3976 sid_to_string(sid_string, &info_sid);
3978 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3979 return NT_STATUS_ACCESS_DENIED;
3981 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3982 return NT_STATUS_NO_MEMORY;
3984 /* get a (unique) handle. open a policy on it. */
3985 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3986 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3988 return NT_STATUS_OK;
3991 /*********************************************************************
3992 _samr_create_dom_alias
3993 *********************************************************************/
3995 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4002 struct samr_info *info;
4006 /* Find the policy handle. Open a policy on it. */
4007 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4008 return NT_STATUS_INVALID_HANDLE;
4010 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4014 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4015 return NT_STATUS_ACCESS_DENIED;
4017 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4019 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4021 /* check if group already exists */
4022 if ( (grp=getgrnam(name)) != NULL)
4023 return NT_STATUS_GROUP_EXISTS;
4025 /* we can create the UNIX group */
4026 if (smb_create_group(name, &gid) != 0)
4027 return NT_STATUS_ACCESS_DENIED;
4029 /* check if the group has been successfully created */
4030 if ((grp=getgrgid(gid)) == NULL)
4031 return NT_STATUS_ACCESS_DENIED;
4033 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4035 sid_copy(&info_sid, get_global_sam_sid());
4036 sid_append_rid(&info_sid, r_u->rid);
4037 sid_to_string(sid_string, &info_sid);
4039 /* add the group to the mapping table */
4040 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
4041 return NT_STATUS_ACCESS_DENIED;
4043 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4044 return NT_STATUS_NO_MEMORY;
4046 /* get a (unique) handle. open a policy on it. */
4047 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4048 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4050 return NT_STATUS_OK;
4053 /*********************************************************************
4054 _samr_query_groupinfo
4056 sends the name/comment pair of a domain group
4057 level 1 send also the number of users of that group
4058 *********************************************************************/
4060 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4066 GROUP_INFO_CTR *ctr;
4069 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4070 return NT_STATUS_INVALID_HANDLE;
4072 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4076 if (!get_domain_group_from_sid(group_sid, &map))
4077 return NT_STATUS_INVALID_HANDLE;
4079 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4081 return NT_STATUS_NO_MEMORY;
4083 switch (q_u->switch_level) {
4085 ctr->switch_value1 = 1;
4086 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4087 return NT_STATUS_NO_SUCH_GROUP;
4088 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4092 ctr->switch_value1 = 3;
4093 init_samr_group_info3(&ctr->group.info3);
4096 ctr->switch_value1 = 4;
4097 init_samr_group_info4(&ctr->group.info4, map.comment);
4100 return NT_STATUS_INVALID_INFO_CLASS;
4103 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4105 return NT_STATUS_OK;
4108 /*********************************************************************
4111 update a domain group's comment.
4112 *********************************************************************/
4114 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4118 GROUP_INFO_CTR *ctr;
4121 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4122 return NT_STATUS_INVALID_HANDLE;
4124 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4128 if (!get_domain_group_from_sid(group_sid, &map))
4129 return NT_STATUS_NO_SUCH_GROUP;
4133 switch (ctr->switch_value1) {
4135 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4138 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4141 return NT_STATUS_INVALID_INFO_CLASS;
4144 if(!pdb_update_group_mapping_entry(&map)) {
4145 return NT_STATUS_NO_SUCH_GROUP;
4148 return NT_STATUS_OK;
4151 /*********************************************************************
4154 update an alias's comment.
4155 *********************************************************************/
4157 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4161 ALIAS_INFO_CTR *ctr;
4164 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4165 return NT_STATUS_INVALID_HANDLE;
4167 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4171 if (!get_local_group_from_sid(group_sid, &map))
4172 return NT_STATUS_NO_SUCH_GROUP;
4176 switch (ctr->switch_value1) {
4178 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4181 return NT_STATUS_INVALID_INFO_CLASS;
4184 if(!pdb_update_group_mapping_entry(&map)) {
4185 return NT_STATUS_NO_SUCH_GROUP;
4188 return NT_STATUS_OK;
4191 /*********************************************************************
4192 _samr_get_dom_pwinfo
4193 *********************************************************************/
4195 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4197 /* Perform access check. Since this rpc does not require a
4198 policy handle it will not be caught by the access checks on
4199 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4201 if (!pipe_access_check(p)) {
4202 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4203 r_u->status = NT_STATUS_ACCESS_DENIED;
4207 /* Actually, returning zeros here works quite well :-). */
4209 return NT_STATUS_OK;
4212 /*********************************************************************
4214 *********************************************************************/
4216 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4221 struct samr_info *info;
4222 SEC_DESC *psd = NULL;
4229 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4230 return NT_STATUS_INVALID_HANDLE;
4232 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4236 /*check if access can be granted as requested by client. */
4237 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4238 se_map_generic(&des_access,&grp_generic_mapping);
4239 if (!NT_STATUS_IS_OK(status =
4240 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4241 des_access, &acc_granted, "_samr_open_group"))) {
4246 /* this should not be hard-coded like this */
4247 if (!sid_equal(&sid, get_global_sam_sid()))
4248 return NT_STATUS_ACCESS_DENIED;
4250 sid_copy(&info_sid, get_global_sam_sid());
4251 sid_append_rid(&info_sid, q_u->rid_group);
4252 sid_to_string(sid_string, &info_sid);
4254 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4255 return NT_STATUS_NO_MEMORY;
4257 info->acc_granted = acc_granted;
4259 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4261 /* check if that group really exists */
4262 if (!get_domain_group_from_sid(info->sid, &map))
4263 return NT_STATUS_NO_SUCH_GROUP;
4265 /* get a (unique) handle. open a policy on it. */
4266 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4267 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4269 return NT_STATUS_OK;
4272 /*********************************************************************
4274 *********************************************************************/
4276 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4278 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4279 return NT_STATUS_NOT_IMPLEMENTED;
4282 /*******************************************************************
4284 ********************************************************************/
4286 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4288 struct samr_info *info = NULL;
4290 uint32 min_pass_len,pass_hist,flag;
4291 time_t u_expire, u_min_age;
4292 NTTIME nt_expire, nt_min_age;
4294 time_t u_lock_duration, u_reset_time;
4295 NTTIME nt_lock_duration, nt_reset_time;
4301 uint32 num_users=0, num_groups=0, num_aliases=0;
4303 uint32 account_policy_temp;
4305 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4306 return NT_STATUS_NO_MEMORY;
4310 r_u->status = NT_STATUS_OK;
4312 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4314 /* find the policy handle. open a policy on it. */
4315 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4316 return NT_STATUS_INVALID_HANDLE;
4318 switch (q_u->switch_value) {
4320 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4321 min_pass_len = account_policy_temp;
4323 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4324 pass_hist = account_policy_temp;
4326 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4327 flag = account_policy_temp;
4329 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4330 u_expire = account_policy_temp;
4332 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4333 u_min_age = account_policy_temp;
4335 unix_to_nt_time_abs(&nt_expire, u_expire);
4336 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4338 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4339 flag, nt_expire, nt_min_age);
4343 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4345 if (!NT_STATUS_IS_OK(r_u->status)) {
4346 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4349 num_users=info->disp_info.num_user_account;
4352 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4353 if (NT_STATUS_IS_ERR(r_u->status)) {
4354 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4357 num_groups=info->disp_info.num_group_account;
4360 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4361 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4362 num_users, num_groups, num_aliases);
4365 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4366 u_logout = account_policy_temp;
4368 unix_to_nt_time_abs(&nt_logout, u_logout);
4370 init_unk_info3(&ctr->info.inf3, nt_logout);
4373 init_unk_info5(&ctr->info.inf5, global_myname());
4376 init_unk_info6(&ctr->info.inf6);
4379 init_unk_info7(&ctr->info.inf7);
4382 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4383 u_lock_duration = account_policy_temp;
4385 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4386 u_reset_time = account_policy_temp;
4388 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4389 lockout = account_policy_temp;
4391 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4392 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4394 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4397 return NT_STATUS_INVALID_INFO_CLASS;
4400 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4402 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4407 /*******************************************************************
4409 ********************************************************************/
4411 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4413 time_t u_expire, u_min_age;
4415 time_t u_lock_duration, u_reset_time;
4417 r_u->status = NT_STATUS_OK;
4419 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4421 /* find the policy handle. open a policy on it. */
4422 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4423 return NT_STATUS_INVALID_HANDLE;
4425 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4427 switch (q_u->switch_value) {
4429 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4430 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4432 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4433 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4434 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4435 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4436 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4441 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4442 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4451 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4452 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4454 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4455 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4456 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4459 return NT_STATUS_INVALID_INFO_CLASS;
4462 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4464 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));