Clear the temporary password buffer before returning.
[usmb.git] / usmb.c
blobd28ae37ae83175a00d5cda92494ff196db63b77d
1 /* usmb - mount SMB shares via FUSE and Samba
2 * Copyright (C) 2006-2008 Geoff Johnstone
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include <sys/time.h> // struct timeval needed by libsmbclient.h
18 #include <unistd.h>
19 #include <libsmbclient.h>
20 #include "samba30-compat.h"
21 #include <fuse.h>
22 #include <assert.h>
23 #include <stdarg.h>
24 #include <stdbool.h>
25 #include <stddef.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include "conffile.h"
30 #include "options.h"
31 #include "usmb.h"
32 #include "usmb_dir.h"
33 #include "usmb_file.h"
34 #include "utils.h"
35 #include "version.h"
38 SMBCCTX *ctx;
39 static char *server, *share, *mountpoint, *options,
40 *domain, *username, *password;
43 char * make_url (const char *path)
45 assert (NULL != share);
47 if ((NULL == path) || ('\0' == path[0]))
48 return xstrdup (share);
49 else
50 return concat_strings (2, share, path);
54 static inline void do_strncpy (char *to, const char *from, int tolen)
56 strncpy (to, from, tolen);
57 to[tolen - 1] = '\0';
61 static void auth_fn (const char *srv UNUSED, const char *shr UNUSED,
62 char *wg, int wglen, char *un, int unlen,
63 char *pw, int pwlen)
65 DEBUG (fprintf (stderr, "Authenticating for \\\\%s\\%s\n", srv, shr));
66 DEBUG (fprintf (stderr, "Domain: %s; User: %s; Password:%s\n",
67 domain, username, password));
69 if (NULL != domain)
70 do_strncpy (wg, domain, wglen);
72 do_strncpy (un, username, unlen);
73 do_strncpy (pw, password, pwlen);
77 static bool create_smb_context (char *domain, char *username, SMBCCTX **pctx)
79 *pctx = smbc_new_context();
81 if (NULL == *pctx)
83 perror ("Cannot create SMB context");
84 return false;
87 smbc_setWorkgroup (*pctx, domain);
88 smbc_setUser (*pctx, username);
89 smbc_setTimeout (*pctx, 5000);
90 smbc_setFunctionAuthData (*pctx, auth_fn);
92 if (NULL == smbc_init_context (*pctx))
94 perror ("Cannot initialise SMB context");
95 smbc_free_context (*pctx, 1);
96 return false;
99 return true;
103 #if 0
104 static int usmb_statfs (const char *path, struct statvfs *vfs)
106 if ((NULL == path) || (NULL == vfs))
107 return -EINVAL;
109 memset (vfs, 0, sizeof (*vfs));
111 vfs->f_bsize = 32768;
112 vfs->f_blocks = 0x7FFFFFFFl;
113 vfs->f_bfree = 0x7FFFFFFFl;
114 vfs->f_bavail = 0x7FFFFFFFl;
116 return 0;
118 #endif
121 static void * usmb_init (struct fuse_conn_info *conn UNUSED)
123 DEBUG (fputs ("usmb_init()\n", stderr));
124 return NULL;
128 static void usmb_destroy (void *unused UNUSED)
130 DEBUG (fputs ("usmb_destroy()\n", stderr));
134 // probably won't (can't ?) implement these:
135 // readlink mknod symlink flush fsync statfs
137 // no easy way of implementing these:
138 // access ftruncate
140 #ifdef __lint
141 #define SET_ELEMENT(name,value) value
142 #else
143 #define SET_ELEMENT(name,value) name = value
144 #endif
145 static struct fuse_operations fuse_ops = {
146 SET_ELEMENT (.getattr, usmb_getattr),
147 SET_ELEMENT (.readlink, NULL),
148 SET_ELEMENT (.getdir, NULL),
149 SET_ELEMENT (.mknod, NULL),
150 SET_ELEMENT (.mkdir, usmb_mkdir),
151 SET_ELEMENT (.unlink, usmb_unlink),
152 SET_ELEMENT (.rmdir, usmb_rmdir),
153 SET_ELEMENT (.symlink, NULL),
154 SET_ELEMENT (.rename, usmb_rename),
155 SET_ELEMENT (.link, NULL),
156 SET_ELEMENT (.chmod, usmb_chmod),
157 SET_ELEMENT (.chown, NULL), // usmb_chown, --not implemented in libsmbclient
158 SET_ELEMENT (.truncate, usmb_truncate),
159 SET_ELEMENT (.utime, usmb_utime),
160 SET_ELEMENT (.open, usmb_open),
161 SET_ELEMENT (.read, usmb_read),
162 SET_ELEMENT (.write, usmb_write),
163 SET_ELEMENT (.statfs, NULL),
164 SET_ELEMENT (.flush, NULL),
165 SET_ELEMENT (.release, usmb_release),
166 SET_ELEMENT (.fsync, NULL),
167 SET_ELEMENT (.setxattr, usmb_setxattr),
168 SET_ELEMENT (.getxattr, usmb_getxattr),
169 SET_ELEMENT (.listxattr, usmb_listxattr),
170 SET_ELEMENT (.removexattr, usmb_removexattr),
171 SET_ELEMENT (.opendir, usmb_opendir),
172 SET_ELEMENT (.readdir, usmb_readdir),
173 SET_ELEMENT (.releasedir, usmb_releasedir),
174 SET_ELEMENT (.fsyncdir, NULL),
175 SET_ELEMENT (.init, usmb_init),
176 SET_ELEMENT (.destroy, usmb_destroy),
177 SET_ELEMENT (.access, NULL),
178 SET_ELEMENT (.create, usmb_create),
179 SET_ELEMENT (.ftruncate, NULL),
180 SET_ELEMENT (.fgetattr, usmb_fgetattr),
181 SET_ELEMENT (.lock, NULL), // TODO: implement
182 SET_ELEMENT (.utimens, NULL), // TODO: implement
183 SET_ELEMENT (.bmap, NULL), // TODO: implement
187 static bool create_share_name (const char *server, const char *sharename)
189 size_t len = strlen ("smb:///") +
190 strlen (server) +
191 strlen (sharename) + 1;
193 if (NULL == (share = malloc (len)))
195 perror ("Cannot allocate share name");
196 return false;
199 snprintf (share, len, "smb://%s/%s", server, sharename);
200 DEBUG (fprintf (stderr, "Share URL: %s\n", share));
201 return true;
205 static void free_strings (char *sharename)
207 xfree (sharename);
208 clear_and_free (password);
209 xfree (username);
210 xfree (domain);
211 xfree (options);
212 xfree (mountpoint);
213 xfree (share);
214 xfree (server);
218 int main (int argc, char **argv)
220 const char *conffile, *mountid;
221 char *sharename = NULL;
223 if (sizeof (uint64_t) < sizeof (uintptr_t))
225 fputs ("usmb is not supported on this platform.\n", stderr);
226 return EXIT_FAILURE;
230 static char conf[256];
231 snprintf (conf, sizeof (conf), "%s/.usmb.conf", getenv ("HOME"));
232 conffile = conf;
235 if (!parse_args (&argc, &argv, &mountid, &conffile))
236 return EXIT_FAILURE;
238 show_about (stdout);
240 if (!conffile_get_mount (conffile, mountid,
241 &server, &sharename, &mountpoint, &options,
242 &domain, &username, &password))
243 return EXIT_FAILURE;
245 if (!create_share_name (server, sharename) ||
246 !create_smb_context (domain, username, &ctx))
248 free_strings (sharename);
249 return EXIT_FAILURE;
252 DEBUG (fprintf (stderr, "Username: %s\\%s\n", domain, username));
254 int fuse_argc;
255 char **fuse_argv;
256 build_fuse_args (options, mountpoint, &fuse_argc, &fuse_argv);
257 int ret = fuse_main (fuse_argc, fuse_argv, &fuse_ops, NULL);
259 smbc_free_context (ctx, 1);
260 free_strings (sharename);
262 return ret;