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

Generated by: LCOV version 1.13