1
0
mirror of https://github.com/samba-team/samba.git synced 2025-11-25 00:23:52 +03:00

r14664: r13868@cabra: derrell | 2006-03-22 17:04:30 -0500

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.
This commit is contained in:
Derrell Lipman
2006-03-22 22:05:19 +00:00
committed by Gerald (Jerry) Carter
parent 07a70f8f86
commit 203b4911c1
5 changed files with 236 additions and 27 deletions

View File

@@ -7,7 +7,6 @@ get_auth_data_fn(const char * pServer,
int maxLenUsername, int maxLenUsername,
char * pPassword, char * pPassword,
int maxLenPassword) int maxLenPassword)
{ {
char temp[128]; char temp[128];

View File

@@ -24,6 +24,16 @@ static void browse(char * path,
int indent); 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 int
main(int argc, char * argv[]) main(int argc, char * argv[])
@@ -31,6 +41,7 @@ main(int argc, char * argv[])
int debug = 0; int debug = 0;
int debug_stderr = 0; int debug_stderr = 0;
int no_auth = 0; int no_auth = 0;
int context_auth = 0;
int scan = 0; int scan = 0;
int iterations = -1; int iterations = -1;
int again; int again;
@@ -63,6 +74,10 @@ main(int argc, char * argv[])
"noauth", 'A', POPT_ARG_NONE, &no_auth, "noauth", 'A', POPT_ARG_NONE, &no_auth,
0, "Do not request authentication data", "integer" 0, "Do not request authentication data", "integer"
}, },
{
"contextauth", 'C', POPT_ARG_NONE, &context_auth,
0, "Use new authentication function with context", "integer"
},
{ {
NULL NULL
} }
@@ -94,12 +109,21 @@ main(int argc, char * argv[])
/* Set mandatory options (is that a contradiction in terms?) */ /* Set mandatory options (is that a contradiction in terms?) */
context->debug = debug; 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 we've been asked to log to stderr instead of stdout... */
if (debug_stderr) { if (debug_stderr) {
/* ... then set the option to do so */ /* ... 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 */ /* Initialize the context using the previously specified options */
@@ -161,6 +185,29 @@ no_auth_data_fn(const char * pServer,
return; 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) static void browse(char * path, int scan, int indent)
{ {
char * p; char * p;

View File

@@ -79,6 +79,18 @@ struct smbc_internal_data {
* Log to standard error instead of the more typical standard output * Log to standard error instead of the more typical standard output
*/ */
BOOL _debug_stderr; 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;
}; };

View File

@@ -204,7 +204,7 @@ typedef struct _SMBCCTX SMBCCTX;
/**@ingroup callback /**@ingroup callback
* Authentication callback function type. * Authentication callback function type (traditional method)
* *
* Type for the the authentication function called by the library to * Type for the the authentication function called by the library to
* obtain authentication credentals * obtain authentication credentals
@@ -237,6 +237,43 @@ typedef void (*smbc_get_auth_data_fn)(const char *srv,
char *wg, int wglen, char *wg, int wglen,
char *un, int unlen, char *un, int unlen,
char *pw, int pwlen); 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 /**@ingroup callback
@@ -422,9 +459,10 @@ struct _SMBCCTX {
int (*unlink_print_job)(SMBCCTX *c, const char *fname, int id); 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 ** Callbacks
* at dereference for increased speed. * These callbacks _always_ have to be initialized because they will
* not be checked at dereference for increased speed.
*/ */
struct _smbc_callbacks { struct _smbc_callbacks {
/** authentication function callback: called upon auth requests /** authentication function callback: called upon auth requests
@@ -578,6 +616,41 @@ SMBCCTX * smbc_new_context(void);
int smbc_free_context(SMBCCTX * context, int shutdown_ctx); int smbc_free_context(SMBCCTX * context, int shutdown_ctx);
/**@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 /**@ingroup misc
* Initialize a SBMCCTX (a context). * Initialize a SBMCCTX (a context).
* *
@@ -585,16 +658,19 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx);
* *
* @param context A pointer to a SMBCCTX obtained from smbc_new_context() * @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 * - EBADF NULL context given
* - ENOMEM Out of memory * - ENOMEM Out of memory
* - ENOENT The smb.conf file would not load * - ENOENT The smb.conf file would not load
* *
* @see smbc_new_context() * @see smbc_new_context()
* *
* @note my_context = smbc_init_context(smbc_new_context()) is perfectly safe, * @note my_context = smbc_init_context(smbc_new_context())
* but it might leak memory on smbc_context_init() failure. Avoid this. * is perfectly safe, but it might leak memory on
* You'll have to call smbc_free_context() yourself on failure. * smbc_context_init() failure. Avoid this.
* You'll have to call smbc_free_context() yourself
* on failure.
*/ */
SMBCCTX * smbc_init_context(SMBCCTX * context); SMBCCTX * smbc_init_context(SMBCCTX * context);

View File

@@ -552,10 +552,21 @@ find_server(SMBCCTX *context,
workgroup, username); workgroup, username);
if (!auth_called && !srv && (!username[0] || !password[0])) { if (!auth_called && !srv && (!username[0] || !password[0])) {
context->callbacks.auth_fn(server, share, if (context->internal->_auth_fn_with_context != NULL) {
context->internal->_auth_fn_with_context(
context,
server, share,
workgroup, sizeof(fstring), workgroup, sizeof(fstring),
username, sizeof(fstring), username, sizeof(fstring),
password, 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 * However, smbc_auth_fn may have picked up info relating to
* an existing connection, so try for an existing connection * an existing connection, so try for an existing connection
@@ -657,10 +668,20 @@ smbc_server(SMBCCTX *context,
*/ */
if (srv->cli.cnum == (uint16) -1) { if (srv->cli.cnum == (uint16) -1) {
/* Ensure we have accurate auth info */ /* Ensure we have accurate auth info */
context->callbacks.auth_fn(server, share, if (context->internal->_auth_fn_with_context != NULL) {
context->internal->_auth_fn_with_context(
context,
server, share,
workgroup, sizeof(fstring), workgroup, sizeof(fstring),
username, sizeof(fstring), username, sizeof(fstring),
password, 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, "?????", if (! cli_send_tconX(&srv->cli, share, "?????",
password, strlen(password)+1)) { password, strlen(password)+1)) {
@@ -901,10 +922,20 @@ smbc_attr_server(SMBCCTX *context,
/* We didn't find a cached connection. Get the password */ /* We didn't find a cached connection. Get the password */
if (*password == '\0') { if (*password == '\0') {
/* ... then retrieve it now. */ /* ... then retrieve it now. */
context->callbacks.auth_fn(server, share, if (context->internal->_auth_fn_with_context != NULL) {
context->internal->_auth_fn_with_context(
context,
server, share,
workgroup, sizeof(fstring), workgroup, sizeof(fstring),
username, sizeof(fstring), username, sizeof(fstring),
password, sizeof(fstring)); password, sizeof(fstring));
} else {
context->callbacks.auth_fn(
server, share,
workgroup, sizeof(fstring),
username, sizeof(fstring),
password, sizeof(fstring));
}
} }
zero_ip(&ip); zero_ip(&ip);
@@ -5976,11 +6007,54 @@ smbc_option_set(SMBCCTX *context,
/* /*
* Log to standard error instead of standard output. * 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 * Initialise the library etc
* *
@@ -6006,7 +6080,8 @@ smbc_init_context(SMBCCTX *context)
return 0; return 0;
} }
if (!context->callbacks.auth_fn || if ((!context->callbacks.auth_fn &&
!context->internal->_auth_fn_with_context) ||
context->debug < 0 || context->debug < 0 ||
context->debug > 100) { context->debug > 100) {