📄 srv_samr_nt.c
字号:
uint32 acc_granted; r_u->status = NT_STATUS_OK; DEBUG(5,("_samr_lookup_names: %d\n", __LINE__)); ZERO_ARRAY(rid); ZERO_ARRAY(type); if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL)) { init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH); return r_u->status; } 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 */ return r_u->status; } if (num_rids > MAX_SAM_ENTRIES) { num_rids = MAX_SAM_ENTRIES; DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids)); } DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid))); for (i = 0; i < num_rids; i++) { fstring name; DOM_SID sid; int ret; r_u->status = NT_STATUS_NONE_MAPPED; rid [i] = 0xffffffff; type[i] = SID_NAME_UNKNOWN; ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0); /* * we are only looking for a name * the SID we get back can be outside * the scope of the pol_sid * * in clear: it prevents to reply to domain\group: yes * when only builtin\group exists. * * a cleaner code is to add the sid of the domain we're looking in * to the local_lookup_name function. */ if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) { sid_split_rid(&sid, &local_rid); if (sid_equal(&sid, &pol_sid)) { rid[i]=local_rid; /* Windows does not return WKN_GRP here, even * on lookups in builtin */ type[i] = (local_type == SID_NAME_WKN_GRP) ? SID_NAME_ALIAS : local_type; r_u->status = NT_STATUS_OK; } } } init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status); DEBUG(5,("_samr_lookup_names: %d\n", __LINE__)); return r_u->status;}/******************************************************************* _samr_chgpasswd_user ********************************************************************/NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u){ fstring user_name; fstring wks; DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__)); r_u->status = NT_STATUS_OK; rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0); rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0); DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks)); /* * Pass the user through the NT -> unix user mapping * function. */ (void)map_username(user_name); /* * UNIX username case mangling not required, pass_oem_change * is case insensitive. */ r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash, q_u->nt_newpass.pass, q_u->nt_oldhash.hash); init_samr_r_chgpasswd_user(r_u, r_u->status); DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__)); return r_u->status;}/*******************************************************************makes a SAMR_R_LOOKUP_RIDS structure.********************************************************************/static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, const char **names, UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name){ uint32 i; UNIHDR *hdr_name=NULL; UNISTR2 *uni_name=NULL; *pp_uni_name = NULL; *pp_hdr_name = NULL; if (num_names != 0) { hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names); if (hdr_name == NULL) return False; uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names); if (uni_name == NULL) return False; } for (i = 0; i < num_names; i++) { DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : "")); init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE); init_uni_hdr(&hdr_name[i], &uni_name[i]); } *pp_uni_name = uni_name; *pp_hdr_name = hdr_name; return True;}/******************************************************************* _samr_lookup_rids ********************************************************************/NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u){ const char **names; uint32 *attrs = NULL; UNIHDR *hdr_name = NULL; UNISTR2 *uni_name = NULL; DOM_SID pol_sid; int num_rids = q_u->num_rids1; uint32 acc_granted; r_u->status = NT_STATUS_OK; DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL)) return NT_STATUS_INVALID_HANDLE; if (num_rids > 1000) { DEBUG(0, ("Got asked for %d rids (more than 1000) -- according " "to samba4 idl this is not possible\n", num_rids)); return NT_STATUS_UNSUCCESSFUL; } names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids); attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids); if ((num_rids != 0) && ((names == NULL) || (attrs == NULL))) return NT_STATUS_NO_MEMORY; become_root(); /* lookup_sid can require root privs */ r_u->status = pdb_lookup_rids(&pol_sid, num_rids, q_u->rid, names, attrs); unbecome_root(); if(!make_samr_lookup_rids(p->mem_ctx, num_rids, names, &hdr_name, &uni_name)) return NT_STATUS_NO_MEMORY; init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, attrs); DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__)); return r_u->status;}/******************************************************************* _samr_open_user. Safe - gives out no passwd info. ********************************************************************/NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u){ SAM_ACCOUNT *sampass=NULL; DOM_SID sid; POLICY_HND domain_pol = q_u->domain_pol; POLICY_HND *user_pol = &r_u->user_pol; struct samr_info *info = NULL; SEC_DESC *psd = NULL; uint32 acc_granted; uint32 des_access = q_u->access_mask; size_t sd_size; BOOL ret; NTSTATUS nt_status; SE_PRIV se_rights; r_u->status = NT_STATUS_OK; /* find the domain policy handle and get domain SID / access bits in the domain policy. */ if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) ) return NT_STATUS_INVALID_HANDLE; nt_status = access_check_samr_function( acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user" ); if ( !NT_STATUS_IS_OK(nt_status) ) return nt_status; nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; /* append the user's RID to it */ if (!sid_append_rid(&sid, q_u->user_rid)) return NT_STATUS_NO_SUCH_USER; /* check if access can be granted as requested by client. */ make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW); se_map_generic(&des_access, &usr_generic_mapping); se_priv_copy( &se_rights, &se_machine_account ); se_priv_add( &se_rights, &se_add_users ); nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access, &acc_granted, "_samr_open_user"); if ( !NT_STATUS_IS_OK(nt_status) ) return nt_status; become_root(); ret=pdb_getsampwsid(sampass, &sid); unbecome_root(); /* check that the SID exists in our domain. */ if (ret == False) { return NT_STATUS_NO_SUCH_USER; } pdb_free_sam(&sampass); /* associate the user's SID and access bits with the new handle. */ if ((info = get_samr_info_by_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, user_pol, free_samr_info, (void *)info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; return r_u->status;}/************************************************************************* get_user_info_7. Safe. Only gives out account_name. *************************************************************************/static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, SAM_USER_INFO_7 *id7, DOM_SID *user_sid){ SAM_ACCOUNT *smbpass=NULL; BOOL ret; NTSTATUS nt_status; nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } become_root(); ret = pdb_getsampwsid(smbpass, user_sid); unbecome_root(); if (ret==False) { DEBUG(4,("User %s not found\n", sid_string_static(user_sid))); return NT_STATUS_NO_SUCH_USER; } DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) )); ZERO_STRUCTP(id7); init_sam_user_info7(id7, pdb_get_username(smbpass) ); pdb_free_sam(&smbpass); return NT_STATUS_OK;}/************************************************************************* get_user_info_9. Only gives out primary group SID. *************************************************************************/static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx, SAM_USER_INFO_9 * id9, DOM_SID *user_sid){ SAM_ACCOUNT *smbpass=NULL; BOOL ret; NTSTATUS nt_status; nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } become_root(); ret = pdb_getsampwsid(smbpass, user_sid); unbecome_root(); if (ret==False) { DEBUG(4,("User %s not found\n", sid_string_static(user_sid))); return NT_STATUS_NO_SUCH_USER; } DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) )); ZERO_STRUCTP(id9); init_sam_user_info9(id9, pdb_get_group_rid(smbpass) ); pdb_free_sam(&smbpass); return NT_STATUS_OK;}/************************************************************************* get_user_info_16. Safe. Only gives out acb bits. *************************************************************************/static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx, SAM_USER_INFO_16 *id16, DOM_SID *user_sid){ SAM_ACCOUNT *smbpass=NULL; BOOL ret; NTSTATUS nt_status; nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } become_root(); ret = pdb_getsampwsid(smbpass, user_sid); unbecome_root(); if (ret==False) { DEBUG(4,("User %s not found\n", sid_string_static(user_sid))); return NT_STATUS_NO_SUCH_USER; } DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) )); ZERO_STRUCTP(id16); init_sam_user_info16(id16, pdb_get_acct_ctrl(smbpass) ); pdb_free_sam(&smbpass); return NT_STATUS_OK;}/************************************************************************* get_user_info_18. OK - this is the killer as it gives out password info. Ensure that this is only allowed on an encrypted connection with a root user. JRA. *************************************************************************/static NTSTATUS get_user_info_18(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_18 * id18, DOM_SID *user_sid){ SAM_ACCOUNT *smbpass=NULL; BOOL ret; NTSTATUS nt_status; if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { return NT_STATUS_ACCESS_DENIED; } if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) { return NT_STATUS_ACCESS_DENIED; } /* * Do *NOT* do become_root()/unbecome_root() here ! JRA. */ nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } ret = pdb_getsampwsid(smbpass, user_sid); if (ret == False) { DEBUG(4, ("User %s not found\n", sid_string_static(user_sid))); pdb_free_sam(&smbpass); return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED; } DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) )); if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) { pdb_free_sam(&smbpass); return NT_STATUS_ACCOUNT_DISABLED; } ZERO_STRUCTP(id18); init_sam_user_info18(id18, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass)); pdb_free_sam(&smbpass); return NT_STATUS_OK;}/************************************************************************* get_user_info_20 *************************************************************************/static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid){ SAM_ACCOUNT *sampass=NULL; BOOL ret; pdb_init_sam_talloc(mem_ctx, &sampass); become_root(); ret = pdb_getsampwsid(sampass, user_sid); unbecome_root(); if (ret == False) { DEBUG(4,("User %s not found\n", sid_string_static(user_sid))); return NT_STATUS_NO_SUCH_USER; } samr_clear_sam_passwd(sampass); DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) )); ZERO_STRUCTP(id20); init_sam_user_info20A(id20, sampass);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -