LCOV - code coverage report
Current view: top level - source3/libsmb - libsmb_context.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 194 390 49.7 %
Date: 2024-04-21 15:09:00 Functions: 7 10 70.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/Netbios implementation.
       3             :    SMB client library implementation
       4             :    Copyright (C) Andrew Tridgell 1998
       5             :    Copyright (C) Richard Sharpe 2000, 2002
       6             :    Copyright (C) John Terpstra 2000
       7             :    Copyright (C) Tom Jansen (Ninja ISD) 2002
       8             :    Copyright (C) Derrell Lipman 2003-2008
       9             :    Copyright (C) Jeremy Allison 2007, 2008
      10             : 
      11             :    This program is free software; you can redistribute it and/or modify
      12             :    it under the terms of the GNU General Public License as published by
      13             :    the Free Software Foundation; either version 3 of the License, or
      14             :    (at your option) any later version.
      15             : 
      16             :    This program is distributed in the hope that it will be useful,
      17             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :    GNU General Public License for more details.
      20             : 
      21             :    You should have received a copy of the GNU General Public License
      22             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include "includes.h"
      26             : #include "libsmb/libsmb.h"
      27             : #include "libsmbclient.h"
      28             : #include "libsmb_internal.h"
      29             : #include "secrets.h"
      30             : #include "../libcli/smb/smbXcli_base.h"
      31             : #include "auth/credentials/credentials.h"
      32             : #include "auth/gensec/gensec.h"
      33             : #include "lib/param/param.h"
      34             : #include "../lib/util/smb_threads.h"
      35             : #include "../lib/util/smb_threads_internal.h"
      36             : 
      37             : /*
      38             :  * Is the logging working / configfile read ?
      39             :  */
      40             : static bool SMBC_initialized = false;
      41             : static unsigned int initialized_ctx_count = 0;
      42             : static void *initialized_ctx_count_mutex = NULL;
      43             : 
      44             : /*
      45             :  * Do some module- and library-wide initializations
      46             :  */
      47             : static void
      48         106 : SMBC_module_init(void * punused)
      49             : {
      50         106 :         bool conf_loaded = False;
      51         106 :         char *home = NULL;
      52         106 :         TALLOC_CTX *frame = talloc_stackframe();
      53             : 
      54         106 :         setup_logging("libsmbclient", DEBUG_STDOUT);
      55             : 
      56             :         /* Here we would open the smb.conf file if needed ... */
      57             : 
      58         106 :         home = getenv("HOME");
      59         106 :         if (home) {
      60         106 :                 char *conf = NULL;
      61         106 :                 if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) {
      62         106 :                         if (lp_load_client(conf)) {
      63           0 :                                 conf_loaded = True;
      64             :                         } else {
      65         106 :                                 DEBUG(5, ("Could not load config file: %s\n",
      66             :                                           conf));
      67             :                         }
      68         106 :                         SAFE_FREE(conf);
      69             :                 }
      70             :         }
      71             : 
      72         106 :         if (!conf_loaded) {
      73             :                 /*
      74             :                  * Well, if that failed, try the get_dyn_CONFIGFILE
      75             :                  * Which points to the standard locn, and if that
      76             :                  * fails, silently ignore it and use the internal
      77             :                  * defaults ...
      78             :                  */
      79             : 
      80         106 :                 if (!lp_load_client(get_dyn_CONFIGFILE())) {
      81           0 :                         DEBUG(5, ("Could not load config file: %s\n",
      82             :                                   get_dyn_CONFIGFILE()));
      83         106 :                 } else if (home) {
      84           0 :                         char *conf;
      85             :                         /*
      86             :                          * We loaded the global config file.  Now lets
      87             :                          * load user-specific modifications to the
      88             :                          * global config.
      89             :                          */
      90         106 :                         if (asprintf(&conf,
      91             :                                      "%s/.smb/smb.conf.append",
      92             :                                      home) > 0) {
      93         106 :                                 if (!lp_load_client_no_reinit(conf)) {
      94         106 :                                         DEBUG(10,
      95             :                                               ("Could not append config file: "
      96             :                                                "%s\n",
      97             :                                                conf));
      98             :                                 }
      99         106 :                                 SAFE_FREE(conf);
     100             :                         }
     101             :                 }
     102             :         }
     103             : 
     104         106 :         load_interfaces();  /* Load the list of interfaces ... */
     105             : 
     106         106 :         reopen_logs();  /* Get logging working ... */
     107             : 
     108             :         /*
     109             :          * Block SIGPIPE (from lib/util_sock.c: write())
     110             :          * It is not needed and should not stop execution
     111             :          */
     112         106 :         BlockSignals(True, SIGPIPE);
     113             : 
     114             :         /* Create the mutex we'll use to protect initialized_ctx_count */
     115         106 :         if (SMB_THREAD_CREATE_MUTEX("initialized_ctx_count_mutex",
     116           0 :                                     initialized_ctx_count_mutex) != 0) {
     117           0 :                 smb_panic("SMBC_module_init: "
     118             :                           "failed to create 'initialized_ctx_count' mutex");
     119             :         }
     120             : 
     121         106 :         TALLOC_FREE(frame);
     122         106 : }
     123             : 
     124             : 
     125             : static void
     126          40 : SMBC_module_terminate(void)
     127             : {
     128          40 :         TALLOC_CTX *frame = talloc_stackframe();
     129          40 :         secrets_shutdown();
     130          40 :         gfree_all();
     131          40 :         SMBC_initialized = false;
     132          40 :         TALLOC_FREE(frame);
     133          40 : }
     134             : 
     135             : 
     136             : /*
     137             :  * Get a new empty handle to fill in with your own info
     138             :  */
     139             : SMBCCTX *
     140         106 : smbc_new_context(void)
     141             : {
     142           0 :         SMBCCTX *context;
     143         106 :         TALLOC_CTX *frame = talloc_stackframe();
     144             : 
     145             :         /* The first call to this function should initialize the module */
     146         106 :         SMB_THREAD_ONCE(&SMBC_initialized, SMBC_module_init, NULL);
     147             : 
     148             :         /*
     149             :          * All newly added context fields should be placed in
     150             :          * SMBC_internal_data, not directly in SMBCCTX.
     151             :          */
     152         106 :         context = SMB_MALLOC_P(SMBCCTX);
     153         106 :         if (!context) {
     154           0 :                 TALLOC_FREE(frame);
     155           0 :                 errno = ENOMEM;
     156           0 :                 return NULL;
     157             :         }
     158             : 
     159         106 :         ZERO_STRUCTP(context);
     160             : 
     161         106 :         context->internal = SMB_MALLOC_P(struct SMBC_internal_data);
     162         106 :         if (!context->internal) {
     163           0 :                 TALLOC_FREE(frame);
     164           0 :                 SAFE_FREE(context);
     165           0 :                 errno = ENOMEM;
     166           0 :                 return NULL;
     167             :         }
     168             : 
     169             :         /* Initialize the context and establish reasonable defaults */
     170         106 :         ZERO_STRUCTP(context->internal);
     171             : 
     172         106 :         context->internal->lp_ctx = loadparm_init_s3(NULL,
     173             :                                                      loadparm_s3_helpers());
     174         106 :         if (context->internal->lp_ctx == NULL) {
     175           0 :                 SAFE_FREE(context->internal);
     176           0 :                 SAFE_FREE(context);
     177           0 :                 TALLOC_FREE(frame);
     178           0 :                 errno = ENOMEM;
     179           0 :                 return NULL;
     180             :         }
     181             : 
     182         106 :         smbc_setDebug(context, 0);
     183         106 :         smbc_setTimeout(context, 20000);
     184         106 :         smbc_setPort(context, 0);
     185             : 
     186         106 :         smbc_setOptionFullTimeNames(context, False);
     187         106 :         smbc_setOptionOpenShareMode(context, SMBC_SHAREMODE_DENY_NONE);
     188         106 :         smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_DEFAULT);
     189         106 :         smbc_setOptionUseCCache(context, True);
     190         106 :         smbc_setOptionCaseSensitive(context, False);
     191         106 :         smbc_setOptionBrowseMaxLmbCount(context, 3);    /* # LMBs to query */
     192         106 :         smbc_setOptionUrlEncodeReaddirEntries(context, False);
     193         106 :         smbc_setOptionOneSharePerServer(context, False);
     194         106 :         smbc_setOptionPosixExtensions(context, false);
     195         106 :         if (getenv("LIBSMBCLIENT_NO_CCACHE") != NULL) {
     196           0 :                 smbc_setOptionUseCCache(context, false);
     197             :         }
     198             : 
     199         106 :         smbc_setFunctionAuthData(context, SMBC_get_auth_data);
     200         106 :         smbc_setFunctionCheckServer(context, SMBC_check_server);
     201         106 :         smbc_setFunctionRemoveUnusedServer(context, SMBC_remove_unused_server);
     202             : 
     203         106 :         smbc_setOptionUserData(context, NULL);
     204         106 :         smbc_setFunctionAddCachedServer(context, SMBC_add_cached_server);
     205         106 :         smbc_setFunctionGetCachedServer(context, SMBC_get_cached_server);
     206         106 :         smbc_setFunctionRemoveCachedServer(context, SMBC_remove_cached_server);
     207         106 :         smbc_setFunctionPurgeCachedServers(context, SMBC_purge_cached_servers);
     208             : 
     209         106 :         smbc_setFunctionOpen(context, SMBC_open_ctx);
     210         106 :         smbc_setFunctionCreat(context, SMBC_creat_ctx);
     211         106 :         smbc_setFunctionRead(context, SMBC_read_ctx);
     212         106 :         smbc_setFunctionSplice(context, SMBC_splice_ctx);
     213         106 :         smbc_setFunctionWrite(context, SMBC_write_ctx);
     214         106 :         smbc_setFunctionClose(context, SMBC_close_ctx);
     215         106 :         smbc_setFunctionUnlink(context, SMBC_unlink_ctx);
     216         106 :         smbc_setFunctionRename(context, SMBC_rename_ctx);
     217         106 :         smbc_setFunctionLseek(context, SMBC_lseek_ctx);
     218         106 :         smbc_setFunctionFtruncate(context, SMBC_ftruncate_ctx);
     219         106 :         smbc_setFunctionStat(context, SMBC_stat_ctx);
     220         106 :         smbc_setFunctionStatVFS(context, SMBC_statvfs_ctx);
     221         106 :         smbc_setFunctionFstatVFS(context, SMBC_fstatvfs_ctx);
     222         106 :         smbc_setFunctionFstat(context, SMBC_fstat_ctx);
     223         106 :         smbc_setFunctionOpendir(context, SMBC_opendir_ctx);
     224         106 :         smbc_setFunctionClosedir(context, SMBC_closedir_ctx);
     225         106 :         smbc_setFunctionReaddir(context, SMBC_readdir_ctx);
     226         106 :         smbc_setFunctionReaddirPlus(context, SMBC_readdirplus_ctx);
     227         106 :         smbc_setFunctionReaddirPlus2(context, SMBC_readdirplus2_ctx);
     228         106 :         smbc_setFunctionGetdents(context, SMBC_getdents_ctx);
     229         106 :         smbc_setFunctionMkdir(context, SMBC_mkdir_ctx);
     230         106 :         smbc_setFunctionRmdir(context, SMBC_rmdir_ctx);
     231         106 :         smbc_setFunctionTelldir(context, SMBC_telldir_ctx);
     232         106 :         smbc_setFunctionLseekdir(context, SMBC_lseekdir_ctx);
     233         106 :         smbc_setFunctionFstatdir(context, SMBC_fstatdir_ctx);
     234         106 :         smbc_setFunctionNotify(context, SMBC_notify_ctx);
     235         106 :         smbc_setFunctionChmod(context, SMBC_chmod_ctx);
     236         106 :         smbc_setFunctionUtimes(context, SMBC_utimes_ctx);
     237         106 :         smbc_setFunctionSetxattr(context, SMBC_setxattr_ctx);
     238         106 :         smbc_setFunctionGetxattr(context, SMBC_getxattr_ctx);
     239         106 :         smbc_setFunctionRemovexattr(context, SMBC_removexattr_ctx);
     240         106 :         smbc_setFunctionListxattr(context, SMBC_listxattr_ctx);
     241             : 
     242         106 :         smbc_setFunctionOpenPrintJob(context, SMBC_open_print_job_ctx);
     243         106 :         smbc_setFunctionPrintFile(context, SMBC_print_file_ctx);
     244         106 :         smbc_setFunctionListPrintJobs(context, SMBC_list_print_jobs_ctx);
     245         106 :         smbc_setFunctionUnlinkPrintJob(context, SMBC_unlink_print_job_ctx);
     246             : 
     247         106 :         TALLOC_FREE(frame);
     248         106 :         return context;
     249             : }
     250             : 
     251             : /*
     252             :  * Free a context
     253             :  *
     254             :  * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed
     255             :  * and thus you'll be leaking memory if not handled properly.
     256             :  *
     257             :  */
     258             : int
     259          40 : smbc_free_context(SMBCCTX *context,
     260             :                   int shutdown_ctx)
     261             : {
     262           0 :         TALLOC_CTX *frame;
     263          40 :         if (!context) {
     264           0 :                 errno = EBADF;
     265           0 :                 return 1;
     266             :         }
     267             : 
     268          40 :         frame = talloc_stackframe();
     269             : 
     270          40 :         if (shutdown_ctx) {
     271           0 :                 SMBCFILE * f;
     272          40 :                 DEBUG(1,("Performing aggressive shutdown.\n"));
     273             : 
     274          40 :                 f = context->internal->files;
     275          42 :                 while (f) {
     276           2 :                         SMBCFILE *next = f->next;
     277           2 :                         smbc_getFunctionClose(context)(context, f);
     278           2 :                         f = next;
     279             :                 }
     280          40 :                 context->internal->files = NULL;
     281             : 
     282             :                 /* First try to remove the servers the nice way. */
     283          40 :                 if (smbc_getFunctionPurgeCachedServers(context)(context)) {
     284           0 :                         SMBCSRV * s;
     285           0 :                         SMBCSRV * next;
     286           0 :                         DEBUG(1, ("Could not purge all servers, "
     287             :                                   "Nice way shutdown failed.\n"));
     288           0 :                         s = context->internal->servers;
     289           0 :                         while (s) {
     290           0 :                                 DEBUG(1, ("Forced shutdown: %p (cli=%p)\n",
     291             :                                           s, s->cli));
     292           0 :                                 cli_shutdown(s->cli);
     293           0 :                                 smbc_getFunctionRemoveCachedServer(context)(context,
     294             :                                                                          s);
     295           0 :                                 next = s->next;
     296           0 :                                 DLIST_REMOVE(context->internal->servers, s);
     297           0 :                                 SAFE_FREE(s);
     298           0 :                                 s = next;
     299             :                         }
     300           0 :                         context->internal->servers = NULL;
     301             :                 }
     302             :         }
     303             :         else {
     304             :                 /* This is the polite way */
     305           0 :                 if (smbc_getFunctionPurgeCachedServers(context)(context)) {
     306           0 :                         DEBUG(1, ("Could not purge all servers, "
     307             :                                   "free_context failed.\n"));
     308           0 :                         errno = EBUSY;
     309           0 :                         TALLOC_FREE(frame);
     310           0 :                         return 1;
     311             :                 }
     312           0 :                 if (context->internal->servers) {
     313           0 :                         DEBUG(1, ("Active servers in context, "
     314             :                                   "free_context failed.\n"));
     315           0 :                         errno = EBUSY;
     316           0 :                         TALLOC_FREE(frame);
     317           0 :                         return 1;
     318             :                 }
     319           0 :                 if (context->internal->files) {
     320           0 :                         DEBUG(1, ("Active files in context, "
     321             :                                   "free_context failed.\n"));
     322           0 :                         errno = EBUSY;
     323           0 :                         TALLOC_FREE(frame);
     324           0 :                         return 1;
     325             :                 }
     326             :         }
     327             : 
     328             :         /* Things we have to clean up */
     329          40 :         smbc_setWorkgroup(context, NULL);
     330          40 :         smbc_setNetbiosName(context, NULL);
     331          40 :         smbc_setUser(context, NULL);
     332             : 
     333          40 :         DEBUG(3, ("Context %p successfully freed\n", context));
     334             : 
     335             :         /* Free any DFS auth context. */
     336          40 :         TALLOC_FREE(context->internal->creds);
     337             : 
     338          40 :         TALLOC_FREE(context->internal->lp_ctx);
     339          40 :         SAFE_FREE(context->internal);
     340          40 :         SAFE_FREE(context);
     341             : 
     342             :         /* Protect access to the count of contexts in use */
     343          40 :         if (SMB_THREAD_LOCK(initialized_ctx_count_mutex) != 0) {
     344           0 :                 smb_panic("error locking 'initialized_ctx_count'");
     345             :         }
     346             : 
     347          40 :         if (initialized_ctx_count) {
     348          40 :                 initialized_ctx_count--;
     349             :         }
     350             : 
     351          40 :         if (initialized_ctx_count == 0) {
     352          40 :             SMBC_module_terminate();
     353             :         }
     354             : 
     355             :         /* Unlock the mutex */
     356          40 :         if (SMB_THREAD_UNLOCK(initialized_ctx_count_mutex) != 0) {
     357           0 :                 smb_panic("error unlocking 'initialized_ctx_count'");
     358             :         }
     359             : 
     360          40 :         TALLOC_FREE(frame);
     361          40 :         return 0;
     362             : }
     363             : 
     364             : 
     365             : /**
     366             :  * Deprecated interface.  Do not use.  Instead, use the various
     367             :  * smbc_setOption*() functions or smbc_setFunctionAuthDataWithContext().
     368             :  */
     369             : void
     370           0 : smbc_option_set(SMBCCTX *context,
     371             :                 char *option_name,
     372             :                 ... /* option_value */)
     373             : {
     374           0 :         va_list ap;
     375           0 :         union {
     376             :                 int i;
     377             :                 bool b;
     378             :                 smbc_get_auth_data_with_context_fn auth_fn;
     379             :                 void *v;
     380             :                 const char *s;
     381             :         } option_value;
     382             : 
     383           0 :         TALLOC_CTX *frame = talloc_stackframe();
     384             : 
     385           0 :         va_start(ap, option_name);
     386             : 
     387           0 :         if (strcmp(option_name, "debug_to_stderr") == 0) {
     388           0 :                 option_value.b = (bool) va_arg(ap, int);
     389           0 :                 smbc_setOptionDebugToStderr(context, option_value.b);
     390             : 
     391           0 :         } else if (strcmp(option_name, "full_time_names") == 0) {
     392           0 :                 option_value.b = (bool) va_arg(ap, int);
     393           0 :                 smbc_setOptionFullTimeNames(context, option_value.b);
     394             : 
     395           0 :         } else if (strcmp(option_name, "open_share_mode") == 0) {
     396           0 :                 option_value.i = va_arg(ap, int);
     397           0 :                 smbc_setOptionOpenShareMode(context, option_value.i);
     398             : 
     399           0 :         } else if (strcmp(option_name, "auth_function") == 0) {
     400           0 :                 option_value.auth_fn =
     401           0 :                         va_arg(ap, smbc_get_auth_data_with_context_fn);
     402           0 :                 smbc_setFunctionAuthDataWithContext(context, option_value.auth_fn);
     403             : 
     404           0 :         } else if (strcmp(option_name, "user_data") == 0) {
     405           0 :                 option_value.v = va_arg(ap, void *);
     406           0 :                 smbc_setOptionUserData(context, option_value.v);
     407             : 
     408           0 :         } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
     409           0 :                 option_value.s = va_arg(ap, const char *);
     410           0 :                 if (strcmp(option_value.s, "none") == 0) {
     411           0 :                         smbc_setOptionSmbEncryptionLevel(context,
     412             :                                                          SMBC_ENCRYPTLEVEL_NONE);
     413           0 :                 } else if (strcmp(option_value.s, "request") == 0) {
     414           0 :                         smbc_setOptionSmbEncryptionLevel(context,
     415             :                                                          SMBC_ENCRYPTLEVEL_REQUEST);
     416           0 :                 } else if (strcmp(option_value.s, "require") == 0) {
     417           0 :                         smbc_setOptionSmbEncryptionLevel(context,
     418             :                                                          SMBC_ENCRYPTLEVEL_REQUIRE);
     419             :                 }
     420             : 
     421           0 :         } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
     422           0 :                 option_value.i = va_arg(ap, int);
     423           0 :                 smbc_setOptionBrowseMaxLmbCount(context, option_value.i);
     424             : 
     425           0 :         } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
     426           0 :                 option_value.b = (bool) va_arg(ap, int);
     427           0 :                 smbc_setOptionUrlEncodeReaddirEntries(context, option_value.b);
     428             : 
     429           0 :         } else if (strcmp(option_name, "one_share_per_server") == 0) {
     430           0 :                 option_value.b = (bool) va_arg(ap, int);
     431           0 :                 smbc_setOptionOneSharePerServer(context, option_value.b);
     432             : 
     433           0 :         } else if (strcmp(option_name, "use_kerberos") == 0) {
     434           0 :                 option_value.b = (bool) va_arg(ap, int);
     435           0 :                 smbc_setOptionUseKerberos(context, option_value.b);
     436             : 
     437           0 :         } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
     438           0 :                 option_value.b = (bool) va_arg(ap, int);
     439           0 :                 smbc_setOptionFallbackAfterKerberos(context, option_value.b);
     440             : 
     441           0 :         } else if (strcmp(option_name, "use_ccache") == 0) {
     442           0 :                 option_value.b = (bool) va_arg(ap, int);
     443           0 :                 smbc_setOptionUseCCache(context, option_value.b);
     444             : 
     445           0 :         } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
     446           0 :                 option_value.b = (bool) va_arg(ap, int);
     447           0 :                 smbc_setOptionNoAutoAnonymousLogin(context, option_value.b);
     448             :         }
     449             : 
     450           0 :         va_end(ap);
     451           0 :         TALLOC_FREE(frame);
     452           0 : }
     453             : 
     454             : 
     455             : /*
     456             :  * Deprecated interface.  Do not use.  Instead, use the various
     457             :  * smbc_getOption*() functions.
     458             :  */
     459             : void *
     460           0 : smbc_option_get(SMBCCTX *context,
     461             :                 char *option_name)
     462             : {
     463           0 :         if (strcmp(option_name, "debug_stderr") == 0) {
     464             : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
     465           0 :                 return (void *) (intptr_t) smbc_getOptionDebugToStderr(context);
     466             : #else
     467             :                 return (void *) smbc_getOptionDebugToStderr(context);
     468             : #endif
     469             : 
     470           0 :         } else if (strcmp(option_name, "full_time_names") == 0) {
     471             : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
     472           0 :                 return (void *) (intptr_t) smbc_getOptionFullTimeNames(context);
     473             : #else
     474             :                 return (void *) smbc_getOptionFullTimeNames(context);
     475             : #endif
     476             : 
     477           0 :         } else if (strcmp(option_name, "open_share_mode") == 0) {
     478             : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
     479           0 :                 return (void *) (intptr_t) smbc_getOptionOpenShareMode(context);
     480             : #else
     481             :                 return (void *) smbc_getOptionOpenShareMode(context);
     482             : #endif
     483             : 
     484           0 :         } else if (strcmp(option_name, "auth_function") == 0) {
     485           0 :                 return (void *) smbc_getFunctionAuthDataWithContext(context);
     486             : 
     487           0 :         } else if (strcmp(option_name, "user_data") == 0) {
     488           0 :                 return smbc_getOptionUserData(context);
     489             : 
     490           0 :         } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
     491           0 :                 switch(smbc_getOptionSmbEncryptionLevel(context))
     492             :                 {
     493           0 :                 case SMBC_ENCRYPTLEVEL_DEFAULT:
     494           0 :                         return discard_const_p(void, "default");
     495           0 :                 case 0:
     496           0 :                         return discard_const_p(void, "none");
     497           0 :                 case 1:
     498           0 :                         return discard_const_p(void, "request");
     499           0 :                 case 2:
     500           0 :                         return discard_const_p(void, "require");
     501             :                 }
     502             : 
     503           0 :         } else if (strcmp(option_name, "smb_encrypt_on") == 0) {
     504           0 :                 SMBCSRV *s;
     505           0 :                 unsigned int num_servers = 0;
     506             : 
     507           0 :                 for (s = context->internal->servers; s; s = s->next) {
     508           0 :                         num_servers++;
     509           0 :                         if (!cli_state_is_encryption_on(s->cli)) {
     510           0 :                                 return (void *)false;
     511             :                         }
     512             :                 }
     513             : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
     514           0 :                 return (void *) (intptr_t) (bool) (num_servers > 0);
     515             : #else
     516             :                 return (void *) (bool) (num_servers > 0);
     517             : #endif
     518             : 
     519           0 :         } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
     520             : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
     521           0 :                 return (void *) (intptr_t) smbc_getOptionBrowseMaxLmbCount(context);
     522             : #else
     523             :                 return (void *) smbc_getOptionBrowseMaxLmbCount(context);
     524             : #endif
     525             : 
     526           0 :         } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
     527             : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
     528           0 :                 return (void *)(intptr_t) smbc_getOptionUrlEncodeReaddirEntries(context);
     529             : #else
     530             :                 return (void *) (bool) smbc_getOptionUrlEncodeReaddirEntries(context);
     531             : #endif
     532             : 
     533           0 :         } else if (strcmp(option_name, "one_share_per_server") == 0) {
     534             : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
     535           0 :                 return (void *) (intptr_t) smbc_getOptionOneSharePerServer(context);
     536             : #else
     537             :                 return (void *) (bool) smbc_getOptionOneSharePerServer(context);
     538             : #endif
     539             : 
     540           0 :         } else if (strcmp(option_name, "use_kerberos") == 0) {
     541             : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
     542           0 :                 return (void *) (intptr_t) smbc_getOptionUseKerberos(context);
     543             : #else
     544             :                 return (void *) (bool) smbc_getOptionUseKerberos(context);
     545             : #endif
     546             : 
     547           0 :         } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
     548             : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
     549           0 :                 return (void *)(intptr_t) smbc_getOptionFallbackAfterKerberos(context);
     550             : #else
     551             :                 return (void *) (bool) smbc_getOptionFallbackAfterKerberos(context);
     552             : #endif
     553             : 
     554           0 :         } else if (strcmp(option_name, "use_ccache") == 0) {
     555             : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
     556           0 :                 return (void *) (intptr_t) smbc_getOptionUseCCache(context);
     557             : #else
     558             :                 return (void *) (bool) smbc_getOptionUseCCache(context);
     559             : #endif
     560             : 
     561           0 :         } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
     562             : #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
     563           0 :                 return (void *) (intptr_t) smbc_getOptionNoAutoAnonymousLogin(context);
     564             : #else
     565             :                 return (void *) (bool) smbc_getOptionNoAutoAnonymousLogin(context);
     566             : #endif
     567             :         }
     568             : 
     569           0 :         return NULL;
     570             : }
     571             : 
     572             : 
     573             : /*
     574             :  * Initialize the library, etc.
     575             :  *
     576             :  * We accept a struct containing handle information.
     577             :  * valid values for info->debug from 0 to 100,
     578             :  * and insist that info->fn must be non-null.
     579             :  */
     580             : SMBCCTX *
     581         106 : smbc_init_context(SMBCCTX *context)
     582             : {
     583           0 :         int pid;
     584           0 :         TALLOC_CTX *frame;
     585             : 
     586         106 :         if (!context) {
     587           0 :                 errno = EBADF;
     588           0 :                 return NULL;
     589             :         }
     590             : 
     591             :         /* Do not initialise the same client twice */
     592         106 :         if (context->internal->initialized) {
     593           0 :                 return NULL;
     594             :         }
     595             : 
     596         106 :         frame = talloc_stackframe();
     597             : 
     598         154 :         if ((!smbc_getFunctionAuthData(context) &&
     599         154 :              !smbc_getFunctionAuthDataWithContext(context)) ||
     600         212 :             smbc_getDebug(context) < 0 ||
     601         106 :             smbc_getDebug(context) > 100) {
     602             : 
     603           0 :                 TALLOC_FREE(frame);
     604           0 :                 errno = EINVAL;
     605           0 :                 return NULL;
     606             : 
     607             :         }
     608             : 
     609         106 :         if (!smbc_getUser(context)) {
     610             :                 /*
     611             :                  * FIXME: Is this the best way to get the user info?
     612             :                  */
     613         106 :                 char *user = getenv("USER");
     614             :                 /* walk around as "guest" if no username can be found */
     615         106 :                 if (!user) {
     616           0 :                         user = SMB_STRDUP("guest");
     617             :                 } else {
     618         106 :                         user = SMB_STRDUP(user);
     619             :                 }
     620             : 
     621         106 :                 if (!user) {
     622           0 :                         TALLOC_FREE(frame);
     623           0 :                         errno = ENOMEM;
     624           0 :                         return NULL;
     625             :                 }
     626             : 
     627         106 :                 smbc_setUser(context, user);
     628         106 :                 SAFE_FREE(user);
     629             : 
     630         106 :                 if (!smbc_getUser(context)) {
     631           0 :                         TALLOC_FREE(frame);
     632           0 :                         errno = ENOMEM;
     633           0 :                         return NULL;
     634             :                 }
     635             :         }
     636             : 
     637         106 :         if (!smbc_getNetbiosName(context)) {
     638             :                 /*
     639             :                  * We try to get our netbios name from the config. If that
     640             :                  * fails we fall back on constructing our netbios name from
     641             :                  * our hostname etc
     642             :                  */
     643           0 :                 char *netbios_name;
     644         106 :                 if (lp_netbios_name()) {
     645         106 :                         netbios_name = SMB_STRDUP(lp_netbios_name());
     646             :                 } else {
     647             :                         /*
     648             :                          * Hmmm, I want to get hostname as well, but I am too
     649             :                          * lazy for the moment
     650             :                          */
     651           0 :                         pid = getpid();
     652           0 :                         netbios_name = (char *)SMB_MALLOC(17);
     653           0 :                         if (!netbios_name) {
     654           0 :                                 TALLOC_FREE(frame);
     655           0 :                                 errno = ENOMEM;
     656           0 :                                 return NULL;
     657             :                         }
     658           0 :                         slprintf(netbios_name, 16,
     659             :                                  "smbc%s%d", smbc_getUser(context), pid);
     660             :                 }
     661             : 
     662         106 :                 if (!netbios_name) {
     663           0 :                         TALLOC_FREE(frame);
     664           0 :                         errno = ENOMEM;
     665           0 :                         return NULL;
     666             :                 }
     667             : 
     668         106 :                 smbc_setNetbiosName(context, netbios_name);
     669         106 :                 SAFE_FREE(netbios_name);
     670             : 
     671         106 :                 if (!smbc_getNetbiosName(context)) {
     672           0 :                         TALLOC_FREE(frame);
     673           0 :                         errno = ENOMEM;
     674           0 :                         return NULL;
     675             :                 }
     676             :         }
     677             : 
     678         106 :         DEBUG(1, ("Using netbios name %s.\n", smbc_getNetbiosName(context)));
     679             : 
     680         106 :         if (!smbc_getWorkgroup(context)) {
     681           0 :                 const char *workgroup;
     682             : 
     683         106 :                 if (lp_workgroup()) {
     684         106 :                         workgroup = lp_workgroup();
     685             :                 } else {
     686             :                         /* TODO: Think about a decent default workgroup */
     687           0 :                         workgroup = "samba";
     688             :                 }
     689             : 
     690         106 :                 smbc_setWorkgroup(context, workgroup);
     691             : 
     692         106 :                 if (!smbc_getWorkgroup(context)) {
     693           0 :                         TALLOC_FREE(frame);
     694           0 :                         errno = ENOMEM;
     695           0 :                         return NULL;
     696             :                 }
     697             :         }
     698             : 
     699         106 :         DEBUG(1, ("Using workgroup %s.\n", smbc_getWorkgroup(context)));
     700             : 
     701             :         /* shortest timeout is 1 second */
     702         106 :         if (smbc_getTimeout(context) > 0 && smbc_getTimeout(context) < 1000)
     703           0 :                 smbc_setTimeout(context, 1000);
     704             : 
     705         106 :         context->internal->initialized = True;
     706             : 
     707             :         /* Protect access to the count of contexts in use */
     708         106 :         if (SMB_THREAD_LOCK(initialized_ctx_count_mutex) != 0) {
     709           0 :                 smb_panic("error locking 'initialized_ctx_count'");
     710             :         }
     711             : 
     712         106 :         initialized_ctx_count++;
     713             : 
     714             :         /* Unlock the mutex */
     715         106 :         if (SMB_THREAD_UNLOCK(initialized_ctx_count_mutex) != 0) {
     716           0 :                 smb_panic("error unlocking 'initialized_ctx_count'");
     717             :         }
     718             : 
     719         106 :         TALLOC_FREE(frame);
     720         106 :         return context;
     721             : }
     722             : 
     723             : 
     724             : /* Return the version of samba, and thus libsmbclient */
     725             : const char *
     726           4 : smbc_version(void)
     727             : {
     728           4 :         return samba_version_string();
     729             : }
     730             : 
     731             : /*
     732             :  * Set the credentials so DFS will work when following referrals.
     733             :  * This function is broken and must be removed. No SMBCCTX arg...
     734             :  * JRA.
     735             :  */
     736             : 
     737             : void
     738           0 : smbc_set_credentials(const char *workgroup,
     739             :                         const char *user,
     740             :                         const char *password,
     741             :                         smbc_bool use_kerberos,
     742             :                         const char *signing_state)
     743             : {
     744           0 :         d_printf("smbc_set_credentials is obsolete. Replace with smbc_set_credentials_with_fallback().\n");
     745           0 : }
     746             : 
     747        3187 : void smbc_set_credentials_with_fallback(SMBCCTX *context,
     748             :                                         const char *workgroup,
     749             :                                         const char *user,
     750             :                                         const char *password)
     751             : {
     752        3187 :         struct cli_credentials *creds = NULL;
     753        3187 :         enum credentials_use_kerberos kerberos_state =
     754             :                 CRED_USE_KERBEROS_DISABLED;
     755             : 
     756        3187 :         if (! context) {
     757             : 
     758           0 :                 return;
     759             :         }
     760             : 
     761        3187 :         if (! workgroup || ! *workgroup) {
     762          10 :                 workgroup = smbc_getWorkgroup(context);
     763             :         }
     764             : 
     765        3187 :         if (! user) {
     766           0 :                 user = smbc_getUser(context);
     767             :         }
     768             : 
     769        3187 :         if (! password) {
     770           0 :                 password = "";
     771             :         }
     772             : 
     773        3187 :         creds = cli_credentials_init(NULL);
     774        3187 :         if (creds == NULL) {
     775           0 :                 DEBUG(0, ("smbc_set_credentials_with_fallback: allocation fail\n"));
     776           0 :                 return;
     777             :         }
     778             : 
     779        3187 :         cli_credentials_set_conf(creds, context->internal->lp_ctx);
     780             : 
     781        3187 :         if (smbc_getOptionUseKerberos(context)) {
     782         310 :                 kerberos_state = CRED_USE_KERBEROS_REQUIRED;
     783             : 
     784         310 :                 if (smbc_getOptionFallbackAfterKerberos(context)) {
     785         294 :                         kerberos_state = CRED_USE_KERBEROS_DESIRED;
     786             :                 }
     787             :         }
     788             : 
     789        3187 :         cli_credentials_set_username(creds, user, CRED_SPECIFIED);
     790        3187 :         cli_credentials_set_password(creds, password, CRED_SPECIFIED);
     791        3187 :         cli_credentials_set_domain(creds, workgroup, CRED_SPECIFIED);
     792        3187 :         cli_credentials_set_kerberos_state(creds,
     793             :                                            kerberos_state,
     794             :                                            CRED_SPECIFIED);
     795        3187 :         if (smbc_getOptionUseCCache(context)) {
     796           0 :                 uint32_t gensec_features;
     797             : 
     798        2861 :                 gensec_features = cli_credentials_get_gensec_features(creds);
     799        2861 :                 gensec_features |= GENSEC_FEATURE_NTLM_CCACHE;
     800        2861 :                 cli_credentials_set_gensec_features(creds,
     801             :                                                     gensec_features,
     802             :                                                     CRED_SPECIFIED);
     803             :         }
     804             : 
     805        3187 :         TALLOC_FREE(context->internal->creds);
     806        3187 :         context->internal->creds = creds;
     807             : }

Generated by: LCOV version 1.14