Modified revamp of the libsmbclient interface.
[jra/samba/.git] / source3 / libsmb / libsmb_context.c
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 int SMBC_initialized = 0;
34
35
36
37 /*
38  * Get a new empty handle to fill in with your own info
39  */
40 SMBCCTX *
41 smbc_new_context(void)
42 {
43     SMBCCTX *context;
44
45     /*
46      * All newly added context fields should be placed in SMBC_internal_data,
47      * not directly in SMBCCTX.
48      */
49 #   undef OLD
50 #   define OLD(field)      context->field
51 #   undef NEW
52 #   define NEW(field)      context->internal->field
53     
54     context = SMB_MALLOC_P(SMBCCTX);
55     if (!context) {
56         errno = ENOMEM;
57         return NULL;
58     }
59     
60     ZERO_STRUCTP(context);
61
62     context->internal = SMB_MALLOC_P(struct SMBC_internal_data);
63     if (!context->internal) {
64         SAFE_FREE(context);
65         errno = ENOMEM;
66         return NULL;
67     }
68
69     /* Initialize the context and establish reasonable defaults */
70     ZERO_STRUCTP(context->internal);
71     
72     OLD(config.debug)              = 0;
73     OLD(config.timeout)            = 20000; /* 20 seconds */
74     
75     NEW(full_time_names)           = False;
76     NEW(share_mode)                = SMBC_SHAREMODE_DENY_NONE;
77     NEW(smb_encryption_level)      = 0;
78     NEW(browse_max_lmb_count)      = 3;    /* # LMBs to query */
79     NEW(urlencode_readdir_entries) = False;
80     NEW(one_share_per_server)      = False;
81     
82     OLD(server.get_auth_data_fn)        = SMBC_get_auth_data;
83     OLD(server.check_server_fn)         = SMBC_check_server;
84     OLD(server.remove_unused_server_fn) = SMBC_remove_unused_server;
85     
86     OLD(cache.server_cache_data)        = NULL;
87     OLD(cache.add_cached_server_fn)     = SMBC_add_cached_server;
88     OLD(cache.get_cached_server_fn)     = SMBC_get_cached_server;
89     OLD(cache.remove_cached_server_fn)  = SMBC_remove_cached_server;
90     OLD(cache.purge_cached_servers_fn)  = SMBC_purge_cached_servers;
91     
92     OLD(posix_emu.open_fn)               = SMBC_open_ctx;
93     OLD(posix_emu.creat_fn)              = SMBC_creat_ctx;
94     OLD(posix_emu.read_fn)               = SMBC_read_ctx;
95     OLD(posix_emu.write_fn)              = SMBC_write_ctx;
96     OLD(posix_emu.close_fn)              = SMBC_close_ctx;
97     OLD(posix_emu.unlink_fn)             = SMBC_unlink_ctx;
98     OLD(posix_emu.rename_fn)             = SMBC_rename_ctx;
99     OLD(posix_emu.lseek_fn)              = SMBC_lseek_ctx;
100     NEW(posix_emu.ftruncate_fn)          = SMBC_ftruncate_ctx;
101     OLD(posix_emu.stat_fn)               = SMBC_stat_ctx;
102     OLD(posix_emu.fstat_fn)              = SMBC_fstat_ctx;
103     OLD(posix_emu.opendir_fn)            = SMBC_opendir_ctx;
104     OLD(posix_emu.closedir_fn)           = SMBC_closedir_ctx;
105     OLD(posix_emu.readdir_fn)            = SMBC_readdir_ctx;
106     OLD(posix_emu.getdents_fn)           = SMBC_getdents_ctx;
107     OLD(posix_emu.mkdir_fn)              = SMBC_mkdir_ctx;
108     OLD(posix_emu.rmdir_fn)              = SMBC_rmdir_ctx;
109     OLD(posix_emu.telldir_fn)            = SMBC_telldir_ctx;
110     OLD(posix_emu.lseekdir_fn)           = SMBC_lseekdir_ctx;
111     OLD(posix_emu.fstatdir_fn)           = SMBC_fstatdir_ctx;
112     OLD(posix_emu.chmod_fn)              = SMBC_chmod_ctx;
113     OLD(posix_emu.utimes_fn)             = SMBC_utimes_ctx;
114     OLD(posix_emu.setxattr_fn)           = SMBC_setxattr_ctx;
115     OLD(posix_emu.getxattr_fn)           = SMBC_getxattr_ctx;
116     OLD(posix_emu.removexattr_fn)        = SMBC_removexattr_ctx;
117     OLD(posix_emu.listxattr_fn)          = SMBC_listxattr_ctx;
118     
119     OLD(printing.open_print_job_fn)      = SMBC_open_print_job_ctx;
120     OLD(printing.print_file_fn)          = SMBC_print_file_ctx;
121     OLD(printing.list_print_jobs_fn)     = SMBC_list_print_jobs_ctx;
122     OLD(printing.unlink_print_job_fn)    = SMBC_unlink_print_job_ctx;
123     
124     return context;
125 #undef OLD
126 #undef NEW
127 }
128
129 /*
130  * Free a context
131  *
132  * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed
133  * and thus you'll be leaking memory if not handled properly.
134  *
135  */
136 int
137 smbc_free_context(SMBCCTX *context,
138                   int shutdown_ctx)
139 {
140     if (!context) {
141         errno = EBADF;
142         return 1;
143     }
144     
145     if (shutdown_ctx) {
146         SMBCFILE * f;
147         DEBUG(1,("Performing aggressive shutdown.\n"));
148         
149         f = context->internal->files;
150         while (f) {
151             (context->posix_emu.close_fn)(context, f);
152             f = f->next;
153         }
154         context->internal->files = NULL;
155         
156         /* First try to remove the servers the nice way. */
157         if (context->cache.purge_cached_servers_fn(context)) {
158             SMBCSRV * s;
159             SMBCSRV * next;
160             DEBUG(1, ("Could not purge all servers, "
161                       "Nice way shutdown failed.\n"));
162             s = context->internal->servers;
163             while (s) {
164                 DEBUG(1, ("Forced shutdown: %p (fd=%d)\n",
165                           s, s->cli->fd));
166                 cli_shutdown(s->cli);
167                 (context->cache.remove_cached_server_fn)(context,
168                                                          s);
169                 next = s->next;
170                 DLIST_REMOVE(context->internal->servers, s);
171                 SAFE_FREE(s);
172                 s = next;
173             }
174             context->internal->servers = NULL;
175         }
176     }
177     else {
178         /* This is the polite way */
179         if ((context->cache.purge_cached_servers_fn)(context)) {
180             DEBUG(1, ("Could not purge all servers, "
181                       "free_context failed.\n"));
182             errno = EBUSY;
183             return 1;
184         }
185         if (context->internal->servers) {
186             DEBUG(1, ("Active servers in context, "
187                       "free_context failed.\n"));
188             errno = EBUSY;
189             return 1;
190         }
191         if (context->internal->files) {
192             DEBUG(1, ("Active files in context, "
193                       "free_context failed.\n"));
194             errno = EBUSY;
195             return 1;
196         }
197     }
198     
199     /* Things we have to clean up */
200     SAFE_FREE(context->config.workgroup);
201     SAFE_FREE(context->config.netbios_name);
202     SAFE_FREE(context->config.user);
203     
204     DEBUG(3, ("Context %p successfully freed\n", context));
205     SAFE_FREE(context);
206     return 0;
207 }
208
209
210 /*
211  * Each time the context structure is changed, we have binary backward
212  * compatibility issues.  Instead of modifying the public portions of the
213  * context structure to add new options, instead, we put them in the internal
214  * portion of the context structure and provide a set function for these new
215  * options.
216  */
217 void
218 smbc_option_set(SMBCCTX *context,
219                 char *option_name,
220                 ... /* option_value */)
221 {
222     va_list ap;
223     union {
224         int i;
225         bool b;
226         smbc_get_auth_data_with_context_fn auth_fn;
227         void *v;
228         const char *s;
229     } option_value;
230     
231     va_start(ap, option_name);
232     
233     if (strcmp(option_name, "debug_to_stderr") == 0) {
234         /*
235          * Log to standard error instead of standard output.
236          */
237         option_value.b = (bool) va_arg(ap, int);
238         context->internal->debug_stderr = option_value.b;
239         
240     } else if (strcmp(option_name, "full_time_names") == 0) {
241         /*
242          * Use new-style time attribute names, e.g. WRITE_TIME rather
243          * than the old-style names such as M_TIME.  This allows also
244          * setting/getting CREATE_TIME which was previously
245          * unimplemented.  (Note that the old C_TIME was supposed to
246          * be CHANGE_TIME but was confused and sometimes referred to
247          * CREATE_TIME.)
248          */
249         option_value.b = (bool) va_arg(ap, int);
250         context->internal->full_time_names = option_value.b;
251         
252     } else if (strcmp(option_name, "open_share_mode") == 0) {
253         /*
254          * The share mode to use for files opened with
255          * SMBC_open_ctx().  The default is SMBC_SHAREMODE_DENY_NONE.
256          */
257         option_value.i = va_arg(ap, int);
258         context->internal->share_mode = (smbc_share_mode) option_value.i;
259         
260     } else if (strcmp(option_name, "user_data") == 0) {
261         /*
262          * Save a user data handle which may be retrieved by the user
263          * with smbc_option_get()
264          */
265         option_value.v = va_arg(ap, void *);
266         context->internal->user_data = option_value.v;
267     } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
268         /*
269          * Save an encoded value for encryption level.
270          * 0 = off, 1 = attempt, 2 = required.
271          */
272         option_value.s = va_arg(ap, const char *);
273         if (strcmp(option_value.s, "none") == 0) {
274             context->internal->smb_encryption_level = 0;
275         } else if (strcmp(option_value.s, "request") == 0) {
276             context->internal->smb_encryption_level = 1;
277         } else if (strcmp(option_value.s, "require") == 0) {
278             context->internal->smb_encryption_level = 2;
279         }
280     } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
281         /*
282          * From how many local master browsers should the list of
283          * workgroups be retrieved?  It can take up to 12 minutes or
284          * longer after a server becomes a local master browser, for
285          * it to have the entire browse list (the list of
286          * workgroups/domains) from an entire network.  Since a client
287          * never knows which local master browser will be found first,
288          * the one which is found first and used to retrieve a browse
289          * list may have an incomplete or empty browse list.  By
290          * requesting the browse list from multiple local master
291          * browsers, a more complete list can be generated.  For small
292          * networks (few workgroups), it is recommended that this
293          * value be set to 0, causing the browse lists from all found
294          * local master browsers to be retrieved and merged.  For
295          * networks with many workgroups, a suitable value for this
296          * variable is probably somewhere around 3. (Default: 3).
297          */
298         option_value.i = va_arg(ap, int);
299         context->internal->browse_max_lmb_count = option_value.i;
300         
301     } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
302         /*
303          * There is a difference in the desired return strings from
304          * smbc_readdir() depending upon whether the filenames are to
305          * be displayed to the user, or whether they are to be
306          * appended to the path name passed to smbc_opendir() to call
307          * a further smbc_ function (e.g. open the file with
308          * smbc_open()).  In the former case, the filename should be
309          * in "human readable" form.  In the latter case, the smbc_
310          * functions expect a URL which must be url-encoded.  Those
311          * functions decode the URL.  If, for example, smbc_readdir()
312          * returned a file name of "abc%20def.txt", passing a path
313          * with this file name attached to smbc_open() would cause
314          * smbc_open to attempt to open the file "abc def.txt" since
315          * the %20 is decoded into a space.
316          *
317          * Set this option to True if the names returned by
318          * smbc_readdir() should be url-encoded such that they can be
319          * passed back to another smbc_ call.  Set it to False if the
320          * names returned by smbc_readdir() are to be presented to the
321          * user.
322          *
323          * For backwards compatibility, this option defaults to False.
324          */
325         option_value.b = (bool) va_arg(ap, int);
326         context->internal->urlencode_readdir_entries = option_value.b;
327         
328     } else if (strcmp(option_name, "one_share_per_server") == 0) {
329         /*
330          * Some Windows versions appear to have a limit to the number
331          * of concurrent SESSIONs and/or TREE CONNECTions.  In
332          * one-shot programs (i.e. the program runs and then quickly
333          * ends, thereby shutting down all connections), it is
334          * probably reasonable to establish a new connection for each
335          * share.  In long-running applications, the limitation can be
336          * avoided by using only a single connection to each server,
337          * and issuing a new TREE CONNECT when the share is accessed.
338          */
339         option_value.b = (bool) va_arg(ap, int);
340         context->options.one_share_per_server = option_value.b;
341         
342     } else if (strcmp(option_name, "use_kerberos") == 0) {
343         option_value.b = (bool) va_arg(ap, int);
344         if (option_value.b) {
345             context->flags.bits |= SMB_CTX_FLAG_USE_KERBEROS;
346         } else {
347             context->flags.bits &= ~SMB_CTX_FLAG_USE_KERBEROS;
348         }
349         
350     } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
351         option_value.b = (bool) va_arg(ap, int);
352         if (option_value.b) {
353             context->flags.bits |= SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS;
354         } else {
355             context->flags.bits &= ~SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS;
356         }
357         
358     } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
359         option_value.b = (bool) va_arg(ap, int);
360         if (option_value.b) {
361             context->flags.bits |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON;
362         } else {
363             context->flags.bits &= ~SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON;
364         }
365     }
366     
367     va_end(ap);
368 }
369
370
371 /*
372  * Retrieve the current value of an option
373  */
374 void *
375 smbc_option_get(SMBCCTX *context,
376                 char *option_name)
377 {
378     int             bits;
379
380     if (strcmp(option_name, "debug_stderr") == 0) {
381         /*
382          * Log to standard error instead of standard output.
383          */
384 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
385         return (void *) (intptr_t) context->internal->debug_stderr;
386 #else
387         return (void *) context->internal->debug_stderr;
388 #endif
389         
390     } else if (strcmp(option_name, "full_time_names") == 0) {
391         /*
392          * Use new-style time attribute names, e.g. WRITE_TIME rather
393          * than the old-style names such as M_TIME.  This allows also
394          * setting/getting CREATE_TIME which was previously
395          * unimplemented.  (Note that the old C_TIME was supposed to
396          * be CHANGE_TIME but was confused and sometimes referred to
397          * CREATE_TIME.)
398          */
399 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
400         return (void *) (intptr_t) context->internal->full_time_names;
401 #else
402         return (void *) context->internal->full_time_names;
403 #endif
404         
405     } else if (strcmp(option_name, "user_data") == 0) {
406         /*
407          * Return the user data handle which was saved by the user
408          * with smbc_option_set()
409          */
410         return context->internal->user_data;
411         
412     } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
413         /*
414          * Return the current smb encrypt negotiate option as a string.
415          */
416         switch (context->internal->smb_encryption_level) {
417         case 0:
418             return (void *) "none";
419         case 1:
420             return (void *) "request";
421         case 2:
422             return (void *) "require";
423         }
424         
425     } else if (strcmp(option_name, "smb_encrypt_on") == 0) {
426         /*
427          * Return the current smb encrypt status option as a bool.
428          * false = off, true = on. We don't know what server is
429          * being requested, so we only return true if all servers
430          * are using an encrypted connection.
431          */
432         SMBCSRV *s;
433         unsigned int num_servers = 0;
434         
435         for (s = context->internal->servers; s; s = s->next) {
436             num_servers++;
437             if (s->cli->trans_enc_state == NULL) {
438                 return (void *)false;
439             }
440         }
441 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
442         return (void *) (intptr_t) (bool) (num_servers > 0);
443 #else
444         return (void *) (bool) (num_servers > 0);
445 #endif
446         
447     } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
448         /*
449          * From how many local master browsers should the list of
450          * workgroups be retrieved?  It can take up to 12 minutes or
451          * longer after a server becomes a local master browser, for
452          * it to have the entire browse list (the list of
453          * workgroups/domains) from an entire network.  Since a client
454          * never knows which local master browser will be found first,
455          * the one which is found first and used to retrieve a browse
456          * list may have an incomplete or empty browse list.  By
457          * requesting the browse list from multiple local master
458          * browsers, a more complete list can be generated.  For small
459          * networks (few workgroups), it is recommended that this
460          * value be set to 0, causing the browse lists from all found
461          * local master browsers to be retrieved and merged.  For
462          * networks with many workgroups, a suitable value for this
463          * variable is probably somewhere around 3. (Default: 3).
464          */
465 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
466         return (void *) (intptr_t) context->internal->browse_max_lmb_count;
467 #else
468         return (void *) context->internal->browse_max_lmb_count;
469 #endif
470         
471     } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
472         /*
473          * There is a difference in the desired return strings from
474          * smbc_readdir() depending upon whether the filenames are to
475          * be displayed to the user, or whether they are to be
476          * appended to the path name passed to smbc_opendir() to call
477          * a further smbc_ function (e.g. open the file with
478          * smbc_open()).  In the former case, the filename should be
479          * in "human readable" form.  In the latter case, the smbc_
480          * functions expect a URL which must be url-encoded.  Those
481          * functions decode the URL.  If, for example, smbc_readdir()
482          * returned a file name of "abc%20def.txt", passing a path
483          * with this file name attached to smbc_open() would cause
484          * smbc_open to attempt to open the file "abc def.txt" since
485          * the %20 is decoded into a space.
486          *
487          * Set this option to True if the names returned by
488          * smbc_readdir() should be url-encoded such that they can be
489          * passed back to another smbc_ call.  Set it to False if the
490          * names returned by smbc_readdir() are to be presented to the
491          * user.
492          *
493          * For backwards compatibility, this option defaults to False.
494          */
495 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
496         return (void *)(intptr_t) context->internal->urlencode_readdir_entries;
497 #else
498         return (void *) (bool) context->internal->urlencode_readdir_entries;
499 #endif
500         
501     } else if (strcmp(option_name, "one_share_per_server") == 0) {
502         /*
503          * Some Windows versions appear to have a limit to the number
504          * of concurrent SESSIONs and/or TREE CONNECTions.  In
505          * one-shot programs (i.e. the program runs and then quickly
506          * ends, thereby shutting down all connections), it is
507          * probably reasonable to establish a new connection for each
508          * share.  In long-running applications, the limitation can be
509          * avoided by using only a single connection to each server,
510          * and issuing a new TREE CONNECT when the share is accessed.
511          */
512 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
513         return (void *) (intptr_t) context->internal->one_share_per_server;
514 #else
515         return (void *) (bool) context->internal->one_share_per_server;
516 #endif
517         
518     } else if (strcmp(option_name, "use_kerberos") == 0) {
519         bits = context->flags.bits;
520 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
521         return (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS
522                 ? (void *) (intptr_t) 1
523                 : (void *) (intptr_t) 0);
524 #else
525         return (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS
526                 ? (void *) (bool) 1
527                 : (void *) (bool) 0);
528 #endif
529         
530     } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
531 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
532         return (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS
533                 ? (void *) (intptr_t) 1
534                 : (void *) (intptr_t) 0);
535 #else
536         return (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS
537                 ? (void *) (bool) 1
538                 : (void *) (bool) 0);
539 #endif
540         
541     } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
542 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
543         return (context->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON
544                 ? (void *) (intptr_t) 1
545                 : (void *) (intptr_t) 0);
546 #else
547         return (context->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON
548                 ? (void *) (bool) 1
549                 : (void *) (bool) 0);
550 #endif
551     }
552     
553     return NULL;
554 }
555
556
557 /*
558  * Initialize the library, etc.
559  *
560  * We accept a struct containing handle information.
561  * valid values for info->debug from 0 to 100,
562  * and insist that info->fn must be non-null.
563  */
564 SMBCCTX *
565 smbc_init_context(SMBCCTX *context)
566 {
567     int pid;
568     char *user = NULL;
569     char *home = NULL;
570     extern bool in_client;
571     
572     if (!context) {
573         errno = EBADF;
574         return NULL;
575     }
576     
577     /* Do not initialise the same client twice */
578     if (context->internal->initialized) {
579         return 0;
580     }
581     
582     if (!context->server.get_auth_data_fn ||
583         context->config.debug < 0 ||
584         context->config.debug > 100) {
585         
586         errno = EINVAL;
587         return NULL;
588         
589     }
590     
591     if (!SMBC_initialized) {
592         /*
593          * Do some library-wide intializations the first time we get
594          * called
595          */
596         bool conf_loaded = False;
597         TALLOC_CTX *frame = talloc_stackframe();
598         
599         /* Set this to what the user wants */
600         DEBUGLEVEL = context->config.debug;
601         
602         load_case_tables();
603         
604         setup_logging("libsmbclient", True);
605         if (context->internal->debug_stderr) {
606             dbf = x_stderr;
607             x_setbuf(x_stderr, NULL);
608         }
609         
610         /* Here we would open the smb.conf file if needed ... */
611         
612         in_client = True; /* FIXME, make a param */
613         
614         home = getenv("HOME");
615         if (home) {
616             char *conf = NULL;
617             if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) {
618                 if (lp_load(conf, True, False, False, True)) {
619                     conf_loaded = True;
620                 } else {
621                     DEBUG(5, ("Could not load config file: %s\n",
622                               conf));
623                 }
624                 SAFE_FREE(conf);
625             }
626         }
627         
628         if (!conf_loaded) {
629             /*
630              * Well, if that failed, try the get_dyn_CONFIGFILE
631              * Which points to the standard locn, and if that
632              * fails, silently ignore it and use the internal
633              * defaults ...
634              */
635             
636             if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) {
637                 DEBUG(5, ("Could not load config file: %s\n",
638                           get_dyn_CONFIGFILE()));
639             } else if (home) {
640                 char *conf;
641                 /*
642                  * We loaded the global config file.  Now lets
643                  * load user-specific modifications to the
644                  * global config.
645                  */
646                 if (asprintf(&conf,
647                              "%s/.smb/smb.conf.append",
648                              home) > 0) {
649                     if (!lp_load(conf, True, False, False, False)) {
650                         DEBUG(10,
651                               ("Could not append config file: "
652                                "%s\n",
653                                conf));
654                     }
655                     SAFE_FREE(conf);
656                 }
657             }
658         }
659         
660         load_interfaces();  /* Load the list of interfaces ... */
661         
662         reopen_logs();  /* Get logging working ... */
663         
664         /*
665          * Block SIGPIPE (from lib/util_sock.c: write())
666          * It is not needed and should not stop execution
667          */
668         BlockSignals(True, SIGPIPE);
669         
670         /* Done with one-time initialisation */
671         SMBC_initialized = 1;
672         
673         TALLOC_FREE(frame);
674     }
675     
676     if (!context->config.user) {
677         /*
678          * FIXME: Is this the best way to get the user info?
679          */
680         user = getenv("USER");
681         /* walk around as "guest" if no username can be found */
682         if (!user) context->config.user = SMB_STRDUP("guest");
683         else context->config.user = SMB_STRDUP(user);
684     }
685     
686     if (!context->config.netbios_name) {
687         /*
688          * We try to get our netbios name from the config. If that
689          * fails we fall back on constructing our netbios name from
690          * our hostname etc
691          */
692         if (global_myname()) {
693             context->config.netbios_name = SMB_STRDUP(global_myname());
694         }
695         else {
696             /*
697              * Hmmm, I want to get hostname as well, but I am too
698              * lazy for the moment
699              */
700             pid = sys_getpid();
701             context->config.netbios_name = (char *)SMB_MALLOC(17);
702             if (!context->config.netbios_name) {
703                 errno = ENOMEM;
704                 return NULL;
705             }
706             slprintf(context->config.netbios_name, 16,
707                      "smbc%s%d", context->config.user, pid);
708         }
709     }
710     
711     DEBUG(1, ("Using netbios name %s.\n", context->config.netbios_name));
712     
713     if (!context->config.workgroup) {
714         if (lp_workgroup()) {
715             context->config.workgroup = SMB_STRDUP(lp_workgroup());
716         }
717         else {
718             /* TODO: Think about a decent default workgroup */
719             context->config.workgroup = SMB_STRDUP("samba");
720         }
721     }
722     
723     DEBUG(1, ("Using workgroup %s.\n", context->config.workgroup));
724     
725     /* shortest timeout is 1 second */
726     if (context->config.timeout > 0 && context->config.timeout < 1000)
727         context->config.timeout = 1000;
728     
729     /*
730      * FIXME: Should we check the function pointers here?
731      */
732     
733     context->internal->initialized = True;
734     
735     return context;
736 }
737
738
739 /* Return the verion of samba, and thus libsmbclient */
740 const char *
741 smbc_version(void)
742 {
743     return samba_version_string();
744 }
745
746
747 /** Get the netbios name used for making connections */
748 char *
749 smbc_getNetbiosName(SMBCCTX *c)
750 {
751     return c->config.netbios_name;
752 }
753
754 /** Set the netbios name used for making connections */
755 void
756 smbc_setNetbiosName(SMBCCTX *c, char * netbios_name)
757 {
758     c->config.netbios_name = netbios_name;
759 }
760
761 /** Get the workgroup used for making connections */
762 char *
763 smbc_getWorkgroup(SMBCCTX *c)
764 {
765     return c->config.workgroup;
766 }
767
768 /** Set the workgroup used for making connections */
769 void
770 smbc_setWorkgroup(SMBCCTX *c, char * workgroup)
771 {
772     c->config.workgroup = workgroup;
773 }
774
775 /** Get the username used for making connections */
776 char *
777 smbc_getUser(SMBCCTX *c)
778 {
779     return c->config.user;
780 }
781
782 /** Set the username used for making connections */
783 void
784 smbc_setUser(SMBCCTX *c, char * user)
785 {
786     c->config.user = user;
787 }
788
789 /** Get the debug level */
790 int
791 smbc_getDebug(SMBCCTX *c)
792 {
793     return c->config.debug;
794 }
795
796 /** Set the debug level */
797 void
798 smbc_setDebug(SMBCCTX *c, int debug)
799 {
800     c->config.debug = debug;
801 }
802
803 /**
804  * Get the timeout used for waiting on connections and response data
805  * (in milliseconds)
806  */
807 int
808 smbc_getTimeout(SMBCCTX *c)
809 {
810     return c->config.timeout;
811 }
812
813 /**
814  * Set the timeout used for waiting on connections and response data
815  * (in milliseconds)
816  */
817 void
818 smbc_setTimeout(SMBCCTX *c, int timeout)
819 {
820     c->config.timeout = timeout;
821 }
822
823 /** Get the function for obtaining authentication data */
824
825 smbc_get_auth_data_fn
826 smbc_getFunctionAuthData(SMBCCTX *c)
827 {
828     return c->server.get_auth_data_fn;
829 }
830
831 /** Set the function for obtaining authentication data */
832 void
833 smbc_setFunctionAuthData(SMBCCTX *c, smbc_get_auth_data_fn fn)
834 {
835     c->server.get_auth_data_fn = fn;
836 }
837
838 /** Get the function for checking if a server is still good */
839 smbc_check_server_fn
840 smbc_getFunctionCheckServer(SMBCCTX *c)
841 {
842     return c->server.check_server_fn;
843 }
844
845 /** Set the function for checking if a server is still good */
846 void
847 smbc_setFunctionCheckServer(SMBCCTX *c, smbc_check_server_fn fn)
848 {
849     c->server.check_server_fn = fn;
850 }
851
852 /** Get the function for removing a server if unused */
853 smbc_remove_unused_server_fn
854 smbc_getFunctionRemoveUnusedServer(SMBCCTX *c)
855 {
856     return c->server.remove_unused_server_fn;
857 }
858
859 /** Set the function for removing a server if unused */
860 void
861 smbc_setFunctionRemoveUnusedServer(SMBCCTX *c,
862                                    smbc_remove_unused_server_fn fn)
863 {
864     c->server.remove_unused_server_fn = fn;
865 }
866
867 /** Get the function to store private data of the server cache */
868 struct
869 smbc_server_cache * smbc_getServerCacheData(SMBCCTX *c)
870 {
871     return c->cache.server_cache_data;
872 }
873
874 /** Set the function to store private data of the server cache */
875 void
876 smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache)
877 {
878     c->cache.server_cache_data = cache;
879 }
880
881
882 /** Get the function for adding a cached server */
883 smbc_add_cached_srv_fn
884 smbc_getFunctionAddCachedServer(SMBCCTX *c)
885 {
886     return c->cache.add_cached_server_fn;
887 }
888
889 /** Set the function for adding a cached server */
890 void
891 smbc_setFunctionAddCachedServer(SMBCCTX *c, smbc_add_cached_srv_fn fn)
892 {
893     c->cache.add_cached_server_fn = fn;
894 }
895
896 /** Get the function for server cache lookup */
897 smbc_get_cached_srv_fn
898 smbc_getFunctionGetCachedServer(SMBCCTX *c)
899 {
900     return c->cache.get_cached_server_fn;
901 }
902
903 /** Set the function for server cache lookup */
904 void
905 smbc_setFunctionGetCachedServer(SMBCCTX *c, smbc_get_cached_srv_fn fn)
906 {
907     c->cache.get_cached_server_fn = fn;
908 }
909
910 /** Get the function for server cache removal */
911 smbc_remove_cached_srv_fn
912 smbc_getFunctionRemoveCachedServer(SMBCCTX *c)
913 {
914     return c->cache.remove_cached_server_fn;
915 }
916
917 /** Set the function for server cache removal */
918 void
919 smbc_setFunctionRemoveCachedServer(SMBCCTX *c,
920                                    smbc_remove_cached_srv_fn fn)
921 {
922     c->cache.remove_cached_server_fn = fn;
923 }
924
925 /**
926  * Get the function for server cache purging.  This function tries to
927  * remove all cached servers (e.g. on disconnect)
928  */
929 smbc_purge_cached_srv_fn
930 smbc_getFunctionPurgeCachedServers(SMBCCTX *c)
931 {
932     return c->cache.purge_cached_servers_fn;
933 }
934
935 /**
936  * Set the function for server cache purging.  This function tries to
937  * remove all cached servers (e.g. on disconnect)
938  */
939 void
940 smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_srv_fn fn)
941 {
942     c->cache.purge_cached_servers_fn = fn;
943 }
944
945 /**
946  * Callable functions for files.
947  */
948
949 smbc_open_fn
950 smbc_getFunctionOpen(SMBCCTX *c)
951 {
952     return c->posix_emu.open_fn;
953 }
954
955 void
956 smbc_setFunctionOpen(SMBCCTX *c, smbc_open_fn fn)
957 {
958     c->posix_emu.open_fn = fn;
959 }
960
961 smbc_creat_fn
962 smbc_getFunctionCreat(SMBCCTX *c)
963 {
964     return c->posix_emu.creat_fn;
965 }
966
967 void
968 smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn fn)
969 {
970     c->posix_emu.creat_fn = fn;
971 }
972
973 smbc_read_fn
974 smbc_getFunctionRead(SMBCCTX *c)
975 {
976     return c->posix_emu.read_fn;
977 }
978
979 void
980 smbc_setFunctionRead(SMBCCTX *c, smbc_read_fn fn)
981 {
982     c->posix_emu.read_fn = fn;
983 }
984
985 smbc_write_fn
986 smbc_getFunctionWrite(SMBCCTX *c)
987 {
988     return c->posix_emu.write_fn;
989 }
990
991 void
992 smbc_setFunctionWrite(SMBCCTX *c, smbc_write_fn fn)
993 {
994     c->posix_emu.write_fn = fn;
995 }
996
997 smbc_unlink_fn
998 smbc_getFunctionUnlink(SMBCCTX *c)
999 {
1000     return c->posix_emu.unlink_fn;
1001 }
1002
1003 void
1004 smbc_setFunctionUnlink(SMBCCTX *c, smbc_unlink_fn fn)
1005 {
1006     c->posix_emu.unlink_fn = fn;
1007 }
1008
1009 smbc_rename_fn
1010 smbc_getFunctionRename(SMBCCTX *c)
1011 {
1012     return c->posix_emu.rename_fn;
1013 }
1014
1015 void
1016 smbc_setFunctionRename(SMBCCTX *c, smbc_rename_fn fn)
1017 {
1018     c->posix_emu.rename_fn = fn;
1019 }
1020
1021 smbc_lseek_fn
1022 smbc_getFunctionLseek(SMBCCTX *c)
1023 {
1024     return c->posix_emu.lseek_fn;
1025 }
1026
1027 void
1028 smbc_setFunctionLseek(SMBCCTX *c, smbc_lseek_fn fn)
1029 {
1030     c->posix_emu.lseek_fn = fn;
1031 }
1032
1033 smbc_stat_fn
1034 smbc_getFunctionStat(SMBCCTX *c)
1035 {
1036     return c->posix_emu.stat_fn;
1037 }
1038
1039 void
1040 smbc_setFunctionStat(SMBCCTX *c, smbc_stat_fn fn)
1041 {
1042     c->posix_emu.stat_fn = fn;
1043 }
1044
1045 smbc_fstat_fn
1046 smbc_getFunctionFstat(SMBCCTX *c)
1047 {
1048     return c->posix_emu.fstat_fn;
1049 }
1050
1051 void
1052 smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn)
1053 {
1054     c->posix_emu.fstat_fn = fn;
1055 }
1056
1057 smbc_ftruncate_fn
1058 smbc_getFunctionFtruncate(SMBCCTX *c)
1059 {
1060     return c->internal->posix_emu.ftruncate_fn;
1061 }
1062
1063 void
1064 smbc_setFunctionFtruncate(SMBCCTX *c, smbc_ftruncate_fn fn)
1065 {
1066     c->internal->posix_emu.ftruncate_fn = fn;
1067 }
1068
1069 smbc_close_fn
1070 smbc_getFunctionClose(SMBCCTX *c)
1071 {
1072     return c->posix_emu.close_fn;
1073 }
1074
1075 void
1076 smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn)
1077 {
1078     c->posix_emu.close_fn = fn;
1079 }
1080
1081
1082 /**
1083  * Callable functions for directories.
1084  */
1085
1086 smbc_opendir_fn
1087 smbc_getFunctionOpendir(SMBCCTX *c)
1088 {
1089     return c->posix_emu.opendir_fn;
1090 }
1091
1092 void
1093 smbc_setFunctionOpendir(SMBCCTX *c, smbc_opendir_fn fn)
1094 {
1095     c->posix_emu.opendir_fn = fn;
1096 }
1097
1098 smbc_closedir_fn
1099 smbc_getFunctionClosedir(SMBCCTX *c)
1100 {
1101     return c->posix_emu.closedir_fn;
1102 }
1103
1104 void
1105 smbc_setFunctionClosedir(SMBCCTX *c, smbc_closedir_fn fn)
1106 {
1107     c->posix_emu.closedir_fn = fn;
1108 }
1109
1110 smbc_readdir_fn
1111 smbc_getFunctionReaddir(SMBCCTX *c)
1112 {
1113     return c->posix_emu.readdir_fn;
1114 }
1115
1116 void
1117 smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn)
1118 {
1119     c->posix_emu.readdir_fn = fn;
1120 }
1121
1122 smbc_getdents_fn
1123 smbc_getFunctionGetdents(SMBCCTX *c)
1124 {
1125     return c->posix_emu.getdents_fn;
1126 }
1127
1128 void
1129 smbc_setFunctionGetdents(SMBCCTX *c, smbc_getdents_fn fn)
1130 {
1131     c->posix_emu.getdents_fn = fn;
1132 }
1133
1134 smbc_mkdir_fn
1135 smbc_getFunctionMkdir(SMBCCTX *c)
1136 {
1137     return c->posix_emu.mkdir_fn;
1138 }
1139
1140 void
1141 smbc_setFunctionMkdir(SMBCCTX *c, smbc_mkdir_fn fn)
1142 {
1143     c->posix_emu.mkdir_fn = fn;
1144 }
1145
1146 smbc_rmdir_fn
1147 smbc_getFunctionRmdir(SMBCCTX *c)
1148 {
1149     return c->posix_emu.rmdir_fn;
1150 }
1151
1152 void
1153 smbc_setFunctionRmdir(SMBCCTX *c, smbc_rmdir_fn fn)
1154 {
1155     c->posix_emu.rmdir_fn = fn;
1156 }
1157
1158 smbc_telldir_fn
1159 smbc_getFunctionTelldir(SMBCCTX *c)
1160 {
1161     return c->posix_emu.telldir_fn;
1162 }
1163
1164 void
1165 smbc_setFunctionTelldir(SMBCCTX *c, smbc_telldir_fn fn)
1166 {
1167     c->posix_emu.telldir_fn = fn;
1168 }
1169
1170 smbc_lseekdir_fn
1171 smbc_getFunctionLseekdir(SMBCCTX *c)
1172 {
1173     return c->posix_emu.lseekdir_fn;
1174 }
1175
1176 void
1177 smbc_setFunctionLseekdir(SMBCCTX *c, smbc_lseekdir_fn fn)
1178 {
1179     c->posix_emu.lseekdir_fn = fn;
1180 }
1181
1182 smbc_fstatdir_fn
1183 smbc_getFunctionFstatdir(SMBCCTX *c)
1184 {
1185     return c->posix_emu.fstatdir_fn;
1186 }
1187
1188 void
1189 smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn)
1190 {
1191     c->posix_emu.fstatdir_fn = fn;
1192 }
1193
1194
1195 /**
1196  * Callable functions applicable to both files and directories.
1197  */
1198
1199 smbc_chmod_fn
1200 smbc_getFunctionChmod(SMBCCTX *c)
1201 {
1202     return c->posix_emu.chmod_fn;
1203 }
1204
1205 void
1206 smbc_setFunctionChmod(SMBCCTX *c, smbc_chmod_fn fn)
1207 {
1208     c->posix_emu.chmod_fn = fn;
1209 }
1210
1211 smbc_utimes_fn
1212 smbc_getFunctionUtimes(SMBCCTX *c)
1213 {
1214     return c->posix_emu.utimes_fn;
1215 }
1216
1217 void
1218 smbc_setFunctionUtimes(SMBCCTX *c, smbc_utimes_fn fn)
1219 {
1220     c->posix_emu.utimes_fn = fn;
1221 }
1222
1223 smbc_setxattr_fn
1224 smbc_getFunctionSetxattr(SMBCCTX *c)
1225 {
1226     return c->posix_emu.setxattr_fn;
1227 }
1228
1229 void
1230 smbc_setFunctionSetxattr(SMBCCTX *c, smbc_setxattr_fn fn)
1231 {
1232     c->posix_emu.setxattr_fn = fn;
1233 }
1234
1235 smbc_getxattr_fn
1236 smbc_getFunctionGetxattr(SMBCCTX *c)
1237 {
1238     return c->posix_emu.getxattr_fn;
1239 }
1240
1241 void
1242 smbc_setFunctionGetxattr(SMBCCTX *c, smbc_getxattr_fn fn)
1243 {
1244     c->posix_emu.getxattr_fn = fn;
1245 }
1246
1247 smbc_removexattr_fn
1248 smbc_getFunctionRemovexattr(SMBCCTX *c)
1249 {
1250     return c->posix_emu.removexattr_fn;
1251 }
1252
1253 void
1254 smbc_setFunctionRemovexattr(SMBCCTX *c, smbc_removexattr_fn fn)
1255 {
1256     c->posix_emu.removexattr_fn = fn;
1257 }
1258
1259 smbc_listxattr_fn
1260 smbc_getFunctionListxattr(SMBCCTX *c)
1261 {
1262     return c->posix_emu.listxattr_fn;
1263 }
1264
1265 void
1266 smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn)
1267 {
1268     c->posix_emu.listxattr_fn = fn;
1269 }
1270
1271
1272 /**
1273  * Callable functions related to printing
1274  */
1275
1276 smbc_print_file_fn
1277 smbc_getFunctionPrintFile(SMBCCTX *c)
1278 {
1279     return c->printing.print_file_fn;
1280 }
1281
1282 void
1283 smbc_setFunctionPrintFile(SMBCCTX *c, smbc_print_file_fn fn)
1284 {
1285     c->printing.print_file_fn = fn;
1286 }
1287
1288 smbc_open_print_job_fn
1289 smbc_getFunctionOpenPrintJob(SMBCCTX *c)
1290 {
1291     return c->printing.open_print_job_fn;
1292 }
1293
1294 void
1295 smbc_setFunctionOpenPrintJob(SMBCCTX *c,
1296                              smbc_open_print_job_fn fn)
1297 {
1298     c->printing.open_print_job_fn = fn;
1299 }
1300
1301 smbc_list_print_jobs_fn
1302 smbc_getFunctionListPrintJobs(SMBCCTX *c)
1303 {
1304     return c->printing.list_print_jobs_fn;
1305 }
1306
1307 void
1308 smbc_setFunctionListPrintJobs(SMBCCTX *c,
1309                               smbc_list_print_jobs_fn fn)
1310 {
1311     c->printing.list_print_jobs_fn = fn;
1312 }
1313
1314 smbc_unlink_print_job_fn
1315 smbc_getFunctionUnlinkPrintJob(SMBCCTX *c)
1316 {
1317     return c->printing.unlink_print_job_fn;
1318 }
1319
1320 void
1321 smbc_setFunctionUnlinkPrintJob(SMBCCTX *c,
1322                                 smbc_unlink_print_job_fn fn)
1323 {
1324     c->printing.unlink_print_job_fn = fn;
1325 }
1326