[GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch.
[samba.git] / source / client / mount.cifs.c
index 7e4c27c820b8368d12b03988dfc81fc0240d6cd0..eb45ae5b4a038ed2ff76a4bce6fd09971e50c1b6 100755 (executable)
@@ -4,7 +4,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,
@@ -13,8 +13,7 @@
    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/>.  */
 
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
@@ -78,6 +77,7 @@ static int free_share_name = 0;
 static char * user_name = NULL;
 static char * mountpassword = NULL;
 char * domain_name = NULL;
+char * prefixpath = NULL;
 
 
 /* BB finish BB
@@ -418,6 +418,11 @@ static int parse_options(char ** optionsp, int * filesys_flags)
                                printf("password too long\n");
                                return 1;
                        }
+               } else if (strncmp(data, "sec", 3) == 0) {
+                       if (value) {
+                               if (!strcmp(value, "none"))
+                                       got_password = 1;
+                       }
                } else if (strncmp(data, "ip", 2) == 0) {
                        if (!value || !*value) {
                                printf("target ip address argument missing");
@@ -566,8 +571,6 @@ static int parse_options(char ** optionsp, int * filesys_flags)
                        *filesys_flags &= ~MS_NOEXEC;
                } else if (strncmp(data, "guest", 5) == 0) {
                        got_password=1;
-                        /* remove the parm since it would otherwise be logged by kern */
-                       goto nocopy;
                } else if (strncmp(data, "ro", 2) == 0) {
                        *filesys_flags |= MS_RDONLY;
                } else if (strncmp(data, "rw", 2) == 0) {
@@ -617,6 +620,7 @@ static int parse_options(char ** optionsp, int * filesys_flags)
 nocopy:
                data = next_keyword;
        }
+       free(*optionsp);
        *optionsp = out;
        return 0;
 }
@@ -804,6 +808,11 @@ continue_unc_parsing:
                                        host_entry = gethostbyname(unc_name);
                                }
                                *(share - 1) = '/'; /* put the slash back */
+                               if ((prefixpath = strchr(share, '/'))) {
+                                       *prefixpath = 0;  /* permanently terminate the string */
+                                       if (!strlen(++prefixpath))
+                                               prefixpath = NULL; /* this needs to be done explicitly */
+                               }
                                if(got_ip) {
                                        if(verboseflag)
                                                printf("ip address specified explicitly\n");
@@ -873,8 +882,8 @@ int main(int argc, char ** argv)
        char * ipaddr = NULL;
        char * uuid = NULL;
        char * mountpoint = NULL;
-       char * options;
-       char * resolved_path;
+       char * options = NULL;
+       char * resolved_path = NULL;
        char * temp;
        int rc;
        int rsize = 0;
@@ -1070,12 +1079,15 @@ int main(int argc, char ** argv)
                get_password_from_file(0, getenv("PASSWD_FILE"));
        }
 
-        if (orgoptions && parse_options(&orgoptions, &flags))
-                return -1;
+        if (orgoptions && parse_options(&orgoptions, &flags)) {
+                rc = -1;
+               goto mount_exit;
+       }
        ipaddr = parse_server(&share_name);
        if((ipaddr == NULL) && (got_ip == 0)) {
                printf("No ip address specified and hostname not found\n");
-               return -1;
+               rc = -1;
+               goto mount_exit;
        }
        
        /* BB save off path and pop after mount returns? */
@@ -1089,17 +1101,20 @@ int main(int argc, char ** argv)
        }
        if(chdir(mountpoint)) {
                printf("mount error: can not change directory into mount target %s\n",mountpoint);
-               return -1;
+               rc = -1;
+               goto mount_exit;
        }
 
        if(stat (".", &statbuf)) {
                printf("mount error: mount point %s does not exist\n",mountpoint);
-               return -1;
+               rc = -1;
+               goto mount_exit;
        }
 
        if (S_ISDIR(statbuf.st_mode) == 0) {
                printf("mount error: mount point %s is not a directory\n",mountpoint);
-               return -1;
+               rc = -1;
+               goto mount_exit;
        }
 
        if((getuid() != 0) && (geteuid() == 0)) {
@@ -1145,6 +1160,8 @@ mount_retry:
                optlen += strlen(ipaddr) + 4;
        if(mountpassword)
                optlen += strlen(mountpassword) + 6;
+       if(options)
+               free(options);
        options = (char *)malloc(optlen + 10 + 64 /* space for commas in password */ + 8 /* space for domain=  , domain name itself was counted as part of the length username string above */);
 
        if(options == NULL) {
@@ -1196,6 +1213,10 @@ mount_retry:
                strcat(options,",");
                strcat(options,orgoptions);
        }
+       if(prefixpath) {
+               strncat(options,",prefixpath=",12);
+               strcat(options,prefixpath); /* no need to cat the / */
+       }       
        if(verboseflag)
                printf("\nmount.cifs kernel mount options %s \n",options);
        if(mount(share_name, mountpoint, "cifs", flags, options)) {
@@ -1223,14 +1244,11 @@ mount_retry:
                                }
                        }
                default:
-                       
                        printf("mount error %d = %s\n",errno,strerror(errno));
                }
                printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n");
-               if(mountpassword) {
-                       memset(mountpassword,0,64);
-               }
-               return -1;
+               rc = -1;
+               goto mount_exit;
        } else {
                pmntfile = setmntent(MOUNTED, "a+");
                if(pmntfile) {
@@ -1260,7 +1278,7 @@ mount_retry:
                                                strcat(mountent.mnt_opts,",user=");
                                                strcat(mountent.mnt_opts,mount_user);
                                        }
-                                       free(mount_user);
+                                       /* free(mount_user); do not free static mem */
                                }
                        }
                        mountent.mnt_freq = 0;
@@ -1273,6 +1291,8 @@ mount_retry:
                    printf("could not update mount table\n");
                }
        }
+       rc = 0;
+mount_exit:
        if(mountpassword) {
                int len = strlen(mountpassword);
                memset(mountpassword,0,len);
@@ -1295,6 +1315,6 @@ mount_retry:
        if(free_share_name) {
                free(share_name);
                }
-       return 0;
+       return rc;
 }