diff -uNrp samba-3.0.24.org/source/auth/auth_compat.c samba-3.0.24/source/auth/auth_compat.c
--- samba-3.0.24.org/source/auth/auth_compat.c	2006-04-20 11:29:20.000000000 +0900
+++ samba-3.0.24/source/auth/auth_compat.c	2007-02-09 11:19:52.000000000 +0900
@@ -92,18 +92,25 @@ static NTSTATUS pass_check_smb(const cha
 check if a username/password pair is ok via the auth subsystem.
 return True if the password is correct, False otherwise
 ****************************************************************************/
+
 BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
 {
 
 	DATA_BLOB null_password = data_blob(NULL, 0);
-	BOOL encrypted = (global_encrypted_passwords_negotiated && password_blob.length == 24);
+	BOOL encrypted = (global_encrypted_passwords_negotiated && (password_blob.length == 24 || password_blob.length > 46));
 	
 	if (encrypted) {
 		/* 
 		 * The password could be either NTLM or plain LM.  Try NTLM first, 
 		 * but fall-through as required.
-		 * NTLMv2 makes no sense here.
+		 * Vista sends NTLMv2 here - we need to try the client given workgroup.
 		 */
+		if (get_session_workgroup()) {
+			if (NT_STATUS_IS_OK(pass_check_smb(smb_name, get_session_workgroup(), null_password, password_blob, null_password, encrypted))) {
+				return True;
+			}
+		}
+
 		if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) {
 			return True;
 		}
@@ -119,5 +126,3 @@ BOOL password_ok(char *smb_name, DATA_BL
 
 	return False;
 }
-
-
diff -uNrp samba-3.0.24.org/source/include/smb.h samba-3.0.24/source/include/smb.h
--- samba-3.0.24.org/source/include/smb.h	2007-02-05 03:59:23.000000000 +0900
+++ samba-3.0.24/source/include/smb.h	2007-02-09 11:20:03.000000000 +0900
@@ -1436,6 +1436,7 @@ char *strdup(char *s);
 #define FLAGS2_LONG_PATH_COMPONENTS    0x0001
 #define FLAGS2_EXTENDED_ATTRIBUTES     0x0002
 #define FLAGS2_SMB_SECURITY_SIGNATURES 0x0004
+#define FLAGS2_UNKNOWN_BIT4            0x0010
 #define FLAGS2_IS_LONG_NAME            0x0040
 #define FLAGS2_EXTENDED_SECURITY       0x0800 
 #define FLAGS2_DFS_PATHNAMES           0x1000
@@ -1499,7 +1500,8 @@ enum ldap_passwd_sync_types {LDAP_PASSWD
 
 /* Remote architectures we know about. */
 enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT,
-			RA_WIN2K, RA_WINXP, RA_WIN2K3, RA_SAMBA, RA_CIFSFS};
+			RA_WIN2K, RA_WINXP, RA_WIN2K3, RA_VISTA,
+			RA_SAMBA, RA_CIFSFS};
 
 /* case handling */
 enum case_handling {CASE_LOWER,CASE_UPPER};
diff -uNrp samba-3.0.24.org/source/lib/util.c samba-3.0.24/source/lib/util.c
--- samba-3.0.24.org/source/lib/util.c	2007-02-09 11:18:37.000000000 +0900
+++ samba-3.0.24/source/lib/util.c	2007-02-09 11:20:03.000000000 +0900
@@ -2204,6 +2204,9 @@ void set_remote_arch(enum remote_arch_ty
 	case RA_WIN2K3:
 		fstrcpy(remote_arch, "Win2K3");
 		break;
+	case RA_VISTA:
+		fstrcpy(remote_arch, "Vista");
+		break;
 	case RA_SAMBA:
 		fstrcpy(remote_arch,"Samba");
 		break;
diff -uNrp samba-3.0.24.org/source/printing/nt_printing.c samba-3.0.24/source/printing/nt_printing.c
--- samba-3.0.24.org/source/printing/nt_printing.c	2007-02-09 11:18:37.000000000 +0900
+++ samba-3.0.24/source/printing/nt_printing.c	2007-02-09 11:19:58.000000000 +0900
@@ -2984,11 +2984,15 @@ static BOOL map_nt_printer_info2_to_dssp
 	return True;
 }
 
+/*****************************************************************
+ ****************************************************************/
+
 static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, 
 			       struct uuid guid)
 {
 	int i;
 	REGVAL_CTR *ctr=NULL;
+	UNISTR2 unistr_guid;
 
 	/* find the DsSpooler key */
 	if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
@@ -2996,8 +3000,18 @@ static void store_printer_guid(NT_PRINTE
 	ctr = info2->data->keys[i].values;
 
 	regval_ctr_delvalue(ctr, "objectGUID");
-	regval_ctr_addvalue(ctr, "objectGUID", REG_BINARY, 
-			    (char *) &guid, sizeof(struct uuid));	
+
+	/* We used to store this as a REG_BINARY but that causes
+	   Vista to whine */
+
+	ZERO_STRUCT( unistr_guid );	
+	init_unistr2( &unistr_guid, smb_uuid_string_static(guid),
+		      UNI_STR_TERMINATE );
+
+	regval_ctr_addvalue(ctr, "objectGUID", REG_SZ, 
+			    (char *)unistr_guid.buffer, 
+			    unistr_guid.uni_max_len*2);
+	
 }
 
 static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
@@ -3254,6 +3268,7 @@ BOOL is_printer_published(Printer_entry 
 	REGISTRY_VALUE *guid_val;
 	WERROR win_rc;
 	int i;
+	BOOL ret = False;
 
 	win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
 
@@ -3267,12 +3282,36 @@ BOOL is_printer_published(Printer_entry 
 		return False;
 	}
 
-	/* fetching printer guids really ought to be a separate function.. */
-	if (guid && regval_size(guid_val) == sizeof(struct uuid))
-		memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid));
+	/* fetching printer guids really ought to be a separate function. */
+
+	if ( guid ) {	
+		fstring guid_str;
+		
+		/* We used to store the guid as REG_BINARY, then swapped 
+		   to REG_SZ for Vista compatibility so check for both */
+
+		switch ( regval_type(guid_val) ){
+		case REG_SZ:		
+			rpcstr_pull( guid_str, regval_data_p(guid_val), 
+				     sizeof(guid_str)-1, -1, STR_TERMINATE );
+			ret = smb_string_to_uuid( guid_str, guid );
+			break;			
+		case REG_BINARY:
+			if ( regval_size(guid_val) != sizeof(struct uuid) ) {
+				ret = False;
+				break;
+			}
+			memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid));
+			break;
+		default:
+			DEBUG(0,("is_printer_published: GUID value stored as "
+				 "invaluid type (%d)\n", regval_type(guid_val) ));			
+			break;
+		}
+	}
 
 	free_a_printer(&printer, 2);
-	return True;
+	return ret;
 }
 #else
 WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
@@ -3539,13 +3578,43 @@ static int unpack_values(NT_PRINTER_DATA
 			break;
 		}
 		
-		/* add the new value */
+		DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
+
+		/* Vista doesn't like unknown REG_BINARY values in DsSpooler.  
+		   Thanks to Martin Zielinski for the hint. */
+
+		if ( type == REG_BINARY && 
+		     strequal( keyname, SPOOL_DSSPOOLER_KEY ) && 
+		     strequal( valuename, "objectGUID" ) ) 
+		{
+			struct uuid guid;
+			UNISTR2 unistr_guid;
+
+			ZERO_STRUCT( unistr_guid );
+			
+			/* convert the GUID to a UNICODE string */
+			
+			memcpy( &guid, data_p, sizeof(struct uuid) );
+			
+			init_unistr2( &unistr_guid, smb_uuid_string_static(guid), 
+				      UNI_STR_TERMINATE );
+			
+			regval_ctr_addvalue( printer_data->keys[key_index].values, 
+					     valuename, REG_SZ, 
+					     (const char *)unistr_guid.buffer, 
+					     unistr_guid.uni_str_len*2 );
+
+		} else {
+			/* add the value */
+
+			regval_ctr_addvalue( printer_data->keys[key_index].values, 
+					     valuename, type, (const char *)data_p, 
+					     size );
+		}
 		
-		regval_ctr_addvalue( printer_data->keys[key_index].values, valuename, type, (const char *)data_p, size );
 
 		SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
 
-		DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
 	}
 
 	return len;
diff -uNrp samba-3.0.24.org/source/rpc_server/srv_spoolss_nt.c samba-3.0.24/source/rpc_server/srv_spoolss_nt.c
--- samba-3.0.24.org/source/rpc_server/srv_spoolss_nt.c	2007-02-09 11:18:37.000000000 +0900
+++ samba-3.0.24/source/rpc_server/srv_spoolss_nt.c	2007-02-09 11:19:58.000000000 +0900
@@ -5848,6 +5848,12 @@ static WERROR update_printer_sec(POLICY_
 		goto done;
 	}
 	
+	if (!secdesc_ctr) {
+		DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
+		result = WERR_INVALID_PARAM;
+		goto done;
+	}
+
 	/* Check the user has permissions to change the security
 	   descriptor.  By experimentation with two NT machines, the user
 	   requires Full Access to the printer to change security
@@ -9378,6 +9384,15 @@ WERROR _spoolss_enumprinterdataex(pipes_
 	
 	/* housekeeping information in the reply */
 	
+	/* Fix from Martin Zielinski <mz@seh.de> - ensure
+	 * the hand marshalled container size is a multiple
+	 * of 4 bytes for RPC alignment.
+	 */
+
+	if (needed % 4) {
+		needed += 4-(needed % 4);
+	}
+
 	r_u->needed 	= needed;
 	r_u->returned 	= num_entries;
 
diff -uNrp samba-3.0.24.org/source/smbd/msdfs.c samba-3.0.24/source/smbd/msdfs.c
--- samba-3.0.24.org/source/smbd/msdfs.c	2007-02-05 03:59:13.000000000 +0900
+++ samba-3.0.24/source/smbd/msdfs.c	2007-02-09 11:19:46.000000000 +0900
@@ -832,9 +832,13 @@ int setup_dfs_referral(connection_struct
 
 	/* create the referral depeding on version */
 	DEBUG(10,("max_referral_level :%d\n",max_referral_level));
-	if(max_referral_level<2 || max_referral_level>3) {
+
+	if (max_referral_level < 2) {
 		max_referral_level = 2;
 	}
+	if (max_referral_level > 3) {
+		max_referral_level = 3;
+	}
 
 	switch(max_referral_level) {
 	case 2:
diff -uNrp samba-3.0.24.org/source/smbd/negprot.c samba-3.0.24/source/smbd/negprot.c
--- samba-3.0.24.org/source/smbd/negprot.c	2007-02-09 11:18:37.000000000 +0900
+++ samba-3.0.24/source/smbd/negprot.c	2007-02-09 11:20:03.000000000 +0900
@@ -263,6 +263,16 @@ static int reply_nt1(char *inbuf, char *
 
 	global_encrypted_passwords_negotiated = lp_encrypted_passwords();
 
+	/* Check the flags field to see if this is Vista.
+	   WinXP sets it and Vista does not. But we have to 
+	   distinguish from NT which doesn't set it either. */
+
+	if ( (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY) &&
+		((SVAL(inbuf, smb_flg2) & FLAGS2_UNKNOWN_BIT4) == 0) ) 
+	{
+		set_remote_arch( RA_VISTA );		
+	}
+
 	/* do spnego in user level security if the client
 	   supports it and we can do encrypted passwords */
 	
@@ -393,6 +403,15 @@ protocol [LM1.2X002]
 protocol [LANMAN2.1]
 protocol [NT LM 0.12]
 
+Vista:
+protocol [PC NETWORK PROGRAM 1.0]
+protocol [LANMAN1.0]
+protocol [Windows for Workgroups 3.1a]
+protocol [LM1.2X002]
+protocol [LANMAN2.1]
+protocol [NT LM 0.12]
+protocol [SMB 2.001]
+
 OS/2:
 protocol [PC NETWORK PROGRAM 1.0]
 protocol [XENIX CORE]
@@ -406,18 +425,19 @@ protocol [LANMAN2.1]
   *
   * This appears to be the matrix of which protocol is used by which
   * MS product.
-       Protocol                       WfWg    Win95   WinNT  Win2K  OS/2
-       PC NETWORK PROGRAM 1.0          1       1       1      1      1
+       Protocol                       WfWg    Win95   WinNT  Win2K  OS/2 Vista
+       PC NETWORK PROGRAM 1.0          1       1       1      1      1     1
        XENIX CORE                                      2             2
        MICROSOFT NETWORKS 3.0          2       2       
        DOS LM1.2X002                   3       3       
        MICROSOFT NETWORKS 1.03                         3
        DOS LANMAN2.1                   4       4       
-       LANMAN1.0                                       4      2      3
-       Windows for Workgroups 3.1a     5       5       5      3
-       LM1.2X002                                       6      4      4
-       LANMAN2.1                                       7      5      5
-       NT LM 0.12                              6       8      6
+       LANMAN1.0                                       4      2      3     2
+       Windows for Workgroups 3.1a     5       5       5      3            3
+       LM1.2X002                                       6      4      4     4
+       LANMAN2.1                                       7      5      5     5
+       NT LM 0.12                              6       8      6            6
+       SMB 2.001                                                           7
   *
   *  tim@fsg.com 09/29/95
   *  Win2K added by matty 17/7/99
@@ -430,6 +450,7 @@ protocol [LANMAN2.1]
 #define ARCH_OS2      0x14     /* Again OS/2 is like NT */
 #define ARCH_SAMBA    0x20
 #define ARCH_CIFSFS   0x40
+#define ARCH_VISTA    0x8C     /* Vista is like XP/2K */
  
 #define ARCH_ALL      0x7F
  
@@ -493,6 +514,8 @@ int reply_negprot(connection_struct *con
 			arch &= ( ARCH_WFWG | ARCH_WIN95 );
 		else if (strcsequal(p,"NT LM 0.12"))
 			arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS);
+		else if (strcsequal(p,"SMB 2.001"))
+			arch = ARCH_VISTA;		
 		else if (strcsequal(p,"LANMAN2.1"))
 			arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
 		else if (strcsequal(p,"LM1.2X002"))
@@ -537,7 +560,13 @@ int reply_negprot(connection_struct *con
 				set_remote_arch(RA_WINNT);
 			break;
 		case ARCH_WIN2K:
-			set_remote_arch(RA_WIN2K);
+			/* Vista may have been set in the negprot so don't 
+			   override it here */
+			if ( get_remote_arch() != RA_VISTA )
+				set_remote_arch(RA_WIN2K);
+			break;
+		case ARCH_VISTA:
+			set_remote_arch(RA_VISTA);
 			break;
 		case ARCH_OS2:
 			set_remote_arch(RA_OS2);
diff -uNrp samba-3.0.24.org/source/smbd/password.c samba-3.0.24/source/smbd/password.c
--- samba-3.0.24.org/source/smbd/password.c	2007-02-09 11:18:37.000000000 +0900
+++ samba-3.0.24/source/smbd/password.c	2007-02-09 11:19:52.000000000 +0900
@@ -23,6 +23,8 @@
 /* users from session setup */
 static char *session_userlist = NULL;
 static int len_session_userlist = 0;
+/* workgroup from session setup. */
+static char *session_workgroup = NULL;
 
 /* this holds info on user ids that are already validated for this VC */
 static user_struct *validated_users;
@@ -406,6 +408,29 @@ void add_session_user(const char *user)
 }
 
 /****************************************************************************
+ In security=share mode we need to store the client workgroup, as that's
+  what Vista uses for the NTLMv2 calculation.
+****************************************************************************/
+
+void add_session_workgroup(const char *workgroup)
+{
+	if (session_workgroup) {
+		SAFE_FREE(session_workgroup);
+	}
+	session_workgroup = smb_xstrdup(workgroup);
+}
+
+/****************************************************************************
+ In security=share mode we need to return the client workgroup, as that's
+  what Vista uses for the NTLMv2 calculation.
+****************************************************************************/
+
+const char *get_session_workgroup(void)
+{
+	return session_workgroup;
+}
+
+/****************************************************************************
  Check if a user is in a netgroup user list. If at first we don't succeed,
  try lower case.
 ****************************************************************************/
diff -uNrp samba-3.0.24.org/source/smbd/posix_acls.c samba-3.0.24/source/smbd/posix_acls.c
--- samba-3.0.24.org/source/smbd/posix_acls.c	2007-02-09 11:18:37.000000000 +0900
+++ samba-3.0.24/source/smbd/posix_acls.c	2007-02-09 11:20:10.000000000 +0900
@@ -655,6 +655,7 @@ static int map_acl_perms_to_permset(conn
 	}
 	return 0;
 }
+
 /****************************************************************************
  Function to create owner and group SIDs from a SMB_STRUCT_STAT.
 ****************************************************************************/
@@ -666,6 +667,27 @@ static void create_file_sids(SMB_STRUCT_
 }
 
 /****************************************************************************
+ Is the identity in two ACEs equal ? Check both SID and uid/gid.
+****************************************************************************/
+
+static BOOL identity_in_ace_equal(canon_ace *ace1, canon_ace *ace2)
+{
+	if (sid_equal(&ace1->trustee, &ace2->trustee)) {
+		return True;
+	}
+	if (ace1->owner_type == ace2->owner_type) {
+		if (ace1->owner_type == UID_ACE &&
+				ace1->unix_ug.uid == ace2->unix_ug.uid) {
+			return True;
+		} else if (ace1->owner_type == GID_ACE &&
+				ace1->unix_ug.gid == ace2->unix_ug.gid) {
+			return True;
+		}
+	}
+	return False;
+}
+
+/****************************************************************************
  Merge aces with a common sid - if both are allow or deny, OR the permissions together and
  delete the second one. If the first is deny, mask the permissions off and delete the allow
  if the permissions become zero, delete the deny if the permissions are non zero.
@@ -692,7 +714,7 @@ static void merge_aces( canon_ace **pp_l
 
 			curr_ace_next = curr_ace->next; /* Save the link in case of delete. */
 
-			if (sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) &&
+			if (identity_in_ace_equal(curr_ace, curr_ace_outer) &&
 				(curr_ace->attr == curr_ace_outer->attr)) {
 
 				if( DEBUGLVL( 10 )) {
@@ -732,7 +754,7 @@ static void merge_aces( canon_ace **pp_l
 			 * we've put on the ACL, we know the deny must be the first one.
 			 */
 
-			if (sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) &&
+			if (identity_in_ace_equal(curr_ace, curr_ace_outer) &&
 				(curr_ace_outer->attr == DENY_ACE) && (curr_ace->attr == ALLOW_ACE)) {
 
 				if( DEBUGLVL( 10 )) {
diff -uNrp samba-3.0.24.org/source/smbd/sesssetup.c samba-3.0.24/source/smbd/sesssetup.c
--- samba-3.0.24.org/source/smbd/sesssetup.c	2007-02-05 03:59:13.000000000 +0900
+++ samba-3.0.24/source/smbd/sesssetup.c	2007-02-09 11:19:52.000000000 +0900
@@ -1035,6 +1035,7 @@ int reply_sesssetup_and_X(connection_str
 
 		map_username(sub_user);
 		add_session_user(sub_user);
+		add_session_workgroup(domain);
 		/* Then force it to null for the benfit of the code below */
 		*user = 0;
 	}
Index: samba-3.0.24/source/lib/dummysmbd.c
===================================================================
--- samba-3.0.24.orig/source/lib/dummysmbd.c	2006-04-19 21:29:23.000000000 -0500
+++ samba-3.0.24/source/lib/dummysmbd.c	2007-02-08 20:15:04.000000000 -0600
@@ -38,3 +38,9 @@
 {
 	return False;
 }
+
+NTSTATUS can_delete_directory(struct connection_struct *conn,
+                                const char *dirname)
+{
+	return NT_STATUS_OK;
+}
Index: samba-3.0.24/source/locking/locking.c
===================================================================
--- samba-3.0.24.orig/source/locking/locking.c	2007-02-04 12:59:23.000000000 -0600
+++ samba-3.0.24/source/locking/locking.c	2007-02-08 20:15:04.000000000 -0600
@@ -1166,6 +1166,11 @@
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
+	/* Don't allow delete on close for non-empty directories. */
+	if (fsp->is_directory) {
+		return can_delete_directory(fsp->conn, fsp->fsp_name);
+	}
+
 	return NT_STATUS_OK;
 }
 
Index: samba-3.0.24/source/smbd/dir.c
===================================================================
--- samba-3.0.24.orig/source/smbd/dir.c	2007-02-04 12:59:13.000000000 -0600
+++ samba-3.0.24/source/smbd/dir.c	2007-02-08 20:15:04.000000000 -0600
@@ -1255,3 +1255,42 @@
 	}
 	return False;
 }
+
+/*****************************************************************
+ Is this directory empty ?
+*****************************************************************/
+
+NTSTATUS can_delete_directory(struct connection_struct *conn,
+				const char *dirname)
+{
+	NTSTATUS status = NT_STATUS_OK;
+	long dirpos = 0;
+	const char *dname;
+	struct smb_Dir *dir_hnd = OpenDir(conn, dirname, NULL, 0);
+
+	if (!dir_hnd) {
+		return map_nt_error_from_unix(errno);
+	}
+
+	while ((dname = ReadDirName(dir_hnd,&dirpos))) {
+		SMB_STRUCT_STAT st;
+
+		/* Quick check for "." and ".." */
+		if (dname[0] == '.') {
+			if (!dname[1] || (dname[1] == '.' && !dname[2])) {
+				continue;
+			}
+		}
+
+		if (!is_visible_file(conn, dirname, dname, &st, True)) {
+			continue;
+		}
+
+		DEBUG(10,("can_delete_directory: got name %s - can't delete\n", dname ));
+		status = NT_STATUS_DIRECTORY_NOT_EMPTY;
+		break;
+	}
+	CloseDir(dir_hnd);
+
+	return status;
+}
