root/source3/libsmb/libsmb_context.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smbc_new_context
  2. smbc_free_context
  3. smbc_option_set
  4. smbc_option_get
  5. smbc_init_context
  6. smbc_version
  7. smbc_set_credentials
  8. smbc_set_credentials_with_fallback

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

/* [<][>][^][v][top][bottom][index][help] */