📄 srv_samr_nt.c
字号:
/* * JRA. I think this should include the null. TNG does not. */ init_unistr2(&uni_name[i], entries[i].account_name, UNI_STR_TERMINATE); init_sam_entry(&sam[i], &uni_name[i], entries[i].rid); } *sam_pp = sam; *uni_name_pp = uni_name;}/******************************************************************* samr_reply_enum_dom_groups ********************************************************************/NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u){ struct samr_info *info = NULL; struct samr_displayentry *groups; uint32 num_groups; 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; r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"); if (!NT_STATUS_IS_OK(r_u->status)) return r_u->status; DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__)); if (info->builtin_domain) { /* No groups in builtin. */ init_samr_r_enum_dom_groups(r_u, q_u->start_idx, 0); DEBUG(5,("_samr_enum_dom_users: No groups in BUILTIN\n")); return r_u->status; } /* the domain group array is being allocated in the function below */ become_root(); if (info->disp_info->groups == NULL) { info->disp_info->groups = pdb_search_groups(); if (info->disp_info->groups == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; } } num_groups = pdb_search_entries(info->disp_info->groups, q_u->start_idx, MAX_SAM_ENTRIES, &groups); unbecome_root(); /* Ensure we cache this enumeration. */ set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT); make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_groups, groups); init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_groups); DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__)); return r_u->status;}/******************************************************************* samr_reply_enum_dom_aliases ********************************************************************/NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u){ struct samr_info *info; struct samr_displayentry *aliases; uint32 num_aliases = 0; /* 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; r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"); if (!NT_STATUS_IS_OK(r_u->status)) return r_u->status; DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_string_static(&info->sid))); become_root(); if (info->disp_info->aliases == NULL) { info->disp_info->aliases = pdb_search_aliases(&info->sid); if (info->disp_info->aliases == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; } } num_aliases = pdb_search_entries(info->disp_info->aliases, q_u->start_idx, MAX_SAM_ENTRIES, &aliases); unbecome_root(); /* Ensure we cache this enumeration. */ set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT); make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_aliases, aliases); init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_aliases, num_aliases); DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__)); return r_u->status;}/******************************************************************* samr_reply_query_dispinfo ********************************************************************/NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u){ struct samr_info *info = NULL; uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */ uint32 max_entries=q_u->max_entries; uint32 enum_context=q_u->start_idx; uint32 max_size=q_u->max_size; SAM_DISPINFO_CTR *ctr; uint32 temp_size=0, total_data_size=0; NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL; uint32 num_account = 0; 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; struct samr_displayentry *entries = NULL; DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__)); r_u->status = NT_STATUS_UNSUCCESSFUL; /* find the policy handle. open a policy on it. */ if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; /* * calculate how many entries we will return. * based on * - the number of entries the client asked * - our limit on that * - the starting point (enumeration context) * - the buffer size the client will accept */ /* * We are a lot more like W2K. Instead of reading the SAM * each time to find the records we need to send back, * we read it once and link that copy to the sam handle. * For large user list (over the MAX_SAM_ENTRIES) * it's a definitive win. * second point to notice: between enumerations * our sam is now the same as it's a snapshoot. * third point: got rid of the static SAM_USER_21 struct * no more intermediate. * con: it uses much more memory, as a full copy is stored * in memory. * * If you want to change it, think twice and think * of the second point , that's really important. * * JFM, 12/20/2001 */ if ((q_u->switch_level < 1) || (q_u->switch_level > 5)) { DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level )); return NT_STATUS_INVALID_INFO_CLASS; } /* first limit the number of entries we will return */ if(max_entries > max_sam_entries) { DEBUG(5, ("samr_reply_query_dispinfo: client requested %d " "entries, limiting to %d\n", max_entries, max_sam_entries)); max_entries = max_sam_entries; } /* calculate the size and limit on the number of entries we will * return */ temp_size=max_entries*struct_size; if (temp_size>max_size) { max_entries=MIN((max_size/struct_size),max_entries);; DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to " "only %d entries\n", max_entries)); } if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR))) return NT_STATUS_NO_MEMORY; ZERO_STRUCTP(ctr); become_root(); /* THe following done as ROOT. Don't return without unbecome_root(). */ switch (q_u->switch_level) { case 0x1: case 0x4: if (info->disp_info->users == NULL) { info->disp_info->users = pdb_search_users(ACB_NORMAL); if (info->disp_info->users == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; } DEBUG(10,("samr_reply_query_dispinfo: starting user enumeration at index %u\n", (unsigned int)enum_context )); } else { DEBUG(10,("samr_reply_query_dispinfo: using cached user enumeration at index %u\n", (unsigned int)enum_context )); } num_account = pdb_search_entries(info->disp_info->users, enum_context, max_entries, &entries); break; case 0x2: if (info->disp_info->machines == NULL) { info->disp_info->machines = pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST); if (info->disp_info->machines == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; } DEBUG(10,("samr_reply_query_dispinfo: starting machine enumeration at index %u\n", (unsigned int)enum_context )); } else { DEBUG(10,("samr_reply_query_dispinfo: using cached machine enumeration at index %u\n", (unsigned int)enum_context )); } num_account = pdb_search_entries(info->disp_info->machines, enum_context, max_entries, &entries); break; case 0x3: case 0x5: if (info->disp_info->groups == NULL) { info->disp_info->groups = pdb_search_groups(); if (info->disp_info->groups == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; } DEBUG(10,("samr_reply_query_dispinfo: starting group enumeration at index %u\n", (unsigned int)enum_context )); } else { DEBUG(10,("samr_reply_query_dispinfo: using cached group enumeration at index %u\n", (unsigned int)enum_context )); } num_account = pdb_search_entries(info->disp_info->groups, enum_context, max_entries, &entries); break; default: unbecome_root(); smb_panic("info class changed"); break; } unbecome_root(); /* Now create reply structure */ switch (q_u->switch_level) { case 0x1: disp_ret = init_sam_dispinfo_1(p->mem_ctx, &ctr->sam.info1, num_account, enum_context, entries); break; case 0x2: disp_ret = init_sam_dispinfo_2(p->mem_ctx, &ctr->sam.info2, num_account, enum_context, entries); break; case 0x3: disp_ret = init_sam_dispinfo_3(p->mem_ctx, &ctr->sam.info3, num_account, enum_context, entries); break; case 0x4: disp_ret = init_sam_dispinfo_4(p->mem_ctx, &ctr->sam.info4, num_account, enum_context, entries); break; case 0x5: disp_ret = init_sam_dispinfo_5(p->mem_ctx, &ctr->sam.info5, num_account, enum_context, entries); break; default: smb_panic("info class changed"); break; } if (!NT_STATUS_IS_OK(disp_ret)) return disp_ret; /* calculate the total size */ total_data_size=num_account*struct_size; if (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_query_dispinfo: %d\n", __LINE__)); init_samr_r_query_dispinfo(r_u, num_account, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status); return r_u->status;}/******************************************************************* samr_reply_query_aliasinfo ********************************************************************/NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u){ DOM_SID sid; struct acct_info info; uint32 acc_granted; BOOL ret; r_u->status = NT_STATUS_OK; DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted, NULL)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) { return r_u->status; } become_root(); ret = pdb_get_aliasinfo(&sid, &info); unbecome_root(); if ( !ret ) return NT_STATUS_NO_SUCH_ALIAS; if ( !(r_u->ctr = TALLOC_ZERO_P( p->mem_ctx, ALIAS_INFO_CTR )) ) return NT_STATUS_NO_MEMORY; switch (q_u->level ) { case 1: r_u->ctr->level = 1; init_samr_alias_info1(&r_u->ctr->alias.info1, info.acct_name, 1, info.acct_desc); break; case 3: r_u->ctr->level = 3; init_samr_alias_info3(&r_u->ctr->alias.info3, info.acct_desc); break; default: return NT_STATUS_INVALID_INFO_CLASS; } DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__)); return r_u->status;}#if 0/******************************************************************* samr_reply_lookup_ids ********************************************************************/ uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u){ uint32 rid[MAX_SAM_ENTRIES]; int num_rids = q_u->num_sids1; r_u->status = NT_STATUS_OK; DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__)); if (num_rids > MAX_SAM_ENTRIES) { num_rids = MAX_SAM_ENTRIES; DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids)); }#if 0 int i; SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids); for (i = 0; i < num_rids && status == 0; i++) { struct sam_passwd *sam_pass; fstring user_name; fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer, q_u->uni_user_name[i].uni_str_len)); /* find the user account */ become_root(); sam_pass = get_smb21pwd_entry(user_name, 0); unbecome_root(); if (sam_pass == NULL) { status = 0xC0000000 | NT_STATUS_NO_SUCH_USER; rid[i] = 0; } else { rid[i] = sam_pass->user_rid; } }#endif num_rids = 1; rid[0] = BUILTIN_ALIAS_RID_USERS; init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK); DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__)); return r_u->status;}#endif/******************************************************************* _samr_lookup_names ********************************************************************/NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u){ uint32 rid[MAX_SAM_ENTRIES]; uint32 local_rid; enum SID_NAME_USE type[MAX_SAM_ENTRIES]; enum SID_NAME_USE local_type; int i; int num_rids = q_u->num_names2; DOM_SID pol_sid; fstring sid_str;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -