Index: rdesktop-1.6.0/configure.ac
===================================================================
--- rdesktop-1.6.0.orig/configure.ac
+++ rdesktop-1.6.0/configure.ac
@@ -887,6 +887,15 @@ AC_ARG_WITH(debug-smartcard,
 	fi
     ])
 
+AC_ARG_WITH(debug-time,
+    [  --with-debug-time  enable debugging of timezone handling code],
+    [
+        if test $withval != "no";
+        then
+	    AC_DEFINE(WITH_DEBUG_TIME,1)
+	fi
+    ])
+
 #
 # target-specific stuff
 #
Index: rdesktop-1.6.0/Makefile.in
===================================================================
--- rdesktop-1.6.0.orig/Makefile.in
+++ rdesktop-1.6.0/Makefile.in
@@ -28,7 +28,7 @@ VNCLINK     = @VNCLINK@
 SOUNDOBJ    = @SOUNDOBJ@
 SCARDOBJ    = @SCARDOBJ@
 
-RDPOBJ   = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o ssl.o
+RDPOBJ   = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o ssl.o w32time.o
 X11OBJ   = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o rdpx11.o
 VNCOBJ   = vnc/rdp2vnc.o vnc/vnc.o vnc/xkeymap.o vnc/x11stubs.o
 
Index: rdesktop-1.6.0/rdesktop.h
===================================================================
--- rdesktop-1.6.0.orig/rdesktop.h
+++ rdesktop-1.6.0/rdesktop.h
@@ -83,6 +83,12 @@
 #define DEBUG_SCARD(args)
 #endif
 
+#ifdef WITH_DEBUG_TIME
+#define DEBUG_TIME(args) printf args;
+#else
+#define DEBUG_TIME(args)
+#endif
+
 #define STRNCPY(dst,src,n)	{ strncpy(dst,src,n-1); dst[n-1] = 0; }
 
 #ifndef MIN
Index: rdesktop-1.6.0/rdp.c
===================================================================
--- rdesktop-1.6.0.orig/rdp.c
+++ rdesktop-1.6.0/rdp.c
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #endif
 #include "rdesktop.h"
+#include "w32time.h"
 
 #ifdef HAVE_ICONV
 #ifdef HAVE_ICONV_H
@@ -330,8 +331,7 @@ rdp_send_logon_info(uint32 flags, char *
 	int packetlen = 0;
 	uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
 	STREAM s;
-	time_t t = time(NULL);
-	time_t tzone;
+	RTL_TIME_ZONE_INFORMATION tzi;
 
 	if (!g_use_rdp5 || 1 == g_server_rdp_version)
 	{
@@ -374,12 +374,14 @@ rdp_send_logon_info(uint32 flags, char *
 			len_ip +	/* Client ip */
 			2 +	/* DLL string length */
 			len_dll +	/* DLL string */
-			2 +	/* Unknown */
-			2 +	/* Unknown */
-			64 +	/* Time zone #0 */
-			2 +	/* Unknown */
-			64 +	/* Time zone #1 */
-			32;	/* Unknown */
+			4 +     /* 32-bit offset in minutes from UTC */
+			64 +	/* Time zone name for standard time (32 wide characters) */
+			16 +    /* Win32 SYSTEM_TIME struct for standard time */
+			4 +     /* 32-bit signed bias from the UTC offset for standard time */
+			64 +	/* Time zone name for daylight savings time (32 wide characters) */
+			16 +    /* Win32 SYSTEM_TIME struct for daylight savings time */
+			4 +     /* 32-bit signed bias from the UTC offset for daylight savings time */
+			12;	/* Unknown */
 
 		s = sec_init(sec_flags, packetlen);
 		DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
@@ -435,26 +437,43 @@ rdp_send_logon_info(uint32 flags, char *
 		out_uint16_le(s, len_dll + 2);
 		rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
 
-		tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
-		out_uint32_le(s, tzone);
-
+		init_tz_info(&tzi);
+		/* The TZ offset from UTC used in the absence of daylight savings time rules */
+		out_uint32_le(s, tzi.Bias);
+
+		/* Standard Time definition */
+		/* Windows does not seem to require this text field to be set to anything
+		   recognizes */
 		rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
 		out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
 
-		out_uint32_le(s, 0x0a0000);
-		out_uint32_le(s, 0x050000);
-		out_uint32_le(s, 3);
-		out_uint32_le(s, 0);
-		out_uint32_le(s, 0);
+		/* This tells Windows the date that standard time should start on.  It is one
+		   of the standard Windows time formats */
+		out_uint16_le(s, tzi.StandardDate.wYear);
+		out_uint16_le(s, tzi.StandardDate.wMonth);
+		out_uint16_le(s, tzi.StandardDate.wDayOfWeek);
+		out_uint16_le(s, tzi.StandardDate.wDay);
+		out_uint16_le(s, tzi.StandardDate.wHour);
+		out_uint16_le(s, tzi.StandardDate.wMinute);
+		out_uint16_le(s, tzi.StandardDate.wSecond);
+		out_uint16_le(s, tzi.StandardDate.wMilliseconds);
+		/* Offset from the normal bias when standard time is in effect */
+		out_uint32_le(s, tzi.StandardBias);
 
+		/* This is the same as the standard time section above, except
+		   for the start of Daylight Savings Time */
 		rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
 		out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
+		out_uint16_le(s, tzi.DaylightDate.wYear);
+		out_uint16_le(s, tzi.DaylightDate.wMonth);
+		out_uint16_le(s, tzi.DaylightDate.wDayOfWeek);
+		out_uint16_le(s, tzi.DaylightDate.wDay);
+		out_uint16_le(s, tzi.DaylightDate.wHour);
+		out_uint16_le(s, tzi.DaylightDate.wMinute);
+		out_uint16_le(s, tzi.DaylightDate.wSecond);
+		out_uint16_le(s, tzi.DaylightDate.wMilliseconds);
+		out_uint32_le(s, tzi.DaylightBias);
 
-		out_uint32_le(s, 0x30000);
-		out_uint32_le(s, 0x050000);
-		out_uint32_le(s, 2);
-		out_uint32(s, 0);
-		out_uint32_le(s, 0xffffffc4);
 		out_uint32_le(s, 0xfffffffe);
 		out_uint32_le(s, g_rdp5_performanceflags);
 		out_uint16(s, 0);
Index: rdesktop-1.6.0/w32time.c
===================================================================
--- /dev/null
+++ rdesktop-1.6.0/w32time.c
@@ -0,0 +1,174 @@
+/* w32time.c - for proper timezone support
+ * 
+ * Nt time functions.
+ *
+ * Functions were taken from Wine, which seems to get this as right
+ * as possible.
+ * 
+ * Functions extracted from wine-0.9.57/dlls/ntdll/time.c
+ * 
+ * Original functions:
+ * Copyright 1999 Juergen Schmied
+ * Copyright 2007 Dmitry Timoshkov
+ * 
+ * Modifications for rdesktop:
+ * Copyright 2008 Sean E. Millichamp
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+ 
+#include <time.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "rdesktop.h"
+#include "w32time.h"
+
+static time_t find_dst_change(unsigned long min, unsigned long max, int *is_dst);
+
+void init_tz_info(RTL_TIME_ZONE_INFORMATION *tzi)
+{
+	struct tm *tm;
+	time_t year_start, year_end, tmp, dlt = 0, std = 0;
+	int is_dst;
+
+	memset(tzi, 0, sizeof(*tzi));
+
+	/* Find the start of the current year */
+	year_start = time(NULL);
+	tm = localtime(&year_start);
+	DEBUG_TIME(("tz data will be valid through year %d\n", tm->tm_year + 1900));
+	tm->tm_isdst = 0;
+	tm->tm_mday = 1;
+	tm->tm_mon = tm->tm_hour = tm->tm_min = tm->tm_sec = tm->tm_wday = tm->tm_yday = 0;
+	year_start = mktime(tm);
+	DEBUG_TIME(("year_start: %s", ctime(&year_start)));
+
+	/* Find the end of the current year */
+	tm->tm_mday = tm->tm_wday = tm->tm_yday = 0;
+	tm->tm_mon = 12;
+	tm->tm_hour = 23;
+	tm->tm_min = tm->tm_sec = 59;
+	year_end = mktime(tm);
+	DEBUG_TIME(("year_end: %s", ctime(&year_end)));
+
+	/* Find the UTC offset at the year's start, Windows calls this
+	   this the "bias" and it is represented in positive or negative
+	   minutes from UTC */
+	tm = gmtime(&year_start);
+	tzi->Bias = (LONG)(mktime(tm) - year_start) / 60;
+	DEBUG_TIME(("bias: %d\n", tzi->Bias));
+
+	tmp = find_dst_change(year_start, year_end, &is_dst);
+	if (is_dst)
+		dlt = tmp;
+	else
+		std = tmp;
+
+	tmp = find_dst_change(tmp, year_end, &is_dst);
+	if (is_dst)
+		dlt = tmp;
+	else
+		std = tmp;
+
+	DEBUG_TIME(("std: %s", ctime(&std)));
+	DEBUG_TIME(("dlt: %s", ctime(&dlt)));
+
+	if (dlt == std || !dlt || !std) {
+		DEBUG_TIME(("there are no daylight saving rules in this time zone\n"));
+	} else {
+		tmp = dlt - tzi->Bias * 60;
+		tm = gmtime(&tmp);
+		DEBUG_TIME(("dlt gmtime: %s", asctime(tm)));
+
+		/* The bias here isn't from UTC, it is from the bias from UTC.  A bias on a bias. */
+		tzi->DaylightBias = -60;
+		tzi->DaylightDate.wYear = tm->tm_year + 1900;
+		tzi->DaylightDate.wMonth = tm->tm_mon + 1;
+		tzi->DaylightDate.wDayOfWeek = tm->tm_wday;
+		tzi->DaylightDate.wDay = tm->tm_mday;
+		tzi->DaylightDate.wHour = tm->tm_hour;
+		tzi->DaylightDate.wMinute = tm->tm_min;
+		tzi->DaylightDate.wSecond = tm->tm_sec;
+		tzi->DaylightDate.wMilliseconds = 0;
+
+		DEBUG_TIME(("daylight (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %d\n",
+			tzi->DaylightDate.wDay, tzi->DaylightDate.wMonth,
+			tzi->DaylightDate.wYear, tzi->DaylightDate.wDayOfWeek,
+			tzi->DaylightDate.wHour, tzi->DaylightDate.wMinute,
+			tzi->DaylightDate.wSecond, tzi->DaylightDate.wMilliseconds,
+			tzi->DaylightBias));
+
+		tmp = std - tzi->Bias * 60 - tzi->DaylightBias * 60;
+		tm = gmtime(&tmp);
+		DEBUG_TIME(("std gmtime: %s", asctime(tm)));
+
+		tzi->StandardBias = 0;
+		tzi->StandardDate.wYear = tm->tm_year + 1900;
+		tzi->StandardDate.wMonth = tm->tm_mon + 1;
+		tzi->StandardDate.wDayOfWeek = tm->tm_wday;
+		tzi->StandardDate.wDay = tm->tm_mday;
+		tzi->StandardDate.wHour = tm->tm_hour;
+		tzi->StandardDate.wMinute = tm->tm_min;
+		tzi->StandardDate.wSecond = tm->tm_sec;
+		tzi->StandardDate.wMilliseconds = 0;
+
+		DEBUG_TIME(("standard (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %d\n",
+			tzi->StandardDate.wDay, tzi->StandardDate.wMonth,
+			tzi->StandardDate.wYear, tzi->StandardDate.wDayOfWeek,
+			tzi->StandardDate.wHour, tzi->StandardDate.wMinute,
+			tzi->StandardDate.wSecond, tzi->StandardDate.wMilliseconds,
+			tzi->StandardBias));
+	}
+
+	return;
+}
+
+/* This essentially does a binary search of the seconds in the year, looking for the exact time when
+ * the timezone changes */
+static time_t find_dst_change(unsigned long min, unsigned long max, int *is_dst)
+{
+	DEBUG_TIME(("Enterting find_dst_change()\n"));
+	time_t start;
+	time_t temptime;
+	struct tm *tm;
+
+	start = min;
+	tm = localtime(&start);
+	*is_dst = !tm->tm_isdst;
+	DEBUG_TIME(("  starting date isdst %d, %s", !*is_dst, ctime(&start)));
+	DEBUG_TIME(("  starting min is: %lu, starting max is: %lu\n", min, max));
+
+	while (min <= max)
+	{
+		time_t pos = (min + max) / 2;
+		
+		tm = localtime(&pos);
+	        temptime = mktime(tm);
+
+		DEBUG_TIME(("    find_dst_change loop: tm_isdst is %d, pos is %s", tm->tm_isdst, ctime(&temptime)));
+		if (tm->tm_isdst != *is_dst) {
+			DEBUG_TIME(("     min was: %lu, setting min to: %lu\n", min, pos+1));
+			min = pos + 1;
+		}
+		else {
+			DEBUG_TIME(("     max was: %lu, setting max to: %lu\n", min, pos-1));
+			max = pos - 1;
+		}
+	}
+	DEBUG_TIME(("Returning from find_dst_change() with min==%lu\n", min));
+	return min;
+}
+
Index: rdesktop-1.6.0/w32time.h
===================================================================
--- /dev/null
+++ rdesktop-1.6.0/w32time.h
@@ -0,0 +1,55 @@
+/*
+ * Windows time structures taken from the Wine project and are
+ * Copyright (C) the Wine project
+ * Extracted from wine-0.9.57/include/winbase.h
+ * 
+ * Any Rdesktop-related modifications:
+ * Copyright 2008 Sean E. Millichamp
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef W32TIME_H_
+#define W32TIME_H_
+
+#include <stdint.h>
+
+typedef int16_t WORD;
+typedef int32_t LONG;
+
+typedef struct _RTL_SYSTEM_TIME{
+	WORD wYear;
+	WORD wMonth;
+	WORD wDayOfWeek;
+	WORD wDay;
+	WORD wHour;
+	WORD wMinute;
+	WORD wSecond;
+	WORD wMilliseconds;
+} RTL_SYSTEM_TIME;
+
+typedef struct _TIME_ZONE_INFORMATION{
+	LONG Bias;
+	char StandardName[64];
+	RTL_SYSTEM_TIME StandardDate;
+	LONG StandardBias;
+	char DaylightName[64];
+	RTL_SYSTEM_TIME DaylightDate;
+	LONG DaylightBias;
+} RTL_TIME_ZONE_INFORMATION;
+
+void init_tz_info(RTL_TIME_ZONE_INFORMATION *tzi);
+
+#endif /*W32TIME_H_*/
