svn commit: samba r14663 - in trunk: examples/libsmbclient source/include source/libsmb

derrell at samba.org derrell at samba.org
Wed Mar 22 22:03:53 GMT 2006


Author: derrell
Date: 2006-03-22 22:03:52 +0000 (Wed, 22 Mar 2006)
New Revision: 14663

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=14663

Log:
Implement enhancement request 3505.  Two additional features are added here.
There is now a method of saving an opaque user data handle in the smbc_
context, and there is now a way to request that the context be passed to the
authentication function.  See examples/libsmbclient/testbrowse.c for an example
of using these features.


Modified:
   trunk/examples/libsmbclient/get_auth_data_fn.h
   trunk/examples/libsmbclient/testbrowse.c
   trunk/source/include/libsmb_internal.h
   trunk/source/include/libsmbclient.h
   trunk/source/libsmb/libsmbclient.c


Changeset:
Modified: trunk/examples/libsmbclient/get_auth_data_fn.h
===================================================================
--- trunk/examples/libsmbclient/get_auth_data_fn.h	2006-03-22 21:49:38 UTC (rev 14662)
+++ trunk/examples/libsmbclient/get_auth_data_fn.h	2006-03-22 22:03:52 UTC (rev 14663)
@@ -7,7 +7,6 @@
                  int maxLenUsername,
                  char * pPassword,
                  int maxLenPassword)
-    
 {
     char temp[128];
     

Modified: trunk/examples/libsmbclient/testbrowse.c
===================================================================
--- trunk/examples/libsmbclient/testbrowse.c	2006-03-22 21:49:38 UTC (rev 14662)
+++ trunk/examples/libsmbclient/testbrowse.c	2006-03-22 22:03:52 UTC (rev 14663)
@@ -24,6 +24,16 @@
                    int indent);
 
 
+static void
+get_auth_data_with_context_fn(SMBCCTX * context,
+                              const char * pServer,
+                              const char * pShare,
+                              char * pWorkgroup,
+                              int maxLenWorkgroup,
+                              char * pUsername,
+                              int maxLenUsername,
+                              char * pPassword,
+                              int maxLenPassword);
 
 int
 main(int argc, char * argv[])
@@ -31,6 +41,7 @@
     int                         debug = 0;
     int                         debug_stderr = 0;
     int                         no_auth = 0;
+    int                         context_auth = 0;
     int                         scan = 0;
     int                         iterations = -1;
     int                         again;
@@ -64,6 +75,10 @@
                 0, "Do not request authentication data", "integer"
             },
             {
+                "contextauth", 'C', POPT_ARG_NONE, &context_auth,
+                0, "Use new authentication function with context", "integer"
+            },
+            {
                 NULL
             }
         };
@@ -94,12 +109,21 @@
 
     /* Set mandatory options (is that a contradiction in terms?) */
     context->debug = debug;
-    context->callbacks.auth_fn = (no_auth ? no_auth_data_fn : get_auth_data_fn);
+    if (context_auth) {
+        context->callbacks.auth_fn = NULL;
+        smbc_option_set(context,
+                        "auth_function",
+                        (void *) get_auth_data_with_context_fn);
+        smbc_option_set(context, "user_data", "hello world");
+    } else {
+        context->callbacks.auth_fn =
+            (no_auth ? no_auth_data_fn : get_auth_data_fn);
+    }
 
     /* If we've been asked to log to stderr instead of stdout... */
     if (debug_stderr) {
         /* ... then set the option to do so */
-        smbc_option_set(context, "debug_stderr");
+        smbc_option_set(context, "debug_stderr", (void *) 1);
     }
 	
     /* Initialize the context using the previously specified options */
@@ -161,6 +185,29 @@
     return;
 }
 
+
+static void
+get_auth_data_with_context_fn(SMBCCTX * context,
+                              const char * pServer,
+                              const char * pShare,
+                              char * pWorkgroup,
+                              int maxLenWorkgroup,
+                              char * pUsername,
+                              int maxLenUsername,
+                              char * pPassword,
+                              int maxLenPassword)
+{
+    printf("Authenticating with context 0x%lx", context);
+    if (context != NULL) {
+        char *user_data = smbc_option_get(context, "user_data");
+        printf(" with user data %s", user_data);
+    }
+    printf("\n");
+
+    get_auth_data_fn(pServer, pShare, pWorkgroup, maxLenWorkgroup,
+                     pUsername, maxLenUsername, pPassword, maxLenPassword);
+}
+
 static void browse(char * path, int scan, int indent)
 {
     char *                      p;

Modified: trunk/source/include/libsmb_internal.h
===================================================================
--- trunk/source/include/libsmb_internal.h	2006-03-22 21:49:38 UTC (rev 14662)
+++ trunk/source/include/libsmb_internal.h	2006-03-22 22:03:52 UTC (rev 14663)
@@ -79,6 +79,18 @@
          * Log to standard error instead of the more typical standard output
          */
         BOOL _debug_stderr;
+
+        /*
+         * Authentication function which includes the context.  This will be
+         * used if set; otherwise context->callbacks.auth_fn() will be used.
+         */
+        smbc_get_auth_data_with_context_fn _auth_fn_with_context;
+
+        /*
+         * An opaque (to this library) user data handle which can be set
+         * and retrieved with smbc_option_set() and smbc_option_get().
+         */
+        void * _user_data;
 };	
 
 

Modified: trunk/source/include/libsmbclient.h
===================================================================
--- trunk/source/include/libsmbclient.h	2006-03-22 21:49:38 UTC (rev 14662)
+++ trunk/source/include/libsmbclient.h	2006-03-22 22:03:52 UTC (rev 14663)
@@ -204,7 +204,7 @@
 
 
 /**@ingroup callback
- * Authentication callback function type.
+ * Authentication callback function type (traditional method)
  * 
  * Type for the the authentication function called by the library to
  * obtain authentication credentals
@@ -237,6 +237,43 @@
                                       char *wg, int wglen, 
                                       char *un, int unlen,
                                       char *pw, int pwlen);
+/**@ingroup callback
+ * Authentication callback function type (method that includes context)
+ * 
+ * Type for the the authentication function called by the library to
+ * obtain authentication credentals
+ *
+ * @param c         Pointer to the smb context
+ *
+ * @param srv       Server being authenticated to
+ *
+ * @param shr       Share being authenticated to
+ *
+ * @param wg        Pointer to buffer containing a "hint" for the
+ *                  workgroup to be authenticated.  Should be filled in
+ *                  with the correct workgroup if the hint is wrong.
+ * 
+ * @param wglen     The size of the workgroup buffer in bytes
+ *
+ * @param un        Pointer to buffer containing a "hint" for the
+ *                  user name to be use for authentication. Should be
+ *                  filled in with the correct workgroup if the hint is
+ *                  wrong.
+ * 
+ * @param unlen     The size of the username buffer in bytes
+ *
+ * @param pw        Pointer to buffer containing to which password 
+ *                  copied
+ * 
+ * @param pwlen     The size of the password buffer in bytes
+ *           
+ */
+typedef void (*smbc_get_auth_data_with_context_fn)(SMBCCTX *c,
+                                                   const char *srv, 
+                                                   const char *shr,
+                                                   char *wg, int wglen, 
+                                                   char *un, int unlen,
+                                                   char *pw, int pwlen);
 
 
 /**@ingroup callback
@@ -422,14 +459,15 @@
 	int        (*unlink_print_job)(SMBCCTX *c, const char *fname, int id);
 
 
-	/** Callbacks
-	 * These callbacks _always_ have to be initialized because they will not be checked
-	 * at dereference for increased speed.
-	 */
+        /*
+        ** Callbacks
+        * These callbacks _always_ have to be initialized because they will
+        * not be checked at dereference for increased speed.
+        */
 	struct _smbc_callbacks {
 		/** authentication function callback: called upon auth requests
 		 */
-		smbc_get_auth_data_fn auth_fn;
+                smbc_get_auth_data_fn auth_fn;
 		
 		/** check if a server is still good
 		 */
@@ -579,22 +617,60 @@
 
 
 /**@ingroup misc
+ * Each time the context structure is changed, we have binary backward
+ * compatibility issues.  Instead of modifying the public portions of the
+ * context structure to add new options, instead, we put them in the internal
+ * portion of the context structure and provide a set function for these new
+ * options.
+ *
+ * @param context   A pointer to a SMBCCTX obtained from smbc_new_context()
+ *
+ * @param option_name
+ *                  The name of the option for which the value is to be set
+ *
+ * @param option_value
+ *                  The new value of the option being set
+ *
+ */
+void
+smbc_option_set(SMBCCTX *context,
+                char *option_name,
+                void *option_value);
+/*
+ * Retrieve the current value of an option
+ *
+ * @param context   A pointer to a SMBCCTX obtained from smbc_new_context()
+ *
+ * @param option_name
+ *                  The name of the option for which the value is to be
+ *                  retrieved
+ *
+ * @return          The value of the specified option.
+ */
+void *
+smbc_option_get(SMBCCTX *context,
+                char *option_name);
+
+/**@ingroup misc
  * Initialize a SBMCCTX (a context).
  *
  * Must be called before using any SMBCCTX API function
  *
  * @param context   A pointer to a SMBCCTX obtained from smbc_new_context()
  *
- * @return          A pointer to the given SMBCCTX on success, NULL on error with errno set:
+ * @return          A pointer to the given SMBCCTX on success,
+ *                  NULL on error with errno set:
  *                  - EBADF  NULL context given
  *                  - ENOMEM Out of memory
  *                  - ENOENT The smb.conf file would not load
  *
  * @see             smbc_new_context()
  *
- * @note            my_context = smbc_init_context(smbc_new_context()) is perfectly safe, 
- *                  but it might leak memory on smbc_context_init() failure. Avoid this.
- *                  You'll have to call smbc_free_context() yourself on failure.  
+ * @note            my_context = smbc_init_context(smbc_new_context())
+ *                  is perfectly safe, but it might leak memory on
+ *                  smbc_context_init() failure. Avoid this.
+ *                  You'll have to call smbc_free_context() yourself
+ *                  on failure.  
  */
 
 SMBCCTX * smbc_init_context(SMBCCTX * context);

Modified: trunk/source/libsmb/libsmbclient.c
===================================================================
--- trunk/source/libsmb/libsmbclient.c	2006-03-22 21:49:38 UTC (rev 14662)
+++ trunk/source/libsmb/libsmbclient.c	2006-03-22 22:03:52 UTC (rev 14663)
@@ -552,10 +552,21 @@
 						   workgroup, username);
 
 	if (!auth_called && !srv && (!username[0] || !password[0])) {
-		context->callbacks.auth_fn(server, share,
-                                           workgroup, sizeof(fstring),
-                                           username, sizeof(fstring),
-                                           password, sizeof(fstring));
+                if (context->internal->_auth_fn_with_context != NULL) {
+                         context->internal->_auth_fn_with_context(
+                                context,
+                                server, share,
+                                workgroup, sizeof(fstring),
+                                username, sizeof(fstring),
+                                password, sizeof(fstring));
+                } else {
+                        context->callbacks.auth_fn(
+                                server, share,
+                                workgroup, sizeof(fstring),
+                                username, sizeof(fstring),
+                                password, sizeof(fstring));
+                }
+
 		/*
                  * However, smbc_auth_fn may have picked up info relating to
                  * an existing connection, so try for an existing connection
@@ -657,10 +668,20 @@
                  */
                 if (srv->cli.cnum == (uint16) -1) {
                         /* Ensure we have accurate auth info */
-                        context->callbacks.auth_fn(server, share,
-                                                   workgroup, sizeof(fstring),
-                                                   username, sizeof(fstring),
-                                                   password, sizeof(fstring));
+                        if (context->internal->_auth_fn_with_context != NULL) {
+                                context->internal->_auth_fn_with_context(
+                                        context,
+                                        server, share,
+                                        workgroup, sizeof(fstring),
+                                        username, sizeof(fstring),
+                                        password, sizeof(fstring));
+                        } else {
+                                context->callbacks.auth_fn(
+                                        server, share,
+                                        workgroup, sizeof(fstring),
+                                        username, sizeof(fstring),
+                                        password, sizeof(fstring));
+                        }
 
                         if (! cli_send_tconX(&srv->cli, share, "?????",
                                              password, strlen(password)+1)) {
@@ -901,10 +922,20 @@
                 /* We didn't find a cached connection.  Get the password */
                 if (*password == '\0') {
                         /* ... then retrieve it now. */
-                        context->callbacks.auth_fn(server, share,
-                                                   workgroup, sizeof(fstring),
-                                                   username, sizeof(fstring),
-                                                   password, sizeof(fstring));
+                        if (context->internal->_auth_fn_with_context != NULL) {
+                                context->internal->_auth_fn_with_context(
+                                        context,
+                                        server, share,
+                                        workgroup, sizeof(fstring),
+                                        username, sizeof(fstring),
+                                        password, sizeof(fstring));
+                        } else {
+                                context->callbacks.auth_fn(
+                                        server, share,
+                                        workgroup, sizeof(fstring),
+                                        username, sizeof(fstring),
+                                        password, sizeof(fstring));
+                        }
                 }
         
                 zero_ip(&ip);
@@ -5976,12 +6007,55 @@
                 /*
                  * Log to standard error instead of standard output.
                  */
-                context->internal->_debug_stderr = True;
+                context->internal->_debug_stderr =
+                        (option_value == NULL ? False : True);
+        } else if (strcmp(option_name, "auth_function") == 0) {
+                /*
+                 * Use the new-style authentication function which includes
+                 * the context.
+                 */
+                context->internal->_auth_fn_with_context = option_value;
+        } else if (strcmp(option_name, "user_data") == 0) {
+                /*
+                 * Save a user data handle which may be retrieved by the user
+                 * with smbc_option_get()
+                 */
+                context->internal->_user_data = option_value;
         }
 }
 
 
 /*
+ * Retrieve the current value of an option
+ */
+void *
+smbc_option_get(SMBCCTX *context,
+                char *option_name)
+{
+        if (strcmp(option_name, "debug_stderr") == 0) {
+                /*
+                 * Log to standard error instead of standard output.
+                 */
+                return (void *) context->internal->_debug_stderr;
+        } else if (strcmp(option_name, "auth_function") == 0) {
+                /*
+                 * Use the new-style authentication function which includes
+                 * the context.
+                 */
+                return (void *) context->internal->_auth_fn_with_context;
+        } else if (strcmp(option_name, "user_data") == 0) {
+                /*
+                 * Save a user data handle which may be retrieved by the user
+                 * with smbc_option_get()
+                 */
+                return context->internal->_user_data;
+        }
+
+        return NULL;
+}
+
+
+/*
  * Initialise the library etc 
  *
  * We accept a struct containing handle information.
@@ -6006,7 +6080,8 @@
                 return 0;
         }
 
-        if (!context->callbacks.auth_fn ||
+        if ((!context->callbacks.auth_fn &&
+             !context->internal->_auth_fn_with_context) ||
             context->debug < 0 ||
             context->debug > 100) {
 



More information about the samba-cvs mailing list