From 18bc76a0c6830358a137b4198e17b1b7ce92b9bf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Mar 2000 12:38:45 +0000 Subject: changed the definition of dos_PutUniCode the previous definition could result is us overflowing a buffer. The null termination was always added yet the size returned did not include the null termination. the new function takes a BOOL null_terminate, and always returns the total number of bytes consumed by the string. (This used to be commit 426c90433396a95033eefcc4af97603abc934221) --- source3/include/proto.h | 2 +- source3/lib/util_unistr.c | 13 +++++++++---- source3/libsmb/namequery.c | 3 +-- source3/nmbd/nmbd_processlogon.c | 13 ++++--------- source3/smbd/trans2.c | 8 ++++---- 5 files changed, 19 insertions(+), 20 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 28dd32e4c5..19ad9b6f33 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -477,7 +477,7 @@ char *string_truncate(char *s, int length); /*The following definitions come from lib/util_unistr.c */ -int dos_PutUniCode(char *dst,const char *src, ssize_t len); +int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate); void ascii_to_unistr(uint16 *dest, const char *src, int maxlen); void unistr_to_ascii(char *dest, const uint16 *src, int len); char *skip_unicode_string(char *buf,int n); diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index 27bd615bf4..6983d1100a 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -46,11 +46,13 @@ static uint16 *ucs2_to_unixcp; the current DOS codepage. len is the length in bytes of the string pointed to by dst. - the return value is the length of the string *without* the trailing - two bytes of zero + if null_terminate is True then null terminate the packet (adds 2 bytes) + + the return value is the length consumed by the string, including the + null termination if applied ********************************************************************/ -int dos_PutUniCode(char *dst,const char *src, ssize_t len) +int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate) { int ret = 0; while (*src && (len > 2)) { @@ -74,7 +76,10 @@ int dos_PutUniCode(char *dst,const char *src, ssize_t len) else src++; } - SSVAL(dst,ret,0); + if (null_terminate) { + SSVAL(dst,ret,0); + ret += 2; + } return(ret); } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 08f26f10d5..290a91f7b5 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -759,8 +759,7 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd mailslot_name = bufp; bufp += (strlen(bufp) + 1); bufp = align2(bufp, buffer); - dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1); - bufp = skip_unicode_string(bufp, 1); + bufp += dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1, True); SIVAL(bufp,0,1); SSVAL(bufp,4,0xFFFF); SSVAL(bufp,6,0xFFFF); diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index bc4c6ea127..0886654de9 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -159,11 +159,8 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); { q = align2(q, buf); - dos_PutUniCode(q, my_name, sizeof(pstring)); /* PDC name */ - q = skip_unicode_string(q, 1); - - dos_PutUniCode(q, global_myworkgroup,sizeof(pstring)); /* Domain name*/ - q = skip_unicode_string(q, 1); + q += dos_PutUniCode(q, my_name, sizeof(pstring), True); /* PDC name */ + q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True); /* Domain name*/ SIVAL(q, 0, ntversion); SSVAL(q, 4, lmnttoken); @@ -239,12 +236,10 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", } q += 2; - dos_PutUniCode(q, reply_name,sizeof(pstring)); - q = skip_unicode_string(q, 1); + q += dos_PutUniCode(q, reply_name,sizeof(pstring), True); unistrcpy(q, uniuser); q = skip_unicode_string(q, 1); /* User name (workstation trust account) */ - dos_PutUniCode(q, lp_workgroup(),sizeof(pstring)); - q = skip_unicode_string(q, 1); /* Domain name. */ + q += dos_PutUniCode(q, lp_workgroup(),sizeof(pstring), True); SIVAL(q, 0, ntversion); q += 4; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 308ba2dacd..24abf60a79 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1179,7 +1179,7 @@ static int call_trans2qfsinfo(connection_struct *conn, #endif /* Old code. */ SIVAL(pdata,4,128); /* Max filename component length */ - fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring)/2); + fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False); SIVAL(pdata,8,fstype_len); data_len = 12 + fstype_len; SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS); @@ -1209,7 +1209,7 @@ static int call_trans2qfsinfo(connection_struct *conn, } else { data_len = 18 + 2*strlen(vname); SIVAL(pdata,12,strlen(vname)*2); - dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring)/2); + dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring), False); } DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", @@ -1480,7 +1480,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, } strupper(short_name); l = strlen(short_name); - dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring)*2); + dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring), False); data_size = 4 + (2*l); SIVAL(pdata,0,2*l); } @@ -1496,7 +1496,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) { l = l*2; SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS); - dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring)*2); + dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring), False); } else { pstrcpy(pdata+4,fname); } -- cgit