client/smbmount.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    SMBFS mount program
00004    Copyright (C) Andrew Tridgell 1999
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 #include "includes.h"
00022 
00023 #include <mntent.h>
00024 #include <asm/types.h>
00025 #include <linux/smb_fs.h>
00026 
00027 extern BOOL in_client;
00028 extern pstring user_socket_options;
00029 extern char *optarg;
00030 extern int optind;
00031 
00032 static pstring credentials;
00033 static pstring my_netbios_name;
00034 static pstring password;
00035 static pstring username;
00036 static pstring workgroup;
00037 static pstring mpoint;
00038 static pstring service;
00039 static pstring options;
00040 
00041 static struct in_addr dest_ip;
00042 static BOOL have_ip;
00043 static int smb_port = 0;
00044 static BOOL got_user;
00045 static BOOL got_pass;
00046 static uid_t mount_uid;
00047 static gid_t mount_gid;
00048 static int mount_ro;
00049 static unsigned mount_fmask;
00050 static unsigned mount_dmask;
00051 static BOOL use_kerberos;
00052 /* TODO: Add code to detect smbfs version in kernel */
00053 static BOOL status32_smbfs = False;
00054 static BOOL smbfs_has_unicode = False;
00055 static BOOL smbfs_has_lfs = False;
00056 
00057 static void usage(void);
00058 
00059 static void exit_parent(int sig)
00060 {
00061         /* parent simply exits when child says go... */
00062         exit(0);
00063 }
00064 
00065 static void daemonize(void)
00066 {
00067         int j, status;
00068         pid_t child_pid;
00069 
00070         signal( SIGTERM, exit_parent );
00071 
00072         if ((child_pid = sys_fork()) < 0) {
00073                 DEBUG(0,("could not fork\n"));
00074         }
00075 
00076         if (child_pid > 0) {
00077                 while( 1 ) {
00078                         j = waitpid( child_pid, &status, 0 );
00079                         if( j < 0 ) {
00080                                 if( EINTR == errno ) {
00081                                         continue;
00082                                 }
00083                                 status = errno;
00084                         }
00085                         break;
00086                 }
00087 
00088                 /* If we get here - the child exited with some error status */
00089                 if (WIFSIGNALED(status))
00090                         exit(128 + WTERMSIG(status));
00091                 else
00092                         exit(WEXITSTATUS(status));
00093         }
00094 
00095         signal( SIGTERM, SIG_DFL );
00096         chdir("/");
00097 }
00098 
00099 static void close_our_files(int client_fd)
00100 {
00101         int i;
00102         struct rlimit limits;
00103 
00104         getrlimit(RLIMIT_NOFILE,&limits);
00105         for (i = 0; i< limits.rlim_max; i++) {
00106                 if (i == client_fd)
00107                         continue;
00108                 close(i);
00109         }
00110 }
00111 
00112 static void usr1_handler(int x)
00113 {
00114         return;
00115 }
00116 
00117 
00118 /***************************************************** 
00119 return a connection to a server
00120 *******************************************************/
00121 static struct cli_state *do_connection(char *the_service)
00122 {
00123         struct cli_state *c;
00124         struct nmb_name called, calling;
00125         char *server_n;
00126         struct in_addr ip;
00127         pstring server;
00128         char *share;
00129 
00130         if (the_service[0] != '\\' || the_service[1] != '\\') {
00131                 usage();
00132                 exit(1);
00133         }
00134 
00135         pstrcpy(server, the_service+2);
00136         share = strchr_m(server,'\\');
00137         if (!share) {
00138                 usage();
00139                 exit(1);
00140         }
00141         *share = 0;
00142         share++;
00143 
00144         server_n = server;
00145 
00146         make_nmb_name(&calling, my_netbios_name, 0x0);
00147         make_nmb_name(&called , server, 0x20);
00148 
00149  again:
00150         zero_ip(&ip);
00151         if (have_ip) ip = dest_ip;
00152 
00153         /* have to open a new connection */
00154         if (!(c=cli_initialise()) || (cli_set_port(c, smb_port) != smb_port) ||
00155             !NT_STATUS_IS_OK(cli_connect(c, server_n, &ip))) {
00156                 DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n));
00157                 if (c) {
00158                         cli_shutdown(c);
00159                 }
00160                 return NULL;
00161         }
00162 
00163         /* SPNEGO doesn't work till we get NTSTATUS error support */
00164         /* But it is REQUIRED for kerberos authentication */
00165         if(!use_kerberos) c->use_spnego = False;
00166 
00167         /* The kernel doesn't yet know how to sign it's packets */
00168         c->sign_info.allow_smb_signing = False;
00169 
00170         /* Use kerberos authentication if specified */
00171         c->use_kerberos = use_kerberos;
00172 
00173         if (!cli_session_request(c, &calling, &called)) {
00174                 char *p;
00175                 DEBUG(0,("%d: session request to %s failed (%s)\n", 
00176                          sys_getpid(), called.name, cli_errstr(c)));
00177                 cli_shutdown(c);
00178                 if ((p=strchr_m(called.name, '.'))) {
00179                         *p = 0;
00180                         goto again;
00181                 }
00182                 if (strcmp(called.name, "*SMBSERVER")) {
00183                         make_nmb_name(&called , "*SMBSERVER", 0x20);
00184                         goto again;
00185                 }
00186                 return NULL;
00187         }
00188 
00189         DEBUG(4,("%d: session request ok\n", sys_getpid()));
00190 
00191         if (!cli_negprot(c)) {
00192                 DEBUG(0,("%d: protocol negotiation failed\n", sys_getpid()));
00193                 cli_shutdown(c);
00194                 return NULL;
00195         }
00196 
00197         if (!got_pass) {
00198                 char *pass = getpass("Password: ");
00199                 if (pass) {
00200                         pstrcpy(password, pass);
00201                 }
00202         }
00203 
00204         /* This should be right for current smbfs. Future versions will support
00205           large files as well as unicode and oplocks. */
00206         c->capabilities &= ~(CAP_NT_SMBS | CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS);
00207         if (!smbfs_has_lfs)
00208                 c->capabilities &= ~CAP_LARGE_FILES;
00209         if (!smbfs_has_unicode)
00210                 c->capabilities &= ~CAP_UNICODE;
00211         if (!status32_smbfs) {
00212                 c->capabilities &= ~CAP_STATUS32;
00213                 c->force_dos_errors = True;
00214         }
00215 
00216         if (!NT_STATUS_IS_OK(cli_session_setup(c, username, 
00217                                                password, strlen(password),
00218                                                password, strlen(password),
00219                                                workgroup))) {
00220                 /* if a password was not supplied then try again with a
00221                         null username */
00222                 if (password[0] || !username[0] ||
00223                     !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0, workgroup))) {
00224                         DEBUG(0,("%d: session setup failed: %s\n",
00225                                 sys_getpid(), cli_errstr(c)));
00226                         cli_shutdown(c);
00227                         return NULL;
00228                 }
00229                 DEBUG(0,("Anonymous login successful\n"));
00230         }
00231 
00232         DEBUG(4,("%d: session setup ok\n", sys_getpid()));
00233 
00234         if (!cli_send_tconX(c, share, "?????",
00235                             password, strlen(password)+1)) {
00236                 DEBUG(0,("%d: tree connect failed: %s\n",
00237                          sys_getpid(), cli_errstr(c)));
00238                 cli_shutdown(c);
00239                 return NULL;
00240         }
00241 
00242         DEBUG(4,("%d: tconx ok\n", sys_getpid()));
00243 
00244         got_pass = True;
00245 
00246         return c;
00247 }
00248 
00249 
00250 /****************************************************************************
00251 unmount smbfs  (this is a bailout routine to clean up if a reconnect fails)
00252         Code blatently stolen from smbumount.c
00253                 -mhw-
00254 ****************************************************************************/
00255 static void smb_umount(char *mount_point)
00256 {
00257         int fd;
00258         struct mntent *mnt;
00259         FILE* mtab;
00260         FILE* new_mtab;
00261 
00262         /* Programmers Note:
00263                 This routine only gets called to the scene of a disaster
00264                 to shoot the survivors...  A connection that was working
00265                 has now apparently failed.  We have an active mount point
00266                 (presumably) that we need to dump.  If we get errors along
00267                 the way - make some noise, but we are already turning out
00268                 the lights to exit anyways...
00269         */
00270         if (umount(mount_point) != 0) {
00271                 DEBUG(0,("%d: Could not umount %s: %s\n",
00272                          sys_getpid(), mount_point, strerror(errno)));
00273                 return;
00274         }
00275 
00276         if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) {
00277                 DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", sys_getpid()));
00278                 return;
00279         }
00280 
00281         close(fd);
00282         
00283         if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
00284                 DEBUG(0,("%d: Can't open " MOUNTED ": %s\n",
00285                          sys_getpid(), strerror(errno)));
00286                 return;
00287         }
00288 
00289 #define MOUNTED_TMP MOUNTED".tmp"
00290 
00291         if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
00292                 DEBUG(0,("%d: Can't open " MOUNTED_TMP ": %s\n",
00293                          sys_getpid(), strerror(errno)));
00294                 endmntent(mtab);
00295                 return;
00296         }
00297 
00298         while ((mnt = getmntent(mtab)) != NULL) {
00299                 if (strcmp(mnt->mnt_dir, mount_point) != 0) {
00300                         addmntent(new_mtab, mnt);
00301                 }
00302         }
00303 
00304         endmntent(mtab);
00305 
00306         if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
00307                 DEBUG(0,("%d: Error changing mode of %s: %s\n",
00308                          sys_getpid(), MOUNTED_TMP, strerror(errno)));
00309                 return;
00310         }
00311 
00312         endmntent(new_mtab);
00313 
00314         if (rename(MOUNTED_TMP, MOUNTED) < 0) {
00315                 DEBUG(0,("%d: Cannot rename %s to %s: %s\n",
00316                          sys_getpid(), MOUNTED, MOUNTED_TMP, strerror(errno)));
00317                 return;
00318         }
00319 
00320         if (unlink(MOUNTED"~") == -1) {
00321                 DEBUG(0,("%d: Can't remove "MOUNTED"~", sys_getpid()));
00322                 return;
00323         }
00324 }
00325 
00326 
00327 /*
00328  * Call the smbfs ioctl to install a connection socket,
00329  * then wait for a signal to reconnect. Note that we do
00330  * not exit after open_sockets() or send_login() errors,
00331  * as the smbfs mount would then have no way to recover.
00332  */
00333 static void send_fs_socket(char *the_service, char *mount_point, struct cli_state *c)
00334 {
00335         int fd, closed = 0, res = 1;
00336         pid_t parentpid = getppid();
00337         struct smb_conn_opt conn_options;
00338 
00339         memset(&conn_options, 0, sizeof(conn_options));
00340 
00341         while (1) {
00342                 if ((fd = open(mount_point, O_RDONLY)) < 0) {
00343                         DEBUG(0,("mount.smbfs[%d]: can't open %s\n",
00344                                  sys_getpid(), mount_point));
00345                         break;
00346                 }
00347 
00348                 conn_options.fd = c->fd;
00349                 conn_options.protocol = c->protocol;
00350                 conn_options.case_handling = SMB_CASE_DEFAULT;
00351                 conn_options.max_xmit = c->max_xmit;
00352                 conn_options.server_uid = c->vuid;
00353                 conn_options.tid = c->cnum;
00354                 conn_options.secmode = c->sec_mode;
00355                 conn_options.rawmode = 0;
00356                 conn_options.sesskey = c->sesskey;
00357                 conn_options.maxraw = 0;
00358                 conn_options.capabilities = c->capabilities;
00359                 conn_options.serverzone = c->serverzone/60;
00360 
00361                 res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options);
00362                 if (res != 0) {
00363                         DEBUG(0,("mount.smbfs[%d]: ioctl failed, res=%d\n",
00364                                  sys_getpid(), res));
00365                         close(fd);
00366                         break;
00367                 }
00368 
00369                 if (parentpid) {
00370                         /* Ok...  We are going to kill the parent.  Now
00371                                 is the time to break the process group... */
00372                         setsid();
00373                         /* Send a signal to the parent to terminate */
00374                         kill(parentpid, SIGTERM);
00375                         parentpid = 0;
00376                 }
00377 
00378                 close(fd);
00379 
00380                 /* This looks wierd but we are only closing the userspace
00381                    side, the connection has already been passed to smbfs and 
00382                    it has increased the usage count on the socket.
00383 
00384                    If we don't do this we will "leak" sockets and memory on
00385                    each reconnection we have to make. */
00386                 c->smb_rw_error = DO_NOT_DO_TDIS;
00387                 cli_shutdown(c);
00388                 c = NULL;
00389 
00390                 if (!closed) {
00391                         /* close the name cache so that close_our_files() doesn't steal its FD */
00392                         namecache_shutdown();
00393 
00394                         /* redirect stdout & stderr since we can't know that
00395                            the library functions we use are using DEBUG. */
00396                         if ( (fd = open("/dev/null", O_WRONLY)) < 0)
00397                                 DEBUG(2,("mount.smbfs: can't open /dev/null\n"));
00398                         close_our_files(fd);
00399                         if (fd >= 0) {
00400                                 dup2(fd, STDOUT_FILENO);
00401                                 dup2(fd, STDERR_FILENO);
00402                                 close(fd);
00403                         }
00404 
00405                         /* here we are no longer interactive */
00406                         set_remote_machine_name("smbmount", False);     /* sneaky ... */
00407                         setup_logging("mount.smbfs", False);
00408                         reopen_logs();
00409                         DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, sys_getpid()));
00410 
00411                         closed = 1;
00412                 }
00413 
00414                 /* Wait for a signal from smbfs ... but don't continue
00415                    until we actually get a new connection. */
00416                 while (!c) {
00417                         CatchSignal(SIGUSR1, &usr1_handler);
00418                         pause();
00419                         DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid()));
00420                         c = do_connection(the_service);
00421                 }
00422         }
00423 
00424         smb_umount(mount_point);
00425         DEBUG(2,("mount.smbfs[%d]: exit\n", sys_getpid()));
00426         exit(1);
00427 }
00428 
00429 
00430 /**
00431  * Mount a smbfs
00432  **/
00433 static void init_mount(void)
00434 {
00435         char mount_point[PATH_MAX+1];
00436         pstring tmp;
00437         pstring svc2;
00438         struct cli_state *c;
00439         char *args[20];
00440         int i, status;
00441 
00442         if (realpath(mpoint, mount_point) == NULL) {
00443                 fprintf(stderr, "Could not resolve mount point %s\n", mpoint);
00444                 return;
00445         }
00446 
00447 
00448         c = do_connection(service);
00449         if (!c) {
00450                 fprintf(stderr,"SMB connection failed\n");
00451                 exit(1);
00452         }
00453 
00454         /*
00455                 Set up to return as a daemon child and wait in the parent
00456                 until the child say it's ready...
00457         */
00458         daemonize();
00459 
00460         pstrcpy(svc2, service);
00461         string_replace(svc2, '\\','/');
00462         string_replace(svc2, ' ','_');
00463 
00464         memset(args, 0, sizeof(args[0])*20);
00465 
00466         i=0;
00467         args[i++] = "smbmnt";
00468 
00469         args[i++] = mount_point;
00470         args[i++] = "-s";
00471         args[i++] = svc2;
00472 
00473         if (mount_ro) {
00474                 args[i++] = "-r";
00475         }
00476         if (mount_uid) {
00477                 slprintf(tmp, sizeof(tmp)-1, "%d", mount_uid);
00478                 args[i++] = "-u";
00479                 args[i++] = smb_xstrdup(tmp);
00480         }
00481         if (mount_gid) {
00482                 slprintf(tmp, sizeof(tmp)-1, "%d", mount_gid);
00483                 args[i++] = "-g";
00484                 args[i++] = smb_xstrdup(tmp);
00485         }
00486         if (mount_fmask) {
00487                 slprintf(tmp, sizeof(tmp)-1, "0%o", mount_fmask);
00488                 args[i++] = "-f";
00489                 args[i++] = smb_xstrdup(tmp);
00490         }
00491         if (mount_dmask) {
00492                 slprintf(tmp, sizeof(tmp)-1, "0%o", mount_dmask);
00493                 args[i++] = "-d";
00494                 args[i++] = smb_xstrdup(tmp);
00495         }
00496         if (options) {
00497                 args[i++] = "-o";
00498                 args[i++] = options;
00499         }
00500 
00501         if (sys_fork() == 0) {
00502                 char *smbmnt_path;
00503 
00504                 asprintf(&smbmnt_path, "%s/smbmnt", dyn_BINDIR);
00505                 
00506                 if (file_exist(smbmnt_path, NULL)) {
00507                         execv(smbmnt_path, args);
00508                         fprintf(stderr,
00509                                 "smbfs/init_mount: execv of %s failed. Error was %s.",
00510                                 smbmnt_path, strerror(errno));
00511                 } else {
00512                         execvp("smbmnt", args);
00513                         fprintf(stderr,
00514                                 "smbfs/init_mount: execv of %s failed. Error was %s.",
00515                                 "smbmnt", strerror(errno));
00516                 }
00517                 free(smbmnt_path);
00518                 exit(1);
00519         }
00520 
00521         if (waitpid(-1, &status, 0) == -1) {
00522                 fprintf(stderr,"waitpid failed: Error was %s", strerror(errno) );
00523                 /* FIXME: do some proper error handling */
00524                 exit(1);
00525         }
00526 
00527         if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
00528                 fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status));
00529                 /* FIXME: do some proper error handling */
00530                 exit(1);
00531         } else if (WIFSIGNALED(status)) {
00532                 fprintf(stderr, "smbmnt killed by signal %d\n", WTERMSIG(status));
00533                 exit(1);
00534         }
00535 
00536         /* Ok...  This is the rubicon for that mount point...  At any point
00537            after this, if the connections fail and can not be reconstructed
00538            for any reason, we will have to unmount the mount point.  There
00539            is no exit from the next call...
00540         */
00541         send_fs_socket(service, mount_point, c);
00542 }
00543 
00544 
00545 /****************************************************************************
00546 get a password from a a file or file descriptor
00547 exit on failure (from smbclient, move to libsmb or shared .c file?)
00548 ****************************************************************************/
00549 static void get_password_file(void)
00550 {
00551         int fd = -1;
00552         char *p;
00553         BOOL close_it = False;
00554         pstring spec;
00555         char pass[128];
00556 
00557         if ((p = getenv("PASSWD_FD")) != NULL) {
00558                 pstrcpy(spec, "descriptor ");
00559                 pstrcat(spec, p);
00560                 sscanf(p, "%d", &fd);
00561                 close_it = False;
00562         } else if ((p = getenv("PASSWD_FILE")) != NULL) {
00563                 fd = sys_open(p, O_RDONLY, 0);
00564                 pstrcpy(spec, p);
00565                 if (fd < 0) {
00566                         fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
00567                                 spec, strerror(errno));
00568                         exit(1);
00569                 }
00570                 close_it = True;
00571         }
00572 
00573         for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
00574             p && p - pass < sizeof(pass);) {
00575                 switch (read(fd, p, 1)) {
00576                 case 1:
00577                         if (*p != '\n' && *p != '\0') {
00578                                 *++p = '\0'; /* advance p, and null-terminate pass */
00579                                 break;
00580                         }
00581                 case 0:
00582                         if (p - pass) {
00583                                 *p = '\0'; /* null-terminate it, just in case... */
00584                                 p = NULL; /* then force the loop condition to become false */
00585                                 break;
00586                         } else {
00587                                 fprintf(stderr, "Error reading password from file %s: %s\n",
00588                                         spec, "empty password\n");
00589                                 exit(1);
00590                         }
00591 
00592                 default:
00593                         fprintf(stderr, "Error reading password from file %s: %s\n",
00594                                 spec, strerror(errno));
00595                         exit(1);
00596                 }
00597         }
00598         pstrcpy(password, pass);
00599         if (close_it)
00600                 close(fd);
00601 }
00602 
00603 /****************************************************************************
00604 get username and password from a credentials file
00605 exit on failure (from smbclient, move to libsmb or shared .c file?)
00606 ****************************************************************************/
00607 static void read_credentials_file(char *filename)
00608 {
00609         FILE *auth;
00610         fstring buf;
00611         uint16 len = 0;
00612         char *ptr, *val, *param;
00613 
00614         if ((auth=sys_fopen(filename, "r")) == NULL)
00615         {
00616                 /* fail if we can't open the credentials file */
00617                 DEBUG(0,("ERROR: Unable to open credentials file!\n"));
00618                 exit (-1);
00619         }
00620 
00621         while (!feof(auth))
00622         {
00623                 /* get a line from the file */
00624                 if (!fgets (buf, sizeof(buf), auth))
00625                         continue;
00626                 len = strlen(buf);
00627 
00628                 if ((len) && (buf[len-1]=='\n'))
00629                 {
00630                         buf[len-1] = '\0';
00631                         len--;
00632                 }
00633                 if (len == 0)
00634                         continue;
00635 
00636                 /* break up the line into parameter & value.
00637                    will need to eat a little whitespace possibly */
00638                 param = buf;
00639                 if (!(ptr = strchr (buf, '=')))
00640                         continue;
00641                 val = ptr+1;
00642                 *ptr = '\0';
00643 
00644                 /* eat leading white space */
00645                 while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
00646                         val++;
00647 
00648                 if (strwicmp("password", param) == 0)
00649                 {
00650                         pstrcpy(password, val);
00651                         got_pass = True;
00652                 }
00653                 else if (strwicmp("username", param) == 0) {
00654                         pstrcpy(username, val);
00655                 }
00656 
00657                 memset(buf, 0, sizeof(buf));
00658         }
00659         fclose(auth);
00660 }
00661 
00662 
00663 /****************************************************************************
00664 usage on the program
00665 ****************************************************************************/
00666 static void usage(void)
00667 {
00668         printf("Usage: mount.smbfs service mountpoint [-o options,...]\n");
00669 
00670         printf("Version %s\n\n",SAMBA_VERSION_STRING);
00671 
00672         printf("Please be aware that smbfs is deprecated in favor of "
00673                "cifs\n\n");
00674 
00675         printf(
00676 "Options:\n\
00677       username=<arg>                  SMB username\n\
00678       password=<arg>                  SMB password\n\
00679       credentials=<filename>          file with username/password\n\
00680       krb                             use kerberos (active directory)\n\
00681       netbiosname=<arg>               source NetBIOS name\n\
00682       uid=<arg>                       mount uid or username\n\
00683       gid=<arg>                       mount gid or groupname\n\
00684       port=<arg>                      remote SMB port number\n\
00685       fmask=<arg>                     file umask\n\
00686       dmask=<arg>                     directory umask\n\
00687       debug=<arg>                     debug level\n\
00688       ip=<arg>                        destination host or IP address\n\
00689       workgroup=<arg>                 workgroup on destination\n\
00690       sockopt=<arg>                   TCP socket options\n\
00691       scope=<arg>                     NetBIOS scope\n\
00692       iocharset=<arg>                 Linux charset (iso8859-1, utf8)\n\
00693       codepage=<arg>                  server codepage (cp850)\n\
00694       unicode                         use unicode when communicating with server\n\
00695       lfs                             large file system support\n\
00696       ttl=<arg>                       dircache time to live\n\
00697       guest                           don't prompt for a password\n\
00698       ro                              mount read-only\n\
00699       rw                              mount read-write\n\
00700 \n\
00701 This command is designed to be run from within /bin/mount by giving\n\
00702 the option '-t smbfs'. For example:\n\
00703   mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test\n\
00704 ");
00705 }
00706 
00707 
00708 /****************************************************************************
00709   Argument parsing for mount.smbfs interface
00710   mount will call us like this:
00711     mount.smbfs device mountpoint -o <options>
00712   
00713   <options> is never empty, containing at least rw or ro
00714  ****************************************************************************/
00715 static void parse_mount_smb(int argc, char **argv)
00716 {
00717         int opt;
00718         char *opts;
00719         char *opteq;
00720         int val;
00721         char *p;
00722 
00723         /* FIXME: This function can silently fail if the arguments are
00724          * not in the expected order.
00725 
00726         > The arguments syntax of smbmount 2.2.3a (smbfs of Debian stable)
00727         > requires that one gives "-o" before further options like username=...
00728         > . Without -o, the username=.. setting is *silently* ignored. I've
00729         > spent about an hour trying to find out why I couldn't log in now..
00730 
00731         */
00732 
00733 
00734         if (argc < 2 || argv[1][0] == '-') {
00735                 usage();
00736                 exit(1);
00737         }
00738         
00739         pstrcpy(service, argv[1]);
00740         pstrcpy(mpoint, argv[2]);
00741 
00742         /* Convert any '/' characters in the service name to
00743            '\' characters */
00744         string_replace(service, '/','\\');
00745         argc -= 2;
00746         argv += 2;
00747 
00748         opt = getopt(argc, argv, "o:");
00749         if(opt != 'o') {
00750                 return;
00751         }
00752 
00753         options[0] = 0;
00754         p = options;
00755 
00756         /*
00757          * option parsing from nfsmount.c (util-linux-2.9u)
00758          */
00759         for (opts = strtok(optarg, ","); opts; opts = strtok(NULL, ",")) {
00760                 DEBUG(3, ("opts: %s\n", opts));
00761                 if ((opteq = strchr_m(opts, '='))) {
00762                         val = atoi(opteq + 1);
00763                         *opteq = '\0';
00764 
00765                         if (!strcmp(opts, "username") || 
00766                             !strcmp(opts, "logon")) {
00767                                 char *lp;
00768                                 got_user = True;
00769                                 pstrcpy(username,opteq+1);
00770                                 if ((lp=strchr_m(username,'%'))) {
00771                                         *lp = 0;
00772                                         pstrcpy(password,lp+1);
00773                                         got_pass = True;
00774                                         memset(strchr_m(opteq+1,'%')+1,'X',strlen(password));
00775                                 }
00776                                 if ((lp=strchr_m(username,'/'))) {
00777                                         *lp = 0;
00778                                         pstrcpy(workgroup,lp+1);
00779                                 }
00780                         } else if(!strcmp(opts, "passwd") ||
00781                                   !strcmp(opts, "password")) {
00782                                 pstrcpy(password,opteq+1);
00783                                 got_pass = True;
00784                                 memset(opteq+1,'X',strlen(password));
00785                         } else if(!strcmp(opts, "credentials")) {
00786                                 pstrcpy(credentials,opteq+1);
00787                         } else if(!strcmp(opts, "netbiosname")) {
00788                                 pstrcpy(my_netbios_name,opteq+1);
00789                         } else if(!strcmp(opts, "uid")) {
00790                                 mount_uid = nametouid(opteq+1);
00791                         } else if(!strcmp(opts, "gid")) {
00792                                 mount_gid = nametogid(opteq+1);
00793                         } else if(!strcmp(opts, "port")) {
00794                                 smb_port = val;
00795                         } else if(!strcmp(opts, "fmask")) {
00796                                 mount_fmask = strtol(opteq+1, NULL, 8);
00797                         } else if(!strcmp(opts, "dmask")) {
00798                                 mount_dmask = strtol(opteq+1, NULL, 8);
00799                         } else if(!strcmp(opts, "debug")) {
00800                                 DEBUGLEVEL = val;
00801                         } else if(!strcmp(opts, "ip")) {
00802                                 dest_ip = *interpret_addr2(opteq+1);
00803                                 if (is_zero_ip(dest_ip)) {
00804                                         fprintf(stderr,"Can't resolve address %s\n", opteq+1);
00805                                         exit(1);
00806                                 }
00807                                 have_ip = True;
00808                         } else if(!strcmp(opts, "workgroup")) {
00809                                 pstrcpy(workgroup,opteq+1);
00810                         } else if(!strcmp(opts, "sockopt")) {
00811                                 pstrcpy(user_socket_options,opteq+1);
00812                         } else if(!strcmp(opts, "scope")) {
00813                                 set_global_scope(opteq+1);
00814                         } else {
00815                                 slprintf(p, sizeof(pstring) - (p - options) - 1, "%s=%s,", opts, opteq+1);
00816                                 p += strlen(p);
00817                         }
00818                 } else {
00819                         val = 1;
00820                         if(!strcmp(opts, "nocaps")) {
00821                                 fprintf(stderr, "Unhandled option: %s\n", opteq+1);
00822                                 exit(1);
00823                         } else if(!strcmp(opts, "guest")) {
00824                                 *password = '\0';
00825                                 got_pass = True;
00826                         } else if(!strcmp(opts, "krb")) {
00827 #ifdef HAVE_KRB5
00828 
00829                                 use_kerberos = True;
00830                                 if(!status32_smbfs)
00831                                         fprintf(stderr, "Warning: kerberos support will only work for samba servers\n");
00832 #else
00833                                 fprintf(stderr,"No kerberos support compiled in\n");
00834                                 exit(1);
00835 #endif
00836                         } else if(!strcmp(opts, "rw")) {
00837                                 mount_ro = 0;
00838                         } else if(!strcmp(opts, "ro")) {
00839                                 mount_ro = 1;
00840                         } else if(!strcmp(opts, "unicode")) {
00841                                 smbfs_has_unicode = True;
00842                         } else if(!strcmp(opts, "lfs")) {
00843                                 smbfs_has_lfs = True;
00844                         } else {
00845                                 strncpy(p, opts, sizeof(pstring) - (p - options) - 1);
00846                                 p += strlen(opts);
00847                                 *p++ = ',';
00848                                 *p = 0;
00849                         }
00850                 }
00851         }
00852 
00853         if (!*service) {
00854                 usage();
00855                 exit(1);
00856         }
00857 
00858         if (p != options) {
00859                 *(p-1) = 0;     /* remove trailing , */
00860                 DEBUG(3,("passthrough options '%s'\n", options));
00861         }
00862 }
00863 
00864 /****************************************************************************
00865   main program
00866 ****************************************************************************/
00867  int main(int argc,char *argv[])
00868 {
00869         char *p;
00870 
00871         DEBUGLEVEL = 1;
00872 
00873         load_case_tables();
00874 
00875         /* here we are interactive, even if run from autofs */
00876         setup_logging("mount.smbfs",True);
00877 
00878 #if 0 /* JRA - Urban says not needed ? */
00879         /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default
00880            is to not announce any unicode capabilities as current smbfs does
00881            not support it. */
00882         p = getenv("CLI_FORCE_ASCII");
00883         if (p && !strcmp(p, "false"))
00884                 unsetenv("CLI_FORCE_ASCII");
00885         else
00886                 setenv("CLI_FORCE_ASCII", "true", 1);
00887 #endif
00888 
00889         in_client = True;   /* Make sure that we tell lp_load we are */
00890 
00891         if (getenv("USER")) {
00892                 pstrcpy(username,getenv("USER"));
00893 
00894                 if ((p=strchr_m(username,'%'))) {
00895                         *p = 0;
00896                         pstrcpy(password,p+1);
00897                         got_pass = True;
00898                         memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password));
00899                 }
00900                 strupper_m(username);
00901         }
00902 
00903         if (getenv("PASSWD")) {
00904                 pstrcpy(password,getenv("PASSWD"));
00905                 got_pass = True;
00906         }
00907 
00908         if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
00909                 get_password_file();
00910                 got_pass = True;
00911         }
00912 
00913         if (*username == 0 && getenv("LOGNAME")) {
00914                 pstrcpy(username,getenv("LOGNAME"));
00915         }
00916 
00917         if (!lp_load(dyn_CONFIGFILE,True,False,False,True)) {
00918                 fprintf(stderr, "Can't load %s - run testparm to debug it\n", 
00919                         dyn_CONFIGFILE);
00920         }
00921 
00922         parse_mount_smb(argc, argv);
00923 
00924         if (use_kerberos && !got_user) {
00925                 got_pass = True;
00926         }
00927 
00928         if (*credentials != 0) {
00929                 read_credentials_file(credentials);
00930         }
00931 
00932         DEBUG(3,("mount.smbfs started (version %s)\n", SAMBA_VERSION_STRING));
00933 
00934         if (*workgroup == 0) {
00935                 pstrcpy(workgroup,lp_workgroup());
00936         }
00937 
00938         load_interfaces();
00939         if (!*my_netbios_name) {
00940                 pstrcpy(my_netbios_name, myhostname());
00941         }
00942         strupper_m(my_netbios_name);
00943 
00944         init_mount();
00945         return 0;
00946 }

Sambaに対してSat Aug 29 21:22:53 2009に生成されました。  doxygen 1.4.7