source: trunk/samba/source/client/smbmount.c@ 77

Last change on this file since 77 was 77, checked in by Paul Smedley, 18 years ago

Update trunk to 3.2.0pre1

File size: 25.2 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 SMBFS mount program
4 Copyright (C) Andrew Tridgell 1999
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include "includes.h"
21
22#include <mntent.h>
23#include <asm/types.h>
24#include <linux/smb_fs.h>
25
26extern BOOL in_client;
27extern pstring user_socket_options;
28extern char *optarg;
29extern int optind;
30
31static pstring credentials;
32static pstring my_netbios_name;
33static pstring password;
34static pstring username;
35static pstring workgroup;
36static pstring mpoint;
37static pstring service;
38static pstring options;
39
40static struct in_addr dest_ip;
41static BOOL have_ip;
42static int smb_port = 0;
43static BOOL got_user;
44static BOOL got_pass;
45static uid_t mount_uid;
46static gid_t mount_gid;
47static int mount_ro;
48static unsigned mount_fmask;
49static unsigned mount_dmask;
50static BOOL use_kerberos;
51/* TODO: Add code to detect smbfs version in kernel */
52static BOOL status32_smbfs = False;
53static BOOL smbfs_has_unicode = False;
54static BOOL smbfs_has_lfs = False;
55
56static void usage(void);
57
58static void exit_parent(int sig)
59{
60 /* parent simply exits when child says go... */
61 exit(0);
62}
63
64static void daemonize(void)
65{
66 int j, status;
67 pid_t child_pid;
68
69 signal( SIGTERM, exit_parent );
70
71 if ((child_pid = sys_fork()) < 0) {
72 DEBUG(0,("could not fork\n"));
73 }
74
75 if (child_pid > 0) {
76 while( 1 ) {
77 j = waitpid( child_pid, &status, 0 );
78 if( j < 0 ) {
79 if( EINTR == errno ) {
80 continue;
81 }
82 status = errno;
83 }
84 break;
85 }
86
87 /* If we get here - the child exited with some error status */
88 if (WIFSIGNALED(status))
89 exit(128 + WTERMSIG(status));
90 else
91 exit(WEXITSTATUS(status));
92 }
93
94 signal( SIGTERM, SIG_DFL );
95 chdir("/");
96}
97
98static void close_our_files(int client_fd)
99{
100 int i;
101 struct rlimit limits;
102
103 getrlimit(RLIMIT_NOFILE,&limits);
104 for (i = 0; i< limits.rlim_max; i++) {
105 if (i == client_fd)
106 continue;
107 close(i);
108 }
109}
110
111static void usr1_handler(int x)
112{
113 return;
114}
115
116
117/*****************************************************
118return a connection to a server
119*******************************************************/
120static struct cli_state *do_connection(char *the_service)
121{
122 struct cli_state *c;
123 struct nmb_name called, calling;
124 char *server_n;
125 struct in_addr ip;
126 pstring server;
127 char *share;
128
129 if (the_service[0] != '\\' || the_service[1] != '\\') {
130 usage();
131 exit(1);
132 }
133
134 pstrcpy(server, the_service+2);
135 share = strchr_m(server,'\\');
136 if (!share) {
137 usage();
138 exit(1);
139 }
140 *share = 0;
141 share++;
142
143 server_n = server;
144
145 make_nmb_name(&calling, my_netbios_name, 0x0);
146 make_nmb_name(&called , server, 0x20);
147
148 again:
149 zero_ip(&ip);
150 if (have_ip) ip = dest_ip;
151
152 /* have to open a new connection */
153 if (!(c=cli_initialise()) || (cli_set_port(c, smb_port) != smb_port) ||
154 !NT_STATUS_IS_OK(cli_connect(c, server_n, &ip))) {
155 DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n));
156 if (c) {
157 cli_shutdown(c);
158 }
159 return NULL;
160 }
161
162 /* SPNEGO doesn't work till we get NTSTATUS error support */
163 /* But it is REQUIRED for kerberos authentication */
164 if(!use_kerberos) c->use_spnego = False;
165
166 /* The kernel doesn't yet know how to sign it's packets */
167 c->sign_info.allow_smb_signing = False;
168
169 /* Use kerberos authentication if specified */
170 c->use_kerberos = use_kerberos;
171
172 if (!cli_session_request(c, &calling, &called)) {
173 char *p;
174 DEBUG(0,("%d: session request to %s failed (%s)\n",
175 sys_getpid(), called.name, cli_errstr(c)));
176 cli_shutdown(c);
177 if ((p=strchr_m(called.name, '.'))) {
178 *p = 0;
179 goto again;
180 }
181 if (strcmp(called.name, "*SMBSERVER")) {
182 make_nmb_name(&called , "*SMBSERVER", 0x20);
183 goto again;
184 }
185 return NULL;
186 }
187
188 DEBUG(4,("%d: session request ok\n", sys_getpid()));
189
190 if (!cli_negprot(c)) {
191 DEBUG(0,("%d: protocol negotiation failed\n", sys_getpid()));
192 cli_shutdown(c);
193 return NULL;
194 }
195
196 if (!got_pass) {
197 char *pass = getpass("Password: ");
198 if (pass) {
199 pstrcpy(password, pass);
200 }
201 }
202
203 /* This should be right for current smbfs. Future versions will support
204 large files as well as unicode and oplocks. */
205 c->capabilities &= ~(CAP_NT_SMBS | CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS);
206 if (!smbfs_has_lfs)
207 c->capabilities &= ~CAP_LARGE_FILES;
208 if (!smbfs_has_unicode)
209 c->capabilities &= ~CAP_UNICODE;
210 if (!status32_smbfs) {
211 c->capabilities &= ~CAP_STATUS32;
212 c->force_dos_errors = True;
213 }
214
215 if (!NT_STATUS_IS_OK(cli_session_setup(c, username,
216 password, strlen(password),
217 password, strlen(password),
218 workgroup))) {
219 /* if a password was not supplied then try again with a
220 null username */
221 if (password[0] || !username[0] ||
222 !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0, workgroup))) {
223 DEBUG(0,("%d: session setup failed: %s\n",
224 sys_getpid(), cli_errstr(c)));
225 cli_shutdown(c);
226 return NULL;
227 }
228 DEBUG(0,("Anonymous login successful\n"));
229 }
230
231 DEBUG(4,("%d: session setup ok\n", sys_getpid()));
232
233 if (!cli_send_tconX(c, share, "?????",
234 password, strlen(password)+1)) {
235 DEBUG(0,("%d: tree connect failed: %s\n",
236 sys_getpid(), cli_errstr(c)));
237 cli_shutdown(c);
238 return NULL;
239 }
240
241 DEBUG(4,("%d: tconx ok\n", sys_getpid()));
242
243 got_pass = True;
244
245 return c;
246}
247
248
249/****************************************************************************
250unmount smbfs (this is a bailout routine to clean up if a reconnect fails)
251 Code blatently stolen from smbumount.c
252 -mhw-
253****************************************************************************/
254static void smb_umount(char *mount_point)
255{
256 int fd;
257 struct mntent *mnt;
258 FILE* mtab;
259 FILE* new_mtab;
260
261 /* Programmers Note:
262 This routine only gets called to the scene of a disaster
263 to shoot the survivors... A connection that was working
264 has now apparently failed. We have an active mount point
265 (presumably) that we need to dump. If we get errors along
266 the way - make some noise, but we are already turning out
267 the lights to exit anyways...
268 */
269 if (umount(mount_point) != 0) {
270 DEBUG(0,("%d: Could not umount %s: %s\n",
271 sys_getpid(), mount_point, strerror(errno)));
272 return;
273 }
274
275 if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) {
276 DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", sys_getpid()));
277 return;
278 }
279
280 close(fd);
281
282 if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
283 DEBUG(0,("%d: Can't open " MOUNTED ": %s\n",
284 sys_getpid(), strerror(errno)));
285 return;
286 }
287
288#define MOUNTED_TMP MOUNTED".tmp"
289
290 if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
291 DEBUG(0,("%d: Can't open " MOUNTED_TMP ": %s\n",
292 sys_getpid(), strerror(errno)));
293 endmntent(mtab);
294 return;
295 }
296
297 while ((mnt = getmntent(mtab)) != NULL) {
298 if (strcmp(mnt->mnt_dir, mount_point) != 0) {
299 addmntent(new_mtab, mnt);
300 }
301 }
302
303 endmntent(mtab);
304
305 if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
306 DEBUG(0,("%d: Error changing mode of %s: %s\n",
307 sys_getpid(), MOUNTED_TMP, strerror(errno)));
308 return;
309 }
310
311 endmntent(new_mtab);
312
313 if (rename(MOUNTED_TMP, MOUNTED) < 0) {
314 DEBUG(0,("%d: Cannot rename %s to %s: %s\n",
315 sys_getpid(), MOUNTED, MOUNTED_TMP, strerror(errno)));
316 return;
317 }
318
319 if (unlink(MOUNTED"~") == -1) {
320 DEBUG(0,("%d: Can't remove "MOUNTED"~", sys_getpid()));
321 return;
322 }
323}
324
325
326/*
327 * Call the smbfs ioctl to install a connection socket,
328 * then wait for a signal to reconnect. Note that we do
329 * not exit after open_sockets() or send_login() errors,
330 * as the smbfs mount would then have no way to recover.
331 */
332static void send_fs_socket(char *the_service, char *mount_point, struct cli_state *c)
333{
334 int fd, closed = 0, res = 1;
335 pid_t parentpid = getppid();
336 struct smb_conn_opt conn_options;
337
338 memset(&conn_options, 0, sizeof(conn_options));
339
340 while (1) {
341 if ((fd = open(mount_point, O_RDONLY)) < 0) {
342 DEBUG(0,("mount.smbfs[%d]: can't open %s\n",
343 sys_getpid(), mount_point));
344 break;
345 }
346
347 conn_options.fd = c->fd;
348 conn_options.protocol = c->protocol;
349 conn_options.case_handling = SMB_CASE_DEFAULT;
350 conn_options.max_xmit = c->max_xmit;
351 conn_options.server_uid = c->vuid;
352 conn_options.tid = c->cnum;
353 conn_options.secmode = c->sec_mode;
354 conn_options.rawmode = 0;
355 conn_options.sesskey = c->sesskey;
356 conn_options.maxraw = 0;
357 conn_options.capabilities = c->capabilities;
358 conn_options.serverzone = c->serverzone/60;
359
360 res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options);
361 if (res != 0) {
362 DEBUG(0,("mount.smbfs[%d]: ioctl failed, res=%d\n",
363 sys_getpid(), res));
364 close(fd);
365 break;
366 }
367
368 if (parentpid) {
369 /* Ok... We are going to kill the parent. Now
370 is the time to break the process group... */
371 setsid();
372 /* Send a signal to the parent to terminate */
373 kill(parentpid, SIGTERM);
374 parentpid = 0;
375 }
376
377 close(fd);
378
379 /* This looks wierd but we are only closing the userspace
380 side, the connection has already been passed to smbfs and
381 it has increased the usage count on the socket.
382
383 If we don't do this we will "leak" sockets and memory on
384 each reconnection we have to make. */
385 c->smb_rw_error = DO_NOT_DO_TDIS;
386 cli_shutdown(c);
387 c = NULL;
388
389 if (!closed) {
390 /* close the name cache so that close_our_files() doesn't steal its FD */
391 namecache_shutdown();
392
393 /* redirect stdout & stderr since we can't know that
394 the library functions we use are using DEBUG. */
395 if ( (fd = open("/dev/null", O_WRONLY)) < 0)
396 DEBUG(2,("mount.smbfs: can't open /dev/null\n"));
397 close_our_files(fd);
398 if (fd >= 0) {
399 dup2(fd, STDOUT_FILENO);
400 dup2(fd, STDERR_FILENO);
401 close(fd);
402 }
403
404 /* here we are no longer interactive */
405 set_remote_machine_name("smbmount", False); /* sneaky ... */
406 setup_logging("mount.smbfs", False);
407 reopen_logs();
408 DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, sys_getpid()));
409
410 closed = 1;
411 }
412
413 /* Wait for a signal from smbfs ... but don't continue
414 until we actually get a new connection. */
415 while (!c) {
416 CatchSignal(SIGUSR1, &usr1_handler);
417 pause();
418 DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid()));
419 c = do_connection(the_service);
420 }
421 }
422
423 smb_umount(mount_point);
424 DEBUG(2,("mount.smbfs[%d]: exit\n", sys_getpid()));
425 exit(1);
426}
427
428
429/**
430 * Mount a smbfs
431 **/
432static void init_mount(void)
433{
434 char mount_point[PATH_MAX+1];
435 pstring tmp;
436 pstring svc2;
437 struct cli_state *c;
438 char *args[20];
439 int i, status;
440
441 if (realpath(mpoint, mount_point) == NULL) {
442 fprintf(stderr, "Could not resolve mount point %s\n", mpoint);
443 return;
444 }
445
446
447 c = do_connection(service);
448 if (!c) {
449 fprintf(stderr,"SMB connection failed\n");
450 exit(1);
451 }
452
453 /*
454 Set up to return as a daemon child and wait in the parent
455 until the child say it's ready...
456 */
457 daemonize();
458
459 pstrcpy(svc2, service);
460 string_replace(svc2, '\\','/');
461 string_replace(svc2, ' ','_');
462
463 memset(args, 0, sizeof(args[0])*20);
464
465 i=0;
466 args[i++] = "smbmnt";
467
468 args[i++] = mount_point;
469 args[i++] = "-s";
470 args[i++] = svc2;
471
472 if (mount_ro) {
473 args[i++] = "-r";
474 }
475 if (mount_uid) {
476 slprintf(tmp, sizeof(tmp)-1, "%d", mount_uid);
477 args[i++] = "-u";
478 args[i++] = smb_xstrdup(tmp);
479 }
480 if (mount_gid) {
481 slprintf(tmp, sizeof(tmp)-1, "%d", mount_gid);
482 args[i++] = "-g";
483 args[i++] = smb_xstrdup(tmp);
484 }
485 if (mount_fmask) {
486 slprintf(tmp, sizeof(tmp)-1, "0%o", mount_fmask);
487 args[i++] = "-f";
488 args[i++] = smb_xstrdup(tmp);
489 }
490 if (mount_dmask) {
491 slprintf(tmp, sizeof(tmp)-1, "0%o", mount_dmask);
492 args[i++] = "-d";
493 args[i++] = smb_xstrdup(tmp);
494 }
495 if (options) {
496 args[i++] = "-o";
497 args[i++] = options;
498 }
499
500 if (sys_fork() == 0) {
501 char *smbmnt_path;
502
503 asprintf(&smbmnt_path, "%s/smbmnt", dyn_BINDIR);
504
505 if (file_exist(smbmnt_path, NULL)) {
506 execv(smbmnt_path, args);
507 fprintf(stderr,
508 "smbfs/init_mount: execv of %s failed. Error was %s.",
509 smbmnt_path, strerror(errno));
510 } else {
511 execvp("smbmnt", args);
512 fprintf(stderr,
513 "smbfs/init_mount: execv of %s failed. Error was %s.",
514 "smbmnt", strerror(errno));
515 }
516 free(smbmnt_path);
517 exit(1);
518 }
519
520 if (waitpid(-1, &status, 0) == -1) {
521 fprintf(stderr,"waitpid failed: Error was %s", strerror(errno) );
522 /* FIXME: do some proper error handling */
523 exit(1);
524 }
525
526 if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
527 fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status));
528 /* FIXME: do some proper error handling */
529 exit(1);
530 } else if (WIFSIGNALED(status)) {
531 fprintf(stderr, "smbmnt killed by signal %d\n", WTERMSIG(status));
532 exit(1);
533 }
534
535 /* Ok... This is the rubicon for that mount point... At any point
536 after this, if the connections fail and can not be reconstructed
537 for any reason, we will have to unmount the mount point. There
538 is no exit from the next call...
539 */
540 send_fs_socket(service, mount_point, c);
541}
542
543
544/****************************************************************************
545get a password from a a file or file descriptor
546exit on failure (from smbclient, move to libsmb or shared .c file?)
547****************************************************************************/
548static void get_password_file(void)
549{
550 int fd = -1;
551 char *p;
552 BOOL close_it = False;
553 pstring spec;
554 char pass[128];
555
556 if ((p = getenv("PASSWD_FD")) != NULL) {
557 pstrcpy(spec, "descriptor ");
558 pstrcat(spec, p);
559 sscanf(p, "%d", &fd);
560 close_it = False;
561 } else if ((p = getenv("PASSWD_FILE")) != NULL) {
562 fd = sys_open(p, O_RDONLY, 0);
563 pstrcpy(spec, p);
564 if (fd < 0) {
565 fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
566 spec, strerror(errno));
567 exit(1);
568 }
569 close_it = True;
570 }
571
572 for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
573 p && p - pass < sizeof(pass);) {
574 switch (read(fd, p, 1)) {
575 case 1:
576 if (*p != '\n' && *p != '\0') {
577 *++p = '\0'; /* advance p, and null-terminate pass */
578 break;
579 }
580 case 0:
581 if (p - pass) {
582 *p = '\0'; /* null-terminate it, just in case... */
583 p = NULL; /* then force the loop condition to become false */
584 break;
585 } else {
586 fprintf(stderr, "Error reading password from file %s: %s\n",
587 spec, "empty password\n");
588 exit(1);
589 }
590
591 default:
592 fprintf(stderr, "Error reading password from file %s: %s\n",
593 spec, strerror(errno));
594 exit(1);
595 }
596 }
597 pstrcpy(password, pass);
598 if (close_it)
599 close(fd);
600}
601
602/****************************************************************************
603get username and password from a credentials file
604exit on failure (from smbclient, move to libsmb or shared .c file?)
605****************************************************************************/
606static void read_credentials_file(char *filename)
607{
608 FILE *auth;
609 fstring buf;
610 uint16 len = 0;
611 char *ptr, *val, *param;
612
613 if ((auth=sys_fopen(filename, "r")) == NULL)
614 {
615 /* fail if we can't open the credentials file */
616 DEBUG(0,("ERROR: Unable to open credentials file!\n"));
617 exit (-1);
618 }
619
620 while (!feof(auth))
621 {
622 /* get a line from the file */
623 if (!fgets (buf, sizeof(buf), auth))
624 continue;
625 len = strlen(buf);
626
627 if ((len) && (buf[len-1]=='\n'))
628 {
629 buf[len-1] = '\0';
630 len--;
631 }
632 if (len == 0)
633 continue;
634
635 /* break up the line into parameter & value.
636 will need to eat a little whitespace possibly */
637 param = buf;
638 if (!(ptr = strchr (buf, '=')))
639 continue;
640 val = ptr+1;
641 *ptr = '\0';
642
643 /* eat leading white space */
644 while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
645 val++;
646
647 if (strwicmp("password", param) == 0)
648 {
649 pstrcpy(password, val);
650 got_pass = True;
651 }
652 else if (strwicmp("username", param) == 0) {
653 pstrcpy(username, val);
654 }
655
656 memset(buf, 0, sizeof(buf));
657 }
658 fclose(auth);
659}
660
661
662/****************************************************************************
663usage on the program
664****************************************************************************/
665static void usage(void)
666{
667 printf("Usage: mount.smbfs service mountpoint [-o options,...]\n");
668
669 printf("Version %s\n\n",SAMBA_VERSION_STRING);
670
671 printf("Please be aware that smbfs is deprecated in favor of "
672 "cifs\n\n");
673
674 printf(
675"Options:\n\
676 username=<arg> SMB username\n\
677 password=<arg> SMB password\n\
678 credentials=<filename> file with username/password\n\
679 krb use kerberos (active directory)\n\
680 netbiosname=<arg> source NetBIOS name\n\
681 uid=<arg> mount uid or username\n\
682 gid=<arg> mount gid or groupname\n\
683 port=<arg> remote SMB port number\n\
684 fmask=<arg> file umask\n\
685 dmask=<arg> directory umask\n\
686 debug=<arg> debug level\n\
687 ip=<arg> destination host or IP address\n\
688 workgroup=<arg> workgroup on destination\n\
689 sockopt=<arg> TCP socket options\n\
690 scope=<arg> NetBIOS scope\n\
691 iocharset=<arg> Linux charset (iso8859-1, utf8)\n\
692 codepage=<arg> server codepage (cp850)\n\
693 unicode use unicode when communicating with server\n\
694 lfs large file system support\n\
695 ttl=<arg> dircache time to live\n\
696 guest don't prompt for a password\n\
697 ro mount read-only\n\
698 rw mount read-write\n\
699\n\
700This command is designed to be run from within /bin/mount by giving\n\
701the option '-t smbfs'. For example:\n\
702 mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test\n\
703");
704}
705
706
707/****************************************************************************
708 Argument parsing for mount.smbfs interface
709 mount will call us like this:
710 mount.smbfs device mountpoint -o <options>
711
712 <options> is never empty, containing at least rw or ro
713 ****************************************************************************/
714static void parse_mount_smb(int argc, char **argv)
715{
716 int opt;
717 char *opts;
718 char *opteq;
719 int val;
720 char *p;
721
722 /* FIXME: This function can silently fail if the arguments are
723 * not in the expected order.
724
725 > The arguments syntax of smbmount 2.2.3a (smbfs of Debian stable)
726 > requires that one gives "-o" before further options like username=...
727 > . Without -o, the username=.. setting is *silently* ignored. I've
728 > spent about an hour trying to find out why I couldn't log in now..
729
730 */
731
732
733 if (argc < 2 || argv[1][0] == '-') {
734 usage();
735 exit(1);
736 }
737
738 pstrcpy(service, argv[1]);
739 pstrcpy(mpoint, argv[2]);
740
741 /* Convert any '/' characters in the service name to
742 '\' characters */
743 string_replace(service, '/','\\');
744 argc -= 2;
745 argv += 2;
746
747 opt = getopt(argc, argv, "o:");
748 if(opt != 'o') {
749 return;
750 }
751
752 options[0] = 0;
753 p = options;
754
755 /*
756 * option parsing from nfsmount.c (util-linux-2.9u)
757 */
758 for (opts = strtok(optarg, ","); opts; opts = strtok(NULL, ",")) {
759 DEBUG(3, ("opts: %s\n", opts));
760 if ((opteq = strchr_m(opts, '='))) {
761 val = atoi(opteq + 1);
762 *opteq = '\0';
763
764 if (!strcmp(opts, "username") ||
765 !strcmp(opts, "logon")) {
766 char *lp;
767 got_user = True;
768 pstrcpy(username,opteq+1);
769 if ((lp=strchr_m(username,'%'))) {
770 *lp = 0;
771 pstrcpy(password,lp+1);
772 got_pass = True;
773 memset(strchr_m(opteq+1,'%')+1,'X',strlen(password));
774 }
775 if ((lp=strchr_m(username,'/'))) {
776 *lp = 0;
777 pstrcpy(workgroup,lp+1);
778 }
779 } else if(!strcmp(opts, "passwd") ||
780 !strcmp(opts, "password")) {
781 pstrcpy(password,opteq+1);
782 got_pass = True;
783 memset(opteq+1,'X',strlen(password));
784 } else if(!strcmp(opts, "credentials")) {
785 pstrcpy(credentials,opteq+1);
786 } else if(!strcmp(opts, "netbiosname")) {
787 pstrcpy(my_netbios_name,opteq+1);
788 } else if(!strcmp(opts, "uid")) {
789 mount_uid = nametouid(opteq+1);
790 } else if(!strcmp(opts, "gid")) {
791 mount_gid = nametogid(opteq+1);
792 } else if(!strcmp(opts, "port")) {
793 smb_port = val;
794 } else if(!strcmp(opts, "fmask")) {
795 mount_fmask = strtol(opteq+1, NULL, 8);
796 } else if(!strcmp(opts, "dmask")) {
797 mount_dmask = strtol(opteq+1, NULL, 8);
798 } else if(!strcmp(opts, "debug")) {
799 DEBUGLEVEL = val;
800 } else if(!strcmp(opts, "ip")) {
801 dest_ip = *interpret_addr2(opteq+1);
802 if (is_zero_ip(dest_ip)) {
803 fprintf(stderr,"Can't resolve address %s\n", opteq+1);
804 exit(1);
805 }
806 have_ip = True;
807 } else if(!strcmp(opts, "workgroup")) {
808 pstrcpy(workgroup,opteq+1);
809 } else if(!strcmp(opts, "sockopt")) {
810 pstrcpy(user_socket_options,opteq+1);
811 } else if(!strcmp(opts, "scope")) {
812 set_global_scope(opteq+1);
813 } else {
814 slprintf(p, sizeof(pstring) - (p - options) - 1, "%s=%s,", opts, opteq+1);
815 p += strlen(p);
816 }
817 } else {
818 val = 1;
819 if(!strcmp(opts, "nocaps")) {
820 fprintf(stderr, "Unhandled option: %s\n", opteq+1);
821 exit(1);
822 } else if(!strcmp(opts, "guest")) {
823 *password = '\0';
824 got_pass = True;
825 } else if(!strcmp(opts, "krb")) {
826#ifdef HAVE_KRB5
827
828 use_kerberos = True;
829 if(!status32_smbfs)
830 fprintf(stderr, "Warning: kerberos support will only work for samba servers\n");
831#else
832 fprintf(stderr,"No kerberos support compiled in\n");
833 exit(1);
834#endif
835 } else if(!strcmp(opts, "rw")) {
836 mount_ro = 0;
837 } else if(!strcmp(opts, "ro")) {
838 mount_ro = 1;
839 } else if(!strcmp(opts, "unicode")) {
840 smbfs_has_unicode = True;
841 } else if(!strcmp(opts, "lfs")) {
842 smbfs_has_lfs = True;
843 } else {
844 strncpy(p, opts, sizeof(pstring) - (p - options) - 1);
845 p += strlen(opts);
846 *p++ = ',';
847 *p = 0;
848 }
849 }
850 }
851
852 if (!*service) {
853 usage();
854 exit(1);
855 }
856
857 if (p != options) {
858 *(p-1) = 0; /* remove trailing , */
859 DEBUG(3,("passthrough options '%s'\n", options));
860 }
861}
862
863/****************************************************************************
864 main program
865****************************************************************************/
866 int main(int argc,char *argv[])
867{
868 char *p;
869
870 DEBUGLEVEL = 1;
871
872 load_case_tables();
873
874 /* here we are interactive, even if run from autofs */
875 setup_logging("mount.smbfs",True);
876
877#if 0 /* JRA - Urban says not needed ? */
878 /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default
879 is to not announce any unicode capabilities as current smbfs does
880 not support it. */
881 p = getenv("CLI_FORCE_ASCII");
882 if (p && !strcmp(p, "false"))
883 unsetenv("CLI_FORCE_ASCII");
884 else
885 setenv("CLI_FORCE_ASCII", "true", 1);
886#endif
887
888 in_client = True; /* Make sure that we tell lp_load we are */
889
890 if (getenv("USER")) {
891 pstrcpy(username,getenv("USER"));
892
893 if ((p=strchr_m(username,'%'))) {
894 *p = 0;
895 pstrcpy(password,p+1);
896 got_pass = True;
897 memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password));
898 }
899 strupper_m(username);
900 }
901
902 if (getenv("PASSWD")) {
903 pstrcpy(password,getenv("PASSWD"));
904 got_pass = True;
905 }
906
907 if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
908 get_password_file();
909 got_pass = True;
910 }
911
912 if (*username == 0 && getenv("LOGNAME")) {
913 pstrcpy(username,getenv("LOGNAME"));
914 }
915
916 if (!lp_load(dyn_CONFIGFILE,True,False,False,True)) {
917 fprintf(stderr, "Can't load %s - run testparm to debug it\n",
918 dyn_CONFIGFILE);
919 }
920
921 parse_mount_smb(argc, argv);
922
923 if (use_kerberos && !got_user) {
924 got_pass = True;
925 }
926
927 if (*credentials != 0) {
928 read_credentials_file(credentials);
929 }
930
931 DEBUG(3,("mount.smbfs started (version %s)\n", SAMBA_VERSION_STRING));
932
933 if (*workgroup == 0) {
934 pstrcpy(workgroup,lp_workgroup());
935 }
936
937 load_interfaces();
938 if (!*my_netbios_name) {
939 pstrcpy(my_netbios_name, myhostname());
940 }
941 strupper_m(my_netbios_name);
942
943 init_mount();
944 return 0;
945}
Note: See TracBrowser for help on using the repository browser.