r13581: Correctly parse a non-null terminated, little-endian UCS2 string in the
authorGünther Deschner <gd@samba.org>
Mon, 20 Feb 2006 23:22:56 +0000 (23:22 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:10:16 +0000 (11:10 -0500)
PAC_LOGON_NAME structure. This was broken on big-endian machines
(Solaris SPARC and ppc). Fixes Bug #3330.

Jerry, this should be in 3.0.21c.

Guenther

source/include/authdata.h
source/libads/authdata.c
source/rpc_parse/parse_prs.c

index 194429ab673c446c19d261dfb7b6e962f95ebc20..7e047687b7da7911cf25c8204f6de09b3b9efe40 100644 (file)
@@ -42,7 +42,7 @@
 typedef struct pac_logon_name {
        NTTIME logon_time;
        uint16 len;
-       uint16 *username; /* might not be null terminated, so not UNISTR */
+       fstring username;
 } PAC_LOGON_NAME;
 
 typedef struct pac_signature_data {
index 55e736ce6aec058bad6c6a8a1c50edfc0493f607..bb4236c4fcdae500be96309dff36b5751c529714 100644 (file)
@@ -42,16 +42,7 @@ static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name,
        if (!prs_uint16("len", ps, depth, &logon_name->len))
                return False;
 
-       if (UNMARSHALLING(ps) && logon_name->len) {
-               logon_name->username = PRS_ALLOC_MEM(ps, uint16, logon_name->len);
-               if (!logon_name->username) {
-                       DEBUG(3, ("No memory available\n"));
-                       return False;
-               }
-       }
-
-       if (!prs_uint16s(True, "name", ps, depth, logon_name->username, 
-                        (logon_name->len / sizeof(uint16))))
+       if (!prs_string_len("name", ps, depth, logon_name->username, logon_name->len))
                return False;
 
        return True;
@@ -891,7 +882,8 @@ static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) {
                nt_status = NT_STATUS_INVALID_PARAMETER;
                goto out;
        }
-       rpcstr_pull(username, logon_name->username, sizeof(username), -1, STR_TERMINATE);
+
+       rpcstr_pull(username, logon_name->username, sizeof(username), logon_name->len, 0);
 
        ret = smb_krb5_parse_name_norealm(context, username, &client_principal_pac);
        if (ret) {
index c4f9f512ab72b6cce951f4ced13fbb176ca574fc..857a24cf0e0b2405abde9912d6b5e84c0b2a2de6 100644 (file)
@@ -1332,6 +1332,49 @@ BOOL prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **
        return True;
 }
 
+/*******************************************************************
+ Stream a null-terminated string of fixed len.
+ ********************************************************************/
+
+BOOL prs_string_len(const char *name, prs_struct *ps, int depth, char *str, int len)
+{
+       char *q;
+       int i;
+       BOOL charmode = True;
+
+       q = prs_mem_get(ps, len+1);
+       if (q == NULL)
+               return False;
+
+       for(i = 0; i < len; i++) {
+               if (UNMARSHALLING(ps))
+                       str[i] = q[i];
+               else
+                       q[i] = str[i];
+       }
+
+       /* The terminating null. */
+       str[i] = '\0';
+
+       if (MARSHALLING(ps)) {
+               q[i] = '\0';
+       }
+
+       ps->data_offset += len+1;
+       
+       DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));
+       if (charmode) {
+               print_asc(5, (unsigned char*)str, len);
+       } else {
+               for (i = 0; i < len; i++)
+                       DEBUG(5,("%04x ", str[i]));
+       }
+       DEBUG(5,("\n"));
+
+       return True;
+}
+
+
 /*******************************************************************
  prs_uint16 wrapper. Call this and it sets up a pointer to where the
  uint16 should be stored, or gets the size if reading.