Re: Authentication Cache for libsmb (gnome-vfs-extras)
- From: Knut Neumann <knut neumann uni-duesseldorf de>
- To: Alex Graveley <alex ximian com>
- Cc: Knut Neumann rz uni-duesseldorf de, gnome-vfs-list gnome org, alexl redhat com
- Subject: Re: Authentication Cache for libsmb (gnome-vfs-extras)
- Date: Thu, 21 Nov 2002 18:29:50 +0100
Am Mit, 2002-11-20 um 04.00 schrieb Alex Graveley:
> Hi,
>
> On Tue, 2002-11-19 at 18:45, Knut Neumann rz uni-duesseldorf de wrote:
> > the attached patch will add an authentication cache system to libsmb:
>
> No patch attached :-)
Ok. I will try it again...hopefully it works this time. I have to add
that from what I have seen in a quick look I would vote to replace head
with ximian-smb. It seems to be a quite clean codebase.
-Knut
--
Knut Neumann <knut neumann uni-duesseldorf de>
Physikalische Grundpraktika - Heinrich-Heine Universitaet Duesseldorf
Raum 25.33.01.63 - Universitaetsstrasse 1 - D-40225 Duesseldorf
fon: +49-211-81-11314 fax: +49-211-81-13105
--- gnome-vfs-extras.virgin/smb-method.c 2002-11-13 16:27:33.000000000 +0100
+++ gnome-vfs-extras/smb-method.c 2002-11-20 23:39:10.000000000 +0100
@@ -162,7 +162,7 @@
extern pstring global_myname;
static GHashTable *virtual_hash = NULL;
-static GHashTable *server_auth_infos = NULL;
+static GHashTable *auth_info_cache = NULL;
#undef DEBUG_SMB_ENABLE
#undef DEBUG_SMB_LOCKS
@@ -181,8 +181,188 @@
#define UNLOCK_SAMBA() g_mutex_unlock (samba_lock)
#endif
+static void
+auth_info_cache_destroy_value (SmbAuthInfo *auth_info) {
+
+ g_free (auth_info->user);
+ g_free (auth_info->password);
+ g_free (auth_info);
+}
+
+static void
+put_auth_to_cache (SmbAuthInfo *auth_info, gchar *server, gchar *share)
+{
+ gchar *key;
+
+ DEBUG_SMB (("put_auth_to_cache\n"));
+
+ if (!server)
+ return;
+
+ if (share) {
+ key = g_strdup_printf ("smb://%s%s", server, share);
+ g_hash_table_insert (auth_info_cache, key, auth_info);
+ key = g_strdup_printf ("smb://%s/<lastshare>", server);
+ g_hash_table_insert (auth_info_cache, key, auth_info);
+ } else {
+ key = g_strdup_printf ("smb://%s", server);
+ g_hash_table_insert (auth_info_cache, key, auth_info);
+ }
+}
+
+SmbAuthInfo *
+get_auth_from_cache (gchar *server, gchar *share)
+{
+ SmbAuthInfo *auth_info = NULL;
+ gchar *key;
+
+ DEBUG_SMB (("get_auth_from_cache\n"));
+
+ if (!server)
+ return auth_info;
+
+ if (share) {
+ key = g_strdup_printf ("smb://%s%s", server, share);
+ auth_info = g_hash_table_lookup (auth_info_cache, key);
+ g_free (key);
+ if (!auth_info) {
+ key = g_strdup_printf ("smb://%s/<lastshare>", server);
+ auth_info = g_hash_table_lookup (auth_info_cache, key);
+ g_free (key);
+ }
+ } else {
+ key = g_strdup_printf ("smb://%s", server);
+ auth_info = g_hash_table_lookup (auth_info_cache, key);
+ g_free (key);
+ }
+
+ return auth_info;
+}
+
+SmbAuthInfo *
+get_auth_from_dialog (gchar *server, gchar *share)
+{
+ GnomeVFSModuleCallbackAuthenticationIn in_args;
+ GnomeVFSModuleCallbackAuthenticationOut out_args;
+ SmbAuthInfo *auth_info = NULL;
+ GnomeVFSResult res = 0;
+
+ DEBUG_SMB (("get_auth_from_dialog\n"));
+ memset (&in_args, 0, sizeof (in_args));
+ memset (&out_args, 0, sizeof (out_args));
+
+ if (share) {
+ in_args.uri = g_strdup_printf ("smb://%s%s", server, share);
+ }
+ else {
+ in_args.uri = g_strdup_printf ("smb://%s", server);
+ }
+
+ UNLOCK_SAMBA();
+
+ res = gnome_vfs_module_callback_invoke (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION,
+ &in_args, sizeof (in_args),
+ &out_args, sizeof (out_args));
+
+ LOCK_SAMBA();
+
+ g_free (in_args.uri);
+
+ if (res && out_args.username)
+ {
+ auth_info = g_new (SmbAuthInfo, 1);
+
+ auth_info->user = out_args.username;
+ auth_info->password = out_args.password;
+ }
+
+ return auth_info;
+}
+
+SmbAuthInfo *
+get_auth_from_uri (GnomeVFSURI *uri)
+{
+ SmbAuthInfo *auth_info = NULL;
+ gchar *user;
+
+ DEBUG_SMB (("get_auth_from_uri\n"));
+
+ user = gnome_vfs_unescape_string (gnome_vfs_uri_get_user_name (uri), NULL);
+
+ if (user) {
+ auth_info = g_new (SmbAuthInfo, 1);
+ auth_info->user = user;
+ auth_info->password = gnome_vfs_unescape_string (gnome_vfs_uri_get_password (uri), NULL);
+ }
+
+ return auth_info;
+}
+static int
+get_auth_by_server (SmbAuthInfo *auth_info, gchar *server, gchar *share, gboolean previous_failed)
+{
+ SmbAuthInfo *auth = NULL;
+
+ DEBUG_SMB (("get_auth_by_server\n"));
+
+ auth_info->user = NULL;
+ auth_info->password = NULL;
+
+ if (previous_failed) {
+ auth = get_auth_from_dialog (server, share);
+ if (auth)
+ put_auth_to_cache (auth, server, share);
+ }
+ else
+ auth = get_auth_from_cache (server, share);
+
+ if (auth) {
+ auth_info->user = auth->user;
+ auth_info->password = auth->password;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static int
+get_auth_by_uri (SmbAuthInfo *auth_info, GnomeVFSURI *uri, gboolean previous_failed)
+{
+ SmbAuthInfo *auth = NULL;
+ gchar *server;
+ gchar *share;
+ int res = 0;
+
+ DEBUG_SMB (("get_auth_by_uri\n"));
+
+ auth_info->user = NULL;
+ auth_info->password = NULL;
+
+ server = gnome_vfs_unescape_string (gnome_vfs_uri_get_host_name (uri), NULL);
+ share = gnome_vfs_unescape_string (gnome_vfs_uri_get_path (uri), NULL);
+
+ if (!previous_failed) {
+ auth = get_auth_from_uri (uri);
+ if (auth) {
+ put_auth_to_cache (auth, server, share);
+
+ auth_info->user = auth->user;
+ auth_info->password = auth->password;
+
+ return TRUE;
+ }
+ }
+
+ res = get_auth_by_server (auth_info, server, share, previous_failed);
+
+ g_free (server);
+ g_free (share);
+
+ return res;
+}
+
/* FIXME / TODO:
*
* Free unused virtual roots + connections after a while
@@ -874,6 +1054,7 @@
dir->u.directory.dir_contents =
g_list_prepend (dir->u.directory.dir_contents, file);
}
+
static GnomeVFSResult
build_server_tree (SmbVirtualFile **out, const char *name)
{
@@ -885,10 +1066,7 @@
struct in_addr ip;
SmbConnection *connection;
gboolean found_workgroup;
- SmbAuthInfo *auth_info;
- char *user, *password;
- GnomeVFSModuleCallbackAuthenticationIn in_args;
- GnomeVFSModuleCallbackAuthenticationOut out_args;
+ SmbAuthInfo auth_info;
gboolean got_shares;
DEBUG_SMB (("build_server_tree (%s)\n", name));
@@ -929,27 +1107,16 @@
DEBUG_SMB (("Enumerating shares in server %s\n", name));
- user = NULL;
- password = NULL;
-
- auth_info = g_hash_table_lookup (server_auth_infos, name);
-
- if (auth_info) {
- user = g_strdup (auth_info->user);
- password = g_strdup (auth_info->password);
- }
-
- memset (&in_args, 0, sizeof (in_args));
-
- in_args.uri = g_strdup_printf ("smb://%s", name);
got_shares = FALSE;
+
+ get_auth_by_server (&auth_info, (gchar *) name, NULL, FALSE);
while (TRUE) {
/* Look for shares in the server named name */
res = smb_server_connection_new (name,
"IPC$",
- user /* user */,
- password /* pwd */,
+ auth_info.user /* user */,
+ auth_info.password /* pwd */,
&connection);
if (!res) {
ret = cli_RNetShareEnum (connection->cli,
@@ -957,21 +1124,9 @@
if (ret == -1) {
error = cli_error(connection->cli, NULL, NULL, NULL);
if (error == EACCES) {
- memset (&out_args, 0, sizeof (out_args));
- UNLOCK_SAMBA();
- res = gnome_vfs_module_callback_invoke (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION,
- &in_args, sizeof (in_args),
- &out_args, sizeof (out_args));
- LOCK_SAMBA();
- if (!res || (out_args.username == NULL)) {
+ if (!get_auth_by_server (&auth_info, (gchar *) name, NULL, TRUE)) {
break;
} else {
- g_free (user);
- g_free (password);
-
- user = out_args.username;
- password = out_args.password;
-
smb_connection_unref (connection);
continue;
@@ -989,32 +1144,6 @@
}
DEBUG_SMB (("Done enumerating shares in server %s\n", name));
- g_free (in_args.uri);
-
- if (!got_shares) {
- if (auth_info == NULL || auth_info->user != user)
- g_free (user);
- if (auth_info == NULL || auth_info->password != password)
- g_free (password);
- } else if (user != NULL || password != NULL) {
- if (auth_info == NULL) {
- auth_info = g_new (SmbAuthInfo, 1);
- auth_info->user = user;
- auth_info->password = password;
- g_hash_table_insert (server_auth_infos, g_strdup (name), auth_info);
- }
-
- if (auth_info->user != user) {
- g_free (auth_info->user);
- auth_info->user = user;
- }
-
- if (auth_info->password != password) {
- g_free (auth_info->password);
- auth_info->password = password;
- }
- }
-
/* Add .directory file */
file = smb_virtual_file_new (SMB_VIRTUAL_TYPE_FILE);
file->name = g_strdup (".directory");
@@ -1076,8 +1205,7 @@
SmbVirtualRoot key;
time_t now;
GnomeVFSResult res;
- char *user;
- char *password;
+ SmbAuthInfo auth_info;
DEBUG_SMB (("lookup_uri (uri: %s)\n", gnome_vfs_uri_to_string (uri, 0)));
@@ -1150,58 +1278,21 @@
((path_remainder != NULL) ||
open_connection_for_share_file)) {
if ((*file)->u.share.connection == NULL) {
- GnomeVFSModuleCallbackAuthenticationIn in_args;
- GnomeVFSModuleCallbackAuthenticationOut out_args;
- gboolean previous_attempt_failed;
-
- memset (&in_args, 0, sizeof (in_args));
-
- in_args.uri = g_strdup_printf ("smb://%s/%s",
- (*file)->u.share.server,
- (*file)->u.share.share);
-
- user = gnome_vfs_unescape_string (gnome_vfs_uri_get_user_name (uri), NULL);
- password = gnome_vfs_unescape_string (gnome_vfs_uri_get_password (uri), NULL);
-
- /* Don't consider it failed if it was an anon try */
- previous_attempt_failed = (user == NULL) ? FALSE : TRUE;
-
+ get_auth_by_uri (&auth_info, uri, FALSE);
while (TRUE) {
res = smb_server_connection_new ((*file)->u.share.server,
(*file)->u.share.share,
- user,
- password,
+ auth_info.user,
+ auth_info.password,
&(*file)->u.share.connection);
if (res == GNOME_VFS_ERROR_LOGIN_FAILED) {
- memset (&out_args, 0, sizeof (out_args));
- UNLOCK_SAMBA();
- res = gnome_vfs_module_callback_invoke (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION,
- &in_args, sizeof (in_args),
- &out_args, sizeof (out_args));
- LOCK_SAMBA();
- if (res == FALSE) {
- res = GNOME_VFS_ERROR_ACCESS_DENIED;
- break;
- } else if (out_args.username == NULL) {
- res = GNOME_VFS_ERROR_ACCESS_DENIED;
+ if (!get_auth_by_uri (&auth_info, uri, TRUE))
break;
- } else {
- g_free (user);
- g_free (password);
-
- user = out_args.username;
- password = out_args.password;
- }
- previous_attempt_failed = TRUE;
} else {
/* Error, or logged in ok */
break;
}
}
-
- g_free (in_args.uri);
- g_free (user);
- g_free (password);
if (res != GNOME_VFS_OK) {
(*file)->u.share.connection = NULL;
@@ -2504,7 +2595,7 @@
DEBUG_SMB (("Couldn't load smb config file"));
}
- server_auth_infos = g_hash_table_new (g_str_hash, g_str_equal);
+ auth_info_cache = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) auth_info_cache_destroy_value);
codepage_initialise (lp_client_code_page());
@@ -2525,5 +2616,6 @@
vfs_module_shutdown (GnomeVFSMethod *method)
{
DEBUG_SMB (("<-- smb module shutdown called -->\n"));
+ g_hash_table_destroy (auth_info_cache);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]