Bring smbmount.c in line with jra's global-cide. global_scope was used here...
[Samba/bjacke.git] / source3 / client / smbmount.c
blobd8f5e1b394f2e20911d4bccd96464beb6e250402
1 /*
2 Unix SMB/CIFS implementation.
3 SMBFS mount program
4 Copyright (C) Andrew Tridgell 1999
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 2 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #define NO_SYSLOG
23 #include "includes.h"
25 #include <mntent.h>
26 #include <asm/types.h>
27 #include <linux/smb_fs.h>
29 extern BOOL in_client;
30 extern pstring user_socket_options;
32 static pstring credentials;
33 static pstring my_netbios_name;
34 static pstring password;
35 static pstring username;
36 static pstring workgroup;
37 static pstring mpoint;
38 static pstring service;
39 static pstring options;
41 static struct in_addr dest_ip;
42 static BOOL have_ip;
43 static int smb_port = 0;
44 static BOOL got_pass;
45 static uid_t mount_uid;
46 static gid_t mount_gid;
47 static int mount_ro;
48 static unsigned mount_fmask;
49 static unsigned mount_dmask;
51 static void usage(void);
53 static void exit_parent(int sig)
55 /* parent simply exits when child says go... */
56 exit(0);
59 static void daemonize(void)
61 int j, status;
62 pid_t child_pid;
64 signal( SIGTERM, exit_parent );
66 if ((child_pid = sys_fork()) < 0) {
67 DEBUG(0,("could not fork\n"));
70 if (child_pid > 0) {
71 while( 1 ) {
72 j = waitpid( child_pid, &status, 0 );
73 if( j < 0 ) {
74 if( EINTR == errno ) {
75 continue;
77 status = errno;
79 break;
81 /* If we get here - the child exited with some error status */
82 exit(status);
85 signal( SIGTERM, SIG_DFL );
86 chdir("/");
89 static void close_our_files(int client_fd)
91 int i;
92 struct rlimit limits;
94 getrlimit(RLIMIT_NOFILE,&limits);
95 for (i = 0; i< limits.rlim_max; i++) {
96 if (i == client_fd)
97 continue;
98 close(i);
102 static void usr1_handler(int x)
104 return;
108 /*****************************************************
109 return a connection to a server
110 *******************************************************/
111 static struct cli_state *do_connection(char *the_service)
113 struct cli_state *c;
114 struct nmb_name called, calling;
115 char *server_n;
116 struct in_addr ip;
117 pstring server;
118 char *share;
120 if (the_service[0] != '\\' || the_service[1] != '\\') {
121 usage();
122 exit(1);
125 pstrcpy(server, the_service+2);
126 share = strchr_m(server,'\\');
127 if (!share) {
128 usage();
129 exit(1);
131 *share = 0;
132 share++;
134 server_n = server;
136 make_nmb_name(&calling, my_netbios_name, 0x0);
137 make_nmb_name(&called , server, 0x20);
139 again:
140 zero_ip(&ip);
141 if (have_ip) ip = dest_ip;
143 /* have to open a new connection */
144 if (!(c=cli_initialise(NULL)) || (cli_set_port(c, smb_port) != smb_port) ||
145 !cli_connect(c, server_n, &ip)) {
146 DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n));
147 if (c) {
148 cli_shutdown(c);
150 return NULL;
153 /* SPNEGO doesn't work till we get NTSTATUS error support */
154 c->use_spnego = False;
156 if (!cli_session_request(c, &calling, &called)) {
157 char *p;
158 DEBUG(0,("%d: session request to %s failed (%s)\n",
159 sys_getpid(), called.name, cli_errstr(c)));
160 cli_shutdown(c);
161 if ((p=strchr_m(called.name, '.'))) {
162 *p = 0;
163 goto again;
165 if (strcmp(called.name, "*SMBSERVER")) {
166 make_nmb_name(&called , "*SMBSERVER", 0x20);
167 goto again;
169 return NULL;
172 DEBUG(4,("%d: session request ok\n", sys_getpid()));
174 if (!cli_negprot(c)) {
175 DEBUG(0,("%d: protocol negotiation failed\n", sys_getpid()));
176 cli_shutdown(c);
177 return NULL;
180 if (!got_pass) {
181 char *pass = getpass("Password: ");
182 if (pass) {
183 pstrcpy(password, pass);
187 /* This should be right for current smbfs. Future versions will support
188 large files as well as unicode and oplocks. */
189 c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS |
190 CAP_NT_FIND | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS);
191 c->force_dos_errors = True;
192 if (!cli_session_setup(c, username,
193 password, strlen(password),
194 password, strlen(password),
195 workgroup)) {
196 /* if a password was not supplied then try again with a
197 null username */
198 if (password[0] || !username[0] ||
199 !cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
200 DEBUG(0,("%d: session setup failed: %s\n",
201 sys_getpid(), cli_errstr(c)));
202 cli_shutdown(c);
203 return NULL;
205 DEBUG(0,("Anonymous login successful\n"));
208 DEBUG(4,("%d: session setup ok\n", sys_getpid()));
210 if (!cli_send_tconX(c, share, "?????",
211 password, strlen(password)+1)) {
212 DEBUG(0,("%d: tree connect failed: %s\n",
213 sys_getpid(), cli_errstr(c)));
214 cli_shutdown(c);
215 return NULL;
218 DEBUG(4,("%d: tconx ok\n", sys_getpid()));
220 got_pass = True;
222 return c;
226 /****************************************************************************
227 unmount smbfs (this is a bailout routine to clean up if a reconnect fails)
228 Code blatently stolen from smbumount.c
229 -mhw-
230 ****************************************************************************/
231 static void smb_umount(char *mount_point)
233 int fd;
234 struct mntent *mnt;
235 FILE* mtab;
236 FILE* new_mtab;
238 /* Programmers Note:
239 This routine only gets called to the scene of a disaster
240 to shoot the survivors... A connection that was working
241 has now apparently failed. We have an active mount point
242 (presumably) that we need to dump. If we get errors along
243 the way - make some noise, but we are already turning out
244 the lights to exit anyways...
246 if (umount(mount_point) != 0) {
247 DEBUG(0,("%d: Could not umount %s: %s\n",
248 sys_getpid(), mount_point, strerror(errno)));
249 return;
252 if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) {
253 DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", sys_getpid()));
254 return;
257 close(fd);
259 if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
260 DEBUG(0,("%d: Can't open " MOUNTED ": %s\n",
261 sys_getpid(), strerror(errno)));
262 return;
265 #define MOUNTED_TMP MOUNTED".tmp"
267 if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
268 DEBUG(0,("%d: Can't open " MOUNTED_TMP ": %s\n",
269 sys_getpid(), strerror(errno)));
270 endmntent(mtab);
271 return;
274 while ((mnt = getmntent(mtab)) != NULL) {
275 if (strcmp(mnt->mnt_dir, mount_point) != 0) {
276 addmntent(new_mtab, mnt);
280 endmntent(mtab);
282 if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
283 DEBUG(0,("%d: Error changing mode of %s: %s\n",
284 sys_getpid(), MOUNTED_TMP, strerror(errno)));
285 return;
288 endmntent(new_mtab);
290 if (rename(MOUNTED_TMP, MOUNTED) < 0) {
291 DEBUG(0,("%d: Cannot rename %s to %s: %s\n",
292 sys_getpid(), MOUNTED, MOUNTED_TMP, strerror(errno)));
293 return;
296 if (unlink(MOUNTED"~") == -1) {
297 DEBUG(0,("%d: Can't remove "MOUNTED"~", sys_getpid()));
298 return;
304 * Call the smbfs ioctl to install a connection socket,
305 * then wait for a signal to reconnect. Note that we do
306 * not exit after open_sockets() or send_login() errors,
307 * as the smbfs mount would then have no way to recover.
309 static void send_fs_socket(char *the_service, char *mount_point, struct cli_state *c)
311 int fd, closed = 0, res = 1;
312 pid_t parentpid = getppid();
313 struct smb_conn_opt conn_options;
315 memset(&conn_options, 0, sizeof(conn_options));
317 while (1) {
318 if ((fd = open(mount_point, O_RDONLY)) < 0) {
319 DEBUG(0,("mount.smbfs[%d]: can't open %s\n",
320 sys_getpid(), mount_point));
321 break;
324 conn_options.fd = c->fd;
325 conn_options.protocol = c->protocol;
326 conn_options.case_handling = SMB_CASE_DEFAULT;
327 conn_options.max_xmit = c->max_xmit;
328 conn_options.server_uid = c->vuid;
329 conn_options.tid = c->cnum;
330 conn_options.secmode = c->sec_mode;
331 conn_options.rawmode = 0;
332 conn_options.sesskey = c->sesskey;
333 conn_options.maxraw = 0;
334 conn_options.capabilities = c->capabilities;
335 conn_options.serverzone = c->serverzone/60;
337 res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options);
338 if (res != 0) {
339 DEBUG(0,("mount.smbfs[%d]: ioctl failed, res=%d\n",
340 sys_getpid(), res));
341 close(fd);
342 break;
345 if (parentpid) {
346 /* Ok... We are going to kill the parent. Now
347 is the time to break the process group... */
348 setsid();
349 /* Send a signal to the parent to terminate */
350 kill(parentpid, SIGTERM);
351 parentpid = 0;
354 close(fd);
356 /* This looks wierd but we are only closing the userspace
357 side, the connection has already been passed to smbfs and
358 it has increased the usage count on the socket.
360 If we don't do this we will "leak" sockets and memory on
361 each reconnection we have to make. */
362 cli_shutdown(c);
363 c = NULL;
365 if (!closed) {
366 /* redirect stdout & stderr since we can't know that
367 the library functions we use are using DEBUG. */
368 if ( (fd = open("/dev/null", O_WRONLY)) < 0)
369 DEBUG(2,("mount.smbfs: can't open /dev/null\n"));
370 close_our_files(fd);
371 if (fd >= 0) {
372 dup2(fd, STDOUT_FILENO);
373 dup2(fd, STDERR_FILENO);
374 close(fd);
377 /* here we are no longer interactive */
378 set_remote_machine_name("smbmount"); /* sneaky ... */
379 setup_logging("mount.smbfs", False);
380 reopen_logs();
381 DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, sys_getpid()));
383 closed = 1;
386 /* Wait for a signal from smbfs ... but don't continue
387 until we actually get a new connection. */
388 while (!c) {
389 CatchSignal(SIGUSR1, &usr1_handler);
390 pause();
391 DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid()));
392 c = do_connection(the_service);
396 smb_umount(mount_point);
397 DEBUG(2,("mount.smbfs[%d]: exit\n", sys_getpid()));
398 exit(1);
403 * Mount a smbfs
405 static void init_mount(void)
407 char mount_point[MAXPATHLEN+1];
408 pstring tmp;
409 pstring svc2;
410 struct cli_state *c;
411 char *args[20];
412 int i, status;
414 if (realpath(mpoint, mount_point) == NULL) {
415 fprintf(stderr, "Could not resolve mount point %s\n", mpoint);
416 return;
420 c = do_connection(service);
421 if (!c) {
422 fprintf(stderr,"SMB connection failed\n");
423 exit(1);
427 Set up to return as a daemon child and wait in the parent
428 until the child say it's ready...
430 daemonize();
432 pstrcpy(svc2, service);
433 string_replace(svc2, '\\','/');
434 string_replace(svc2, ' ','_');
436 memset(args, 0, sizeof(args[0])*20);
438 i=0;
439 args[i++] = "smbmnt";
441 args[i++] = mount_point;
442 args[i++] = "-s";
443 args[i++] = svc2;
445 if (mount_ro) {
446 args[i++] = "-r";
448 if (mount_uid) {
449 slprintf(tmp, sizeof(tmp)-1, "%d", mount_uid);
450 args[i++] = "-u";
451 args[i++] = smb_xstrdup(tmp);
453 if (mount_gid) {
454 slprintf(tmp, sizeof(tmp)-1, "%d", mount_gid);
455 args[i++] = "-g";
456 args[i++] = smb_xstrdup(tmp);
458 if (mount_fmask) {
459 slprintf(tmp, sizeof(tmp)-1, "0%o", mount_fmask);
460 args[i++] = "-f";
461 args[i++] = smb_xstrdup(tmp);
463 if (mount_dmask) {
464 slprintf(tmp, sizeof(tmp)-1, "0%o", mount_dmask);
465 args[i++] = "-d";
466 args[i++] = smb_xstrdup(tmp);
468 if (options) {
469 args[i++] = "-o";
470 args[i++] = options;
473 if (sys_fork() == 0) {
474 char *smbmnt_path;
476 asprintf(&smbmnt_path, "%s/smbmnt", dyn_BINDIR);
478 if (file_exist(smbmnt_path, NULL)) {
479 execv(smbmnt_path, args);
480 fprintf(stderr,
481 "smbfs/init_mount: execv of %s failed. Error was %s.",
482 smbmnt_path, strerror(errno));
483 } else {
484 execvp("smbmnt", args);
485 fprintf(stderr,
486 "smbfs/init_mount: execv of %s failed. Error was %s.",
487 "smbmnt", strerror(errno));
489 free(smbmnt_path);
490 exit(1);
493 if (waitpid(-1, &status, 0) == -1) {
494 fprintf(stderr,"waitpid failed: Error was %s", strerror(errno) );
495 /* FIXME: do some proper error handling */
496 exit(1);
499 if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
500 fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status));
501 /* FIXME: do some proper error handling */
502 exit(1);
505 /* Ok... This is the rubicon for that mount point... At any point
506 after this, if the connections fail and can not be reconstructed
507 for any reason, we will have to unmount the mount point. There
508 is no exit from the next call...
510 send_fs_socket(service, mount_point, c);
514 /****************************************************************************
515 get a password from a a file or file descriptor
516 exit on failure (from smbclient, move to libsmb or shared .c file?)
517 ****************************************************************************/
518 static void get_password_file(void)
520 int fd = -1;
521 char *p;
522 BOOL close_it = False;
523 pstring spec;
524 char pass[128];
526 if ((p = getenv("PASSWD_FD")) != NULL) {
527 pstrcpy(spec, "descriptor ");
528 pstrcat(spec, p);
529 sscanf(p, "%d", &fd);
530 close_it = False;
531 } else if ((p = getenv("PASSWD_FILE")) != NULL) {
532 fd = sys_open(p, O_RDONLY, 0);
533 pstrcpy(spec, p);
534 if (fd < 0) {
535 fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
536 spec, strerror(errno));
537 exit(1);
539 close_it = True;
542 for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
543 p && p - pass < sizeof(pass);) {
544 switch (read(fd, p, 1)) {
545 case 1:
546 if (*p != '\n' && *p != '\0') {
547 *++p = '\0'; /* advance p, and null-terminate pass */
548 break;
550 case 0:
551 if (p - pass) {
552 *p = '\0'; /* null-terminate it, just in case... */
553 p = NULL; /* then force the loop condition to become false */
554 break;
555 } else {
556 fprintf(stderr, "Error reading password from file %s: %s\n",
557 spec, "empty password\n");
558 exit(1);
561 default:
562 fprintf(stderr, "Error reading password from file %s: %s\n",
563 spec, strerror(errno));
564 exit(1);
567 pstrcpy(password, pass);
568 if (close_it)
569 close(fd);
572 /****************************************************************************
573 get username and password from a credentials file
574 exit on failure (from smbclient, move to libsmb or shared .c file?)
575 ****************************************************************************/
576 static void read_credentials_file(char *filename)
578 FILE *auth;
579 fstring buf;
580 uint16 len = 0;
581 char *ptr, *val, *param;
583 if ((auth=sys_fopen(filename, "r")) == NULL)
585 /* fail if we can't open the credentials file */
586 DEBUG(0,("ERROR: Unable to open credentials file!\n"));
587 exit (-1);
590 while (!feof(auth))
592 /* get a line from the file */
593 if (!fgets (buf, sizeof(buf), auth))
594 continue;
595 len = strlen(buf);
597 if ((len) && (buf[len-1]=='\n'))
599 buf[len-1] = '\0';
600 len--;
602 if (len == 0)
603 continue;
605 /* break up the line into parameter & value.
606 will need to eat a little whitespace possibly */
607 param = buf;
608 if (!(ptr = strchr (buf, '=')))
609 continue;
610 val = ptr+1;
611 *ptr = '\0';
613 /* eat leading white space */
614 while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
615 val++;
617 if (strwicmp("password", param) == 0)
619 pstrcpy(password, val);
620 got_pass = True;
622 else if (strwicmp("username", param) == 0)
623 pstrcpy(username, val);
625 memset(buf, 0, sizeof(buf));
627 fclose(auth);
631 /****************************************************************************
632 usage on the program
633 ****************************************************************************/
634 static void usage(void)
636 printf("Usage: mount.smbfs service mountpoint [-o options,...]\n");
638 printf("Version %s\n\n",VERSION);
640 printf(
641 "Options:\n\
642 username=<arg> SMB username\n\
643 password=<arg> SMB password\n\
644 credentials=<filename> file with username/password\n\
645 netbiosname=<arg> source NetBIOS name\n\
646 uid=<arg> mount uid or username\n\
647 gid=<arg> mount gid or groupname\n\
648 port=<arg> remote SMB port number\n\
649 fmask=<arg> file umask\n\
650 dmask=<arg> directory umask\n\
651 debug=<arg> debug level\n\
652 ip=<arg> destination host or IP address\n\
653 workgroup=<arg> workgroup on destination\n\
654 sockopt=<arg> TCP socket options\n\
655 scope=<arg> NetBIOS scope\n\
656 iocharset=<arg> Linux charset (iso8859-1, utf8)\n\
657 codepage=<arg> server codepage (cp850)\n\
658 ttl=<arg> dircache time to live\n\
659 guest don't prompt for a password\n\
660 ro mount read-only\n\
661 rw mount read-write\n\
663 This command is designed to be run from within /bin/mount by giving\n\
664 the option '-t smbfs'. For example:\n\
665 mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test\n\
670 /****************************************************************************
671 Argument parsing for mount.smbfs interface
672 mount will call us like this:
673 mount.smbfs device mountpoint -o <options>
675 <options> is never empty, containing at least rw or ro
676 ****************************************************************************/
677 static void parse_mount_smb(int argc, char **argv)
679 int opt;
680 char *opts;
681 char *opteq;
682 extern char *optarg;
683 int val;
684 char *p;
686 if (argc < 2 || argv[1][0] == '-') {
687 usage();
688 exit(1);
691 pstrcpy(service, argv[1]);
692 pstrcpy(mpoint, argv[2]);
694 /* Convert any '/' characters in the service name to
695 '\' characters */
696 string_replace(service, '/','\\');
697 argc -= 2;
698 argv += 2;
700 opt = getopt(argc, argv, "o:");
701 if(opt != 'o') {
702 return;
705 options[0] = 0;
706 p = options;
709 * option parsing from nfsmount.c (util-linux-2.9u)
711 for (opts = strtok(optarg, ","); opts; opts = strtok(NULL, ",")) {
712 DEBUG(3, ("opts: %s\n", opts));
713 if ((opteq = strchr_m(opts, '='))) {
714 val = atoi(opteq + 1);
715 *opteq = '\0';
717 if (!strcmp(opts, "username") ||
718 !strcmp(opts, "logon")) {
719 char *lp;
720 pstrcpy(username,opteq+1);
721 if ((lp=strchr_m(username,'%'))) {
722 *lp = 0;
723 pstrcpy(password,lp+1);
724 got_pass = True;
725 memset(strchr_m(opteq+1,'%')+1,'X',strlen(password));
727 if ((lp=strchr_m(username,'/'))) {
728 *lp = 0;
729 pstrcpy(workgroup,lp+1);
731 } else if(!strcmp(opts, "passwd") ||
732 !strcmp(opts, "password")) {
733 pstrcpy(password,opteq+1);
734 got_pass = True;
735 memset(opteq+1,'X',strlen(password));
736 } else if(!strcmp(opts, "credentials")) {
737 pstrcpy(credentials,opteq+1);
738 } else if(!strcmp(opts, "netbiosname")) {
739 pstrcpy(my_netbios_name,opteq+1);
740 } else if(!strcmp(opts, "uid")) {
741 mount_uid = nametouid(opteq+1);
742 } else if(!strcmp(opts, "gid")) {
743 mount_gid = nametogid(opteq+1);
744 } else if(!strcmp(opts, "port")) {
745 smb_port = val;
746 } else if(!strcmp(opts, "fmask")) {
747 mount_fmask = strtol(opteq+1, NULL, 8);
748 } else if(!strcmp(opts, "dmask")) {
749 mount_dmask = strtol(opteq+1, NULL, 8);
750 } else if(!strcmp(opts, "debug")) {
751 DEBUGLEVEL = val;
752 } else if(!strcmp(opts, "ip")) {
753 dest_ip = *interpret_addr2(opteq+1);
754 if (is_zero_ip(dest_ip)) {
755 fprintf(stderr,"Can't resolve address %s\n", opteq+1);
756 exit(1);
758 have_ip = True;
759 } else if(!strcmp(opts, "workgroup")) {
760 pstrcpy(workgroup,opteq+1);
761 } else if(!strcmp(opts, "sockopt")) {
762 pstrcpy(user_socket_options,opteq+1);
763 } else if(!strcmp(opts, "scope")) {
764 pstrcpy(global_scope(),opteq+1);
765 } else {
766 slprintf(p, sizeof(pstring) - (p - options) - 1, "%s=%s,", opts, opteq+1);
767 p += strlen(p);
769 } else {
770 val = 1;
771 if(!strcmp(opts, "nocaps")) {
772 fprintf(stderr, "Unhandled option: %s\n", opteq+1);
773 exit(1);
774 } else if(!strcmp(opts, "guest")) {
775 *password = '\0';
776 got_pass = True;
777 } else if(!strcmp(opts, "rw")) {
778 mount_ro = 0;
779 } else if(!strcmp(opts, "ro")) {
780 mount_ro = 1;
781 } else {
782 strncpy(p, opts, sizeof(pstring) - (p - options) - 1);
783 p += strlen(opts);
784 *p++ = ',';
785 *p = 0;
790 if (!*service) {
791 usage();
792 exit(1);
795 if (p != options) {
796 *(p-1) = 0; /* remove trailing , */
797 DEBUG(3,("passthrough options '%s'\n", options));
801 /****************************************************************************
802 main program
803 ****************************************************************************/
804 int main(int argc,char *argv[])
806 extern char *optarg;
807 extern int optind;
808 char *p;
810 DEBUGLEVEL = 1;
812 /* here we are interactive, even if run from autofs */
813 setup_logging("mount.smbfs",True);
815 #if 0 /* JRA - Urban says not needed ? */
816 /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default
817 is to not announce any unicode capabilities as current smbfs does
818 not support it. */
819 p = getenv("CLI_FORCE_ASCII");
820 if (p && !strcmp(p, "false"))
821 unsetenv("CLI_FORCE_ASCII");
822 else
823 setenv("CLI_FORCE_ASCII", "true", 1);
824 #endif
826 in_client = True; /* Make sure that we tell lp_load we are */
828 if (getenv("USER")) {
829 pstrcpy(username,getenv("USER"));
831 if ((p=strchr_m(username,'%'))) {
832 *p = 0;
833 pstrcpy(password,p+1);
834 got_pass = True;
835 memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password));
837 strupper(username);
840 if (getenv("PASSWD")) {
841 pstrcpy(password,getenv("PASSWD"));
842 got_pass = True;
845 if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
846 get_password_file();
847 got_pass = True;
850 if (*username == 0 && getenv("LOGNAME")) {
851 pstrcpy(username,getenv("LOGNAME"));
854 if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
855 fprintf(stderr, "Can't load %s - run testparm to debug it\n",
856 dyn_CONFIGFILE);
859 parse_mount_smb(argc, argv);
861 if (*credentials != 0) {
862 read_credentials_file(credentials);
865 DEBUG(3,("mount.smbfs started (version %s)\n", VERSION));
867 if (*workgroup == 0) {
868 pstrcpy(workgroup,lp_workgroup());
871 load_interfaces();
872 if (!*my_netbios_name) {
873 pstrcpy(my_netbios_name, myhostname());
875 strupper(my_netbios_name);
877 init_mount();
878 return 0;