Patch to fix SMB browsing bugs



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Attached is a patch which fixes a number of SMB browsing bugs. Haven't
hacked gnome-vfs before, so I hope this is the right place to post this.
The patch allows authentication of IPC$ and the master browser which
allows proper browsing on a domain.

There are still some other issues.

There seems to be a deadlock or race in the authentication code. In many
cases the gnome_vfs_module_callback_invoke call in invoke_fill_auth
(modules/smb-method.c) never returns.

When stracing or debugging the process (ie: gnome-vfs-daemon or
nautilus) all works reliably and as expected, so I suspect a
locking/race issue. Any ideas what this could could be?

Cheers,
Nate
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFBm4Oae/sRCNknZa8RAhJ5AJ4oXSjY8JL4X4+OWBhm+IPWib5B3QCdEC8Y
Zvi3YlytJ3nfzXuTnV3txAA=
=F1kt
-----END PGP SIGNATURE-----
Index: smb-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/smb-method.c,v
retrieving revision 1.12
diff -u -r1.12 smb-method.c
--- modules/smb-method.c	11 Oct 2004 08:53:06 -0000	1.12
+++ modules/smb-method.c	17 Nov 2004 05:09:12 -0000
@@ -486,7 +486,7 @@
 }
 
 static void
-update_workgroup_cache (void)
+update_workgroup_cache (GnomeVFSURI *foruri)
 {
 	SMBCFILE *dir;
 	time_t t;
@@ -508,7 +508,7 @@
 	
 	LOCK_SMB();
 	workgroups_errno = 0;
-	init_auth (NULL);
+	init_auth (foruri);
 	dir = smb_context->opendir (smb_context, "smb://");
 	if (dir != NULL) {
 		while ((dirent = smb_context->readdir (smb_context, dir)) != NULL) {
@@ -553,7 +553,7 @@
 	    uri->text[0] == 0 ||
 	    strcmp (uri->text, "/") == 0) {
 		/* smb://foo/ */
-		update_workgroup_cache ();
+		update_workgroup_cache (uri);
 		if (!g_ascii_strcasecmp(toplevel->host_name,
 					DEFAULT_WORKGROUP_NAME) ||
 		    g_hash_table_lookup (workgroups, toplevel->host_name)) {
@@ -565,7 +565,7 @@
 	first_slash = strchr (uri->text + 1, '/');
 	if (first_slash == NULL) {
 		/* smb://foo/bar */
-		update_workgroup_cache ();
+		update_workgroup_cache (uri);
 		if (!g_ascii_strcasecmp(toplevel->host_name,
 					DEFAULT_WORKGROUP_NAME) ||
 		    g_hash_table_lookup (workgroups, toplevel->host_name)) {
@@ -656,6 +656,19 @@
 	return TRUE;
 }
 
+static char *
+get_current_display_uri (const char *server, const char *share)
+{
+    if (current_uri != NULL)
+        return gnome_vfs_uri_to_string (current_uri, 0);
+    else
+        return g_strdup_printf ("smb://%s%s%s%s", 
+                                    server ? server : "", 
+                                    server ? "/" : "",
+                                    share ? share : "",
+                                    share ? "/" : "");
+}
+
 static gboolean
 invoke_fill_auth (const char *server,
 		 const char *share,
@@ -677,20 +690,22 @@
 	}
 
 	memset (&in_args, 0, sizeof (in_args));
-	in_args.uri = gnome_vfs_uri_to_string (current_uri, 0);
+	in_args.uri = get_current_display_uri (server, share);
 	in_args.protocol = "smb";
 	in_args.server = (char *)server;
 	in_args.object = (char *)share;
 	in_args.username = (char *)username;
 	in_args.domain = (char *)domain;
-	in_args.port = ((GnomeVFSToplevelURI *)current_uri)->host_port;
+	in_args.port = 0;
 
 	memset (&out_args, 0, sizeof (out_args));
 
+    DEBUG_SMB (("calling fill authentication\n"));
 	invoked = gnome_vfs_module_callback_invoke
 		(GNOME_VFS_MODULE_CALLBACK_FILL_AUTHENTICATION,
 		 &in_args, sizeof (in_args),
 		 &out_args, sizeof (out_args));
+    DEBUG_SMB (("back from fill authentication\n"));
 
 	if (invoked && out_args.valid) {
 		*username_out = g_strdup (out_args.username);
@@ -734,12 +749,12 @@
 	}
 	
 	memset (&in_args, 0, sizeof (in_args));
-	in_args.uri = gnome_vfs_uri_to_string (current_uri, 0);
+    in_args.uri = get_current_display_uri (server, share);
 	in_args.flags = GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_PASSWORD | GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_SAVING_SUPPORTED;
 	if (done_auth) {
 		in_args.flags |= GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_PREVIOUS_ATTEMPT_FAILED;
 	}
-	if (((GnomeVFSToplevelURI *)current_uri)->user_name == NULL) {
+	if (!current_uri || ((GnomeVFSToplevelURI *)current_uri)->user_name == NULL) {
 		in_args.flags |=
 			GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_USERNAME |
 			GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_DOMAIN;
@@ -749,16 +764,18 @@
 	in_args.object = (char *)share;
 	in_args.username = (char *)username;
 	in_args.domain = (char *)domain;
-	in_args.port = ((GnomeVFSToplevelURI *)current_uri)->host_port;
+	in_args.port = 0;
 
 	/* TODO: set default_user & default_domain? */
 	
 	memset (&out_args, 0, sizeof (out_args));
 
+    DEBUG_SMB (("calling full authentication\n"));
 	invoked = gnome_vfs_module_callback_invoke
 		(GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION,
 		 &in_args, sizeof (in_args),
 		 &out_args, sizeof (out_args));
+    DEBUG_SMB (("back from full authentication\n"));
 
 	if (invoked) {
 		*cancel_auth_out = out_args.abort_auth;
@@ -807,12 +824,12 @@
 	}
 	
 	memset (&in_args, 0, sizeof (in_args));
-	in_args.uri = gnome_vfs_uri_to_string (current_uri, 0);
+    in_args.uri = get_current_display_uri (server, share);
 	in_args.keyring = (char *)keyring;
 	in_args.protocol = "smb";
 	in_args.server = (char *)server;
 	in_args.object = (char *)share;
-	in_args.port = ((GnomeVFSToplevelURI *)current_uri)->host_port;
+	in_args.port = 0;
 	in_args.authtype = NULL;
 	in_args.username = (char *)username;
 	in_args.domain = (char *)domain;
@@ -872,23 +889,16 @@
 
 	if (server_name == NULL || server_name[0] == 0) {
 		/* We never authenticate for the toplevel (enumerating workgroups) */
+        DEBUG_SMB (("not authenticating for top level\n"));
 		return;
 	}
 
-	if (current_uri == NULL) {
-		/* TODO: What to do with this,
-		   comes from e.g. enumerating workgroups which needs login on
-		   master browser $IPC.
-		*/
-		DEBUG_SMB (("auth_fn - no current_uri, ignoring\n"));
-		return;
-	}
-	
 	got_default_user = FALSE;
 	username = NULL;
 	domain = NULL;
 	current_toplevel_uri =	(GnomeVFSToplevelURI *)current_uri;
-	if (current_toplevel_uri->user_name != NULL &&
+	if (current_toplevel_uri && 
+        current_toplevel_uri->user_name != NULL &&
 	    current_toplevel_uri->user_name[0] != 0) {
 		tmp = strchr (current_toplevel_uri->user_name, ';');
 		if (tmp != NULL) {
@@ -915,20 +925,6 @@
 		}
 	}
 
-	if (strcmp (share_name,"IPC$") == 0) {
-		/* Don't authenticate to IPC$ using dialog, but allow name+domain in uri */
-		if (username != NULL) {
-			strncpy (username_out, username, unmaxlen);
-		}
-		if (domain != NULL) {
-			strncpy (domain_out, domain, domainmaxlen);
-		}
-		strncpy (password_out, "", pwmaxlen);
-		g_free (username);
-		g_free (domain);
-		return;
-	}
-
 	if (got_default_user ||
 	    (username != NULL && username[0] != 0)) {
 		SmbServerCacheEntry server_lookup;
@@ -947,7 +943,8 @@
 			} 
 			strncpy (password_out, "", pwmaxlen);
 
-			/* Server is in cache already, no need to get password */
+    	    /* Server is in cache already, no need to get password */
+            DEBUG_SMB (("server already in cache\n"));
 			return ;
 		}
 	}
@@ -983,6 +980,7 @@
 			g_free (real_domain);
 			g_free (real_password);
 
+            DEBUG_SMB (("returning via preauth\n"));
 			return;
 		}
 	}
@@ -1031,7 +1029,7 @@
 	}
 	
 	done_auth = TRUE;
-
+    DEBUG_SMB (("returning from auth_fn"));
 	return;
 }
 
@@ -1461,6 +1459,7 @@
 	if (err < 0) {
 		UNLOCK_SMB();
 		g_free (path);
+        DEBUG_SMB (("returning error. stat failed"));
 		return gnome_vfs_result_from_errno ();
 	}
 
@@ -1568,7 +1567,7 @@
 	type = smb_uri_type (uri);
 
 	if (type == SMB_URI_WHOLE_NETWORK) {
-		update_workgroup_cache ();
+		update_workgroup_cache (uri);
 		
 		if (workgroups_errno != 0) {
 			gnome_vfs_result_from_errno_code (workgroups_errno);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]