📄 srv_samr_nt.c
字号:
sid_str)); } free_samr_cache(disp_info, sid_str); }}/******************************************************************* Ensure password info is never given out. Paranioa... JRA. ********************************************************************/static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass){ if (!sam_pass) return; /* These now zero out the old password */ pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT); pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);}static uint32 count_sam_users(struct disp_info *info, uint16 acct_flags){ struct samr_displayentry *entry; if (info->builtin_domain) { /* No users in builtin. */ return 0; } if (info->users == NULL) { info->users = pdb_search_users(acct_flags); if (info->users == NULL) { return 0; } } /* Fetch the last possible entry, thus trigger an enumeration */ pdb_search_entries(info->users, 0xffffffff, 1, &entry); /* Ensure we cache this enumeration. */ set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT); return info->users->num_entries;}static uint32 count_sam_groups(struct disp_info *info){ struct samr_displayentry *entry; if (info->builtin_domain) { /* No groups in builtin. */ return 0; } if (info->groups == NULL) { info->groups = pdb_search_groups(); if (info->groups == NULL) { return 0; } } /* Fetch the last possible entry, thus trigger an enumeration */ pdb_search_entries(info->groups, 0xffffffff, 1, &entry); /* Ensure we cache this enumeration. */ set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT); return info->groups->num_entries;}static uint32 count_sam_aliases(struct disp_info *info){ struct samr_displayentry *entry; if (info->aliases == NULL) { info->aliases = pdb_search_aliases(&info->sid); if (info->aliases == NULL) { return 0; } } /* Fetch the last possible entry, thus trigger an enumeration */ pdb_search_entries(info->aliases, 0xffffffff, 1, &entry); /* Ensure we cache this enumeration. */ set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT); return info->aliases->num_entries;}/******************************************************************* _samr_close_hnd ********************************************************************/NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u){ r_u->status = NT_STATUS_OK; /* close the policy handle */ if (!close_policy_hnd(p, &q_u->pol)) return NT_STATUS_OBJECT_NAME_INVALID; DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__)); return r_u->status;}/******************************************************************* samr_reply_open_domain ********************************************************************/NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u){ struct samr_info *info; SEC_DESC *psd = NULL; uint32 acc_granted; uint32 des_access = q_u->flags; NTSTATUS status; size_t sd_size; SE_PRIV se_rights; r_u->status = NT_STATUS_OK; /* find the connection policy handle. */ if ( !find_policy_by_hnd(p, &q_u->pol, (void**)(void *)&info) ) return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function( info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_open_domain" ); if ( !NT_STATUS_IS_OK(status) ) return status; /*check if access can be granted as requested by client. */ make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 ); se_map_generic( &des_access, &dom_generic_mapping ); se_priv_copy( &se_rights, &se_machine_account ); se_priv_add( &se_rights, &se_add_users ); status = access_check_samr_object( psd, p->pipe_user.nt_user_token, &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access, &acc_granted, "_samr_open_domain" ); if ( !NT_STATUS_IS_OK(status) ) return status; if (!sid_check_is_domain(&q_u->dom_sid.sid) && !sid_check_is_builtin(&q_u->dom_sid.sid)) { return NT_STATUS_NO_SUCH_DOMAIN; } /* associate the domain SID with the (unique) handle. */ if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL) return NT_STATUS_NO_MEMORY; info->acc_granted = acc_granted; /* get a (unique) handle. open a policy on it. */ if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; DEBUG(5,("samr_open_domain: %d\n", __LINE__)); return r_u->status;}/******************************************************************* _samr_get_usrdom_pwinfo ********************************************************************/NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u){ struct samr_info *info = NULL; r_u->status = NT_STATUS_OK; /* find the policy handle. open a policy on it. */ if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; if (!sid_check_is_in_our_domain(&info->sid)) return NT_STATUS_OBJECT_TYPE_MISMATCH; init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK); DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__)); /* * NT sometimes return NT_STATUS_ACCESS_DENIED * I don't know yet why. */ return r_u->status;}/******************************************************************* _samr_set_sec_obj ********************************************************************/NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u){ DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n")); return NT_STATUS_NOT_IMPLEMENTED;}/***************************************************************************************************************************************/static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted, DISP_INFO **ppdisp_info){ struct samr_info *info = NULL; /* find the policy handle. open a policy on it. */ if (!find_policy_by_hnd(p, pol, (void **)(void *)&info)) return False; if (!info) return False; *sid = info->sid; *acc_granted = info->acc_granted; if (ppdisp_info) { *ppdisp_info = info->disp_info; } return True;}/******************************************************************* _samr_query_sec_obj ********************************************************************/NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u){ DOM_SID pol_sid; fstring str_sid; SEC_DESC * psd = NULL; uint32 acc_granted; size_t sd_size; r_u->status = NT_STATUS_OK; /* Get the SID. */ if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted, NULL)) return NT_STATUS_INVALID_HANDLE; DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid))); /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */ /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */ if (pol_sid.sid_rev_num == 0) { DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n")); r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); } else if (sid_equal(&pol_sid,get_global_sam_sid())) { /* check if it is our domain SID */ DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid))); r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0); } else if (sid_equal(&pol_sid,&global_sid_Builtin)) { /* check if it is the Builtin Domain */ /* TODO: Builtin probably needs a different SD with restricted write access*/ DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid))); r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0); } else if (sid_check_is_in_our_domain(&pol_sid) || sid_check_is_in_builtin(&pol_sid)) { /* TODO: different SDs have to be generated for aliases groups and users. Currently all three get a default user SD */ DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid))); r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &pol_sid, SAMR_USR_RIGHTS_WRITE_PW); } else { return NT_STATUS_OBJECT_TYPE_MISMATCH; } if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL) return NT_STATUS_NO_MEMORY; if (NT_STATUS_IS_OK(r_u->status)) r_u->ptr = 1; return r_u->status;}/*******************************************************************makes a SAM_ENTRY / UNISTR2* structure from a user list.********************************************************************/static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp, uint32 num_entries, uint32 start_idx, struct samr_displayentry *entries){ uint32 i; SAM_ENTRY *sam; UNISTR2 *uni_name; *sam_pp = NULL; *uni_name_pp = NULL; if (num_entries == 0) return NT_STATUS_OK; sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries); uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_entries); if (sam == NULL || uni_name == NULL) { DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n")); return NT_STATUS_NO_MEMORY; } for (i = 0; i < num_entries; i++) { UNISTR2 uni_temp_name; /* * usrmgr expects a non-NULL terminated string with * trust relationships */ if (entries[i].acct_flags & ACB_DOMTRUST) { init_unistr2(&uni_temp_name, entries[i].account_name, UNI_FLAGS_NONE); } else { init_unistr2(&uni_temp_name, entries[i].account_name, UNI_STR_TERMINATE); } init_sam_entry(&sam[i], &uni_temp_name, entries[i].rid); copy_unistr2(&uni_name[i], &uni_temp_name); } *sam_pp = sam; *uni_name_pp = uni_name; return NT_STATUS_OK;}/******************************************************************* samr_reply_enum_dom_users ********************************************************************/NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u){ struct samr_info *info = NULL; int num_account; uint32 enum_context=q_u->start_idx; enum remote_arch_types ra_type = get_remote_arch(); int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K; uint32 max_entries = max_sam_entries; struct samr_displayentry *entries = NULL; r_u->status = NT_STATUS_OK; /* find the policy handle. open a policy on it. */ if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_users"))) { return r_u->status; } DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__)); if (info->builtin_domain) { /* No users in builtin. */ init_samr_r_enum_dom_users(r_u, q_u->start_idx, 0); DEBUG(5,("_samr_enum_dom_users: No users in BUILTIN\n")); return r_u->status; } become_root(); /* AS ROOT !!!! */ if ((info->disp_info->enum_users != NULL) && (info->disp_info->enum_acb_mask != q_u->acb_mask)) { pdb_search_destroy(info->disp_info->enum_users); info->disp_info->enum_users = NULL; } if (info->disp_info->enum_users == NULL) { info->disp_info->enum_users = pdb_search_users(q_u->acb_mask); info->disp_info->enum_acb_mask = q_u->acb_mask; } if (info->disp_info->enum_users == NULL) { /* END AS ROOT !!!! */ unbecome_root(); return NT_STATUS_ACCESS_DENIED; } num_account = pdb_search_entries(info->disp_info->enum_users, enum_context, max_entries, &entries); /* END AS ROOT !!!! */ unbecome_root(); if (num_account == 0) { DEBUG(5, ("_samr_enum_dom_users: enumeration handle over " "total entries\n")); return NT_STATUS_OK; } r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_account, enum_context, entries); if (!NT_STATUS_IS_OK(r_u->status)) return r_u->status; if (max_entries <= num_account) { r_u->status = STATUS_MORE_ENTRIES; } else { r_u->status = NT_STATUS_OK; } /* Ensure we cache this enumeration. */ set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT); DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__)); init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_account, num_account); DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__)); return r_u->status;}/*******************************************************************makes a SAM_ENTRY / UNISTR2* structure from a group list.********************************************************************/static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp, uint32 num_sam_entries, struct samr_displayentry *entries){ uint32 i; SAM_ENTRY *sam; UNISTR2 *uni_name; *sam_pp = NULL; *uni_name_pp = NULL; if (num_sam_entries == 0) return; sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries); uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries); if (sam == NULL || uni_name == NULL) { DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n")); return; } for (i = 0; i < num_sam_entries; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -