Fixed reading of strings from big-endian RPC clients.
authorJeremy Allison <jra@samba.org>
Tue, 13 Mar 2001 01:44:05 +0000 (01:44 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 13 Mar 2001 01:44:05 +0000 (01:44 +0000)
Jeremy.

source/include/proto.h
source/lib/util_unistr.c
source/rpc_server/srv_lsa_nt.c
source/rpc_server/srv_netlog_nt.c
source/rpc_server/srv_pipe.c
source/rpc_server/srv_reg_nt.c
source/rpc_server/srv_samr_nt.c
source/rpc_server/srv_srvsvc_nt.c

index 774f623adb75026edb655091e108b9c7a170e80b..006b26cf054de81a40573aaa343ceed331397835 100644 (file)
@@ -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);
index 5e6f6a59456846ad5f663897f91d2696beb8d159..b1cb9ec4107883efbdf85b2ca4467372e35eaf53 100644 (file)
@@ -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;
 
@@ -221,6 +257,38 @@ char *dos_unistr2_to_str(UNISTR2 *str)
        return lbuf;
 }
 
+/*******************************************************************
+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
index d1a7c049d86c02fc403a9e9feb0172eea500848f..6e70d8cc87b31d2db5f35f35c30fe96bff84c056 100644 (file)
@@ -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;
index f022b6f06b48ddce13863a1f1727b06ca9017b2b..6a6254574c993a31d8e3f374064423551b88a37c 100644 (file)
@@ -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));
         
index bc5b2ab473b057d805ea05e48d8073caf8bbf644..16243043d400d111c32ab66bca71611bcb64ff61 100644 (file)
@@ -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);
index 4f941e3e1bd32142f461818ca02b9a0c2268ae20..c953fe9d2abb554fb7275751153896b639f7c5f4 100644 (file)
@@ -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));
 
index 9f0ce9b05da20929e77c0839ebc4a48ac54c26b6..4ff7125fce7390c95a3a09d154e417088a44af8c 100644 (file)
@@ -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();
index 6e0043b0bb1fdfa27c54f82a7a03676745fa0e13..01e289866b1200a8429cb1b00e454fa901e1d49d 100644 (file)
@@ -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__));