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