Ignore:
Timestamp:
May 27, 2009, 9:09:42 AM (16 years ago)
Author:
Herwig Bauernfeind
Message:

Update 3.2 branch to 3.2.8

File:
1 edited

Legend:

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

    r228 r232  
    8080#define MOUNT_PASSWD_SIZE 64
    8181#define DOMAIN_SIZE 64
     82
     83/* currently maximum length of IPv6 address string */
     84#define MAX_ADDRESS_LEN INET6_ADDRSTRLEN
    8285
    8386const char *thisprogram;
     
    188191        }
    189192        return username;
    190 }
    191 
    192 static char * parse_cifs_url(char * unc_name)
    193 {
    194         printf("\nMounting cifs URL not implemented yet. Attempt to mount %s\n",unc_name);
    195         return NULL;
    196193}
    197194
     
    494491                        if (!value || !*value) {
    495492                                printf("target ip address argument missing");
    496                         } else if (strnlen(value, 35) < 35) {
     493                        } else if (strnlen(value, MAX_ADDRESS_LEN) <= MAX_ADDRESS_LEN) {
    497494                                if(verboseflag)
    498495                                        printf("ip address %s override specified\n",value);
     
    879876
    880877/* Note that caller frees the returned buffer if necessary */
    881 static char * parse_server(char ** punc_name)
     878static struct addrinfo *
     879parse_server(char ** punc_name)
    882880{
    883881        char * unc_name = *punc_name;
    884882        int length = strnlen(unc_name, MAX_UNC_LEN);
    885883        char * share;
    886         char * ipaddress_string = NULL;
    887         struct hostent * host_entry = NULL;
    888         struct in_addr server_ipaddr;
     884        struct addrinfo *addrlist;
     885        int rc;
    889886
    890887        if(length > (MAX_UNC_LEN - 1)) {
     
    892889                return NULL;
    893890        }
    894         if (strncasecmp("cifs://",unc_name,7) == 0)
    895                 return parse_cifs_url(unc_name+7);
    896         if (strncasecmp("smb://",unc_name,6) == 0) {
    897                 return parse_cifs_url(unc_name+6);
     891        if ((strncasecmp("cifs://", unc_name, 7) == 0) ||
     892            (strncasecmp("smb://", unc_name, 6) == 0)) {
     893                printf("\nMounting cifs URL not implemented yet. Attempt to mount %s\n", unc_name);
     894                return NULL;
    898895        }
    899896
     
    936933                                share += 1;
    937934                                if(got_ip == 0) {
    938                                         host_entry = gethostbyname(unc_name);
     935                                        rc = getaddrinfo(unc_name, NULL, NULL, &addrlist);
     936                                        if (rc != 0) {
     937                                                printf("mount error: could not resolve address for %s: %s\n",
     938                                                        unc_name, gai_strerror(rc));
     939                                                addrlist = NULL;
     940                                        }
    939941                                }
    940942                                *(share - 1) = '/'; /* put delimiter back */
     
    951953                                        return NULL;
    952954                                }
    953                                 if(host_entry == NULL) {
    954                                         printf("mount error: could not find target server. TCP name %s not found\n", unc_name);
    955                                         return NULL;
    956                                 } else {
    957                                         /* BB should we pass an alternate version of the share name as Unicode */
    958                                         /* BB what about ipv6? BB */
    959                                         /* BB add retries with alternate servers in list */
    960 
    961                                         memcpy(&server_ipaddr.s_addr, host_entry->h_addr, 4);
    962 
    963                                         ipaddress_string = inet_ntoa(server_ipaddr);                                                                                     
    964                                         if(ipaddress_string == NULL) {
    965                                                 printf("mount error: could not get valid ip address for target server\n");
    966                                                 return NULL;
    967                                         }
    968                                         return ipaddress_string;
    969                                 }
     955                                /* BB should we pass an alternate version of the share name as Unicode */
     956
     957                                return addrlist;
    970958                        } else {
    971959                                /* BB add code to find DFS root (send null path on get DFS Referral to specified server here */
     
    10311019        char * orgoptions = NULL;
    10321020        char * share_name = NULL;
    1033         char * ipaddr = NULL;
     1021        const char * ipaddr = NULL;
    10341022        char * uuid = NULL;
    10351023        char * mountpoint = NULL;
    10361024        char * options = NULL;
     1025        char * optionstail;
    10371026        char * resolved_path = NULL;
    10381027        char * temp;
     
    10471036        int orgoptlen = 0;
    10481037        size_t options_size = 0;
     1038        size_t current_len;
    10491039        int retry = 0; /* set when we have to retry mount with uppercase */
     1040        struct addrinfo *addrhead = NULL, *addr;
    10501041        struct stat statbuf;
    10511042        struct utsname sysinfo;
    10521043        struct mntent mountent;
     1044        struct sockaddr_in *addr4;
     1045        struct sockaddr_in6 *addr6;
    10531046        FILE * pmntfile;
    10541047
     
    12421235                goto mount_exit;
    12431236        }
    1244         ipaddr = parse_server(&share_name);
    1245         if((ipaddr == NULL) && (got_ip == 0)) {
     1237        addrhead = addr = parse_server(&share_name);
     1238        if((addrhead == NULL) && (got_ip == 0)) {
    12461239                printf("No ip address specified and hostname not found\n");
    12471240                rc = EX_USAGE;
     
    13071300        /* FIXME launch daemon (handles dfs name resolution and credential change)
    13081301           remember to clear parms and overwrite password field before launching */
    1309 mount_retry:
    13101302        if(orgoptions) {
    13111303                optlen = strlen(orgoptions);
     
    13221314        if(user_name)
    13231315                optlen += strlen(user_name) + 6;
    1324         if(ipaddr)
    1325                 optlen += strlen(ipaddr) + 4;
     1316        optlen += MAX_ADDRESS_LEN + 4;
    13261317        if(mountpassword)
    13271318                optlen += strlen(mountpassword) + 6;
     1319mount_retry:
    13281320        SAFE_FREE(options);
    13291321        options_size = optlen + 10 + DOMAIN_SIZE;
     
    13351327        }
    13361328
    1337         options[0] = 0;
    1338         strlcpy(options,"unc=",options_size);
     1329        strlcpy(options, "unc=", options_size);
    13391330        strlcat(options,share_name,options_size);
    13401331        /* scan backwards and reverse direction of slash */
     
    13421333        if(temp > options + 6)
    13431334                *temp = '\\';
    1344         if(ipaddr) {
    1345                 strlcat(options,",ip=",options_size);
    1346                 strlcat(options,ipaddr,options_size);
    1347         }
    1348 
    13491335        if(user_name) {
    13501336                /* check for syntax like user=domain\user */
     
    13881374        replace_char(dev_name, '\\', '/', strlen(share_name));
    13891375
    1390         if(mount(dev_name, mountpoint, "cifs", flags, options)) {
    1391         /* remember to kill daemon on error */
     1376        if (!got_ip && addr) {
     1377                strlcat(options, ",ip=", options_size);
     1378                current_len = strnlen(options, options_size);
     1379                optionstail = options + current_len;
     1380                switch (addr->ai_addr->sa_family) {
     1381                case AF_INET6:
     1382                        addr6 = (struct sockaddr_in6 *) addr->ai_addr;
     1383                        ipaddr = inet_ntop(AF_INET6, &addr6->sin6_addr, optionstail,
     1384                                           options_size - current_len);
     1385                        break;
     1386                case AF_INET:
     1387                        addr4 = (struct sockaddr_in *) addr->ai_addr;
     1388                        ipaddr = inet_ntop(AF_INET, &addr4->sin_addr, optionstail,
     1389                                           options_size - current_len);
     1390                        break;
     1391                }
     1392
     1393                /* if the address looks bogus, try the next one */
     1394                if (!ipaddr) {
     1395                        addr = addr->ai_next;
     1396                        if (addr)
     1397                                goto mount_retry;
     1398                        rc = EX_SYSERR;
     1399                        goto mount_exit;
     1400                }
     1401        }
     1402
     1403        if (mount(dev_name, mountpoint, "cifs", flags, options)) {
    13921404                switch (errno) {
    1393                 case 0:
    1394                         printf("mount failed but no error number set\n");
     1405                case ECONNREFUSED:
     1406                case EHOSTUNREACH:
     1407                        if (addr) {
     1408                                addr = addr->ai_next;
     1409                                if (addr)
     1410                                        goto mount_retry;
     1411                        }
    13951412                        break;
    13961413                case ENODEV:
     
    14071424                                }
    14081425                        }
    1409                 default:
    1410                         printf("mount error %d = %s\n",errno,strerror(errno));
    1411                 }
     1426                }
     1427                printf("mount error(%d): %s\n", errno, strerror(errno));
    14121428                printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n");
    14131429                rc = EX_FAIL;
    1414         } else {
    1415                 atexit(unlock_mtab);
    1416                 rc = lock_mtab();
    1417                 if (rc) {
    1418                         printf("cannot lock mtab");
    1419                         goto mount_exit;
    1420                 }
    1421                 pmntfile = setmntent(MOUNTED, "a+");
    1422                 if (!pmntfile) {
    1423                         printf("could not update mount table\n");
    1424                         unlock_mtab();
    1425                         rc = EX_FILEIO;
    1426                         goto mount_exit;
    1427                 }
    1428                 mountent.mnt_fsname = dev_name;
    1429                 mountent.mnt_dir = mountpoint;
    1430                 mountent.mnt_type = CONST_DISCARD(char *,"cifs");
    1431                 mountent.mnt_opts = (char *)malloc(220);
    1432                 if(mountent.mnt_opts) {
    1433                         char * mount_user = getusername();
    1434                         memset(mountent.mnt_opts,0,200);
    1435                         if(flags & MS_RDONLY)
    1436                                 strlcat(mountent.mnt_opts,"ro",220);
    1437                         else
    1438                                 strlcat(mountent.mnt_opts,"rw",220);
    1439                         if(flags & MS_MANDLOCK)
    1440                                 strlcat(mountent.mnt_opts,",mand",220);
    1441                         if(flags & MS_NOEXEC)
    1442                                 strlcat(mountent.mnt_opts,",noexec",220);
    1443                         if(flags & MS_NOSUID)
    1444                                 strlcat(mountent.mnt_opts,",nosuid",220);
    1445                         if(flags & MS_NODEV)
    1446                                 strlcat(mountent.mnt_opts,",nodev",220);
    1447                         if(flags & MS_SYNCHRONOUS)
    1448                                 strlcat(mountent.mnt_opts,",sync",220);
    1449                         if(mount_user) {
    1450                                 if(getuid() != 0) {
    1451                                         strlcat(mountent.mnt_opts,
    1452                                                 ",user=", 220);
    1453                                         strlcat(mountent.mnt_opts,
    1454                                                 mount_user, 220);
    1455                                 }
    1456                         }
    1457                 }
    1458                 mountent.mnt_freq = 0;
    1459                 mountent.mnt_passno = 0;
    1460                 rc = addmntent(pmntfile,&mountent);
    1461                 endmntent(pmntfile);
     1430                goto mount_exit;
     1431        }
     1432
     1433        atexit(unlock_mtab);
     1434        rc = lock_mtab();
     1435        if (rc) {
     1436                printf("cannot lock mtab");
     1437                goto mount_exit;
     1438        }
     1439        pmntfile = setmntent(MOUNTED, "a+");
     1440        if (!pmntfile) {
     1441                printf("could not update mount table\n");
    14621442                unlock_mtab();
    1463                 SAFE_FREE(mountent.mnt_opts);
    1464                 if (rc)
    1465                         rc = EX_FILEIO;
    1466         }
     1443                rc = EX_FILEIO;
     1444                goto mount_exit;
     1445        }
     1446        mountent.mnt_fsname = dev_name;
     1447        mountent.mnt_dir = mountpoint;
     1448        mountent.mnt_type = CONST_DISCARD(char *,"cifs");
     1449        mountent.mnt_opts = (char *)malloc(220);
     1450        if(mountent.mnt_opts) {
     1451                char * mount_user = getusername();
     1452                memset(mountent.mnt_opts,0,200);
     1453                if(flags & MS_RDONLY)
     1454                        strlcat(mountent.mnt_opts,"ro",220);
     1455                else
     1456                        strlcat(mountent.mnt_opts,"rw",220);
     1457                if(flags & MS_MANDLOCK)
     1458                        strlcat(mountent.mnt_opts,",mand",220);
     1459                if(flags & MS_NOEXEC)
     1460                        strlcat(mountent.mnt_opts,",noexec",220);
     1461                if(flags & MS_NOSUID)
     1462                        strlcat(mountent.mnt_opts,",nosuid",220);
     1463                if(flags & MS_NODEV)
     1464                        strlcat(mountent.mnt_opts,",nodev",220);
     1465                if(flags & MS_SYNCHRONOUS)
     1466                        strlcat(mountent.mnt_opts,",sync",220);
     1467                if(mount_user) {
     1468                        if(getuid() != 0) {
     1469                                strlcat(mountent.mnt_opts,
     1470                                        ",user=", 220);
     1471                                strlcat(mountent.mnt_opts,
     1472                                        mount_user, 220);
     1473                        }
     1474                }
     1475        }
     1476        mountent.mnt_freq = 0;
     1477        mountent.mnt_passno = 0;
     1478        rc = addmntent(pmntfile,&mountent);
     1479        endmntent(pmntfile);
     1480        unlock_mtab();
     1481        SAFE_FREE(mountent.mnt_opts);
     1482        if (rc)
     1483                rc = EX_FILEIO;
    14671484mount_exit:
    14681485        if(mountpassword) {
     
    14721489        }
    14731490
     1491        if (addrhead)
     1492                freeaddrinfo(addrhead);
    14741493        SAFE_FREE(options);
    14751494        SAFE_FREE(orgoptions);
Note: See TracChangeset for help on using the changeset viewer.