1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-05 12:22:11 +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 used to be commit 203b4911c1)
This commit is contained in:
Derrell Lipman
2006-03-22 22:05:19 +00:00
committed by Gerald (Jerry) Carter
parent 853ad11aaf
commit e836508704
5 changed files with 236 additions and 27 deletions

View File

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

View File

@ -24,6 +24,16 @@ static void browse(char * path,
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 @@ main(int argc, char * argv[])
int debug = 0;
int debug_stderr = 0;
int no_auth = 0;
int context_auth = 0;
int scan = 0;
int iterations = -1;
int again;
@ -63,6 +74,10 @@ main(int argc, char * argv[])
"noauth", 'A', POPT_ARG_NONE, &no_auth,
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 @@ main(int argc, char * argv[])
/* 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 @@ no_auth_data_fn(const char * pServer,
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;

View File

@ -79,6 +79,18 @@ struct smbc_internal_data {
* 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;
};

View File

@ -204,7 +204,7 @@ typedef struct _SMBCCTX SMBCCTX;
/**@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 @@ typedef void (*smbc_get_auth_data_fn)(const char *srv,
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 @@ struct _SMBCCTX {
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
*/
@ -578,6 +616,41 @@ SMBCCTX * smbc_new_context(void);
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
* 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()
*
* @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);

View File

@ -552,10 +552,21 @@ find_server(SMBCCTX *context,
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 @@ smbc_server(SMBCCTX *context,
*/
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 @@ smbc_attr_server(SMBCCTX *context,
/* 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,11 +6007,54 @@ smbc_option_set(SMBCCTX *context,
/*
* 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
*
@ -6006,7 +6080,8 @@ smbc_init_context(SMBCCTX *context)
return 0;
}
if (!context->callbacks.auth_fn ||
if ((!context->callbacks.auth_fn &&
!context->internal->_auth_fn_with_context) ||
context->debug < 0 ||
context->debug > 100) {