diff options
-rw-r--r-- | source3/include/proto.h | 2 | ||||
-rw-r--r-- | source3/lib/util_unistr.c | 68 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa_nt.c | 6 | ||||
-rw-r--r-- | source3/rpc_server/srv_netlog_nt.c | 10 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 6 | ||||
-rw-r--r-- | source3/rpc_server/srv_reg_nt.c | 4 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 8 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc_nt.c | 2 |
8 files changed, 88 insertions, 18 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 774f623adb..006b26cf05 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -599,8 +599,10 @@ size_t dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminat void unistr_to_dos(char *dest, const char *src, size_t len); char *skip_unibuf(char *src, size_t len); char *dos_unistrn2(uint16 *src, int len); +char *rpc_unistrn2(uint16 *src, int len, BOOL endian); char *dos_unistr2(uint16 *src); char *dos_unistr2_to_str(UNISTR2 *str); +char *rpc_unistr2_to_str(UNISTR2 *str, BOOL endian); void ascii_to_unistr(uint16 *dest, const char *src, int maxlen); void unistr_to_ascii(char *dest, const uint16 *src, int len); void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen); diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index 5e6f6a5945..b1cb9ec410 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -161,6 +161,42 @@ char *dos_unistrn2(uint16 *src, int len) return lbuf; } +/******************************************************************* + Return a DOS codepage version of a big or little endian unicode string. + len is the filename length (ignoring any terminating zero) in uin16 + units. Always null terminates. Endian is 1 if it's big endian. + Hack alert: uses fixed buffer(s). +********************************************************************/ + +char *rpc_unistrn2(uint16 *src, int len, BOOL endian) +{ + static char lbufs[8][MAXUNI]; + static int nexti; + char *lbuf = lbufs[nexti]; + char *p; + + nexti = (nexti+1)%8; + + for (p = lbuf; (len > 0) && (p-lbuf < MAXUNI-3) && *src; len--, src++) { + uint16 ucs2_val; + uint16 cp_val; + + RW_SVAL(True,endian,src,ucs2_val,0); + + cp_val = ucs2_to_doscp[ucs2_val]; + + if (cp_val < 256) + *p++ = (char)cp_val; + else { + *p++ = (cp_val >> 8) & 0xff; + *p++ = (cp_val & 0xff); + } + } + + *p = 0; + return lbuf; +} + static char lbufs[8][MAXUNI]; static int nexti; @@ -222,6 +258,38 @@ char *dos_unistr2_to_str(UNISTR2 *str) } /******************************************************************* +Return a DOS codepage version of a big or little-endian unicode string +********************************************************************/ + +char *rpc_unistr2_to_str(UNISTR2 *str, BOOL endian) +{ + char *lbuf = lbufs[nexti]; + char *p; + uint16 *src = str->buffer; + int max_size = MIN(MAXUNI-3, str->uni_str_len); + + nexti = (nexti+1)%8; + + for (p = lbuf; (p-lbuf < max_size) && *src; src++) { + uint16 ucs2_val; + uint16 cp_val; + + RW_SVAL(True,endian,src,ucs2_val,0); + cp_val = ucs2_to_doscp[ucs2_val]; + + if (cp_val < 256) + *p++ = (char)cp_val; + else { + *p++ = (cp_val >> 8) & 0xff; + *p++ = (cp_val & 0xff); + } + } + + *p = 0; + return lbuf; +} + +/******************************************************************* Put an ASCII string into a UNICODE array (uint16's). use little-endian ucs2 ********************************************************************/ diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index d1a7c049d8..6e70d8cc87 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -109,7 +109,7 @@ static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid) static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2, int num_entries, UNISTR2 name[MAX_LOOKUP_SIDS], - uint32 *mapped_count) + uint32 *mapped_count, BOOL endian) { int i; int total = 0; @@ -128,7 +128,7 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2, /* Split name into domain and user component */ - pstrcpy(full_name, dos_unistr2_to_str(&name[i])); + pstrcpy(full_name, rpc_unistr2_to_str(&name[i], endian)); split_domain_name(full_name, dom_name, user); /* Lookup name */ @@ -479,7 +479,7 @@ uint32 _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_N return NT_STATUS_NO_MEMORY; /* set up the LSA Lookup RIDs response */ - init_lsa_rid2s(ref, rids, num_entries, names, &mapped_count); + init_lsa_rid2s(ref, rids, num_entries, names, &mapped_count, p->endian); init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count); return r_u->status; diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index f022b6f06b..6a6254574c 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -181,8 +181,8 @@ uint32 _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u) if (!get_valid_user_struct(p->vuid)) return NT_STATUS_NO_SUCH_USER; - fstrcpy(mach_acct, dos_unistrn2(q_u->uni_logon_clnt.buffer, - q_u->uni_logon_clnt.uni_str_len)); + fstrcpy(mach_acct, rpc_unistrn2(q_u->uni_logon_clnt.buffer, + q_u->uni_logon_clnt.uni_str_len, p->endian)); strlower(mach_acct); fstrcat(mach_acct, "$"); @@ -280,8 +280,8 @@ uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_ DEBUG(5,("_net_srv_pwset: %d\n", __LINE__)); - pstrcpy(mach_acct, dos_unistrn2(q_u->clnt_id.login.uni_acct_name.buffer, - q_u->clnt_id.login.uni_acct_name.uni_str_len)); + pstrcpy(mach_acct, rpc_unistrn2(q_u->clnt_id.login.uni_acct_name.buffer, + q_u->clnt_id.login.uni_acct_name.uni_str_len, p->endian)); DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct)); @@ -497,7 +497,7 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_ /* check username exists */ - pstrcpy(nt_username, dos_unistrn2(uni_samlogon_user->buffer, uni_samlogon_user->uni_str_len)); + pstrcpy(nt_username, rpc_unistrn2(uni_samlogon_user->buffer, uni_samlogon_user->uni_str_len, p->endian)); DEBUG(3,("User:[%s]\n", nt_username)); diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index bc5b2ab473..16243043d4 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -296,9 +296,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm */ if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { - fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2)); - fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2)); - fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2)); + fstrcpy(user_name, rpc_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2, p->endian)); + fstrcpy(domain, rpc_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2, p->endian)); + fstrcpy(wks, rpc_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2, p->endian)); } else { fstrcpy(user_name, ntlmssp_resp->user); fstrcpy(domain, ntlmssp_resp->domain); diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c index 4f941e3e1b..c953fe9d2a 100644 --- a/source3/rpc_server/srv_reg_nt.c +++ b/source3/rpc_server/srv_reg_nt.c @@ -85,7 +85,7 @@ uint32 _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY if (!find_policy_by_hnd(p, &q_u->pol, NULL)) return NT_STATUS_INVALID_HANDLE; - fstrcpy(name, dos_unistrn2(q_u->uni_name.buffer, q_u->uni_name.uni_str_len)); + fstrcpy(name, rpc_unistrn2(q_u->uni_name.buffer, q_u->uni_name.uni_str_len, p->endian)); DEBUG(5,("reg_open_entry: %s\n", name)); @@ -129,7 +129,7 @@ uint32 _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u) if (find_policy_by_hnd(p, &q_u->pol, NULL) == -1) return NT_STATUS_INVALID_HANDLE; - fstrcpy(name, dos_unistrn2(q_u->uni_type.buffer, q_u->uni_type.uni_str_len)); + fstrcpy(name, rpc_unistrn2(q_u->uni_type.buffer, q_u->uni_type.uni_str_len, p->endian)); DEBUG(5,("reg_info: checking key: %s\n", name)); diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 9f0ce9b05d..4ff7125fce 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -1196,7 +1196,7 @@ uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOK rid [i] = 0xffffffff; type[i] = SID_NAME_UNKNOWN; - fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer, q_u->uni_name[i].uni_str_len)); + fstrcpy(name, rpc_unistrn2(q_u->uni_name[i].buffer, q_u->uni_name[i].uni_str_len, p->endian)); if(sid_equal(&pol_sid, &global_sam_sid)) { DOM_SID sid; @@ -1227,8 +1227,8 @@ uint32 _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_ r_u->status = NT_STATUS_NOPROBLEMO; - fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len)); - fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len)); + fstrcpy(user_name, rpc_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len, p->endian)); + fstrcpy(wks , rpc_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len, p->endian)); DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks)); @@ -1709,7 +1709,7 @@ uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CR reply if the account already exists... */ - fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len)); + fstrcpy(mach_acct, rpc_unistrn2(user_account.buffer, user_account.uni_str_len, p->endian)); strlower(mach_acct); become_root(); diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 6e0043b0bb..01e289866b 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -814,7 +814,7 @@ uint32 _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, S DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__)); /* Create the list of shares for the response. */ - share_name = dos_unistr2_to_str(&q_u->uni_share_name); + share_name = rpc_unistr2_to_str(&q_u->uni_share_name, p->endian); init_srv_r_net_share_get_info(r_u, share_name, q_u->info_level); DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__)); |