Changeset 232 for branches/samba-3.2.x/source/client/mount.cifs.c
- Timestamp:
- May 27, 2009, 9:09:42 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.2.x/source/client/mount.cifs.c
r228 r232 80 80 #define MOUNT_PASSWD_SIZE 64 81 81 #define DOMAIN_SIZE 64 82 83 /* currently maximum length of IPv6 address string */ 84 #define MAX_ADDRESS_LEN INET6_ADDRSTRLEN 82 85 83 86 const char *thisprogram; … … 188 191 } 189 192 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;196 193 } 197 194 … … 494 491 if (!value || !*value) { 495 492 printf("target ip address argument missing"); 496 } else if (strnlen(value, 35) < 35) {493 } else if (strnlen(value, MAX_ADDRESS_LEN) <= MAX_ADDRESS_LEN) { 497 494 if(verboseflag) 498 495 printf("ip address %s override specified\n",value); … … 879 876 880 877 /* Note that caller frees the returned buffer if necessary */ 881 static char * parse_server(char ** punc_name) 878 static struct addrinfo * 879 parse_server(char ** punc_name) 882 880 { 883 881 char * unc_name = *punc_name; 884 882 int length = strnlen(unc_name, MAX_UNC_LEN); 885 883 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; 889 886 890 887 if(length > (MAX_UNC_LEN - 1)) { … … 892 889 return NULL; 893 890 } 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; 898 895 } 899 896 … … 936 933 share += 1; 937 934 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 } 939 941 } 940 942 *(share - 1) = '/'; /* put delimiter back */ … … 951 953 return NULL; 952 954 } 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; 970 958 } else { 971 959 /* BB add code to find DFS root (send null path on get DFS Referral to specified server here */ … … 1031 1019 char * orgoptions = NULL; 1032 1020 char * share_name = NULL; 1033 c har * ipaddr = NULL;1021 const char * ipaddr = NULL; 1034 1022 char * uuid = NULL; 1035 1023 char * mountpoint = NULL; 1036 1024 char * options = NULL; 1025 char * optionstail; 1037 1026 char * resolved_path = NULL; 1038 1027 char * temp; … … 1047 1036 int orgoptlen = 0; 1048 1037 size_t options_size = 0; 1038 size_t current_len; 1049 1039 int retry = 0; /* set when we have to retry mount with uppercase */ 1040 struct addrinfo *addrhead = NULL, *addr; 1050 1041 struct stat statbuf; 1051 1042 struct utsname sysinfo; 1052 1043 struct mntent mountent; 1044 struct sockaddr_in *addr4; 1045 struct sockaddr_in6 *addr6; 1053 1046 FILE * pmntfile; 1054 1047 … … 1242 1235 goto mount_exit; 1243 1236 } 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)) { 1246 1239 printf("No ip address specified and hostname not found\n"); 1247 1240 rc = EX_USAGE; … … 1307 1300 /* FIXME launch daemon (handles dfs name resolution and credential change) 1308 1301 remember to clear parms and overwrite password field before launching */ 1309 mount_retry:1310 1302 if(orgoptions) { 1311 1303 optlen = strlen(orgoptions); … … 1322 1314 if(user_name) 1323 1315 optlen += strlen(user_name) + 6; 1324 if(ipaddr) 1325 optlen += strlen(ipaddr) + 4; 1316 optlen += MAX_ADDRESS_LEN + 4; 1326 1317 if(mountpassword) 1327 1318 optlen += strlen(mountpassword) + 6; 1319 mount_retry: 1328 1320 SAFE_FREE(options); 1329 1321 options_size = optlen + 10 + DOMAIN_SIZE; … … 1335 1327 } 1336 1328 1337 options[0] = 0; 1338 strlcpy(options,"unc=",options_size); 1329 strlcpy(options, "unc=", options_size); 1339 1330 strlcat(options,share_name,options_size); 1340 1331 /* scan backwards and reverse direction of slash */ … … 1342 1333 if(temp > options + 6) 1343 1334 *temp = '\\'; 1344 if(ipaddr) {1345 strlcat(options,",ip=",options_size);1346 strlcat(options,ipaddr,options_size);1347 }1348 1349 1335 if(user_name) { 1350 1336 /* check for syntax like user=domain\user */ … … 1388 1374 replace_char(dev_name, '\\', '/', strlen(share_name)); 1389 1375 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)) { 1392 1404 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 } 1395 1412 break; 1396 1413 case ENODEV: … … 1407 1424 } 1408 1425 } 1409 default: 1410 printf("mount error %d = %s\n",errno,strerror(errno)); 1411 } 1426 } 1427 printf("mount error(%d): %s\n", errno, strerror(errno)); 1412 1428 printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n"); 1413 1429 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"); 1462 1442 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; 1467 1484 mount_exit: 1468 1485 if(mountpassword) { … … 1472 1489 } 1473 1490 1491 if (addrhead) 1492 freeaddrinfo(addrhead); 1474 1493 SAFE_FREE(options); 1475 1494 SAFE_FREE(orgoptions);
Note:
See TracChangeset
for help on using the changeset viewer.