Merge branch 'master' of ssh://git.samba.org/data/git/samba into selftest
[bbaumbach/samba-autobuild/.git] / source4 / client / smbmount.c
index 235a45a3f1df651a171993ad62c017f0ed67a537..37c9eaadc47b3c2f541a46e6c614ba5ed02e1577 100644 (file)
@@ -5,7 +5,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "system/passwd.h"
 
 #include <mntent.h>
 #include <asm/types.h>
 #include <linux/smb_fs.h>
 
-extern BOOL in_client;
-
 static pstring credentials;
 static pstring my_netbios_name;
 static pstring password;
@@ -36,18 +34,18 @@ static pstring service;
 static pstring options;
 
 static struct in_addr dest_ip;
-static BOOL have_ip;
+static bool have_ip;
 static int smb_port = 0;
-static BOOL got_user;
-static BOOL got_pass;
+static bool got_user;
+static bool got_pass;
 static uid_t mount_uid;
 static gid_t mount_gid;
 static int mount_ro;
 static uint_t mount_fmask;
 static uint_t mount_dmask;
-static BOOL use_kerberos;
+static bool use_kerberos;
 /* TODO: Add code to detect smbfs version in kernel */
-static BOOL status32_smbfs = False;
+static bool status32_smbfs = false;
 
 static void usage(void);
 
@@ -113,7 +111,8 @@ static void usr1_handler(int x)
 /***************************************************** 
 return a connection to a server
 *******************************************************/
-static struct smbcli_state *do_connection(char *the_service)
+static struct smbcli_state *do_connection(const char *the_service, bool unicode, int maxprotocol,
+                                         struct smbcli_session_options session_options)
 {
        struct smbcli_state *c;
        struct nmb_name called, calling;
@@ -139,7 +138,7 @@ static struct smbcli_state *do_connection(char *the_service)
        server_n = server;
 
        make_nmb_name(&calling, my_netbios_name, 0x0);
-       make_nmb_name(&called , server, 0x20);
+       choose_called_name(&called, server, 0x20);
 
  again:
         zero_ip(&ip);
@@ -150,17 +149,17 @@ static struct smbcli_state *do_connection(char *the_service)
            !smbcli_connect(c, server_n, &ip)) {
                DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n));
                if (c) {
-                       smbcli_shutdown(c);
+                       talloc_free(c);
                }
                return NULL;
        }
 
        /* SPNEGO doesn't work till we get NTSTATUS error support */
        /* But it is REQUIRED for kerberos authentication */
-       if(!use_kerberos) c->use_spnego = False;
+       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;
+       c->sign_info.allow_smb_signing = false;
 
        /* Use kerberos authentication if specified */
        c->use_kerberos = use_kerberos;
@@ -169,7 +168,7 @@ static struct smbcli_state *do_connection(char *the_service)
                char *p;
                DEBUG(0,("%d: session request to %s failed (%s)\n", 
                         sys_getpid(), called.name, smbcli_errstr(c)));
-               smbcli_shutdown(c);
+               talloc_free(c);
                if ((p=strchr_m(called.name, '.'))) {
                        *p = 0;
                        goto again;
@@ -183,9 +182,9 @@ static struct smbcli_state *do_connection(char *the_service)
 
        DEBUG(4,("%d: session request ok\n", sys_getpid()));
 
-       if (!smbcli_negprot(c)) {
+       if (!smbcli_negprot(c, unicode, maxprotocol)) {
                DEBUG(0,("%d: protocol negotiation failed\n", sys_getpid()));
-               smbcli_shutdown(c);
+               talloc_free(c);
                return NULL;
        }
 
@@ -206,20 +205,21 @@ static struct smbcli_state *do_connection(char *the_service)
            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->force_dos_errors = true;
        }
 
        if (!smbcli_session_setup(c, username, 
                               password, strlen(password),
                               password, strlen(password),
-                              workgroup)) {
+                              workgroup, session_options)) {
                /* if a password was not supplied then try again with a
                        null username */
                if (password[0] || !username[0] ||
-                               !smbcli_session_setup(c, "", "", 0, "", 0, workgroup)) {
+                               !smbcli_session_setup(c, "", "", 0, "", 0, workgroup, 
+                                                     session_options)) {
                        DEBUG(0,("%d: session setup failed: %s\n",
                                sys_getpid(), smbcli_errstr(c)));
-                       smbcli_shutdown(c);
+                       talloc_free(c);
                        return NULL;
                }
                DEBUG(0,("Anonymous login successful\n"));
@@ -227,17 +227,16 @@ static struct smbcli_state *do_connection(char *the_service)
 
        DEBUG(4,("%d: session setup ok\n", sys_getpid()));
 
-       if (!smbcli_send_tconX(c, share, "?????",
-                           password, strlen(password)+1)) {
+       if (!smbcli_tconX(c, share, "?????", password, strlen(password)+1)) {
                DEBUG(0,("%d: tree connect failed: %s\n",
                         sys_getpid(), smbcli_errstr(c)));
-               smbcli_shutdown(c);
+               talloc_free(c);
                return NULL;
        }
 
        DEBUG(4,("%d: tconx ok\n", sys_getpid()));
 
-       got_pass = True;
+       got_pass = true;
 
        return c;
 }
@@ -248,7 +247,7 @@ unmount smbfs  (this is a bailout routine to clean up if a reconnect fails)
        Code blatently stolen from smbumount.c
                -mhw-
 ****************************************************************************/
-static void smb_umount(char *mount_point)
+static void smb_umount(const char *mount_point)
 {
        int fd;
         struct mntent *mnt;
@@ -326,11 +325,15 @@ static void smb_umount(char *mount_point)
  * not exit after open_sockets() or send_login() errors,
  * as the smbfs mount would then have no way to recover.
  */
-static void send_fs_socket(char *the_service, char *mount_point, struct smbcli_state *c)
+static void send_fs_socket(struct loadparm_context *lp_ctx,
+                          const char *the_service, const char *mount_point, struct smbcli_state *c)
 {
        int fd, closed = 0, res = 1;
        pid_t parentpid = getppid();
        struct smb_conn_opt conn_options;
+       struct smbcli_session_options session_options;
+
+       lp_smbcli_session_options(lp_ctx, &session_options);
 
        memset(&conn_options, 0, sizeof(conn_options));
 
@@ -379,7 +382,7 @@ static void send_fs_socket(char *the_service, char *mount_point, struct smbcli_s
 
                   If we don't do this we will "leak" sockets and memory on
                   each reconnection we have to make. */
-               smbcli_shutdown(c);
+               talloc_free(c);
                c = NULL;
 
                if (!closed) {
@@ -409,7 +412,10 @@ static void send_fs_socket(char *the_service, char *mount_point, struct smbcli_s
                        CatchSignal(SIGUSR1, &usr1_handler);
                        pause();
                        DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid()));
-                       c = do_connection(the_service);
+                       c = do_connection(the_service, 
+                                         lp_unicode(lp_ctx), 
+                                         lp_cli_maxprotocol(lp_ctx),
+                                         session_options);
                }
        }
 
@@ -422,7 +428,7 @@ static void send_fs_socket(char *the_service, char *mount_point, struct smbcli_s
 /**
  * Mount a smbfs
  **/
-static void init_mount(void)
+static void init_mount(struct loadparm_context *lp_ctx)
 {
        char mount_point[MAXPATHLEN+1];
        pstring tmp;
@@ -430,14 +436,17 @@ static void init_mount(void)
        struct smbcli_state *c;
        char *args[20];
        int i, status;
+       struct smbcli_session_options session_options;
 
        if (realpath(mpoint, mount_point) == NULL) {
                fprintf(stderr, "Could not resolve mount point %s\n", mpoint);
                return;
        }
 
+       lp_smbcli_session_options(lp_ctx, &session_options);
 
-       c = do_connection(service);
+       c = do_connection(service, lp_unicode(lp_ctx), lp_cli_maxprotocol(lp_ctx),
+                         session_options);
        if (!c) {
                fprintf(stderr,"SMB connection failed\n");
                exit(1);
@@ -495,7 +504,7 @@ static void init_mount(void)
 
                asprintf(&smbmnt_path, "%s/smbmnt", dyn_BINDIR);
                
-               if (file_exist(smbmnt_path, NULL)) {
+               if (file_exist(smbmnt_path)) {
                        execv(smbmnt_path, args);
                        fprintf(stderr,
                                "smbfs/init_mount: execv of %s failed. Error was %s.",
@@ -530,7 +539,7 @@ static void init_mount(void)
           for any reason, we will have to unmount the mount point.  There
           is no exit from the next call...
        */
-       send_fs_socket(service, mount_point, c);
+       send_fs_socket(lp_ctx, service, mount_point, c);
 }
 
 
@@ -542,7 +551,7 @@ static void get_password_file(void)
 {
        int fd = -1;
        char *p;
-       BOOL close_it = False;
+       bool close_it = false;
        pstring spec;
        char pass[128];
 
@@ -550,16 +559,16 @@ static void get_password_file(void)
                pstrcpy(spec, "descriptor ");
                pstrcat(spec, p);
                sscanf(p, "%d", &fd);
-               close_it = False;
+               close_it = false;
        } else if ((p = getenv("PASSWD_FILE")) != NULL) {
-               fd = sys_open(p, O_RDONLY, 0);
+               fd = open(p, O_RDONLY, 0);
                pstrcpy(spec, p);
                if (fd < 0) {
                        fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
                                spec, strerror(errno));
                        exit(1);
                }
-               close_it = True;
+               close_it = true;
        }
 
        for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
@@ -640,7 +649,7 @@ static void read_credentials_file(char *filename)
                if (strwicmp("password", param) == 0)
                {
                        pstrcpy(password, val);
-                       got_pass = True;
+                       got_pass = true;
                }
                else if (strwicmp("username", param) == 0) {
                        pstrcpy(username, val);
@@ -753,12 +762,12 @@ static void parse_mount_smb(int argc, char **argv)
                         if (!strcmp(opts, "username") || 
                            !strcmp(opts, "logon")) {
                                char *lp;
-                               got_user = True;
+                               got_user = true;
                                pstrcpy(username,opteq+1);
                                if ((lp=strchr_m(username,'%'))) {
                                        *lp = 0;
                                        pstrcpy(password,lp+1);
-                                       got_pass = True;
+                                       got_pass = true;
                                        memset(strchr_m(opteq+1,'%')+1,'X',strlen(password));
                                }
                                if ((lp=strchr_m(username,'/'))) {
@@ -768,7 +777,7 @@ static void parse_mount_smb(int argc, char **argv)
                        } else if(!strcmp(opts, "passwd") ||
                                  !strcmp(opts, "password")) {
                                pstrcpy(password,opteq+1);
-                               got_pass = True;
+                               got_pass = true;
                                memset(opteq+1,'X',strlen(password));
                        } else if(!strcmp(opts, "credentials")) {
                                pstrcpy(credentials,opteq+1);
@@ -787,12 +796,12 @@ static void parse_mount_smb(int argc, char **argv)
                        } else if(!strcmp(opts, "debug")) {
                                DEBUGLEVEL = val;
                        } else if(!strcmp(opts, "ip")) {
-                               dest_ip = *interpret_addr2(opteq+1);
+                               dest_ip = interpret_addr2(opteq+1);
                                if (is_zero_ip(dest_ip)) {
                                        fprintf(stderr,"Can't resolve address %s\n", opteq+1);
                                        exit(1);
                                }
-                               have_ip = True;
+                               have_ip = true;
                        } else if(!strcmp(opts, "workgroup")) {
                                pstrcpy(workgroup,opteq+1);
                        } else if(!strcmp(opts, "sockopt")) {
@@ -810,11 +819,11 @@ static void parse_mount_smb(int argc, char **argv)
                                exit(1);
                        } else if(!strcmp(opts, "guest")) {
                                *password = '\0';
-                               got_pass = True;
+                               got_pass = true;
                        } else if(!strcmp(opts, "krb")) {
 #ifdef HAVE_KRB5
 
-                               use_kerberos = True;
+                               use_kerberos = true;
                                if(!status32_smbfs)
                                        fprintf(stderr, "Warning: kerberos support will only work for samba servers\n");
 #else
@@ -853,6 +862,7 @@ static void parse_mount_smb(int argc, char **argv)
        extern char *optarg;
        extern int optind;
        char *p;
+       struct loadparm_context *lp_ctx;
 
        DEBUGLEVEL = 1;
 
@@ -870,43 +880,43 @@ static void parse_mount_smb(int argc, char **argv)
                setenv("CLI_FORCE_ASCII", "true", 1);
 #endif
 
-       in_client = True;   /* Make sure that we tell lp_load we are */
-
        if (getenv("USER")) {
                pstrcpy(username,getenv("USER"));
 
                if ((p=strchr_m(username,'%'))) {
                        *p = 0;
                        pstrcpy(password,p+1);
-                       got_pass = True;
+                       got_pass = true;
                        memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password));
                }
                strupper(username);
        }
 
        if (getenv("PASSWD")) {
-               pstrcpy(password,getenv("PASSWD"));
-               got_pass = True;
+               pstrcpy(password, getenv("PASSWD"));
+               got_pass = true;
        }
 
        if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
                get_password_file();
-               got_pass = True;
+               got_pass = true;
        }
 
        if (*username == 0 && getenv("LOGNAME")) {
                pstrcpy(username,getenv("LOGNAME"));
        }
 
-       if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
+       lp_ctx = loadparm_init(talloc_autofree_context());
+
+       if (!lp_load(lp_ctx, dyn_CONFIGFILE)) {
                fprintf(stderr, "Can't load %s - run testparm to debug it\n", 
-                       dyn_CONFIGFILE);
+                       lp_config_file());
        }
 
        parse_mount_smb(argc, argv);
 
        if (use_kerberos && !got_user) {
-               got_pass = True;
+               got_pass = true;
        }
 
        if (*credentials != 0) {
@@ -916,15 +926,14 @@ static void parse_mount_smb(int argc, char **argv)
        DEBUG(3,("mount.smbfs started (version %s)\n", VERSION));
 
        if (*workgroup == 0) {
-               pstrcpy(workgroup,lp_workgroup());
+               pstrcpy(workgroup, lp_workgroup());
        }
 
-       load_interfaces();
        if (!*my_netbios_name) {
                pstrcpy(my_netbios_name, myhostname());
        }
        strupper(my_netbios_name);
 
-       init_mount();
+       init_mount(lp_ctx);
        return 0;
 }