summaryrefslogtreecommitdiff
path: root/source3/libsmb/libsmb_context.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb/libsmb_context.c')
-rw-r--r--source3/libsmb/libsmb_context.c1508
1 files changed, 826 insertions, 682 deletions
diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c
index 6b7a19e1e4..8af49d12be 100644
--- a/source3/libsmb/libsmb_context.c
+++ b/source3/libsmb/libsmb_context.c
@@ -40,88 +40,88 @@ static int SMBC_initialized = 0;
SMBCCTX *
smbc_new_context(void)
{
- SMBCCTX *context;
-
- /*
- * All newly added context fields should be placed in SMBC_internal_data,
- * not directly in SMBCCTX.
- */
-# undef OLD
-# define OLD(field) context->field
-# undef NEW
-# define NEW(field) context->internal->field
-
- context = SMB_MALLOC_P(SMBCCTX);
- if (!context) {
- errno = ENOMEM;
- return NULL;
- }
-
- ZERO_STRUCTP(context);
-
- context->internal = SMB_MALLOC_P(struct SMBC_internal_data);
- if (!context->internal) {
- SAFE_FREE(context);
- errno = ENOMEM;
- return NULL;
- }
-
- /* Initialize the context and establish reasonable defaults */
- ZERO_STRUCTP(context->internal);
-
- OLD(config.debug) = 0;
- OLD(config.timeout) = 20000; /* 20 seconds */
-
- NEW(full_time_names) = False;
- NEW(share_mode) = SMBC_SHAREMODE_DENY_NONE;
- NEW(smb_encryption_level) = 0;
- NEW(browse_max_lmb_count) = 3; /* # LMBs to query */
- NEW(urlencode_readdir_entries) = False;
- NEW(one_share_per_server) = False;
-
- OLD(server.get_auth_data_fn) = SMBC_get_auth_data;
- OLD(server.check_server_fn) = SMBC_check_server;
- OLD(server.remove_unused_server_fn) = SMBC_remove_unused_server;
-
- OLD(cache.server_cache_data) = NULL;
- OLD(cache.add_cached_server_fn) = SMBC_add_cached_server;
- OLD(cache.get_cached_server_fn) = SMBC_get_cached_server;
- OLD(cache.remove_cached_server_fn) = SMBC_remove_cached_server;
- OLD(cache.purge_cached_servers_fn) = SMBC_purge_cached_servers;
-
- OLD(posix_emu.open_fn) = SMBC_open_ctx;
- OLD(posix_emu.creat_fn) = SMBC_creat_ctx;
- OLD(posix_emu.read_fn) = SMBC_read_ctx;
- OLD(posix_emu.write_fn) = SMBC_write_ctx;
- OLD(posix_emu.close_fn) = SMBC_close_ctx;
- OLD(posix_emu.unlink_fn) = SMBC_unlink_ctx;
- OLD(posix_emu.rename_fn) = SMBC_rename_ctx;
- OLD(posix_emu.lseek_fn) = SMBC_lseek_ctx;
- NEW(posix_emu.ftruncate_fn) = SMBC_ftruncate_ctx;
- OLD(posix_emu.stat_fn) = SMBC_stat_ctx;
- OLD(posix_emu.fstat_fn) = SMBC_fstat_ctx;
- OLD(posix_emu.opendir_fn) = SMBC_opendir_ctx;
- OLD(posix_emu.closedir_fn) = SMBC_closedir_ctx;
- OLD(posix_emu.readdir_fn) = SMBC_readdir_ctx;
- OLD(posix_emu.getdents_fn) = SMBC_getdents_ctx;
- OLD(posix_emu.mkdir_fn) = SMBC_mkdir_ctx;
- OLD(posix_emu.rmdir_fn) = SMBC_rmdir_ctx;
- OLD(posix_emu.telldir_fn) = SMBC_telldir_ctx;
- OLD(posix_emu.lseekdir_fn) = SMBC_lseekdir_ctx;
- OLD(posix_emu.fstatdir_fn) = SMBC_fstatdir_ctx;
- OLD(posix_emu.chmod_fn) = SMBC_chmod_ctx;
- OLD(posix_emu.utimes_fn) = SMBC_utimes_ctx;
- OLD(posix_emu.setxattr_fn) = SMBC_setxattr_ctx;
- OLD(posix_emu.getxattr_fn) = SMBC_getxattr_ctx;
- OLD(posix_emu.removexattr_fn) = SMBC_removexattr_ctx;
- OLD(posix_emu.listxattr_fn) = SMBC_listxattr_ctx;
-
- OLD(printing.open_print_job_fn) = SMBC_open_print_job_ctx;
- OLD(printing.print_file_fn) = SMBC_print_file_ctx;
- OLD(printing.list_print_jobs_fn) = SMBC_list_print_jobs_ctx;
- OLD(printing.unlink_print_job_fn) = SMBC_unlink_print_job_ctx;
-
- return context;
+ SMBCCTX *context;
+
+ /*
+ * All newly added context fields should be placed in
+ * SMBC_internal_data, not directly in SMBCCTX.
+ */
+#undef OLD
+#define OLD(field) context->field
+#undef NEW
+#define NEW(field) context->internal->field
+
+ context = SMB_MALLOC_P(SMBCCTX);
+ if (!context) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ ZERO_STRUCTP(context);
+
+ context->internal = SMB_MALLOC_P(struct SMBC_internal_data);
+ if (!context->internal) {
+ SAFE_FREE(context);
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ /* Initialize the context and establish reasonable defaults */
+ ZERO_STRUCTP(context->internal);
+
+ OLD(config.debug) = 0;
+ OLD(config.timeout) = 20000; /* 20 seconds */
+
+ NEW(full_time_names) = False;
+ NEW(share_mode) = SMBC_SHAREMODE_DENY_NONE;
+ NEW(smb_encryption_level) = 0;
+ OLD(options.browse_max_lmb_count) = 3; /* # LMBs to query */
+ OLD(options.urlencode_readdir_entries) = False;
+ OLD(options.one_share_per_server) = False;
+
+ OLD(server.get_auth_data_fn) = SMBC_get_auth_data;
+ OLD(server.check_server_fn) = SMBC_check_server;
+ OLD(server.remove_unused_server_fn) = SMBC_remove_unused_server;
+
+ OLD(cache.server_cache_data) = NULL;
+ OLD(cache.add_cached_server_fn) = SMBC_add_cached_server;
+ OLD(cache.get_cached_server_fn) = SMBC_get_cached_server;
+ OLD(cache.remove_cached_server_fn) = SMBC_remove_cached_server;
+ OLD(cache.purge_cached_servers_fn) = SMBC_purge_cached_servers;
+
+ OLD(posix_emu.open_fn) = SMBC_open_ctx;
+ OLD(posix_emu.creat_fn) = SMBC_creat_ctx;
+ OLD(posix_emu.read_fn) = SMBC_read_ctx;
+ OLD(posix_emu.write_fn) = SMBC_write_ctx;
+ OLD(posix_emu.close_fn) = SMBC_close_ctx;
+ OLD(posix_emu.unlink_fn) = SMBC_unlink_ctx;
+ OLD(posix_emu.rename_fn) = SMBC_rename_ctx;
+ OLD(posix_emu.lseek_fn) = SMBC_lseek_ctx;
+ NEW(posix_emu.ftruncate_fn) = SMBC_ftruncate_ctx;
+ OLD(posix_emu.stat_fn) = SMBC_stat_ctx;
+ OLD(posix_emu.fstat_fn) = SMBC_fstat_ctx;
+ OLD(posix_emu.opendir_fn) = SMBC_opendir_ctx;
+ OLD(posix_emu.closedir_fn) = SMBC_closedir_ctx;
+ OLD(posix_emu.readdir_fn) = SMBC_readdir_ctx;
+ OLD(posix_emu.getdents_fn) = SMBC_getdents_ctx;
+ OLD(posix_emu.mkdir_fn) = SMBC_mkdir_ctx;
+ OLD(posix_emu.rmdir_fn) = SMBC_rmdir_ctx;
+ OLD(posix_emu.telldir_fn) = SMBC_telldir_ctx;
+ OLD(posix_emu.lseekdir_fn) = SMBC_lseekdir_ctx;
+ OLD(posix_emu.fstatdir_fn) = SMBC_fstatdir_ctx;
+ OLD(posix_emu.chmod_fn) = SMBC_chmod_ctx;
+ OLD(posix_emu.utimes_fn) = SMBC_utimes_ctx;
+ OLD(posix_emu.setxattr_fn) = SMBC_setxattr_ctx;
+ OLD(posix_emu.getxattr_fn) = SMBC_getxattr_ctx;
+ OLD(posix_emu.removexattr_fn) = SMBC_removexattr_ctx;
+ OLD(posix_emu.listxattr_fn) = SMBC_listxattr_ctx;
+
+ OLD(printing.open_print_job_fn) = SMBC_open_print_job_ctx;
+ OLD(printing.print_file_fn) = SMBC_print_file_ctx;
+ OLD(printing.list_print_jobs_fn) = SMBC_list_print_jobs_ctx;
+ OLD(printing.unlink_print_job_fn) = SMBC_unlink_print_job_ctx;
+
+ return context;
#undef OLD
#undef NEW
}
@@ -137,420 +137,268 @@ int
smbc_free_context(SMBCCTX *context,
int shutdown_ctx)
{
- if (!context) {
- errno = EBADF;
- return 1;
- }
-
- if (shutdown_ctx) {
- SMBCFILE * f;
- DEBUG(1,("Performing aggressive shutdown.\n"));
-
- f = context->internal->files;
- while (f) {
- (context->posix_emu.close_fn)(context, f);
- f = f->next;
+ if (!context) {
+ errno = EBADF;
+ return 1;
}
- context->internal->files = NULL;
- /* First try to remove the servers the nice way. */
- if (context->cache.purge_cached_servers_fn(context)) {
- SMBCSRV * s;
- SMBCSRV * next;
- DEBUG(1, ("Could not purge all servers, "
- "Nice way shutdown failed.\n"));
- s = context->internal->servers;
- while (s) {
- DEBUG(1, ("Forced shutdown: %p (fd=%d)\n",
- s, s->cli->fd));
- cli_shutdown(s->cli);
- (context->cache.remove_cached_server_fn)(context,
- s);
- next = s->next;
- DLIST_REMOVE(context->internal->servers, s);
- SAFE_FREE(s);
- s = next;
- }
- context->internal->servers = NULL;
- }
- }
- else {
- /* This is the polite way */
- if ((context->cache.purge_cached_servers_fn)(context)) {
- DEBUG(1, ("Could not purge all servers, "
- "free_context failed.\n"));
- errno = EBUSY;
- return 1;
- }
- if (context->internal->servers) {
- DEBUG(1, ("Active servers in context, "
- "free_context failed.\n"));
- errno = EBUSY;
- return 1;
+ if (shutdown_ctx) {
+ SMBCFILE * f;
+ DEBUG(1,("Performing aggressive shutdown.\n"));
+
+ f = context->internal->files;
+ while (f) {
+ (context->posix_emu.close_fn)(context, f);
+ f = f->next;
+ }
+ context->internal->files = NULL;
+
+ /* First try to remove the servers the nice way. */
+ if (context->cache.purge_cached_servers_fn(context)) {
+ SMBCSRV * s;
+ SMBCSRV * next;
+ DEBUG(1, ("Could not purge all servers, "
+ "Nice way shutdown failed.\n"));
+ s = context->internal->servers;
+ while (s) {
+ DEBUG(1, ("Forced shutdown: %p (fd=%d)\n",
+ s, s->cli->fd));
+ cli_shutdown(s->cli);
+ (context->cache.remove_cached_server_fn)(context,
+ s);
+ next = s->next;
+ DLIST_REMOVE(context->internal->servers, s);
+ SAFE_FREE(s);
+ s = next;
+ }
+ context->internal->servers = NULL;
+ }
}
- if (context->internal->files) {
- DEBUG(1, ("Active files in context, "
- "free_context failed.\n"));
- errno = EBUSY;
- return 1;
+ else {
+ /* This is the polite way */
+ if ((context->cache.purge_cached_servers_fn)(context)) {
+ DEBUG(1, ("Could not purge all servers, "
+ "free_context failed.\n"));
+ errno = EBUSY;
+ return 1;
+ }
+ if (context->internal->servers) {
+ DEBUG(1, ("Active servers in context, "
+ "free_context failed.\n"));
+ errno = EBUSY;
+ return 1;
+ }
+ if (context->internal->files) {
+ DEBUG(1, ("Active files in context, "
+ "free_context failed.\n"));
+ errno = EBUSY;
+ return 1;
+ }
}
- }
-
- /* Things we have to clean up */
- SAFE_FREE(context->config.workgroup);
- SAFE_FREE(context->config.netbios_name);
- SAFE_FREE(context->config.user);
-
- DEBUG(3, ("Context %p successfully freed\n", context));
- SAFE_FREE(context);
- return 0;
+
+ /* Things we have to clean up */
+ SAFE_FREE(context->config.workgroup);
+ SAFE_FREE(context->config.netbios_name);
+ SAFE_FREE(context->config.user);
+
+ DEBUG(3, ("Context %p successfully freed\n", context));
+ SAFE_FREE(context);
+ return 0;
}
-/*
- * 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.
+/**
+ * Deprecated interface. Do not use. Instead, use the various
+ * smbc_setOption*() functions or smbc_setFunctionAuthDataWithContext().
*/
void
smbc_option_set(SMBCCTX *context,
char *option_name,
... /* option_value */)
{
- va_list ap;
- union {
- int i;
- bool b;
- smbc_get_auth_data_with_context_fn auth_fn;
- void *v;
- const char *s;
- } option_value;
-
- va_start(ap, option_name);
-
- if (strcmp(option_name, "debug_to_stderr") == 0) {
- /*
- * Log to standard error instead of standard output.
- */
- option_value.b = (bool) va_arg(ap, int);
- context->internal->debug_stderr = option_value.b;
-
- } else if (strcmp(option_name, "full_time_names") == 0) {
- /*
- * Use new-style time attribute names, e.g. WRITE_TIME rather
- * than the old-style names such as M_TIME. This allows also
- * setting/getting CREATE_TIME which was previously
- * unimplemented. (Note that the old C_TIME was supposed to
- * be CHANGE_TIME but was confused and sometimes referred to
- * CREATE_TIME.)
- */
- option_value.b = (bool) va_arg(ap, int);
- context->internal->full_time_names = option_value.b;
-
- } else if (strcmp(option_name, "open_share_mode") == 0) {
- /*
- * The share mode to use for files opened with
- * SMBC_open_ctx(). The default is SMBC_SHAREMODE_DENY_NONE.
- */
- option_value.i = va_arg(ap, int);
- context->internal->share_mode = (smbc_share_mode) option_value.i;
-
- } else if (strcmp(option_name, "user_data") == 0) {
- /*
- * Save a user data handle which may be retrieved by the user
- * with smbc_option_get()
- */
- option_value.v = va_arg(ap, void *);
- context->internal->user_data = option_value.v;
- } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
- /*
- * Save an encoded value for encryption level.
- * 0 = off, 1 = attempt, 2 = required.
- */
- option_value.s = va_arg(ap, const char *);
- if (strcmp(option_value.s, "none") == 0) {
- context->internal->smb_encryption_level = 0;
- } else if (strcmp(option_value.s, "request") == 0) {
- context->internal->smb_encryption_level = 1;
- } else if (strcmp(option_value.s, "require") == 0) {
- context->internal->smb_encryption_level = 2;
- }
- } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
- /*
- * From how many local master browsers should the list of
- * workgroups be retrieved? It can take up to 12 minutes or
- * longer after a server becomes a local master browser, for
- * it to have the entire browse list (the list of
- * workgroups/domains) from an entire network. Since a client
- * never knows which local master browser will be found first,
- * the one which is found first and used to retrieve a browse
- * list may have an incomplete or empty browse list. By
- * requesting the browse list from multiple local master
- * browsers, a more complete list can be generated. For small
- * networks (few workgroups), it is recommended that this
- * value be set to 0, causing the browse lists from all found
- * local master browsers to be retrieved and merged. For
- * networks with many workgroups, a suitable value for this
- * variable is probably somewhere around 3. (Default: 3).
- */
- option_value.i = va_arg(ap, int);
- context->internal->browse_max_lmb_count = option_value.i;
+ va_list ap;
+ union {
+ int i;
+ bool b;
+ smbc_get_auth_data_with_context_fn auth_fn;
+ void *v;
+ const char *s;
+ } option_value;
- } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
- /*
- * There is a difference in the desired return strings from
- * smbc_readdir() depending upon whether the filenames are to
- * be displayed to the user, or whether they are to be
- * appended to the path name passed to smbc_opendir() to call
- * a further smbc_ function (e.g. open the file with
- * smbc_open()). In the former case, the filename should be
- * in "human readable" form. In the latter case, the smbc_
- * functions expect a URL which must be url-encoded. Those
- * functions decode the URL. If, for example, smbc_readdir()
- * returned a file name of "abc%20def.txt", passing a path
- * with this file name attached to smbc_open() would cause
- * smbc_open to attempt to open the file "abc def.txt" since
- * the %20 is decoded into a space.
- *
- * Set this option to True if the names returned by
- * smbc_readdir() should be url-encoded such that they can be
- * passed back to another smbc_ call. Set it to False if the
- * names returned by smbc_readdir() are to be presented to the
- * user.
- *
- * For backwards compatibility, this option defaults to False.
- */
- option_value.b = (bool) va_arg(ap, int);
- context->internal->urlencode_readdir_entries = option_value.b;
+ va_start(ap, option_name);
- } else if (strcmp(option_name, "one_share_per_server") == 0) {
- /*
- * Some Windows versions appear to have a limit to the number
- * of concurrent SESSIONs and/or TREE CONNECTions. In
- * one-shot programs (i.e. the program runs and then quickly
- * ends, thereby shutting down all connections), it is
- * probably reasonable to establish a new connection for each
- * share. In long-running applications, the limitation can be
- * avoided by using only a single connection to each server,
- * and issuing a new TREE CONNECT when the share is accessed.
- */
- option_value.b = (bool) va_arg(ap, int);
- context->options.one_share_per_server = option_value.b;
-
- } else if (strcmp(option_name, "use_kerberos") == 0) {
- option_value.b = (bool) va_arg(ap, int);
- if (option_value.b) {
- context->flags.bits |= SMB_CTX_FLAG_USE_KERBEROS;
- } else {
- context->flags.bits &= ~SMB_CTX_FLAG_USE_KERBEROS;
- }
-
- } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
- option_value.b = (bool) va_arg(ap, int);
- if (option_value.b) {
- context->flags.bits |= SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS;
- } else {
- context->flags.bits &= ~SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS;
+ if (strcmp(option_name, "debug_to_stderr") == 0) {
+ option_value.b = (bool) va_arg(ap, int);
+ smbc_setOptionDebugToStderr(context, option_value.b);
+
+ } else if (strcmp(option_name, "full_time_names") == 0) {
+ option_value.b = (bool) va_arg(ap, int);
+ smbc_setOptionFullTimeNames(context, option_value.b);
+
+ } else if (strcmp(option_name, "open_share_mode") == 0) {
+ option_value.i = va_arg(ap, int);
+ smbc_setOptionOpenShareMode(context, option_value.i);
+
+ } else if (strcmp(option_name, "auth_function") == 0) {
+ option_value.auth_fn =
+ va_arg(ap, smbc_get_auth_data_with_context_fn);
+ smbc_setFunctionAuthDataWithContext(context, option_value.auth_fn);
+
+ } else if (strcmp(option_name, "user_data") == 0) {
+ option_value.v = va_arg(ap, void *);
+ smbc_setOptionUserData(context, option_value.v);
+
+ } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
+ option_value.s = va_arg(ap, const char *);
+ if (strcmp(option_value.s, "none") == 0) {
+ smbc_setOptionSmbEncryptionLevel(context,
+ SMBC_ENCRYPTLEVEL_NONE);
+ } else if (strcmp(option_value.s, "request") == 0) {
+ smbc_setOptionSmbEncryptionLevel(context,
+ SMBC_ENCRYPTLEVEL_REQUEST);
+ } else if (strcmp(option_value.s, "require") == 0) {
+ smbc_setOptionSmbEncryptionLevel(context,
+ SMBC_ENCRYPTLEVEL_REQUIRE);
+ }
+
+ } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
+ option_value.i = va_arg(ap, int);
+ smbc_setOptionBrowseMaxLmbCount(context, option_value.i);
+
+ } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
+ option_value.b = (bool) va_arg(ap, int);
+ smbc_setOptionUrlEncodeReaddirEntries(context, option_value.b);
+
+ } else if (strcmp(option_name, "one_share_per_server") == 0) {
+ option_value.b = (bool) va_arg(ap, int);
+ smbc_setOptionOneSharePerServer(context, option_value.b);
+
+ } else if (strcmp(option_name, "use_kerberos") == 0) {
+ option_value.b = (bool) va_arg(ap, int);
+ smbc_setOptionUseKerberos(context, option_value.b);
+
+ } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
+ option_value.b = (bool) va_arg(ap, int);
+ smbc_setOptionFallbackAfterKerberos(context, option_value.b);
+
+ } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
+ option_value.b = (bool) va_arg(ap, int);
+ smbc_setOptionNoAutoAnonymousLogin(context, option_value.b);
}
- } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
- option_value.b = (bool) va_arg(ap, int);
- if (option_value.b) {
- context->flags.bits |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON;
- } else {
- context->flags.bits &= ~SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON;
- }
- }
-
- va_end(ap);
+ va_end(ap);
}
/*
- * Retrieve the current value of an option
+ * Deprecated interface. Do not use. Instead, use the various
+ * smbc_getOption*() functions.
*/
void *
smbc_option_get(SMBCCTX *context,
char *option_name)
{
- int bits;
-
- if (strcmp(option_name, "debug_stderr") == 0) {
- /*
- * Log to standard error instead of standard output.
- */
+ int bits;
+
+ if (strcmp(option_name, "debug_stderr") == 0) {
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
- return (void *) (intptr_t) context->internal->debug_stderr;
+ return (void *) (intptr_t) smbc_getOptionDebugToStderr(context);
#else
- return (void *) context->internal->debug_stderr;
+ return (void *) smbc_getOptionDebugToStderr(context);
#endif
-
- } else if (strcmp(option_name, "full_time_names") == 0) {
- /*
- * Use new-style time attribute names, e.g. WRITE_TIME rather
- * than the old-style names such as M_TIME. This allows also
- * setting/getting CREATE_TIME which was previously
- * unimplemented. (Note that the old C_TIME was supposed to
- * be CHANGE_TIME but was confused and sometimes referred to
- * CREATE_TIME.)
- */
+
+ } else if (strcmp(option_name, "full_time_names") == 0) {
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
- return (void *) (intptr_t) context->internal->full_time_names;
+ return (void *) (intptr_t) smbc_getOptionFullTimeNames(context);
#else
- return (void *) context->internal->full_time_names;
+ return (void *) smbc_getOptionFullTimeNames(context);
#endif
-
- } else if (strcmp(option_name, "user_data") == 0) {
- /*
- * Return the user data handle which was saved by the user
- * with smbc_option_set()
- */
- return context->internal->user_data;
-
- } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
- /*
- * Return the current smb encrypt negotiate option as a string.
- */
- switch (context->internal->smb_encryption_level) {
- case 0:
- return (void *) "none";
- case 1:
- return (void *) "request";
- case 2:
- return (void *) "require";
- }
-
- } else if (strcmp(option_name, "smb_encrypt_on") == 0) {
- /*
- * Return the current smb encrypt status option as a bool.
- * false = off, true = on. We don't know what server is
- * being requested, so we only return true if all servers
- * are using an encrypted connection.
- */
- SMBCSRV *s;
- unsigned int num_servers = 0;
-
- for (s = context->internal->servers; s; s = s->next) {
- num_servers++;
- if (s->cli->trans_enc_state == NULL) {
- return (void *)false;
- }
- }
+
+ } else if (strcmp(option_name, "open_share_mode") == 0) {
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
- return (void *) (intptr_t) (bool) (num_servers > 0);
+ return (void *) (intptr_t) smbc_getOptionOpenShareMode(context);
#else
- return (void *) (bool) (num_servers > 0);
+ return (void *) smbc_getOptionOpenShareMode(context);
#endif
-
- } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
- /*
- * From how many local master browsers should the list of
- * workgroups be retrieved? It can take up to 12 minutes or
- * longer after a server becomes a local master browser, for
- * it to have the entire browse list (the list of
- * workgroups/domains) from an entire network. Since a client
- * never knows which local master browser will be found first,
- * the one which is found first and used to retrieve a browse
- * list may have an incomplete or empty browse list. By
- * requesting the browse list from multiple local master
- * browsers, a more complete list can be generated. For small
- * networks (few workgroups), it is recommended that this
- * value be set to 0, causing the browse lists from all found
- * local master browsers to be retrieved and merged. For
- * networks with many workgroups, a suitable value for this
- * variable is probably somewhere around 3. (Default: 3).
- */
+
+ } else if (strcmp(option_name, "auth_function") == 0) {
+ return (void *) smbc_getFunctionAuthDataWithContext(context);
+
+ } else if (strcmp(option_name, "user_data") == 0) {
+ return smbc_getOptionUserData(context);
+
+ } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
+ switch(smbc_getOptionSmbEncryptionLevel(context))
+ {
+ case 0:
+ return (void *) "none";
+ case 1:
+ return (void *) "request";
+ case 2:
+ return (void *) "require";
+ }
+
+ } else if (strcmp(option_name, "smb_encrypt_on") == 0) {
+ SMBCSRV *s;
+ unsigned int num_servers = 0;
+
+ for (s = context->internal->servers; s; s = s->next) {
+ num_servers++;
+ if (s->cli->trans_enc_state == NULL) {
+ return (void *)false;
+ }
+ }
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
- return (void *) (intptr_t) context->internal->browse_max_lmb_count;
+ return (void *) (intptr_t) (bool) (num_servers > 0);
#else
- return (void *) context->internal->browse_max_lmb_count;
+ return (void *) (bool) (num_servers > 0);
#endif
-
- } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
- /*
- * There is a difference in the desired return strings from
- * smbc_readdir() depending upon whether the filenames are to
- * be displayed to the user, or whether they are to be
- * appended to the path name passed to smbc_opendir() to call
- * a further smbc_ function (e.g. open the file with
- * smbc_open()). In the former case, the filename should be
- * in "human readable" form. In the latter case, the smbc_
- * functions expect a URL which must be url-encoded. Those
- * functions decode the URL. If, for example, smbc_readdir()
- * returned a file name of "abc%20def.txt", passing a path
- * with this file name attached to smbc_open() would cause
- * smbc_open to attempt to open the file "abc def.txt" since
- * the %20 is decoded into a space.
- *
- * Set this option to True if the names returned by
- * smbc_readdir() should be url-encoded such that they can be
- * passed back to another smbc_ call. Set it to False if the
- * names returned by smbc_readdir() are to be presented to the
- * user.
- *
- * For backwards compatibility, this option defaults to False.
- */
+
+ } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
- return (void *)(intptr_t) context->internal->urlencode_readdir_entries;
+ return (void *) (intptr_t) smbc_getOptionBrowseMaxLmbCount(context);
#else
- return (void *) (bool) context->internal->urlencode_readdir_entries;
+ return (void *) smbc_getOptionBrowseMaxLmbCount(context);
#endif
-
- } else if (strcmp(option_name, "one_share_per_server") == 0) {
- /*
- * Some Windows versions appear to have a limit to the number
- * of concurrent SESSIONs and/or TREE CONNECTions. In
- * one-shot programs (i.e. the program runs and then quickly
- * ends, thereby shutting down all connections), it is
- * probably reasonable to establish a new connection for each
- * share. In long-running applications, the limitation can be
- * avoided by using only a single connection to each server,
- * and issuing a new TREE CONNECT when the share is accessed.
- */
+
+ } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
- return (void *) (intptr_t) context->internal->one_share_per_server;
+ return (void *)(intptr_t) smbc_getOptionUrlEncodeReaddirEntries(context);
#else
- return (void *) (bool) context->internal->one_share_per_server;
+ return (void *) (bool) smbc_getOptionUrlEncodeReaddirEntries(context);
#endif
-
- } else if (strcmp(option_name, "use_kerberos") == 0) {
- bits = context->flags.bits;
+
+ } else if (strcmp(option_name, "one_share_per_server") == 0) {
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
- return (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS
- ? (void *) (intptr_t) 1
- : (void *) (intptr_t) 0);
+ return (void *) (intptr_t) smbc_getOptionOneSharePerServer(context);
#else
- return (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS
- ? (void *) (bool) 1
- : (void *) (bool) 0);
+ return (void *) (bool) smbc_getOptionOneSharePerServer(context);
#endif
-
- } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
+
+ } else if (strcmp(option_name, "use_kerberos") == 0) {
+ bits = context->flags.bits;
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
- return (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS
- ? (void *) (intptr_t) 1
- : (void *) (intptr_t) 0);
+ return (void *) (intptr_t) smbc_getOptionUseKerberos(context);
#else
- return (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS
- ? (void *) (bool) 1
- : (void *) (bool) 0);
+ return (void *) (bool) smbc_getOptionUseKerberos(context);
#endif
-
- } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
+
+ } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
- return (context->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON
- ? (void *) (intptr_t) 1
- : (void *) (intptr_t) 0);
+ return (void *)(intptr_t) smbc_getOptionFallbackAfterKerberos(context);
#else
- return (context->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON
- ? (void *) (bool) 1
- : (void *) (bool) 0);
+ return (void *) (bool) smbc_getOptionFallbackAfterKerberos(context);
#endif
- }
-
- return NULL;
+
+ } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
+#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
+ return (void *) (intptr_t) smbc_getOptionNoAutoAnonymousLogin(context);
+#else
+ return (void *) (bool) smbc_getOptionNoAutoAnonymousLogin(context);
+#endif
+ }
+
+ return NULL;
}
@@ -564,175 +412,175 @@ smbc_option_get(SMBCCTX *context,
SMBCCTX *
smbc_init_context(SMBCCTX *context)
{
- int pid;
- char *user = NULL;
- char *home = NULL;
- extern bool in_client;
-
- if (!context) {
- errno = EBADF;
- return NULL;
- }
-
- /* Do not initialise the same client twice */
- if (context->internal->initialized) {
- return 0;
- }
-
- if (!context->server.get_auth_data_fn ||
- context->config.debug < 0 ||
- context->config.debug > 100) {
+ int pid;
+ char *user = NULL;
+ char *home = NULL;
+ extern bool in_client;
- errno = EINVAL;
- return NULL;
-
- }
-
- if (!SMBC_initialized) {
- /*
- * Do some library-wide intializations the first time we get
- * called
- */
- bool conf_loaded = False;
- TALLOC_CTX *frame = talloc_stackframe();
-
- /* Set this to what the user wants */
- DEBUGLEVEL = context->config.debug;
-
- load_case_tables();
-
- setup_logging("libsmbclient", True);
- if (context->internal->debug_stderr) {
- dbf = x_stderr;
- x_setbuf(x_stderr, NULL);
+ if (!context) {
+ errno = EBADF;
+ return NULL;
}
- /* Here we would open the smb.conf file if needed ... */
+ /* Do not initialise the same client twice */
+ if (context->internal->initialized) {
+ return 0;
+ }
- in_client = True; /* FIXME, make a param */
+ if (!context->server.get_auth_data_fn ||
+ context->config.debug < 0 ||
+ context->config.debug > 100) {
+
+ errno = EINVAL;
+ return NULL;
+
+ }
- home = getenv("HOME");
- if (home) {
- char *conf = NULL;
- if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) {
- if (lp_load(conf, True, False, False, True)) {
- conf_loaded = True;
- } else {
- DEBUG(5, ("Could not load config file: %s\n",
- conf));
+ if (!SMBC_initialized) {
+ /*
+ * Do some library-wide intializations the first time we get
+ * called
+ */
+ bool conf_loaded = False;
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ /* Set this to what the user wants */
+ DEBUGLEVEL = context->config.debug;
+
+ load_case_tables();
+
+ setup_logging("libsmbclient", True);
+ if (context->internal->debug_stderr) {
+ dbf = x_stderr;
+ x_setbuf(x_stderr, NULL);
}
- SAFE_FREE(conf);
- }
+
+ /* Here we would open the smb.conf file if needed ... */
+
+ in_client = True; /* FIXME, make a param */
+
+ home = getenv("HOME");
+ if (home) {
+ char *conf = NULL;
+ if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) {
+ if (lp_load(conf, True, False, False, True)) {
+ conf_loaded = True;
+ } else {
+ DEBUG(5, ("Could not load config file: %s\n",
+ conf));
+ }
+ SAFE_FREE(conf);
+ }
+ }
+
+ if (!conf_loaded) {
+ /*
+ * Well, if that failed, try the get_dyn_CONFIGFILE
+ * Which points to the standard locn, and if that
+ * fails, silently ignore it and use the internal
+ * defaults ...
+ */
+
+ if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) {
+ DEBUG(5, ("Could not load config file: %s\n",
+ get_dyn_CONFIGFILE()));
+ } else if (home) {
+ char *conf;
+ /*
+ * We loaded the global config file. Now lets
+ * load user-specific modifications to the
+ * global config.
+ */
+ if (asprintf(&conf,
+ "%s/.smb/smb.conf.append",
+ home) > 0) {
+ if (!lp_load(conf, True, False, False, False)) {
+ DEBUG(10,
+ ("Could not append config file: "
+ "%s\n",
+ conf));
+ }
+ SAFE_FREE(conf);
+ }
+ }
+ }
+
+ load_interfaces(); /* Load the list of interfaces ... */
+
+ reopen_logs(); /* Get logging working ... */
+
+ /*
+ * Block SIGPIPE (from lib/util_sock.c: write())
+ * It is not needed and should not stop execution
+ */
+ BlockSignals(True, SIGPIPE);
+
+ /* Done with one-time initialisation */
+ SMBC_initialized = 1;
+
+ TALLOC_FREE(frame);
}
- if (!conf_loaded) {
- /*
- * Well, if that failed, try the get_dyn_CONFIGFILE
- * Which points to the standard locn, and if that
- * fails, silently ignore it and use the internal
- * defaults ...
- */
-
- if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) {
- DEBUG(5, ("Could not load config file: %s\n",
- get_dyn_CONFIGFILE()));
- } else if (home) {
- char *conf;
+ if (!context->config.user) {
/*
- * We loaded the global config file. Now lets
- * load user-specific modifications to the
- * global config.
+ * FIXME: Is this the best way to get the user info?
*/
- if (asprintf(&conf,
- "%s/.smb/smb.conf.append",
- home) > 0) {
- if (!lp_load(conf, True, False, False, False)) {
- DEBUG(10,
- ("Could not append config file: "
- "%s\n",
- conf));
- }
- SAFE_FREE(conf);
+ user = getenv("USER");
+ /* walk around as "guest" if no username can be found */
+ if (!user) context->config.user = SMB_STRDUP("guest");
+ else context->config.user = SMB_STRDUP(user);
+ }
+
+ if (!context->config.netbios_name) {
+ /*
+ * We try to get our netbios name from the config. If that
+ * fails we fall back on constructing our netbios name from
+ * our hostname etc
+ */
+ if (global_myname()) {
+ context->config.netbios_name = SMB_STRDUP(global_myname());
+ }
+ else {
+ /*
+ * Hmmm, I want to get hostname as well, but I am too
+ * lazy for the moment
+ */
+ pid = sys_getpid();
+ context->config.netbios_name = (char *)SMB_MALLOC(17);
+ if (!context->config.netbios_name) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ slprintf(context->config.netbios_name, 16,
+ "smbc%s%d", context->config.user, pid);
+ }
+ }
+
+ DEBUG(1, ("Using netbios name %s.\n", context->config.netbios_name));
+
+ if (!context->config.workgroup) {
+ if (lp_workgroup()) {
+ context->config.workgroup = SMB_STRDUP(lp_workgroup());
+ }
+ else {
+ /* TODO: Think about a decent default workgroup */
+ context->config.workgroup = SMB_STRDUP("samba");
}
- }
}
- load_interfaces(); /* Load the list of interfaces ... */
+ DEBUG(1, ("Using workgroup %s.\n", context->config.workgroup));
- reopen_logs(); /* Get logging working ... */
+ /* shortest timeout is 1 second */
+ if (context->config.timeout > 0 && context->config.timeout < 1000)
+ context->config.timeout = 1000;
/*
- * Block SIGPIPE (from lib/util_sock.c: write())
- * It is not needed and should not stop execution
+ * FIXME: Should we check the function pointers here?
*/
- BlockSignals(True, SIGPIPE);
- /* Done with one-time initialisation */
- SMBC_initialized = 1;
+ context->internal->initialized = True;
- TALLOC_FREE(frame);
- }
-
- if (!context->config.user) {
- /*
- * FIXME: Is this the best way to get the user info?
- */
- user = getenv("USER");
- /* walk around as "guest" if no username can be found */
- if (!user) context->config.user = SMB_STRDUP("guest");
- else context->config.user = SMB_STRDUP(user);
- }
-
- if (!context->config.netbios_name) {
- /*
- * We try to get our netbios name from the config. If that
- * fails we fall back on constructing our netbios name from
- * our hostname etc
- */
- if (global_myname()) {
- context->config.netbios_name = SMB_STRDUP(global_myname());
- }
- else {
- /*
- * Hmmm, I want to get hostname as well, but I am too
- * lazy for the moment
- */
- pid = sys_getpid();
- context->config.netbios_name = (char *)SMB_MALLOC(17);
- if (!context->config.netbios_name) {
- errno = ENOMEM;
- return NULL;
- }
- slprintf(context->config.netbios_name, 16,
- "smbc%s%d", context->config.user, pid);
- }
- }
-
- DEBUG(1, ("Using netbios name %s.\n", context->config.netbios_name));
-
- if (!context->config.workgroup) {
- if (lp_workgroup()) {
- context->config.workgroup = SMB_STRDUP(lp_workgroup());
- }
- else {
- /* TODO: Think about a decent default workgroup */
- context->config.workgroup = SMB_STRDUP("samba");
- }
- }
-
- DEBUG(1, ("Using workgroup %s.\n", context->config.workgroup));
-
- /* shortest timeout is 1 second */
- if (context->config.timeout > 0 && context->config.timeout < 1000)
- context->config.timeout = 1000;
-
- /*
- * FIXME: Should we check the function pointers here?
- */
-
- context->internal->initialized = True;
-
- return context;
+ return context;
}
@@ -740,7 +588,7 @@ smbc_init_context(SMBCCTX *context)
const char *
smbc_version(void)
{
- return samba_version_string();
+ return samba_version_string();
}
@@ -748,56 +596,56 @@ smbc_version(void)
char *
smbc_getNetbiosName(SMBCCTX *c)
{
- return c->config.netbios_name;
+ return c->config.netbios_name;
}
/** Set the netbios name used for making connections */
void
smbc_setNetbiosName(SMBCCTX *c, char * netbios_name)
{
- c->config.netbios_name = netbios_name;
+ c->config.netbios_name = netbios_name;
}
/** Get the workgroup used for making connections */
char *
smbc_getWorkgroup(SMBCCTX *c)
{
- return c->config.workgroup;
+ return c->config.workgroup;
}
/** Set the workgroup used for making connections */
void
smbc_setWorkgroup(SMBCCTX *c, char * workgroup)
{
- c->config.workgroup = workgroup;
+ c->config.workgroup = workgroup;
}
/** Get the username used for making connections */
char *
smbc_getUser(SMBCCTX *c)
{
- return c->config.user;
+ return c->config.user;
}
/** Set the username used for making connections */
void
smbc_setUser(SMBCCTX *c, char * user)
{
- c->config.user = user;
+ c->config.user = user;
}
/** Get the debug level */
int
smbc_getDebug(SMBCCTX *c)
{
- return c->config.debug;
+ return c->config.debug;
}
/** Set the debug level */
void
smbc_setDebug(SMBCCTX *c, int debug)
{
- c->config.debug = debug;
+ c->config.debug = debug;
}
/**
@@ -807,7 +655,7 @@ smbc_setDebug(SMBCCTX *c, int debug)
int
smbc_getTimeout(SMBCCTX *c)
{
- return c->config.timeout;
+ return c->config.timeout;
}
/**
@@ -817,43 +665,339 @@ smbc_getTimeout(SMBCCTX *c)
void
smbc_setTimeout(SMBCCTX *c, int timeout)
{
- c->config.timeout = timeout;
+ c->config.timeout = timeout;
}
-/** Get the function for obtaining authentication data */
+/** Get whether to log to standard error instead of standard output */
+smbc_bool
+smbc_getOptionDebugToStderr(SMBCCTX *c)
+{
+ return c->internal->debug_stderr;
+}
+
+/** Set whether to log to standard error instead of standard output */
+void
+smbc_setOptionDebugToStderr(SMBCCTX *c, smbc_bool b)
+{
+ c->internal->debug_stderr = b;
+}
+
+/**
+ * Get whether to use new-style time attribute names, e.g. WRITE_TIME rather
+ * than the old-style names such as M_TIME. This allows also setting/getting
+ * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME
+ * was supposed to be CHANGE_TIME but was confused and sometimes referred to
+ * CREATE_TIME.)
+ */
+smbc_bool
+smbc_getOptionFullTimeNames(SMBCCTX *c)
+{
+ return c->internal->full_time_names;
+}
+
+/**
+ * Set whether to use new-style time attribute names, e.g. WRITE_TIME rather
+ * than the old-style names such as M_TIME. This allows also setting/getting
+ * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME
+ * was supposed to be CHANGE_TIME but was confused and sometimes referred to
+ * CREATE_TIME.)
+ */
+void
+smbc_setOptionFullTimeNames(SMBCCTX *c, smbc_bool b)
+{
+ c->internal->full_time_names = b;
+}
+
+/**
+ * Get the share mode to use for files opened with SMBC_open_ctx(). The
+ * default is SMBC_SHAREMODE_DENY_NONE.
+ */
+smbc_share_mode
+smbc_getOptionOpenShareMode(SMBCCTX *c)
+{
+ return c->internal->share_mode;
+}
+
+/**
+ * Set the share mode to use for files opened with SMBC_open_ctx(). The
+ * default is SMBC_SHAREMODE_DENY_NONE.
+ */
+void
+smbc_setOptionOpenShareMode(SMBCCTX *c, smbc_share_mode share_mode)
+{
+ c->internal->share_mode = share_mode;
+}
+
+/** Retrieve a previously set user data handle */
+void *
+smbc_getOptionUserData(SMBCCTX *c)
+{
+ return c->internal->user_data;
+}
+
+/** Save a user data handle */
+void
+smbc_setOptionUserData(SMBCCTX *c, void *user_data)
+{
+ c->internal->user_data = user_data;
+}
+/** Get the encoded value for encryption level. */
+smbc_smb_encrypt_level
+smbc_getOptionSmbEncryptionLevel(SMBCCTX *c)
+{
+ return c->internal->smb_encryption_level;
+}
+
+/** Set the encoded value for encryption level. */
+void
+smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level)
+{
+ c->internal->smb_encryption_level = level;
+}
+
+/**
+ * Get from how many local master browsers should the list of workgroups be
+ * retrieved. It can take up to 12 minutes or longer after a server becomes a
+ * local master browser, for it to have the entire browse list (the list of
+ * workgroups/domains) from an entire network. Since a client never knows
+ * which local master browser will be found first, the one which is found
+ * first and used to retrieve a browse list may have an incomplete or empty
+ * browse list. By requesting the browse list from multiple local master
+ * browsers, a more complete list can be generated. For small networks (few
+ * workgroups), it is recommended that this value be set to 0, causing the
+ * browse lists from all found local master browsers to be retrieved and
+ * merged. For networks with many workgroups, a suitable value for this
+ * variable is probably somewhere around 3. (Default: 3).
+ */
+int
+smbc_getOptionBrowseMaxLmbCount(SMBCCTX *c)
+{
+ return c->options.browse_max_lmb_count;
+}
+
+/**
+ * Set from how many local master browsers should the list of workgroups be
+ * retrieved. It can take up to 12 minutes or longer after a server becomes a
+ * local master browser, for it to have the entire browse list (the list of
+ * workgroups/domains) from an entire network. Since a client never knows
+ * which local master browser will be found first, the one which is found
+ * first and used to retrieve a browse list may have an incomplete or empty
+ * browse list. By requesting the browse list from multiple local master
+ * browsers, a more complete list can be generated. For small networks (few
+ * workgroups), it is recommended that this value be set to 0, causing the
+ * browse lists from all found local master browsers to be retrieved and
+ * merged. For networks with many workgroups, a suitable value for this
+ * variable is probably somewhere around 3. (Default: 3).
+ */
+void
+smbc_setOptionBrowseMaxLmbCount(SMBCCTX *c, int count)
+{
+ c->options.browse_max_lmb_count = count;
+}
+
+/**
+ * Get whether to url-encode readdir entries.
+ *
+ * There is a difference in the desired return strings from
+ * smbc_readdir() depending upon whether the filenames are to
+ * be displayed to the user, or whether they are to be
+ * appended to the path name passed to smbc_opendir() to call
+ * a further smbc_ function (e.g. open the file with
+ * smbc_open()). In the former case, the filename should be
+ * in "human readable" form. In the latter case, the smbc_
+ * functions expect a URL which must be url-encoded. Those
+ * functions decode the URL. If, for example, smbc_readdir()
+ * returned a file name of "abc%20def.txt", passing a path
+ * with this file name attached to smbc_open() would cause
+ * smbc_open to attempt to open the file "abc def.txt" since
+ * the %20 is decoded into a space.
+ *
+ * Set this option to True if the names returned by
+ * smbc_readdir() should be url-encoded such that they can be
+ * passed back to another smbc_ call. Set it to False if the
+ * names returned by smbc_readdir() are to be presented to the
+ * user.
+ *
+ * For backwards compatibility, this option defaults to False.
+ */
+smbc_bool
+smbc_getOptionUrlEncodeReaddirEntries(SMBCCTX *c)
+{
+ return c->options.urlencode_readdir_entries;
+}
+
+/**
+ * Set whether to url-encode readdir entries.
+ *
+ * There is a difference in the desired return strings from
+ * smbc_readdir() depending upon whether the filenames are to
+ * be displayed to the user, or whether they are to be
+ * appended to the path name passed to smbc_opendir() to call
+ * a further smbc_ function (e.g. open the file with
+ * smbc_open()). In the former case, the filename should be
+ * in "human readable" form. In the latter case, the smbc_
+ * functions expect a URL which must be url-encoded. Those
+ * functions decode the URL. If, for example, smbc_readdir()
+ * returned a file name of "abc%20def.txt", passing a path
+ * with this file name attached to smbc_open() would cause
+ * smbc_open to attempt to open the file "abc def.txt" since
+ * the %20 is decoded into a space.
+ *
+ * Set this option to True if the names returned by
+ * smbc_readdir() should be url-encoded such that they can be
+ * passed back to another smbc_ call. Set it to False if the
+ * names returned by smbc_readdir() are to be presented to the
+ * user.
+ *
+ * For backwards compatibility, this option defaults to False.
+ */
+void
+smbc_setOptionUrlEncodeReaddirEntries(SMBCCTX *c, smbc_bool b)
+{
+ c->options.urlencode_readdir_entries = b;
+}
+
+/**
+ * Get whether to use the same connection for all shares on a server.
+ *
+ * Some Windows versions appear to have a limit to the number
+ * of concurrent SESSIONs and/or TREE CONNECTions. In
+ * one-shot programs (i.e. the program runs and then quickly
+ * ends, thereby shutting down all connections), it is
+ * probably reasonable to establish a new connection for each
+ * share. In long-running applications, the limitation can be
+ * avoided by using only a single connection to each server,
+ * and issuing a new TREE CONNECT when the share is accessed.
+ */
+smbc_bool
+smbc_getOptionOneSharePerServer(SMBCCTX *c)
+{
+ return c->options.one_share_per_server;
+}
+
+/**
+ * Set whether to use the same connection for all shares on a server.
+ *
+ * Some Windows versions appear to have a limit to the number
+ * of concurrent SESSIONs and/or TREE CONNECTions. In
+ * one-shot programs (i.e. the program runs and then quickly
+ * ends, thereby shutting down all connections), it is
+ * probably reasonable to establish a new connection for each
+ * share. In long-running applications, the limitation can be
+ * avoided by using only a single connection to each server,
+ * and issuing a new TREE CONNECT when the share is accessed.
+ */
+void
+smbc_setOptionOneSharePerServer(SMBCCTX *c, smbc_bool b)
+{
+ c->options.one_share_per_server = b;
+}
+
+/** Get whether to enable use of kerberos */
+smbc_bool
+smbc_getOptionUseKerberos(SMBCCTX *c)
+{
+ return c->flags.bits & SMB_CTX_FLAG_USE_KERBEROS ? True : False;
+}
+
+/** Set whether to enable use of kerberos */
+void
+smbc_setOptionUseKerberos(SMBCCTX *c, smbc_bool b)
+{
+ if (b) {
+ c->flags.bits |= SMB_CTX_FLAG_USE_KERBEROS;
+ } else {
+ c->flags.bits &= ~SMB_CTX_FLAG_USE_KERBEROS;
+ }
+}
+
+/** Get whether to fallback after kerberos */
+smbc_bool
+smbc_getOptionFallbackAfterKerberos(SMBCCTX *c)
+{
+ return c->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS ? True : False;
+}
+
+/** Set whether to fallback after kerberos */
+void
+smbc_setOptionFallbackAfterKerberos(SMBCCTX *c, smbc_bool b)
+{
+ if (b) {
+ c->flags.bits |= SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS;
+ } else {
+ c->flags.bits &= ~SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS;
+ }
+}
+
+/** Get whether to automatically select anonymous login */
+smbc_bool
+smbc_getOptionNoAutoAnonymousLogin(SMBCCTX *c)
+{
+ return c->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON ? True : False;
+}
+
+/** Set whether to automatically select anonymous login */
+void
+smbc_setOptionNoAutoAnonymousLogin(SMBCCTX *c, smbc_bool b)
+{
+ if (b) {
+ c->flags.bits |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON;
+ } else {
+ c->flags.bits &= ~SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON;
+ }
+}
+
+/** Get the function for obtaining authentication data */
smbc_get_auth_data_fn
smbc_getFunctionAuthData(SMBCCTX *c)
{
- return c->server.get_auth_data_fn;
+ return c->server.get_auth_data_fn;
}
/** Set the function for obtaining authentication data */
void
smbc_setFunctionAuthData(SMBCCTX *c, smbc_get_auth_data_fn fn)
{
- c->server.get_auth_data_fn = fn;
+ c->internal->auth_fn_with_context = NULL;
+ c->server.get_auth_data_fn = fn;
+}
+
+/** Get the new-style authentication function which includes the context. */
+smbc_get_auth_data_with_context_fn
+smbc_getFunctionAuthDataWithContext(SMBCCTX *c)
+{
+ return c->internal->auth_fn_with_context;
+}
+
+/** Set the new-style authentication function which includes the context. */
+void
+smbc_setFunctionAuthDataWithContext(SMBCCTX *c,
+ smbc_get_auth_data_with_context_fn fn)
+{
+ c->server.get_auth_data_fn = NULL;
+ c->internal->auth_fn_with_context = fn;
}
/** Get the function for checking if a server is still good */
smbc_check_server_fn
smbc_getFunctionCheckServer(SMBCCTX *c)
{
- return c->server.check_server_fn;
+ return c->server.check_server_fn;
}
/** Set the function for checking if a server is still good */
void
smbc_setFunctionCheckServer(SMBCCTX *c, smbc_check_server_fn fn)
{
- c->server.check_server_fn = fn;
+ c->server.check_server_fn = fn;
}
/** Get the function for removing a server if unused */
smbc_remove_unused_server_fn
smbc_getFunctionRemoveUnusedServer(SMBCCTX *c)
{
- return c->server.remove_unused_server_fn;
+ return c->server.remove_unused_server_fn;
}
/** Set the function for removing a server if unused */
@@ -861,21 +1005,21 @@ void
smbc_setFunctionRemoveUnusedServer(SMBCCTX *c,
smbc_remove_unused_server_fn fn)
{
- c->server.remove_unused_server_fn = fn;
+ c->server.remove_unused_server_fn = fn;
}
/** Get the function to store private data of the server cache */
struct
smbc_server_cache * smbc_getServerCacheData(SMBCCTX *c)
{
- return c->cache.server_cache_data;
+ return c->cache.server_cache_data;
}
/** Set the function to store private data of the server cache */
void
smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache)
{
- c->cache.server_cache_data = cache;
+ c->cache.server_cache_data = cache;
}
@@ -883,35 +1027,35 @@ smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache)
smbc_add_cached_srv_fn
smbc_getFunctionAddCachedServer(SMBCCTX *c)
{
- return c->cache.add_cached_server_fn;
+ return c->cache.add_cached_server_fn;
}
/** Set the function for adding a cached server */
void
smbc_setFunctionAddCachedServer(SMBCCTX *c, smbc_add_cached_srv_fn fn)
{
- c->cache.add_cached_server_fn = fn;
+ c->cache.add_cached_server_fn = fn;
}
/** Get the function for server cache lookup */
smbc_get_cached_srv_fn
smbc_getFunctionGetCachedServer(SMBCCTX *c)
{
- return c->cache.get_cached_server_fn;
+ return c->cache.get_cached_server_fn;
}
/** Set the function for server cache lookup */
void
smbc_setFunctionGetCachedServer(SMBCCTX *c, smbc_get_cached_srv_fn fn)
{
- c->cache.get_cached_server_fn = fn;
+ c->cache.get_cached_server_fn = fn;
}
/** Get the function for server cache removal */
smbc_remove_cached_srv_fn
smbc_getFunctionRemoveCachedServer(SMBCCTX *c)
{
- return c->cache.remove_cached_server_fn;
+ return c->cache.remove_cached_server_fn;
}
/** Set the function for server cache removal */
@@ -919,7 +1063,7 @@ void
smbc_setFunctionRemoveCachedServer(SMBCCTX *c,
smbc_remove_cached_srv_fn fn)
{
- c->cache.remove_cached_server_fn = fn;
+ c->cache.remove_cached_server_fn = fn;
}
/**
@@ -929,7 +1073,7 @@ smbc_setFunctionRemoveCachedServer(SMBCCTX *c,
smbc_purge_cached_srv_fn
smbc_getFunctionPurgeCachedServers(SMBCCTX *c)
{
- return c->cache.purge_cached_servers_fn;
+ return c->cache.purge_cached_servers_fn;
}
/**
@@ -939,7 +1083,7 @@ smbc_getFunctionPurgeCachedServers(SMBCCTX *c)
void
smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_srv_fn fn)
{
- c->cache.purge_cached_servers_fn = fn;
+ c->cache.purge_cached_servers_fn = fn;
}
/**
@@ -949,133 +1093,133 @@ smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_srv_fn fn)
smbc_open_fn
smbc_getFunctionOpen(SMBCCTX *c)
{
- return c->posix_emu.open_fn;
+ return c->posix_emu.open_fn;
}
void
smbc_setFunctionOpen(SMBCCTX *c, smbc_open_fn fn)
{
- c->posix_emu.open_fn = fn;
+ c->posix_emu.open_fn = fn;
}
smbc_creat_fn
smbc_getFunctionCreat(SMBCCTX *c)
{
- return c->posix_emu.creat_fn;
+ return c->posix_emu.creat_fn;
}
void
smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn fn)
{
- c->posix_emu.creat_fn = fn;
+ c->posix_emu.creat_fn = fn;
}
smbc_read_fn
smbc_getFunctionRead(SMBCCTX *c)
{
- return c->posix_emu.read_fn;
+ return c->posix_emu.read_fn;
}
void
smbc_setFunctionRead(SMBCCTX *c, smbc_read_fn fn)
{
- c->posix_emu.read_fn = fn;
+ c->posix_emu.read_fn = fn;
}
smbc_write_fn
smbc_getFunctionWrite(SMBCCTX *c)
{
- return c->posix_emu.write_fn;
+ return c->posix_emu.write_fn;
}
void
smbc_setFunctionWrite(SMBCCTX *c, smbc_write_fn fn)
{
- c->posix_emu.write_fn = fn;
+ c->posix_emu.write_fn = fn;
}
smbc_unlink_fn
smbc_getFunctionUnlink(SMBCCTX *c)
{
- return c->posix_emu.unlink_fn;
+ return c->posix_emu.unlink_fn;
}
void
smbc_setFunctionUnlink(SMBCCTX *c, smbc_unlink_fn fn)
{
- c->posix_emu.unlink_fn = fn;
+ c->posix_emu.unlink_fn = fn;
}
smbc_rename_fn
smbc_getFunctionRename(SMBCCTX *c)
{
- return c->posix_emu.rename_fn;
+ return c->posix_emu.rename_fn;
}
void
smbc_setFunctionRename(SMBCCTX *c, smbc_rename_fn fn)
{
- c->posix_emu.rename_fn = fn;
+ c->posix_emu.rename_fn = fn;
}
smbc_lseek_fn
smbc_getFunctionLseek(SMBCCTX *c)
{
- return c->posix_emu.lseek_fn;
+ return c->posix_emu.lseek_fn;
}
void
smbc_setFunctionLseek(SMBCCTX *c, smbc_lseek_fn fn)
{
- c->posix_emu.lseek_fn = fn;
+ c->posix_emu.lseek_fn = fn;
}
smbc_stat_fn
smbc_getFunctionStat(SMBCCTX *c)
{
- return c->posix_emu.stat_fn;
+ return c->posix_emu.stat_fn;
}
void
smbc_setFunctionStat(SMBCCTX *c, smbc_stat_fn fn)
{
- c->posix_emu.stat_fn = fn;
+ c->posix_emu.stat_fn = fn;
}
smbc_fstat_fn
smbc_getFunctionFstat(SMBCCTX *c)
{
- return c->posix_emu.fstat_fn;
+ return c->posix_emu.fstat_fn;
}
void
smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn)
{
- c->posix_emu.fstat_fn = fn;
+ c->posix_emu.fstat_fn = fn;
}
smbc_ftruncate_fn
smbc_getFunctionFtruncate(SMBCCTX *c)
{
- return c->internal->posix_emu.ftruncate_fn;
+ return c->internal->posix_emu.ftruncate_fn;
}
void
smbc_setFunctionFtruncate(SMBCCTX *c, smbc_ftruncate_fn fn)
{
- c->internal->posix_emu.ftruncate_fn = fn;
+ c->internal->posix_emu.ftruncate_fn = fn;
}
smbc_close_fn
smbc_getFunctionClose(SMBCCTX *c)
{
- return c->posix_emu.close_fn;
+ return c->posix_emu.close_fn;
}
void
smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn)
{
- c->posix_emu.close_fn = fn;
+ c->posix_emu.close_fn = fn;
}
@@ -1086,109 +1230,109 @@ smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn)
smbc_opendir_fn
smbc_getFunctionOpendir(SMBCCTX *c)
{
- return c->posix_emu.opendir_fn;
+ return c->posix_emu.opendir_fn;
}
void
smbc_setFunctionOpendir(SMBCCTX *c, smbc_opendir_fn fn)
{
- c->posix_emu.opendir_fn = fn;
+ c->posix_emu.opendir_fn = fn;
}
smbc_closedir_fn
smbc_getFunctionClosedir(SMBCCTX *c)
{
- return c->posix_emu.closedir_fn;
+ return c->posix_emu.closedir_fn;
}
void
smbc_setFunctionClosedir(SMBCCTX *c, smbc_closedir_fn fn)
{
- c->posix_emu.closedir_fn = fn;
+ c->posix_emu.closedir_fn = fn;
}
smbc_readdir_fn
smbc_getFunctionReaddir(SMBCCTX *c)
{
- return c->posix_emu.readdir_fn;
+ return c->posix_emu.readdir_fn;
}
void
smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn)
{
- c->posix_emu.readdir_fn = fn;
+ c->posix_emu.readdir_fn = fn;
}
smbc_getdents_fn
smbc_getFunctionGetdents(SMBCCTX *c)
{
- return c->posix_emu.getdents_fn;
+ return c->posix_emu.getdents_fn;
}
void
smbc_setFunctionGetdents(SMBCCTX *c, smbc_getdents_fn fn)
{
- c->posix_emu.getdents_fn = fn;
+ c->posix_emu.getdents_fn = fn;
}
smbc_mkdir_fn
smbc_getFunctionMkdir(SMBCCTX *c)
{
- return c->posix_emu.mkdir_fn;
+ return c->posix_emu.mkdir_fn;
}
void
smbc_setFunctionMkdir(SMBCCTX *c, smbc_mkdir_fn fn)
{
- c->posix_emu.mkdir_fn = fn;
+ c->posix_emu.mkdir_fn = fn;
}
smbc_rmdir_fn
smbc_getFunctionRmdir(SMBCCTX *c)
{
- return c->posix_emu.rmdir_fn;
+ return c->posix_emu.rmdir_fn;
}
void
smbc_setFunctionRmdir(SMBCCTX *c, smbc_rmdir_fn fn)
{
- c->posix_emu.rmdir_fn = fn;
+ c->posix_emu.rmdir_fn = fn;
}
smbc_telldir_fn
smbc_getFunctionTelldir(SMBCCTX *c)
{
- return c->posix_emu.telldir_fn;
+ return c->posix_emu.telldir_fn;
}
void
smbc_setFunctionTelldir(SMBCCTX *c, smbc_telldir_fn fn)
{
- c->posix_emu.telldir_fn = fn;
+ c->posix_emu.telldir_fn = fn;
}
smbc_lseekdir_fn
smbc_getFunctionLseekdir(SMBCCTX *c)
{
- return c->posix_emu.lseekdir_fn;
+ return c->posix_emu.lseekdir_fn;
}
void
smbc_setFunctionLseekdir(SMBCCTX *c, smbc_lseekdir_fn fn)
{
- c->posix_emu.lseekdir_fn = fn;
+ c->posix_emu.lseekdir_fn = fn;
}
smbc_fstatdir_fn
smbc_getFunctionFstatdir(SMBCCTX *c)
{
- return c->posix_emu.fstatdir_fn;
+ return c->posix_emu.fstatdir_fn;
}
void
smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn)
{
- c->posix_emu.fstatdir_fn = fn;
+ c->posix_emu.fstatdir_fn = fn;
}
@@ -1199,73 +1343,73 @@ smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn)
smbc_chmod_fn
smbc_getFunctionChmod(SMBCCTX *c)
{
- return c->posix_emu.chmod_fn;
+ return c->posix_emu.chmod_fn;
}
void
smbc_setFunctionChmod(SMBCCTX *c, smbc_chmod_fn fn)
{
- c->posix_emu.chmod_fn = fn;
+ c->posix_emu.chmod_fn = fn;
}
smbc_utimes_fn
smbc_getFunctionUtimes(SMBCCTX *c)
{
- return c->posix_emu.utimes_fn;
+ return c->posix_emu.utimes_fn;
}
void
smbc_setFunctionUtimes(SMBCCTX *c, smbc_utimes_fn fn)
{
- c->posix_emu.utimes_fn = fn;
+ c->posix_emu.utimes_fn = fn;
}
smbc_setxattr_fn
smbc_getFunctionSetxattr(SMBCCTX *c)
{
- return c->posix_emu.setxattr_fn;
+ return c->posix_emu.setxattr_fn;
}
void
smbc_setFunctionSetxattr(SMBCCTX *c, smbc_setxattr_fn fn)
{
- c->posix_emu.setxattr_fn = fn;
+ c->posix_emu.setxattr_fn = fn;
}
smbc_getxattr_fn
smbc_getFunctionGetxattr(SMBCCTX *c)
{
- return c->posix_emu.getxattr_fn;
+ return c->posix_emu.getxattr_fn;
}
void
smbc_setFunctionGetxattr(SMBCCTX *c, smbc_getxattr_fn fn)
{
- c->posix_emu.getxattr_fn = fn;
+ c->posix_emu.getxattr_fn = fn;
}
smbc_removexattr_fn
smbc_getFunctionRemovexattr(SMBCCTX *c)
{
- return c->posix_emu.removexattr_fn;
+ return c->posix_emu.removexattr_fn;
}
void
smbc_setFunctionRemovexattr(SMBCCTX *c, smbc_removexattr_fn fn)
{
- c->posix_emu.removexattr_fn = fn;
+ c->posix_emu.removexattr_fn = fn;
}
smbc_listxattr_fn
smbc_getFunctionListxattr(SMBCCTX *c)
{
- return c->posix_emu.listxattr_fn;
+ return c->posix_emu.listxattr_fn;
}
void
smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn)
{
- c->posix_emu.listxattr_fn = fn;
+ c->posix_emu.listxattr_fn = fn;
}
@@ -1276,51 +1420,51 @@ smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn)
smbc_print_file_fn
smbc_getFunctionPrintFile(SMBCCTX *c)
{
- return c->printing.print_file_fn;
+ return c->printing.print_file_fn;
}
void
smbc_setFunctionPrintFile(SMBCCTX *c, smbc_print_file_fn fn)
{
- c->printing.print_file_fn = fn;
+ c->printing.print_file_fn = fn;
}
smbc_open_print_job_fn
smbc_getFunctionOpenPrintJob(SMBCCTX *c)
{
- return c->printing.open_print_job_fn;
+ return c->printing.open_print_job_fn;
}
void
smbc_setFunctionOpenPrintJob(SMBCCTX *c,
smbc_open_print_job_fn fn)
{
- c->printing.open_print_job_fn = fn;
+ c->printing.open_print_job_fn = fn;
}
smbc_list_print_jobs_fn
smbc_getFunctionListPrintJobs(SMBCCTX *c)
{
- return c->printing.list_print_jobs_fn;
+ return c->printing.list_print_jobs_fn;
}
void
smbc_setFunctionListPrintJobs(SMBCCTX *c,
smbc_list_print_jobs_fn fn)
{
- c->printing.list_print_jobs_fn = fn;
+ c->printing.list_print_jobs_fn = fn;
}
smbc_unlink_print_job_fn
smbc_getFunctionUnlinkPrintJob(SMBCCTX *c)
{
- return c->printing.unlink_print_job_fn;
+ return c->printing.unlink_print_job_fn;
}
void
smbc_setFunctionUnlinkPrintJob(SMBCCTX *c,
- smbc_unlink_print_job_fn fn)
+ smbc_unlink_print_job_fn fn)
{
- c->printing.unlink_print_job_fn = fn;
+ c->printing.unlink_print_job_fn = fn;
}