Ignore:
Timestamp:
Aug 5, 2009, 6:34:45 PM (16 years ago)
Author:
Herwig Bauernfeind
Message:

Update 3.0 to final 3.0.36 (source)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.0/source/client/mount.cifs.c

    r165 r312  
    22   Mount helper utility for Linux CIFS VFS (virtual filesystem) client
    33   Copyright (C) 2003,2008 Steve French  (sfrench@us.ibm.com)
     4   Copyright (C) 2008 Jeremy Allison (jra@samba.org)
    45
    56   This program is free software; you can redistribute it and/or modify
    67   it under the terms of the GNU General Public License as published by
    7    the Free Software Foundation; either version 2 of the License, or
     8   the Free Software Foundation; either version 3 of the License, or
    89   (at your option) any later version.
    910   
     
    1415   
    1516   You should have received a copy of the GNU General Public License
    16    along with this program; if not, write to the Free Software
    17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
     17   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
    1818
    1919#ifndef _GNU_SOURCE
     
    5858#endif /* MOUNT_CIFS_VENDOR_SUFFIX */
    5959
     60#ifdef _SAMBA_BUILD_
     61#include "include/config.h"
     62#endif
     63
    6064#ifndef MS_MOVE
    6165#define MS_MOVE 8192
     
    7074#define CONST_DISCARD(type, ptr)      ((type) ((void *) (ptr)))
    7175
     76#ifndef SAFE_FREE
     77#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
     78#endif
     79
     80#define MOUNT_PASSWD_SIZE 64
     81#define DOMAIN_SIZE 64
     82
     83/* currently maximum length of IPv6 address string */
     84#define MAX_ADDRESS_LEN INET6_ADDRSTRLEN
     85
    7286const char *thisprogram;
    7387int verboseflag = 0;
     88int fakemnt = 0;
    7489static int got_password = 0;
    7590static int got_user = 0;
     
    89104/* like strncpy but does not 0 fill the buffer and always null
    90105 *    terminates. bufsize is the size of the destination buffer */
     106
     107#ifndef HAVE_STRLCPY
    91108static size_t strlcpy(char *d, const char *s, size_t bufsize)
    92109{
     
    99116        return ret;
    100117}
     118#endif
    101119
    102120/* like strncat but does not 0 fill the buffer and always null
    103121 *    terminates. bufsize is the length of the buffer, which should
    104122 *       be one more than the maximum resulting string length */
     123
     124#ifndef HAVE_STRLCAT
    105125static size_t strlcat(char *d, const char *s, size_t bufsize)
    106126{
     
    121141        return ret;
    122142}
     143#endif
    123144
    124145/* BB finish BB
     
    143164        printf("\n\tcredentials=<filename>,guest,perm,noperm,setuids,nosetuids,rw,ro,");
    144165        printf("\n\tsep=<char>,iocharset=<codepage>,suid,nosuid,exec,noexec,serverino,");
    145         printf("\n\tdirectio,mapchars,nomapchars,nolock,servernetbiosname=<SRV_RFC1001NAME>");
     166        printf("\n\tmapchars,nomapchars,nolock,servernetbiosname=<SRV_RFC1001NAME>");
     167        printf("\n\tdirectio,nounix,cifsacl,sec=<authentication mechanism>,sign");
    146168        printf("\n\nOptions not needed for servers supporting CIFS Unix extensions");
    147169        printf("\n\t(e.g. unneeded for mounts to most Samba versions):");
     
    150172        printf("\n\tport=<tcpport>,rsize=<size>,wsize=<size>,unc=<unc_name>,ip=<ip_address>,");
    151173        printf("\n\tdev,nodev,nouser_xattr,netbiosname=<OUR_RFC1001NAME>,hard,soft,intr,");
    152         printf("\n\tnointr,ignorecase,noposixpaths,noacl");
     174        printf("\n\tnointr,ignorecase,noposixpaths,noacl,prefixpath=<path>,nobrl");
     175        printf("\n\tin6_addr");
    153176        printf("\n\nOptions are described in more detail in the manual page");
    154177        printf("\n\tman 8 mount.cifs\n");
     
    156179        printf("\n\t%s -V\n",thisprogram);
    157180
    158         if(mountpassword) {
    159                 memset(mountpassword,0,64);
    160                 free(mountpassword);
    161                 mountpassword = NULL;
    162         }
     181        SAFE_FREE(mountpassword);
    163182        exit(EX_USAGE);
    164183}
     
    173192        }
    174193        return username;
    175 }
    176 
    177 static char * parse_cifs_url(char * unc_name)
    178 {
    179         printf("\nMounting cifs URL not implemented yet. Attempt to mount %s\n",unc_name);
    180         return NULL;
    181194}
    182195
     
    193206        if(line_buf == NULL) {
    194207                fclose(fs);
    195                 return -ENOMEM;
     208                return ENOMEM;
    196209        }
    197210
     
    213226                                        if ((temp_val[length] == '\n')
    214227                                            || (temp_val[length] == '\0')) {
     228                                                temp_val[length] = '\0';
    215229                                                break;
    216230                                        }
     
    219233                                        printf("mount.cifs failed due to malformed username in credentials file");
    220234                                        memset(line_buf,0,4096);
    221                                         if(mountpassword) {
    222                                                 memset(mountpassword,0,64);
    223                                         }
    224235                                        exit(EX_USAGE);
    225236                                } else {
     
    228239                                        /* BB adding free of user_name string before exit,
    229240                                                not really necessary but would be cleaner */
    230                                         strncpy(user_name,temp_val, length);
     241                                        strlcpy(user_name,temp_val, length+1);
    231242                                }
    232243                        }
     
    236247                                /* go past equals sign */
    237248                                temp_val++;
    238                                 for(length = 0;length<65;length++) {
     249                                for(length = 0;length<MOUNT_PASSWD_SIZE+1;length++) {
    239250                                        if ((temp_val[length] == '\n')
    240251                                            || (temp_val[length] == '\0')) {
     252                                                temp_val[length] = '\0';
    241253                                                break;
    242254                                        }
    243255                                }
    244                                 if(length > 64) {
     256                                if(length > MOUNT_PASSWD_SIZE) {
    245257                                        printf("mount.cifs failed: password in credentials file too long\n");
    246258                                        memset(line_buf,0, 4096);
    247                                         if(mountpassword) {
    248                                                 memset(mountpassword,0,64);
    249                                         }
    250259                                        exit(EX_USAGE);
    251260                                } else {
    252261                                        if(mountpassword == NULL) {
    253                                                 mountpassword = (char *)calloc(65,1);
     262                                                mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1);
    254263                                        } else
    255                                                 memset(mountpassword,0,64);
     264                                                memset(mountpassword,0,MOUNT_PASSWD_SIZE);
    256265                                        if(mountpassword) {
    257                                                 strncpy(mountpassword,temp_val,length);
     266                                                strlcpy(mountpassword,temp_val,MOUNT_PASSWD_SIZE+1);
    258267                                                got_password = 1;
    259268                                        }
     
    267276                                if(verboseflag)
    268277                                        printf("\nDomain %s\n",temp_val);
    269                                 for(length = 0;length<65;length++) {
     278                                for(length = 0;length<DOMAIN_SIZE+1;length++) {
    270279                                        if ((temp_val[length] == '\n')
    271280                                            || (temp_val[length] == '\0')) {
     281                                                temp_val[length] = '\0';
    272282                                                break;
    273283                                        }
    274284                                }
    275                                 if(length > 64) {
     285                                if(length > DOMAIN_SIZE) {
    276286                                        printf("mount.cifs failed: domain in credentials file too long\n");
    277                                         if(mountpassword) {
    278                                                 memset(mountpassword,0,64);
    279                                         }
    280287                                        exit(EX_USAGE);
    281288                                } else {
    282289                                        if(domain_name == NULL) {
    283                                                 domain_name = (char *)calloc(65,1);
     290                                                domain_name = (char *)calloc(DOMAIN_SIZE+1,1);
    284291                                        } else
    285                                                 memset(domain_name,0,64);
     292                                                memset(domain_name,0,DOMAIN_SIZE);
    286293                                        if(domain_name) {
    287                                                 strncpy(domain_name,temp_val,length);
     294                                                strlcpy(domain_name,temp_val,DOMAIN_SIZE+1);
    288295                                                got_domain = 1;
    289296                                        }
     
    294301        }
    295302        fclose(fs);
    296         if(line_buf) {
    297                 memset(line_buf,0,4096);
    298                 free(line_buf);
    299                 line_buf = NULL;
    300         }
     303        SAFE_FREE(line_buf);
    301304        return 0;
    302305}
     
    309312
    310313        if(mountpassword == NULL)
    311                 mountpassword = (char *)calloc(65,1);
     314                mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1);
    312315        else
    313                 memset(mountpassword, 0, 64);
     316                memset(mountpassword, 0, MOUNT_PASSWD_SIZE);
    314317
    315318        if (mountpassword == NULL) {
     
    328331        /* else file already open and fd provided */
    329332
    330         for(i=0;i<64;i++) {
     333        for(i=0;i<MOUNT_PASSWD_SIZE;i++) {
    331334                rc = read(file_descript,&c,1);
    332335                if(rc < 0) {
    333336                        printf("mount.cifs failed. Error %s reading password file\n",strerror(errno));
    334                         memset(mountpassword,0,64);
    335337                        if(filename != NULL)
    336338                                close(file_descript);
     
    344346                } else /* read valid character */ {
    345347                        if((c == 0) || (c == '\n')) {
     348                                mountpassword[i] = '\0';
    346349                                break;
    347350                        } else
     
    349352                }
    350353        }
    351         if((i == 64) && (verboseflag)) {
    352                 printf("\nWarning: password longer than 64 characters specified in cifs password file");
     354        if((i == MOUNT_PASSWD_SIZE) && (verboseflag)) {
     355                printf("\nWarning: password longer than %d characters specified in cifs password file",
     356                        MOUNT_PASSWD_SIZE);
    353357        }
    354358        got_password = 1;
     
    428432                                } else {
    429433                                        printf("username specified with no parameter\n");
     434                                        SAFE_FREE(out);
    430435                                        return 1;       /* needs_arg; */
    431436                                }
     
    437442                                                *percent_char = ',';
    438443                                                if(mountpassword == NULL)
    439                                                         mountpassword = (char *)calloc(65,1);
     444                                                        mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1);
    440445                                                if(mountpassword) {
    441446                                                        if(got_password)
     
    443448                                                        got_password = 1;
    444449                                                        percent_char++;
    445                                                         strncpy(mountpassword, percent_char,64);
     450                                                        strlcpy(mountpassword, percent_char,MOUNT_PASSWD_SIZE+1);
    446451                                                /*  remove password from username */
    447452                                                        while(*percent_char != 0) {
     
    460465                                } else {
    461466                                        printf("username too long\n");
     467                                        SAFE_FREE(out);
    462468                                        return 1;
    463469                                }
     
    475481                        } else {
    476482                                printf("password too long\n");
     483                                SAFE_FREE(out);
    477484                                return 1;
    478485                        }
     
    486493                        if (!value || !*value) {
    487494                                printf("target ip address argument missing");
    488                         } else if (strnlen(value, 35) < 35) {
     495                        } else if (strnlen(value, MAX_ADDRESS_LEN) <= MAX_ADDRESS_LEN) {
    489496                                if(verboseflag)
    490497                                        printf("ip address %s override specified\n",value);
     
    492499                        } else {
    493500                                printf("ip address too long\n");
     501                                SAFE_FREE(out);
    494502                                return 1;
    495503                        }
     
    499507                        if (!value || !*value) {
    500508                                printf("invalid path to network resource\n");
     509                                SAFE_FREE(out);
    501510                                return 1;  /* needs_arg; */
    502511                        } else if(strnlen(value,5) < 5) {
     
    513522                                } else if (strncmp(value, "\\\\", 2) != 0) {                       
    514523                                        printf("UNC Path does not begin with // or \\\\ \n");
     524                                        SAFE_FREE(out);
    515525                                        return 1;
    516526                                } else {
     
    522532                        } else {
    523533                                printf("CIFS: UNC name too long\n");
     534                                SAFE_FREE(out);
    524535                                return 1;
    525536                        }
    526                 } else if ((strncmp(data, "domain", 3) == 0)
    527                            || (strncmp(data, "workgroup", 5) == 0)) {
     537                } else if ((strncmp(data, "dom" /* domain */, 3) == 0)
     538                           || (strncmp(data, "workg", 5) == 0)) {
     539                        /* note this allows for synonyms of "domain"
     540                           such as "DOM" and "dom" and "workgroup"
     541                           and "WORKGRP" etc. */
    528542                        if (!value || !*value) {
    529543                                printf("CIFS: invalid domain name\n");
     544                                SAFE_FREE(out);
    530545                                return 1;       /* needs_arg; */
    531546                        }
    532                         if (strnlen(value, 65) < 65) {
     547                        if (strnlen(value, DOMAIN_SIZE+1) < DOMAIN_SIZE+1) {
    533548                                got_domain = 1;
    534549                        } else {
    535550                                printf("domain name too long\n");
     551                                SAFE_FREE(out);
    536552                                return 1;
    537553                        }
     
    540556                                rc = open_cred_file(value);
    541557                                if(rc) {
    542                                         printf("error %d opening credential file %s\n",rc, value);
     558                                        printf("error %d (%s) opening credential file %s\n",
     559                                                rc, strerror(rc), value);
     560                                        SAFE_FREE(out);
    543561                                        return 1;
    544562                                }
    545563                        } else {
    546564                                printf("invalid credential file name specified\n");
     565                                SAFE_FREE(out);
    547566                                return 1;
    548567                        }
     
    583602                        if (!value || !*value) {
    584603                                printf ("Option '%s' requires a numerical argument\n", data);
     604                                SAFE_FREE(out);
    585605                                return 1;
    586606                        }
     
    597617                        if (!value || !*value) {
    598618                                printf ("Option '%s' requires a numerical argument\n", data);
     619                                SAFE_FREE(out);
    599620                                return 1;
    600621                        }
     
    630651                        *filesys_flags &= ~MS_NOEXEC;
    631652                } else if (strncmp(data, "guest", 5) == 0) {
    632                         got_password=1;
     653                        user_name = (char *)calloc(1, 1);
     654                        got_user = 1;
     655                        got_password = 1;
    633656                } else if (strncmp(data, "ro", 2) == 0) {
    634657                        *filesys_flags |= MS_RDONLY;
     
    718741        }
    719742
    720         free(*optionsp);
     743        SAFE_FREE(*optionsp);
    721744        *optionsp = out;
    722745        return 0;
     
    746769        if(number_of_commas == 0)
    747770                return;
    748         if(number_of_commas > 64) {
     771        if(number_of_commas > MOUNT_PASSWD_SIZE) {
    749772                /* would otherwise overflow the mount options buffer */
    750773                printf("\nInvalid password. Password contains too many commas.\n");
     
    765788        new_pass_buf[len+number_of_commas] = 0;
    766789
    767         free(*ppasswrd);
     790        SAFE_FREE(*ppasswrd);
    768791        *ppasswrd = new_pass_buf;
    769792       
     
    860883
    861884/* Note that caller frees the returned buffer if necessary */
    862 static char * parse_server(char ** punc_name)
     885static struct addrinfo *
     886parse_server(char ** punc_name)
    863887{
    864888        char * unc_name = *punc_name;
    865889        int length = strnlen(unc_name, MAX_UNC_LEN);
    866890        char * share;
    867         char * ipaddress_string = NULL;
    868         struct hostent * host_entry = NULL;
    869         struct in_addr server_ipaddr;
     891        struct addrinfo *addrlist;
     892        int rc;
    870893
    871894        if(length > (MAX_UNC_LEN - 1)) {
     
    873896                return NULL;
    874897        }
    875         if (strncasecmp("cifs://",unc_name,7) == 0)
    876                 return parse_cifs_url(unc_name+7);
    877         if (strncasecmp("smb://",unc_name,6) == 0) {
    878                 return parse_cifs_url(unc_name+6);
     898        if ((strncasecmp("cifs://", unc_name, 7) == 0) ||
     899            (strncasecmp("smb://", unc_name, 6) == 0)) {
     900                printf("\nMounting cifs URL not implemented yet. Attempt to mount %s\n", unc_name);
     901                return NULL;
    879902        }
    880903
     
    896919                                }
    897920                                *share = '/';
    898                                 strncpy((*punc_name)+2,unc_name,length);
    899                                 free(unc_name);
     921                                strlcpy((*punc_name)+2,unc_name,length+1);
     922                                SAFE_FREE(unc_name);
    900923                                unc_name = *punc_name;
    901924                                unc_name[length+2] = 0;
     
    917940                                share += 1;
    918941                                if(got_ip == 0) {
    919                                         host_entry = gethostbyname(unc_name);
     942                                        rc = getaddrinfo(unc_name, NULL, NULL, &addrlist);
     943                                        if (rc != 0) {
     944                                                printf("mount error: could not resolve address for %s: %s\n",
     945                                                        unc_name, gai_strerror(rc));
     946                                                addrlist = NULL;
     947                                        }
    920948                                }
    921949                                *(share - 1) = '/'; /* put delimiter back */
     
    932960                                        return NULL;
    933961                                }
    934                                 if(host_entry == NULL) {
    935                                         printf("mount error: could not find target server. TCP name %s not found\n", unc_name);
    936                                         return NULL;
    937                                 } else {
    938                                         /* BB should we pass an alternate version of the share name as Unicode */
    939                                         /* BB what about ipv6? BB */
    940                                         /* BB add retries with alternate servers in list */
    941 
    942                                         memcpy(&server_ipaddr.s_addr, host_entry->h_addr, 4);
    943 
    944                                         ipaddress_string = inet_ntoa(server_ipaddr);                                                                                     
    945                                         if(ipaddress_string == NULL) {
    946                                                 printf("mount error: could not get valid ip address for target server\n");
    947                                                 return NULL;
    948                                         }
    949                                         return ipaddress_string;
    950                                 }
     962                                /* BB should we pass an alternate version of the share name as Unicode */
     963
     964                                return addrlist;
    951965                        } else {
    952966                                /* BB add code to find DFS root (send null path on get DFS Referral to specified server here */
     
    10121026        char * orgoptions = NULL;
    10131027        char * share_name = NULL;
    1014         char * ipaddr = NULL;
     1028        const char * ipaddr = NULL;
    10151029        char * uuid = NULL;
    10161030        char * mountpoint = NULL;
    10171031        char * options = NULL;
     1032        char * optionstail;
    10181033        char * resolved_path = NULL;
    10191034        char * temp;
    10201035        char * dev_name;
    1021         int rc;
     1036        int rc = 0;
    10221037        int rsize = 0;
    10231038        int wsize = 0;
     
    10281043        int orgoptlen = 0;
    10291044        size_t options_size = 0;
     1045        size_t current_len;
    10301046        int retry = 0; /* set when we have to retry mount with uppercase */
     1047        struct addrinfo *addrhead = NULL, *addr;
    10311048        struct stat statbuf;
    10321049        struct utsname sysinfo;
    10331050        struct mntent mountent;
     1051        struct sockaddr_in *addr4;
     1052        struct sockaddr_in6 *addr6;
    10341053        FILE * pmntfile;
    10351054
     
    10631082                mountpoint = argv[2];
    10641083        } else {
     1084                if ((strcmp (argv[1], "--version") == 0) ||
     1085                    ((strcmp (argv[1], "-V") == 0))) {
     1086                        printf ("mount.cifs version: %s.%s%s\n",
     1087                        MOUNT_CIFS_VERSION_MAJOR,
     1088                        MOUNT_CIFS_VERSION_MINOR,
     1089                        MOUNT_CIFS_VENDOR_SUFFIX);
     1090                        exit (0);
     1091                }
    10651092                mount_cifs_usage();
    10661093                exit(EX_USAGE);
     
    10881115                        exit(EX_USAGE);
    10891116                case 'n':
    1090                     ++nomtab;
    1091                     break;
     1117                        ++nomtab;
     1118                        break;
    10921119                case 'b':
    10931120#ifdef MS_BIND
     
    11231150                        MOUNT_CIFS_VERSION_MINOR,
    11241151                        MOUNT_CIFS_VENDOR_SUFFIX);
    1125                         if(mountpassword) {
    1126                                 memset(mountpassword,0,64);
    1127                         }
    11281152                        exit (0);
    11291153                case 'w':
     
    11861210                case 'p':
    11871211                        if(mountpassword == NULL)
    1188                                 mountpassword = (char *)calloc(65,1);
     1212                                mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1);
    11891213                        if(mountpassword) {
    11901214                                got_password = 1;
    1191                                 strncpy(mountpassword,optarg,64);
     1215                                strlcpy(mountpassword,optarg,MOUNT_PASSWD_SIZE+1);
    11921216                        }
    11931217                        break;
     
    11961220                        break;
    11971221                case 't':
     1222                        break;
     1223                case 'f':
     1224                        ++fakemnt;
    11981225                        break;
    11991226                default:
     
    12111238        if (getenv("PASSWD")) {
    12121239                if(mountpassword == NULL)
    1213                         mountpassword = (char *)calloc(65,1);
     1240                        mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1);
    12141241                if(mountpassword) {
    1215                         strncpy(mountpassword,getenv("PASSWD"),64);
     1242                        strlcpy(mountpassword,getenv("PASSWD"),MOUNT_PASSWD_SIZE+1);
    12161243                        got_password = 1;
    12171244                }
     
    12261253                goto mount_exit;
    12271254        }
    1228         ipaddr = parse_server(&share_name);
    1229         if((ipaddr == NULL) && (got_ip == 0)) {
     1255        addrhead = addr = parse_server(&share_name);
     1256        if((addrhead == NULL) && (got_ip == 0)) {
    12301257                printf("No ip address specified and hostname not found\n");
    12311258                rc = EX_USAGE;
     
    12741301
    12751302        if(got_user == 0) {
    1276                 user_name = getusername();
     1303                /* Note that the password will not be retrieved from the
     1304                   USER env variable (ie user%password form) as there is
     1305                   already a PASSWD environment varaible */
     1306                if (getenv("USER"))
     1307                        user_name = strdup(getenv("USER"));
     1308                if (user_name == NULL)
     1309                        user_name = getusername();
    12771310                got_user = 1;
    12781311        }
    12791312       
    12801313        if(got_password == 0) {
    1281                 char *tmp_pass;
    1282                 tmp_pass = getpass("Password: "); /* BB obsolete sys call but
    1283                                                      no good replacement yet */
    1284                 mountpassword = (char *)calloc(65,1);
     1314                char *tmp_pass = getpass("Password: "); /* BB obsolete sys call but
     1315                                                           no good replacement yet. */
     1316                mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1);
    12851317                if (!tmp_pass || !mountpassword) {
    12861318                        printf("Password not entered, exiting\n");
    12871319                        exit(EX_USAGE);
    12881320                }
    1289                 strncpy(mountpassword, tmp_pass, 64);
    1290                                                  
     1321                strlcpy(mountpassword, tmp_pass, MOUNT_PASSWD_SIZE+1);
    12911322                got_password = 1;
    12921323        }
    12931324        /* FIXME launch daemon (handles dfs name resolution and credential change)
    12941325           remember to clear parms and overwrite password field before launching */
    1295 mount_retry:
    12961326        if(orgoptions) {
    12971327                optlen = strlen(orgoptions);
     
    13081338        if(user_name)
    13091339                optlen += strlen(user_name) + 6;
    1310         if(ipaddr)
    1311                 optlen += strlen(ipaddr) + 4;
     1340        optlen += MAX_ADDRESS_LEN + 4;
    13121341        if(mountpassword)
    13131342                optlen += strlen(mountpassword) + 6;
    1314         if(options) {
    1315                 free(options);
    1316                 options = NULL;
    1317         }
    1318         options_size = optlen + 10 + 64;
     1343mount_retry:
     1344        SAFE_FREE(options);
     1345        options_size = optlen + 10 + DOMAIN_SIZE;
    13191346        options = (char *)malloc(options_size /* space for commas in password */ + 8 /* space for domain=  , domain name itself was counted as part of the length username string above */);
    13201347
     
    13241351        }
    13251352
    1326         options[0] = 0;
    1327         strlcpy(options,"unc=",options_size);
     1353        strlcpy(options, "unc=", options_size);
    13281354        strlcat(options,share_name,options_size);
    13291355        /* scan backwards and reverse direction of slash */
     
    13311357        if(temp > options + 6)
    13321358                *temp = '\\';
    1333         if(ipaddr) {
    1334                 strlcat(options,",ip=",options_size);
    1335                 strlcat(options,ipaddr,options_size);
    1336         }
    1337 
    13381359        if(user_name) {
    13391360                /* check for syntax like user=domain\user */
     
    13771398        replace_char(dev_name, '\\', '/', strlen(share_name));
    13781399
    1379         if(mount(dev_name, mountpoint, "cifs", flags, options)) {
    1380         /* remember to kill daemon on error */
     1400        if (!got_ip && addr) {
     1401                strlcat(options, ",ip=", options_size);
     1402                current_len = strnlen(options, options_size);
     1403                optionstail = options + current_len;
     1404                switch (addr->ai_addr->sa_family) {
     1405                case AF_INET6:
     1406                        addr6 = (struct sockaddr_in6 *) addr->ai_addr;
     1407                        ipaddr = inet_ntop(AF_INET6, &addr6->sin6_addr, optionstail,
     1408                                           options_size - current_len);
     1409                        break;
     1410                case AF_INET:
     1411                        addr4 = (struct sockaddr_in *) addr->ai_addr;
     1412                        ipaddr = inet_ntop(AF_INET, &addr4->sin_addr, optionstail,
     1413                                           options_size - current_len);
     1414                        break;
     1415                }
     1416
     1417                /* if the address looks bogus, try the next one */
     1418                if (!ipaddr) {
     1419                        addr = addr->ai_next;
     1420                        if (addr)
     1421                                goto mount_retry;
     1422                        rc = EX_SYSERR;
     1423                        goto mount_exit;
     1424                }
     1425        }
     1426
     1427        if (!fakemnt && mount(dev_name, mountpoint, "cifs", flags, options)) {
    13811428                switch (errno) {
    1382                 case 0:
    1383                         printf("mount failed but no error number set\n");
     1429                case ECONNREFUSED:
     1430                case EHOSTUNREACH:
     1431                        if (addr) {
     1432                                addr = addr->ai_next;
     1433                                if (addr)
     1434                                        goto mount_retry;
     1435                        }
    13841436                        break;
    13851437                case ENODEV:
     
    13961448                                }
    13971449                        }
    1398                 default:
    1399                         printf("mount error %d = %s\n",errno,strerror(errno));
    1400                 }
     1450                }
     1451                printf("mount error(%d): %s\n", errno, strerror(errno));
    14011452                printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n");
    14021453                rc = EX_FAIL;
    1403         } else {
    1404                 atexit(unlock_mtab);
    1405                 rc = lock_mtab();
    1406                 if (rc) {
    1407                         printf("cannot lock mtab");
    1408                         goto mount_exit;
    1409                 }
    1410                 pmntfile = setmntent(MOUNTED, "a+");
    1411                 if (!pmntfile) {
    1412                         printf("could not update mount table\n");
    1413                         unlock_mtab();
    1414                         rc = EX_FILEIO;
    1415                         goto mount_exit;
    1416                 }
    1417                 mountent.mnt_fsname = dev_name;
    1418                 mountent.mnt_dir = mountpoint;
    1419                 mountent.mnt_type = CONST_DISCARD(char *,"cifs");
    1420                 mountent.mnt_opts = (char *)malloc(220);
    1421                 if(mountent.mnt_opts) {
    1422                         char * mount_user = getusername();
    1423                         memset(mountent.mnt_opts,0,200);
    1424                         if(flags & MS_RDONLY)
    1425                                 strlcat(mountent.mnt_opts,"ro",220);
    1426                         else
    1427                                 strlcat(mountent.mnt_opts,"rw",220);
    1428                         if(flags & MS_MANDLOCK)
    1429                                 strlcat(mountent.mnt_opts,",mand",220);
    1430                         if(flags & MS_NOEXEC)
    1431                                 strlcat(mountent.mnt_opts,",noexec",220);
    1432                         if(flags & MS_NOSUID)
    1433                                 strlcat(mountent.mnt_opts,",nosuid",220);
    1434                         if(flags & MS_NODEV)
    1435                                 strlcat(mountent.mnt_opts,",nodev",220);
    1436                         if(flags & MS_SYNCHRONOUS)
    1437                                 strlcat(mountent.mnt_opts,",sync",220);
    1438                         if(mount_user) {
    1439                                 if(getuid() != 0) {
    1440                                         strlcat(mountent.mnt_opts,
    1441                                                 ",user=", 220);
    1442                                         strlcat(mountent.mnt_opts,
    1443                                                 mount_user, 220);
    1444                                 }
    1445                         }
    1446                 }
    1447                 mountent.mnt_freq = 0;
    1448                 mountent.mnt_passno = 0;
    1449                 rc = addmntent(pmntfile,&mountent);
    1450                 endmntent(pmntfile);
     1454                goto mount_exit;
     1455        }
     1456
     1457        if (nomtab)
     1458                goto mount_exit;
     1459        atexit(unlock_mtab);
     1460        rc = lock_mtab();
     1461        if (rc) {
     1462                printf("cannot lock mtab");
     1463                goto mount_exit;
     1464        }
     1465        pmntfile = setmntent(MOUNTED, "a+");
     1466        if (!pmntfile) {
     1467                printf("could not update mount table\n");
    14511468                unlock_mtab();
    1452                 if(mountent.mnt_opts) {
    1453                         free(mountent.mnt_opts);
    1454                         mountent.mnt_opts = NULL;
    1455                 }
    1456                 if (rc)
    1457                         rc = EX_FILEIO;
    1458         }
     1469                rc = EX_FILEIO;
     1470                goto mount_exit;
     1471        }
     1472        mountent.mnt_fsname = dev_name;
     1473        mountent.mnt_dir = mountpoint;
     1474        mountent.mnt_type = CONST_DISCARD(char *,"cifs");
     1475        mountent.mnt_opts = (char *)malloc(220);
     1476        if(mountent.mnt_opts) {
     1477                char * mount_user = getusername();
     1478                memset(mountent.mnt_opts,0,200);
     1479                if(flags & MS_RDONLY)
     1480                        strlcat(mountent.mnt_opts,"ro",220);
     1481                else
     1482                        strlcat(mountent.mnt_opts,"rw",220);
     1483                if(flags & MS_MANDLOCK)
     1484                        strlcat(mountent.mnt_opts,",mand",220);
     1485                if(flags & MS_NOEXEC)
     1486                        strlcat(mountent.mnt_opts,",noexec",220);
     1487                if(flags & MS_NOSUID)
     1488                        strlcat(mountent.mnt_opts,",nosuid",220);
     1489                if(flags & MS_NODEV)
     1490                        strlcat(mountent.mnt_opts,",nodev",220);
     1491                if(flags & MS_SYNCHRONOUS)
     1492                        strlcat(mountent.mnt_opts,",sync",220);
     1493                if(mount_user) {
     1494                        if(getuid() != 0) {
     1495                                strlcat(mountent.mnt_opts,
     1496                                        ",user=", 220);
     1497                                strlcat(mountent.mnt_opts,
     1498                                        mount_user, 220);
     1499                        }
     1500                }
     1501        }
     1502        mountent.mnt_freq = 0;
     1503        mountent.mnt_passno = 0;
     1504        rc = addmntent(pmntfile,&mountent);
     1505        endmntent(pmntfile);
     1506        unlock_mtab();
     1507        SAFE_FREE(mountent.mnt_opts);
     1508        if (rc)
     1509                rc = EX_FILEIO;
    14591510mount_exit:
    14601511        if(mountpassword) {
    14611512                int len = strlen(mountpassword);
    14621513                memset(mountpassword,0,len);
    1463                 free(mountpassword);
    1464                 mountpassword = NULL;
    1465         }
    1466 
    1467         if(options) {
    1468                 memset(options,0,optlen);
    1469                 free(options);
    1470                 options = NULL;
    1471         }
    1472 
    1473         if(orgoptions) {
    1474                 memset(orgoptions,0,orgoptlen);
    1475                 free(orgoptions);
    1476                 orgoptions = NULL;
    1477         }
    1478         if(resolved_path) {
    1479                 free(resolved_path);
    1480                 resolved_path = NULL;
    1481         }
    1482 
    1483         free(share_name);
     1514                SAFE_FREE(mountpassword);
     1515        }
     1516
     1517        if (addrhead)
     1518                freeaddrinfo(addrhead);
     1519        SAFE_FREE(options);
     1520        SAFE_FREE(orgoptions);
     1521        SAFE_FREE(resolved_path);
     1522        SAFE_FREE(share_name);
    14841523        exit(rc);
    14851524}
Note: See TracChangeset for help on using the changeset viewer.