merge from 2.2 and regenerate
[Samba.git] / source / client / smbmount.c
blob8b56d21bec77e739d7c2833d03efb9daddbe4cc0
1 /*
2 Unix SMB/Netbios implementation.
3 Version 2.0.
4 SMBFS mount program
5 Copyright (C) Andrew Tridgell 1999
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #define NO_SYSLOG
24 #include "includes.h"
26 #include <mntent.h>
27 #include <asm/types.h>
28 #include <linux/smb_fs.h>
30 extern BOOL in_client;
31 extern pstring user_socket_options;
32 extern BOOL append_log;
33 extern fstring remote_machine;
35 static pstring credentials;
36 static pstring my_netbios_name;
37 static pstring password;
38 static pstring username;
39 static pstring workgroup;
40 static pstring mpoint;
41 static pstring service;
42 static pstring options;
44 static struct in_addr dest_ip;
45 static BOOL have_ip;
46 static int smb_port = 0;
47 static BOOL got_pass;
48 static uid_t mount_uid;
49 static gid_t mount_gid;
50 static int mount_ro;
51 static unsigned mount_fmask;
52 static unsigned mount_dmask;
54 static void usage(void);
56 static void exit_parent(int sig)
58 /* parent simply exits when child says go... */
59 exit(0);
62 static void daemonize(void)
64 int j, status;
65 pid_t child_pid;
67 signal( SIGTERM, exit_parent );
69 if ((child_pid = sys_fork()) < 0) {
70 DEBUG(0,("could not fork\n"));
73 if (child_pid > 0) {
74 while( 1 ) {
75 j = waitpid( child_pid, &status, 0 );
76 if( j < 0 ) {
77 if( EINTR == errno ) {
78 continue;
80 status = errno;
82 break;
84 /* If we get here - the child exited with some error status */
85 exit(status);
88 signal( SIGTERM, SIG_DFL );
89 chdir("/");
92 static void close_our_files(int client_fd)
94 int i;
95 struct rlimit limits;
97 getrlimit(RLIMIT_NOFILE,&limits);
98 for (i = 0; i< limits.rlim_max; i++) {
99 if (i == client_fd)
100 continue;
101 close(i);
105 static void usr1_handler(int x)
107 return;
111 /*****************************************************
112 return a connection to a server
113 *******************************************************/
114 static struct cli_state *do_connection(char *the_service)
116 struct cli_state *c;
117 struct nmb_name called, calling;
118 char *server_n;
119 struct in_addr ip;
120 pstring server;
121 char *share;
123 if (the_service[0] != '\\' || the_service[1] != '\\') {
124 usage();
125 exit(1);
128 pstrcpy(server, the_service+2);
129 share = strchr_m(server,'\\');
130 if (!share) {
131 usage();
132 exit(1);
134 *share = 0;
135 share++;
137 server_n = server;
139 make_nmb_name(&calling, my_netbios_name, 0x0);
140 make_nmb_name(&called , server, 0x20);
142 again:
143 zero_ip(&ip);
144 if (have_ip) ip = dest_ip;
146 /* have to open a new connection */
147 if (!(c=cli_initialise(NULL)) || (cli_set_port(c, smb_port) != smb_port) ||
148 !cli_connect(c, server_n, &ip)) {
149 DEBUG(0,("%d: Connection to %s failed\n", getpid(), server_n));
150 if (c) {
151 cli_shutdown(c);
153 return NULL;
156 /* SPNEGO doesn't work till we get NTSTATUS error support */
157 c->use_spnego = False;
159 if (!cli_session_request(c, &calling, &called)) {
160 char *p;
161 DEBUG(0,("%d: session request to %s failed (%s)\n",
162 getpid(), called.name, cli_errstr(c)));
163 cli_shutdown(c);
164 if ((p=strchr_m(called.name, '.'))) {
165 *p = 0;
166 goto again;
168 if (strcmp(called.name, "*SMBSERVER")) {
169 make_nmb_name(&called , "*SMBSERVER", 0x20);
170 goto again;
172 return NULL;
175 DEBUG(4,("%d: session request ok\n", getpid()));
177 if (!cli_negprot(c)) {
178 DEBUG(0,("%d: protocol negotiation failed\n", getpid()));
179 cli_shutdown(c);
180 return NULL;
183 if (!got_pass) {
184 char *pass = getpass("Password: ");
185 if (pass) {
186 pstrcpy(password, pass);
190 /* This should be right for current smbfs. Future versions will support
191 large files as well as unicode and oplocks. */
192 c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS |
193 CAP_NT_FIND | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS);
194 c->force_dos_errors = True;
195 if (!cli_session_setup(c, username,
196 password, strlen(password),
197 password, strlen(password),
198 workgroup)) {
199 /* if a password was not supplied then try again with a
200 null username */
201 if (password[0] || !username[0] ||
202 !cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
203 DEBUG(0,("%d: session setup failed: %s\n",
204 getpid(), cli_errstr(c)));
205 cli_shutdown(c);
206 return NULL;
208 DEBUG(0,("Anonymous login successful\n"));
211 DEBUG(4,("%d: session setup ok\n", getpid()));
213 if (!cli_send_tconX(c, share, "?????",
214 password, strlen(password)+1)) {
215 DEBUG(0,("%d: tree connect failed: %s\n",
216 getpid(), cli_errstr(c)));
217 cli_shutdown(c);
218 return NULL;
221 DEBUG(4,("%d: tconx ok\n", getpid()));
223 got_pass = True;
225 return c;
229 /****************************************************************************
230 unmount smbfs (this is a bailout routine to clean up if a reconnect fails)
231 Code blatently stolen from smbumount.c
232 -mhw-
233 ****************************************************************************/
234 static void smb_umount(char *mount_point)
236 int fd;
237 struct mntent *mnt;
238 FILE* mtab;
239 FILE* new_mtab;
241 /* Programmers Note:
242 This routine only gets called to the scene of a disaster
243 to shoot the survivors... A connection that was working
244 has now apparently failed. We have an active mount point
245 (presumably) that we need to dump. If we get errors along
246 the way - make some noise, but we are already turning out
247 the lights to exit anyways...
249 if (umount(mount_point) != 0) {
250 DEBUG(0,("%d: Could not umount %s: %s\n",
251 getpid(), mount_point, strerror(errno)));
252 return;
255 if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) {
256 DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", getpid()));
257 return;
260 close(fd);
262 if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
263 DEBUG(0,("%d: Can't open " MOUNTED ": %s\n",
264 getpid(), strerror(errno)));
265 return;
268 #define MOUNTED_TMP MOUNTED".tmp"
270 if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
271 DEBUG(0,("%d: Can't open " MOUNTED_TMP ": %s\n",
272 getpid(), strerror(errno)));
273 endmntent(mtab);
274 return;
277 while ((mnt = getmntent(mtab)) != NULL) {
278 if (strcmp(mnt->mnt_dir, mount_point) != 0) {
279 addmntent(new_mtab, mnt);
283 endmntent(mtab);
285 if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
286 DEBUG(0,("%d: Error changing mode of %s: %s\n",
287 getpid(), MOUNTED_TMP, strerror(errno)));
288 return;
291 endmntent(new_mtab);
293 if (rename(MOUNTED_TMP, MOUNTED) < 0) {
294 DEBUG(0,("%d: Cannot rename %s to %s: %s\n",
295 getpid(), MOUNTED, MOUNTED_TMP, strerror(errno)));
296 return;
299 if (unlink(MOUNTED"~") == -1) {
300 DEBUG(0,("%d: Can't remove "MOUNTED"~", getpid()));
301 return;
307 * Call the smbfs ioctl to install a connection socket,
308 * then wait for a signal to reconnect. Note that we do
309 * not exit after open_sockets() or send_login() errors,
310 * as the smbfs mount would then have no way to recover.
312 static void send_fs_socket(char *the_service, char *mount_point, struct cli_state *c)
314 int fd, closed = 0, res = 1;
315 pid_t parentpid = getppid();
316 struct smb_conn_opt conn_options;
318 memset(&conn_options, 0, sizeof(conn_options));
320 while (1) {
321 if ((fd = open(mount_point, O_RDONLY)) < 0) {
322 DEBUG(0,("mount.smbfs[%d]: can't open %s\n",
323 getpid(), mount_point));
324 break;
327 conn_options.fd = c->fd;
328 conn_options.protocol = c->protocol;
329 conn_options.case_handling = SMB_CASE_DEFAULT;
330 conn_options.max_xmit = c->max_xmit;
331 conn_options.server_uid = c->vuid;
332 conn_options.tid = c->cnum;
333 conn_options.secmode = c->sec_mode;
334 conn_options.rawmode = 0;
335 conn_options.sesskey = c->sesskey;
336 conn_options.maxraw = 0;
337 conn_options.capabilities = c->capabilities;
338 conn_options.serverzone = c->serverzone/60;
340 res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options);
341 if (res != 0) {
342 DEBUG(0,("mount.smbfs[%d]: ioctl failed, res=%d\n",
343 getpid(), res));
344 close(fd);
345 break;
348 if (parentpid) {
349 /* Ok... We are going to kill the parent. Now
350 is the time to break the process group... */
351 setsid();
352 /* Send a signal to the parent to terminate */
353 kill(parentpid, SIGTERM);
354 parentpid = 0;
357 close(fd);
359 /* This looks wierd but we are only closing the userspace
360 side, the connection has already been passed to smbfs and
361 it has increased the usage count on the socket.
363 If we don't do this we will "leak" sockets and memory on
364 each reconnection we have to make. */
365 cli_shutdown(c);
366 c = NULL;
368 if (!closed) {
369 /* redirect stdout & stderr since we can't know that
370 the library functions we use are using DEBUG. */
371 if ( (fd = open("/dev/null", O_WRONLY)) < 0)
372 DEBUG(2,("mount.smbfs: can't open /dev/null\n"));
373 close_our_files(fd);
374 if (fd >= 0) {
375 dup2(fd, STDOUT_FILENO);
376 dup2(fd, STDERR_FILENO);
377 close(fd);
380 /* here we are no longer interactive */
381 pstrcpy(remote_machine, "smbmount"); /* sneaky ... */
382 setup_logging("mount.smbfs", False);
383 append_log = True;
384 reopen_logs();
385 DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, getpid()));
387 closed = 1;
390 /* Wait for a signal from smbfs ... but don't continue
391 until we actually get a new connection. */
392 while (!c) {
393 CatchSignal(SIGUSR1, &usr1_handler);
394 pause();
395 DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", getpid()));
396 c = do_connection(the_service);
400 smb_umount(mount_point);
401 DEBUG(2,("mount.smbfs[%d]: exit\n", getpid()));
402 exit(1);
407 * Mount a smbfs
409 static void init_mount(void)
411 char mount_point[MAXPATHLEN+1];
412 pstring tmp;
413 pstring svc2;
414 struct cli_state *c;
415 char *args[20];
416 int i, status;
418 if (realpath(mpoint, mount_point) == NULL) {
419 fprintf(stderr, "Could not resolve mount point %s\n", mpoint);
420 return;
424 c = do_connection(service);
425 if (!c) {
426 fprintf(stderr,"SMB connection failed\n");
427 exit(1);
431 Set up to return as a daemon child and wait in the parent
432 until the child say it's ready...
434 daemonize();
436 pstrcpy(svc2, service);
437 string_replace(svc2, '\\','/');
438 string_replace(svc2, ' ','_');
440 memset(args, 0, sizeof(args[0])*20);
442 i=0;
443 args[i++] = "smbmnt";
445 args[i++] = mount_point;
446 args[i++] = "-s";
447 args[i++] = svc2;
449 if (mount_ro) {
450 args[i++] = "-r";
452 if (mount_uid) {
453 slprintf(tmp, sizeof(tmp)-1, "%d", mount_uid);
454 args[i++] = "-u";
455 args[i++] = smb_xstrdup(tmp);
457 if (mount_gid) {
458 slprintf(tmp, sizeof(tmp)-1, "%d", mount_gid);
459 args[i++] = "-g";
460 args[i++] = smb_xstrdup(tmp);
462 if (mount_fmask) {
463 slprintf(tmp, sizeof(tmp)-1, "0%o", mount_fmask);
464 args[i++] = "-f";
465 args[i++] = smb_xstrdup(tmp);
467 if (mount_dmask) {
468 slprintf(tmp, sizeof(tmp)-1, "0%o", mount_dmask);
469 args[i++] = "-d";
470 args[i++] = smb_xstrdup(tmp);
472 if (options) {
473 args[i++] = "-o";
474 args[i++] = options;
477 if (sys_fork() == 0) {
478 char *smbmnt_path;
480 asprintf(&smbmnt_path, "%s/smbmnt", dyn_BINDIR);
482 if (file_exist(smbmnt_path, NULL)) {
483 execv(smbmnt_path, args);
484 fprintf(stderr,
485 "smbfs/init_mount: execv of %s failed. Error was %s.",
486 smbmnt_path, strerror(errno));
487 } else {
488 execvp("smbmnt", args);
489 fprintf(stderr,
490 "smbfs/init_mount: execv of %s failed. Error was %s.",
491 "smbmnt", strerror(errno));
493 free(smbmnt_path);
494 exit(1);
497 if (waitpid(-1, &status, 0) == -1) {
498 fprintf(stderr,"waitpid failed: Error was %s", strerror(errno) );
499 /* FIXME: do some proper error handling */
500 exit(1);
503 if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
504 fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status));
505 /* FIXME: do some proper error handling */
506 exit(1);
509 /* Ok... This is the rubicon for that mount point... At any point
510 after this, if the connections fail and can not be reconstructed
511 for any reason, we will have to unmount the mount point. There
512 is no exit from the next call...
514 send_fs_socket(service, mount_point, c);
518 /****************************************************************************
519 get a password from a a file or file descriptor
520 exit on failure (from smbclient, move to libsmb or shared .c file?)
521 ****************************************************************************/
522 static void get_password_file(void)
524 int fd = -1;
525 char *p;
526 BOOL close_it = False;
527 pstring spec;
528 char pass[128];
530 if ((p = getenv("PASSWD_FD")) != NULL) {
531 pstrcpy(spec, "descriptor ");
532 pstrcat(spec, p);
533 sscanf(p, "%d", &fd);
534 close_it = False;
535 } else if ((p = getenv("PASSWD_FILE")) != NULL) {
536 fd = sys_open(p, O_RDONLY, 0);
537 pstrcpy(spec, p);
538 if (fd < 0) {
539 fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
540 spec, strerror(errno));
541 exit(1);
543 close_it = True;
546 for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
547 p && p - pass < sizeof(pass);) {
548 switch (read(fd, p, 1)) {
549 case 1:
550 if (*p != '\n' && *p != '\0') {
551 *++p = '\0'; /* advance p, and null-terminate pass */
552 break;
554 case 0:
555 if (p - pass) {
556 *p = '\0'; /* null-terminate it, just in case... */
557 p = NULL; /* then force the loop condition to become false */
558 break;
559 } else {
560 fprintf(stderr, "Error reading password from file %s: %s\n",
561 spec, "empty password\n");
562 exit(1);
565 default:
566 fprintf(stderr, "Error reading password from file %s: %s\n",
567 spec, strerror(errno));
568 exit(1);
571 pstrcpy(password, pass);
572 if (close_it)
573 close(fd);
576 /****************************************************************************
577 get username and password from a credentials file
578 exit on failure (from smbclient, move to libsmb or shared .c file?)
579 ****************************************************************************/
580 static void read_credentials_file(char *filename)
582 FILE *auth;
583 fstring buf;
584 uint16 len = 0;
585 char *ptr, *val, *param;
587 if ((auth=sys_fopen(filename, "r")) == NULL)
589 /* fail if we can't open the credentials file */
590 DEBUG(0,("ERROR: Unable to open credentials file!\n"));
591 exit (-1);
594 while (!feof(auth))
596 /* get a line from the file */
597 if (!fgets (buf, sizeof(buf), auth))
598 continue;
599 len = strlen(buf);
601 if ((len) && (buf[len-1]=='\n'))
603 buf[len-1] = '\0';
604 len--;
606 if (len == 0)
607 continue;
609 /* break up the line into parameter & value.
610 will need to eat a little whitespace possibly */
611 param = buf;
612 if (!(ptr = strchr (buf, '=')))
613 continue;
614 val = ptr+1;
615 *ptr = '\0';
617 /* eat leading white space */
618 while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
619 val++;
621 if (strwicmp("password", param) == 0)
623 pstrcpy(password, val);
624 got_pass = True;
626 else if (strwicmp("username", param) == 0)
627 pstrcpy(username, val);
629 memset(buf, 0, sizeof(buf));
631 fclose(auth);
635 /****************************************************************************
636 usage on the program
637 ****************************************************************************/
638 static void usage(void)
640 printf("Usage: mount.smbfs service mountpoint [-o options,...]\n");
642 printf("Version %s\n\n",VERSION);
644 printf(
645 "Options:\n\
646 username=<arg> SMB username\n\
647 password=<arg> SMB password\n\
648 credentials=<filename> file with username/password\n\
649 netbiosname=<arg> source NetBIOS name\n\
650 uid=<arg> mount uid or username\n\
651 gid=<arg> mount gid or groupname\n\
652 port=<arg> remote SMB port number\n\
653 fmask=<arg> file umask\n\
654 dmask=<arg> directory umask\n\
655 debug=<arg> debug level\n\
656 ip=<arg> destination host or IP address\n\
657 workgroup=<arg> workgroup on destination\n\
658 sockopt=<arg> TCP socket options\n\
659 scope=<arg> NetBIOS scope\n\
660 iocharset=<arg> Linux charset (iso8859-1, utf8)\n\
661 codepage=<arg> server codepage (cp850)\n\
662 ttl=<arg> dircache time to live\n\
663 guest don't prompt for a password\n\
664 ro mount read-only\n\
665 rw mount read-write\n\
667 This command is designed to be run from within /bin/mount by giving\n\
668 the option '-t smbfs'. For example:\n\
669 mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test\n\
674 /****************************************************************************
675 Argument parsing for mount.smbfs interface
676 mount will call us like this:
677 mount.smbfs device mountpoint -o <options>
679 <options> is never empty, containing at least rw or ro
680 ****************************************************************************/
681 static void parse_mount_smb(int argc, char **argv)
683 int opt;
684 char *opts;
685 char *opteq;
686 extern char *optarg;
687 int val;
688 extern pstring global_scope;
689 char *p;
691 if (argc < 2 || argv[1][0] == '-') {
692 usage();
693 exit(1);
696 pstrcpy(service, argv[1]);
697 pstrcpy(mpoint, argv[2]);
699 /* Convert any '/' characters in the service name to
700 '\' characters */
701 string_replace(service, '/','\\');
702 argc -= 2;
703 argv += 2;
705 opt = getopt(argc, argv, "o:");
706 if(opt != 'o') {
707 return;
710 options[0] = 0;
711 p = options;
714 * option parsing from nfsmount.c (util-linux-2.9u)
716 for (opts = strtok(optarg, ","); opts; opts = strtok(NULL, ",")) {
717 DEBUG(3, ("opts: %s\n", opts));
718 if ((opteq = strchr_m(opts, '='))) {
719 val = atoi(opteq + 1);
720 *opteq = '\0';
722 if (!strcmp(opts, "username") ||
723 !strcmp(opts, "logon")) {
724 char *lp;
725 pstrcpy(username,opteq+1);
726 if ((lp=strchr_m(username,'%'))) {
727 *lp = 0;
728 pstrcpy(password,lp+1);
729 got_pass = True;
730 memset(strchr_m(opteq+1,'%')+1,'X',strlen(password));
732 if ((lp=strchr_m(username,'/'))) {
733 *lp = 0;
734 pstrcpy(workgroup,lp+1);
736 } else if(!strcmp(opts, "passwd") ||
737 !strcmp(opts, "password")) {
738 pstrcpy(password,opteq+1);
739 got_pass = True;
740 memset(opteq+1,'X',strlen(password));
741 } else if(!strcmp(opts, "credentials")) {
742 pstrcpy(credentials,opteq+1);
743 } else if(!strcmp(opts, "netbiosname")) {
744 pstrcpy(my_netbios_name,opteq+1);
745 } else if(!strcmp(opts, "uid")) {
746 mount_uid = nametouid(opteq+1);
747 } else if(!strcmp(opts, "gid")) {
748 mount_gid = nametogid(opteq+1);
749 } else if(!strcmp(opts, "port")) {
750 smb_port = val;
751 } else if(!strcmp(opts, "fmask")) {
752 mount_fmask = strtol(opteq+1, NULL, 8);
753 } else if(!strcmp(opts, "dmask")) {
754 mount_dmask = strtol(opteq+1, NULL, 8);
755 } else if(!strcmp(opts, "debug")) {
756 DEBUGLEVEL = val;
757 } else if(!strcmp(opts, "ip")) {
758 dest_ip = *interpret_addr2(opteq+1);
759 if (is_zero_ip(dest_ip)) {
760 fprintf(stderr,"Can't resolve address %s\n", opteq+1);
761 exit(1);
763 have_ip = True;
764 } else if(!strcmp(opts, "workgroup")) {
765 pstrcpy(workgroup,opteq+1);
766 } else if(!strcmp(opts, "sockopt")) {
767 pstrcpy(user_socket_options,opteq+1);
768 } else if(!strcmp(opts, "scope")) {
769 pstrcpy(global_scope,opteq+1);
770 } else {
771 slprintf(p, sizeof(pstring) - (p - options) - 1, "%s=%s,", opts, opteq+1);
772 p += strlen(p);
774 } else {
775 val = 1;
776 if(!strcmp(opts, "nocaps")) {
777 fprintf(stderr, "Unhandled option: %s\n", opteq+1);
778 exit(1);
779 } else if(!strcmp(opts, "guest")) {
780 *password = '\0';
781 got_pass = True;
782 } else if(!strcmp(opts, "rw")) {
783 mount_ro = 0;
784 } else if(!strcmp(opts, "ro")) {
785 mount_ro = 1;
786 } else {
787 strncpy(p, opts, sizeof(pstring) - (p - options) - 1);
788 p += strlen(opts);
789 *p++ = ',';
790 *p = 0;
795 if (!*service) {
796 usage();
797 exit(1);
800 if (p != options) {
801 *(p-1) = 0; /* remove trailing , */
802 DEBUG(3,("passthrough options '%s'\n", options));
806 /****************************************************************************
807 main program
808 ****************************************************************************/
809 int main(int argc,char *argv[])
811 extern char *optarg;
812 extern int optind;
813 char *p;
815 DEBUGLEVEL = 1;
817 /* here we are interactive, even if run from autofs */
818 setup_logging("mount.smbfs",True);
820 #if 0 /* JRA - Urban says not needed ? */
821 /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default
822 is to not announce any unicode capabilities as current smbfs does
823 not support it. */
824 p = getenv("CLI_FORCE_ASCII");
825 if (p && !strcmp(p, "false"))
826 unsetenv("CLI_FORCE_ASCII");
827 else
828 setenv("CLI_FORCE_ASCII", "true", 1);
829 #endif
831 in_client = True; /* Make sure that we tell lp_load we are */
833 if (getenv("USER")) {
834 pstrcpy(username,getenv("USER"));
836 if ((p=strchr_m(username,'%'))) {
837 *p = 0;
838 pstrcpy(password,p+1);
839 got_pass = True;
840 memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password));
842 strupper(username);
845 if (getenv("PASSWD")) {
846 pstrcpy(password,getenv("PASSWD"));
847 got_pass = True;
850 if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
851 get_password_file();
852 got_pass = True;
855 if (*username == 0 && getenv("LOGNAME")) {
856 pstrcpy(username,getenv("LOGNAME"));
859 if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
860 fprintf(stderr, "Can't load %s - run testparm to debug it\n",
861 dyn_CONFIGFILE);
864 parse_mount_smb(argc, argv);
866 if (*credentials != 0) {
867 read_credentials_file(credentials);
870 DEBUG(3,("mount.smbfs started (version %s)\n", VERSION));
872 if (*workgroup == 0) {
873 pstrcpy(workgroup,lp_workgroup());
876 load_interfaces();
877 if (!*my_netbios_name) {
878 pstrcpy(my_netbios_name, myhostname());
880 strupper(my_netbios_name);
882 init_mount();
883 return 0;