trying to get HEAD building again. If you want the code
[gd/samba-autobuild/.git] / source3 / client / smbmount.c
index 8b56d21bec77e739d7c2833d03efb9daddbe4cc0..343d4f267576b7b7cf2821f8d9016817763f38ea 100644 (file)
@@ -1,6 +1,5 @@
 /* 
-   Unix SMB/Netbios implementation.
-   Version 2.0.
+   Unix SMB/CIFS implementation.
    SMBFS mount program
    Copyright (C) Andrew Tridgell 1999
    
@@ -29,8 +28,6 @@
 
 extern BOOL in_client;
 extern pstring user_socket_options;
-extern BOOL append_log;
-extern fstring remote_machine;
 
 static pstring credentials;
 static pstring my_netbios_name;
@@ -44,12 +41,18 @@ static pstring options;
 static struct in_addr dest_ip;
 static BOOL have_ip;
 static int smb_port = 0;
+static BOOL got_user;
 static BOOL got_pass;
 static uid_t mount_uid;
 static gid_t mount_gid;
 static int mount_ro;
 static unsigned mount_fmask;
 static unsigned mount_dmask;
+static BOOL use_kerberos;
+/* TODO: Add code to detect smbfs version in kernel */
+static BOOL status32_smbfs = False;
+static BOOL smbfs_has_unicode = False;
+static BOOL smbfs_has_lfs = False;
 
 static void usage(void);
 
@@ -81,8 +84,12 @@ static void daemonize(void)
                        }
                        break;
                }
+
                /* If we get here - the child exited with some error status */
-               exit(status);
+               if (WIFSIGNALED(status))
+                       exit(128 + WTERMSIG(status));
+               else
+                       exit(WEXITSTATUS(status));
        }
 
        signal( SIGTERM, SIG_DFL );
@@ -146,7 +153,7 @@ static struct cli_state *do_connection(char *the_service)
        /* have to open a new connection */
        if (!(c=cli_initialise(NULL)) || (cli_set_port(c, smb_port) != smb_port) ||
            !cli_connect(c, server_n, &ip)) {
-               DEBUG(0,("%d: Connection to %s failed\n", getpid(), server_n));
+               DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n));
                if (c) {
                        cli_shutdown(c);
                }
@@ -154,12 +161,19 @@ static struct cli_state *do_connection(char *the_service)
        }
 
        /* SPNEGO doesn't work till we get NTSTATUS error support */
-       c->use_spnego = False;
+       /* But it is REQUIRED for kerberos authentication */
+       if(!use_kerberos) c->use_spnego = False;
+
+       /* The kernel doesn't yet know how to sign it's packets */
+       c->sign_info.allow_smb_signing = False;
+
+       /* Use kerberos authentication if specified */
+       c->use_kerberos = use_kerberos;
 
        if (!cli_session_request(c, &calling, &called)) {
                char *p;
                DEBUG(0,("%d: session request to %s failed (%s)\n", 
-                        getpid(), called.name, cli_errstr(c)));
+                        sys_getpid(), called.name, cli_errstr(c)));
                cli_shutdown(c);
                if ((p=strchr_m(called.name, '.'))) {
                        *p = 0;
@@ -172,10 +186,10 @@ static struct cli_state *do_connection(char *the_service)
                return NULL;
        }
 
-       DEBUG(4,("%d: session request ok\n", getpid()));
+       DEBUG(4,("%d: session request ok\n", sys_getpid()));
 
        if (!cli_negprot(c)) {
-               DEBUG(0,("%d: protocol negotiation failed\n", getpid()));
+               DEBUG(0,("%d: protocol negotiation failed\n", sys_getpid()));
                cli_shutdown(c);
                return NULL;
        }
@@ -189,9 +203,16 @@ static struct cli_state *do_connection(char *the_service)
 
        /* This should be right for current smbfs. Future versions will support
          large files as well as unicode and oplocks. */
-       c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS |
-                               CAP_NT_FIND | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS);
-       c->force_dos_errors = True;
+       c->capabilities &= ~(CAP_NT_SMBS | CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS);
+       if (!smbfs_has_lfs)
+               c->capabilities &= ~CAP_LARGE_FILES;
+       if (!smbfs_has_unicode)
+               c->capabilities &= ~CAP_UNICODE;
+       if (!status32_smbfs) {
+               c->capabilities &= ~CAP_STATUS32;
+               c->force_dos_errors = True;
+       }
+
        if (!cli_session_setup(c, username, 
                               password, strlen(password),
                               password, strlen(password),
@@ -201,24 +222,24 @@ static struct cli_state *do_connection(char *the_service)
                if (password[0] || !username[0] ||
                                !cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
                        DEBUG(0,("%d: session setup failed: %s\n",
-                               getpid(), cli_errstr(c)));
+                               sys_getpid(), cli_errstr(c)));
                        cli_shutdown(c);
                        return NULL;
                }
                DEBUG(0,("Anonymous login successful\n"));
        }
 
-       DEBUG(4,("%d: session setup ok\n", getpid()));
+       DEBUG(4,("%d: session setup ok\n", sys_getpid()));
 
        if (!cli_send_tconX(c, share, "?????",
                            password, strlen(password)+1)) {
                DEBUG(0,("%d: tree connect failed: %s\n",
-                        getpid(), cli_errstr(c)));
+                        sys_getpid(), cli_errstr(c)));
                cli_shutdown(c);
                return NULL;
        }
 
-       DEBUG(4,("%d: tconx ok\n", getpid()));
+       DEBUG(4,("%d: tconx ok\n", sys_getpid()));
 
        got_pass = True;
 
@@ -248,12 +269,12 @@ static void smb_umount(char *mount_point)
        */
         if (umount(mount_point) != 0) {
                 DEBUG(0,("%d: Could not umount %s: %s\n",
-                        getpid(), mount_point, strerror(errno)));
+                        sys_getpid(), mount_point, strerror(errno)));
                 return;
         }
 
         if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) {
-                DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", getpid()));
+                DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", sys_getpid()));
                 return;
         }
 
@@ -261,7 +282,7 @@ static void smb_umount(char *mount_point)
        
         if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
                 DEBUG(0,("%d: Can't open " MOUNTED ": %s\n",
-                        getpid(), strerror(errno)));
+                        sys_getpid(), strerror(errno)));
                 return;
         }
 
@@ -269,7 +290,7 @@ static void smb_umount(char *mount_point)
 
         if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
                 DEBUG(0,("%d: Can't open " MOUNTED_TMP ": %s\n",
-                        getpid(), strerror(errno)));
+                        sys_getpid(), strerror(errno)));
                 endmntent(mtab);
                 return;
         }
@@ -284,7 +305,7 @@ static void smb_umount(char *mount_point)
 
         if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
                 DEBUG(0,("%d: Error changing mode of %s: %s\n",
-                        getpid(), MOUNTED_TMP, strerror(errno)));
+                        sys_getpid(), MOUNTED_TMP, strerror(errno)));
                 return;
         }
 
@@ -292,12 +313,12 @@ static void smb_umount(char *mount_point)
 
         if (rename(MOUNTED_TMP, MOUNTED) < 0) {
                 DEBUG(0,("%d: Cannot rename %s to %s: %s\n",
-                        getpid(), MOUNTED, MOUNTED_TMP, strerror(errno)));
+                        sys_getpid(), MOUNTED, MOUNTED_TMP, strerror(errno)));
                 return;
         }
 
         if (unlink(MOUNTED"~") == -1) {
-                DEBUG(0,("%d: Can't remove "MOUNTED"~", getpid()));
+                DEBUG(0,("%d: Can't remove "MOUNTED"~", sys_getpid()));
                 return;
         }
 }
@@ -320,7 +341,7 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
        while (1) {
                if ((fd = open(mount_point, O_RDONLY)) < 0) {
                        DEBUG(0,("mount.smbfs[%d]: can't open %s\n",
-                                getpid(), mount_point));
+                                sys_getpid(), mount_point));
                        break;
                }
 
@@ -340,7 +361,7 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
                res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options);
                if (res != 0) {
                        DEBUG(0,("mount.smbfs[%d]: ioctl failed, res=%d\n",
-                                getpid(), res));
+                                sys_getpid(), res));
                        close(fd);
                        break;
                }
@@ -378,11 +399,10 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
                        }
 
                        /* here we are no longer interactive */
-                       pstrcpy(remote_machine, "smbmount");    /* sneaky ... */
+                       set_remote_machine_name("smbmount", False);     /* sneaky ... */
                        setup_logging("mount.smbfs", False);
-                       append_log = True;
                        reopen_logs();
-                       DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, getpid()));
+                       DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, sys_getpid()));
 
                        closed = 1;
                }
@@ -392,13 +412,13 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
                while (!c) {
                        CatchSignal(SIGUSR1, &usr1_handler);
                        pause();
-                       DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", getpid()));
+                       DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid()));
                        c = do_connection(the_service);
                }
        }
 
        smb_umount(mount_point);
-       DEBUG(2,("mount.smbfs[%d]: exit\n", getpid()));
+       DEBUG(2,("mount.smbfs[%d]: exit\n", sys_getpid()));
        exit(1);
 }
 
@@ -504,6 +524,9 @@ static void init_mount(void)
                fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status));
                /* FIXME: do some proper error handling */
                exit(1);
+       } else if (WIFSIGNALED(status)) {
+               fprintf(stderr, "smbmnt killed by signal %d\n", WTERMSIG(status));
+               exit(1);
        }
 
        /* Ok...  This is the rubicon for that mount point...  At any point
@@ -623,8 +646,9 @@ static void read_credentials_file(char *filename)
                        pstrcpy(password, val);
                        got_pass = True;
                }
-               else if (strwicmp("username", param) == 0)
+               else if (strwicmp("username", param) == 0) {
                        pstrcpy(username, val);
+               }
 
                memset(buf, 0, sizeof(buf));
        }
@@ -646,6 +670,7 @@ static void usage(void)
       username=<arg>                  SMB username\n\
       password=<arg>                  SMB password\n\
       credentials=<filename>          file with username/password\n\
+      krb                             use kerberos (active directory)\n\
       netbiosname=<arg>               source NetBIOS name\n\
       uid=<arg>                       mount uid or username\n\
       gid=<arg>                       mount gid or groupname\n\
@@ -659,6 +684,8 @@ static void usage(void)
       scope=<arg>                     NetBIOS scope\n\
       iocharset=<arg>                 Linux charset (iso8859-1, utf8)\n\
       codepage=<arg>                  server codepage (cp850)\n\
+      unicode                         use unicode when communicating with server\n\
+      lfs                             large file system support\n\
       ttl=<arg>                       dircache time to live\n\
       guest                           don't prompt for a password\n\
       ro                              mount read-only\n\
@@ -685,9 +712,19 @@ static void parse_mount_smb(int argc, char **argv)
        char *opteq;
        extern char *optarg;
        int val;
-       extern pstring global_scope;
        char *p;
 
+       /* FIXME: This function can silently fail if the arguments are
+        * not in the expected order.
+
+       > The arguments syntax of smbmount 2.2.3a (smbfs of Debian stable)
+       > requires that one gives "-o" before further options like username=...
+       > . Without -o, the username=.. setting is *silently* ignored. I've
+       > spent about an hour trying to find out why I couldn't log in now..
+
+       */
+
+
        if (argc < 2 || argv[1][0] == '-') {
                usage();
                exit(1);
@@ -722,6 +759,7 @@ static void parse_mount_smb(int argc, char **argv)
                         if (!strcmp(opts, "username") || 
                            !strcmp(opts, "logon")) {
                                char *lp;
+                               got_user = True;
                                pstrcpy(username,opteq+1);
                                if ((lp=strchr_m(username,'%'))) {
                                        *lp = 0;
@@ -766,7 +804,7 @@ static void parse_mount_smb(int argc, char **argv)
                        } else if(!strcmp(opts, "sockopt")) {
                                pstrcpy(user_socket_options,opteq+1);
                        } else if(!strcmp(opts, "scope")) {
-                               pstrcpy(global_scope,opteq+1);
+                               set_global_scope(opteq+1);
                        } else {
                                slprintf(p, sizeof(pstring) - (p - options) - 1, "%s=%s,", opts, opteq+1);
                                p += strlen(p);
@@ -779,10 +817,24 @@ static void parse_mount_smb(int argc, char **argv)
                        } else if(!strcmp(opts, "guest")) {
                                *password = '\0';
                                got_pass = True;
+                       } else if(!strcmp(opts, "krb")) {
+#ifdef HAVE_KRB5
+
+                               use_kerberos = True;
+                               if(!status32_smbfs)
+                                       fprintf(stderr, "Warning: kerberos support will only work for samba servers\n");
+#else
+                               fprintf(stderr,"No kerberos support compiled in\n");
+                               exit(1);
+#endif
                        } else if(!strcmp(opts, "rw")) {
                                mount_ro = 0;
                        } else if(!strcmp(opts, "ro")) {
                                mount_ro = 1;
+                       } else if(!strcmp(opts, "unicode")) {
+                               smbfs_has_unicode = True;
+                       } else if(!strcmp(opts, "lfs")) {
+                               smbfs_has_lfs = True;
                        } else {
                                strncpy(p, opts, sizeof(pstring) - (p - options) - 1);
                                p += strlen(opts);
@@ -839,7 +891,7 @@ static void parse_mount_smb(int argc, char **argv)
                        got_pass = True;
                        memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password));
                }
-               strupper(username);
+               strupper_m(username);
        }
 
        if (getenv("PASSWD")) {
@@ -863,6 +915,10 @@ static void parse_mount_smb(int argc, char **argv)
 
        parse_mount_smb(argc, argv);
 
+       if (use_kerberos && !got_user) {
+               got_pass = True;
+       }
+
        if (*credentials != 0) {
                read_credentials_file(credentials);
        }
@@ -877,7 +933,7 @@ static void parse_mount_smb(int argc, char **argv)
        if (!*my_netbios_name) {
                pstrcpy(my_netbios_name, myhostname());
        }
-       strupper(my_netbios_name);
+       strupper_m(my_netbios_name);
 
        init_mount();
        return 0;