Changeset 312 for branches/samba-3.0/source/client/mount.cifs.c
- Timestamp:
- Aug 5, 2009, 6:34:45 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.0/source/client/mount.cifs.c
r165 r312 2 2 Mount helper utility for Linux CIFS VFS (virtual filesystem) client 3 3 Copyright (C) 2003,2008 Steve French (sfrench@us.ibm.com) 4 Copyright (C) 2008 Jeremy Allison (jra@samba.org) 4 5 5 6 This program is free software; you can redistribute it and/or modify 6 7 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2of the License, or8 the Free Software Foundation; either version 3 of the License, or 8 9 (at your option) any later version. 9 10 … … 14 15 15 16 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/>. */ 18 18 19 19 #ifndef _GNU_SOURCE … … 58 58 #endif /* MOUNT_CIFS_VENDOR_SUFFIX */ 59 59 60 #ifdef _SAMBA_BUILD_ 61 #include "include/config.h" 62 #endif 63 60 64 #ifndef MS_MOVE 61 65 #define MS_MOVE 8192 … … 70 74 #define CONST_DISCARD(type, ptr) ((type) ((void *) (ptr))) 71 75 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 72 86 const char *thisprogram; 73 87 int verboseflag = 0; 88 int fakemnt = 0; 74 89 static int got_password = 0; 75 90 static int got_user = 0; … … 89 104 /* like strncpy but does not 0 fill the buffer and always null 90 105 * terminates. bufsize is the size of the destination buffer */ 106 107 #ifndef HAVE_STRLCPY 91 108 static size_t strlcpy(char *d, const char *s, size_t bufsize) 92 109 { … … 99 116 return ret; 100 117 } 118 #endif 101 119 102 120 /* like strncat but does not 0 fill the buffer and always null 103 121 * terminates. bufsize is the length of the buffer, which should 104 122 * be one more than the maximum resulting string length */ 123 124 #ifndef HAVE_STRLCAT 105 125 static size_t strlcat(char *d, const char *s, size_t bufsize) 106 126 { … … 121 141 return ret; 122 142 } 143 #endif 123 144 124 145 /* BB finish BB … … 143 164 printf("\n\tcredentials=<filename>,guest,perm,noperm,setuids,nosetuids,rw,ro,"); 144 165 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"); 146 168 printf("\n\nOptions not needed for servers supporting CIFS Unix extensions"); 147 169 printf("\n\t(e.g. unneeded for mounts to most Samba versions):"); … … 150 172 printf("\n\tport=<tcpport>,rsize=<size>,wsize=<size>,unc=<unc_name>,ip=<ip_address>,"); 151 173 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"); 153 176 printf("\n\nOptions are described in more detail in the manual page"); 154 177 printf("\n\tman 8 mount.cifs\n"); … … 156 179 printf("\n\t%s -V\n",thisprogram); 157 180 158 if(mountpassword) { 159 memset(mountpassword,0,64); 160 free(mountpassword); 161 mountpassword = NULL; 162 } 181 SAFE_FREE(mountpassword); 163 182 exit(EX_USAGE); 164 183 } … … 173 192 } 174 193 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;181 194 } 182 195 … … 193 206 if(line_buf == NULL) { 194 207 fclose(fs); 195 return -ENOMEM;208 return ENOMEM; 196 209 } 197 210 … … 213 226 if ((temp_val[length] == '\n') 214 227 || (temp_val[length] == '\0')) { 228 temp_val[length] = '\0'; 215 229 break; 216 230 } … … 219 233 printf("mount.cifs failed due to malformed username in credentials file"); 220 234 memset(line_buf,0,4096); 221 if(mountpassword) {222 memset(mountpassword,0,64);223 }224 235 exit(EX_USAGE); 225 236 } else { … … 228 239 /* BB adding free of user_name string before exit, 229 240 not really necessary but would be cleaner */ 230 str ncpy(user_name,temp_val, length);241 strlcpy(user_name,temp_val, length+1); 231 242 } 232 243 } … … 236 247 /* go past equals sign */ 237 248 temp_val++; 238 for(length = 0;length< 65;length++) {249 for(length = 0;length<MOUNT_PASSWD_SIZE+1;length++) { 239 250 if ((temp_val[length] == '\n') 240 251 || (temp_val[length] == '\0')) { 252 temp_val[length] = '\0'; 241 253 break; 242 254 } 243 255 } 244 if(length > 64) {256 if(length > MOUNT_PASSWD_SIZE) { 245 257 printf("mount.cifs failed: password in credentials file too long\n"); 246 258 memset(line_buf,0, 4096); 247 if(mountpassword) {248 memset(mountpassword,0,64);249 }250 259 exit(EX_USAGE); 251 260 } else { 252 261 if(mountpassword == NULL) { 253 mountpassword = (char *)calloc( 65,1);262 mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); 254 263 } else 255 memset(mountpassword,0, 64);264 memset(mountpassword,0,MOUNT_PASSWD_SIZE); 256 265 if(mountpassword) { 257 str ncpy(mountpassword,temp_val,length);266 strlcpy(mountpassword,temp_val,MOUNT_PASSWD_SIZE+1); 258 267 got_password = 1; 259 268 } … … 267 276 if(verboseflag) 268 277 printf("\nDomain %s\n",temp_val); 269 for(length = 0;length< 65;length++) {278 for(length = 0;length<DOMAIN_SIZE+1;length++) { 270 279 if ((temp_val[length] == '\n') 271 280 || (temp_val[length] == '\0')) { 281 temp_val[length] = '\0'; 272 282 break; 273 283 } 274 284 } 275 if(length > 64) {285 if(length > DOMAIN_SIZE) { 276 286 printf("mount.cifs failed: domain in credentials file too long\n"); 277 if(mountpassword) {278 memset(mountpassword,0,64);279 }280 287 exit(EX_USAGE); 281 288 } else { 282 289 if(domain_name == NULL) { 283 domain_name = (char *)calloc( 65,1);290 domain_name = (char *)calloc(DOMAIN_SIZE+1,1); 284 291 } else 285 memset(domain_name,0, 64);292 memset(domain_name,0,DOMAIN_SIZE); 286 293 if(domain_name) { 287 str ncpy(domain_name,temp_val,length);294 strlcpy(domain_name,temp_val,DOMAIN_SIZE+1); 288 295 got_domain = 1; 289 296 } … … 294 301 } 295 302 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); 301 304 return 0; 302 305 } … … 309 312 310 313 if(mountpassword == NULL) 311 mountpassword = (char *)calloc( 65,1);314 mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); 312 315 else 313 memset(mountpassword, 0, 64);316 memset(mountpassword, 0, MOUNT_PASSWD_SIZE); 314 317 315 318 if (mountpassword == NULL) { … … 328 331 /* else file already open and fd provided */ 329 332 330 for(i=0;i< 64;i++) {333 for(i=0;i<MOUNT_PASSWD_SIZE;i++) { 331 334 rc = read(file_descript,&c,1); 332 335 if(rc < 0) { 333 336 printf("mount.cifs failed. Error %s reading password file\n",strerror(errno)); 334 memset(mountpassword,0,64);335 337 if(filename != NULL) 336 338 close(file_descript); … … 344 346 } else /* read valid character */ { 345 347 if((c == 0) || (c == '\n')) { 348 mountpassword[i] = '\0'; 346 349 break; 347 350 } else … … 349 352 } 350 353 } 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); 353 357 } 354 358 got_password = 1; … … 428 432 } else { 429 433 printf("username specified with no parameter\n"); 434 SAFE_FREE(out); 430 435 return 1; /* needs_arg; */ 431 436 } … … 437 442 *percent_char = ','; 438 443 if(mountpassword == NULL) 439 mountpassword = (char *)calloc( 65,1);444 mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); 440 445 if(mountpassword) { 441 446 if(got_password) … … 443 448 got_password = 1; 444 449 percent_char++; 445 str ncpy(mountpassword, percent_char,64);450 strlcpy(mountpassword, percent_char,MOUNT_PASSWD_SIZE+1); 446 451 /* remove password from username */ 447 452 while(*percent_char != 0) { … … 460 465 } else { 461 466 printf("username too long\n"); 467 SAFE_FREE(out); 462 468 return 1; 463 469 } … … 475 481 } else { 476 482 printf("password too long\n"); 483 SAFE_FREE(out); 477 484 return 1; 478 485 } … … 486 493 if (!value || !*value) { 487 494 printf("target ip address argument missing"); 488 } else if (strnlen(value, 35) < 35) {495 } else if (strnlen(value, MAX_ADDRESS_LEN) <= MAX_ADDRESS_LEN) { 489 496 if(verboseflag) 490 497 printf("ip address %s override specified\n",value); … … 492 499 } else { 493 500 printf("ip address too long\n"); 501 SAFE_FREE(out); 494 502 return 1; 495 503 } … … 499 507 if (!value || !*value) { 500 508 printf("invalid path to network resource\n"); 509 SAFE_FREE(out); 501 510 return 1; /* needs_arg; */ 502 511 } else if(strnlen(value,5) < 5) { … … 513 522 } else if (strncmp(value, "\\\\", 2) != 0) { 514 523 printf("UNC Path does not begin with // or \\\\ \n"); 524 SAFE_FREE(out); 515 525 return 1; 516 526 } else { … … 522 532 } else { 523 533 printf("CIFS: UNC name too long\n"); 534 SAFE_FREE(out); 524 535 return 1; 525 536 } 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. */ 528 542 if (!value || !*value) { 529 543 printf("CIFS: invalid domain name\n"); 544 SAFE_FREE(out); 530 545 return 1; /* needs_arg; */ 531 546 } 532 if (strnlen(value, 65) < 65) {547 if (strnlen(value, DOMAIN_SIZE+1) < DOMAIN_SIZE+1) { 533 548 got_domain = 1; 534 549 } else { 535 550 printf("domain name too long\n"); 551 SAFE_FREE(out); 536 552 return 1; 537 553 } … … 540 556 rc = open_cred_file(value); 541 557 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); 543 561 return 1; 544 562 } 545 563 } else { 546 564 printf("invalid credential file name specified\n"); 565 SAFE_FREE(out); 547 566 return 1; 548 567 } … … 583 602 if (!value || !*value) { 584 603 printf ("Option '%s' requires a numerical argument\n", data); 604 SAFE_FREE(out); 585 605 return 1; 586 606 } … … 597 617 if (!value || !*value) { 598 618 printf ("Option '%s' requires a numerical argument\n", data); 619 SAFE_FREE(out); 599 620 return 1; 600 621 } … … 630 651 *filesys_flags &= ~MS_NOEXEC; 631 652 } 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; 633 656 } else if (strncmp(data, "ro", 2) == 0) { 634 657 *filesys_flags |= MS_RDONLY; … … 718 741 } 719 742 720 free(*optionsp);743 SAFE_FREE(*optionsp); 721 744 *optionsp = out; 722 745 return 0; … … 746 769 if(number_of_commas == 0) 747 770 return; 748 if(number_of_commas > 64) {771 if(number_of_commas > MOUNT_PASSWD_SIZE) { 749 772 /* would otherwise overflow the mount options buffer */ 750 773 printf("\nInvalid password. Password contains too many commas.\n"); … … 765 788 new_pass_buf[len+number_of_commas] = 0; 766 789 767 free(*ppasswrd);790 SAFE_FREE(*ppasswrd); 768 791 *ppasswrd = new_pass_buf; 769 792 … … 860 883 861 884 /* Note that caller frees the returned buffer if necessary */ 862 static char * parse_server(char ** punc_name) 885 static struct addrinfo * 886 parse_server(char ** punc_name) 863 887 { 864 888 char * unc_name = *punc_name; 865 889 int length = strnlen(unc_name, MAX_UNC_LEN); 866 890 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; 870 893 871 894 if(length > (MAX_UNC_LEN - 1)) { … … 873 896 return NULL; 874 897 } 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; 879 902 } 880 903 … … 896 919 } 897 920 *share = '/'; 898 str ncpy((*punc_name)+2,unc_name,length);899 free(unc_name);921 strlcpy((*punc_name)+2,unc_name,length+1); 922 SAFE_FREE(unc_name); 900 923 unc_name = *punc_name; 901 924 unc_name[length+2] = 0; … … 917 940 share += 1; 918 941 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 } 920 948 } 921 949 *(share - 1) = '/'; /* put delimiter back */ … … 932 960 return NULL; 933 961 } 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; 951 965 } else { 952 966 /* BB add code to find DFS root (send null path on get DFS Referral to specified server here */ … … 1012 1026 char * orgoptions = NULL; 1013 1027 char * share_name = NULL; 1014 c har * ipaddr = NULL;1028 const char * ipaddr = NULL; 1015 1029 char * uuid = NULL; 1016 1030 char * mountpoint = NULL; 1017 1031 char * options = NULL; 1032 char * optionstail; 1018 1033 char * resolved_path = NULL; 1019 1034 char * temp; 1020 1035 char * dev_name; 1021 int rc ;1036 int rc = 0; 1022 1037 int rsize = 0; 1023 1038 int wsize = 0; … … 1028 1043 int orgoptlen = 0; 1029 1044 size_t options_size = 0; 1045 size_t current_len; 1030 1046 int retry = 0; /* set when we have to retry mount with uppercase */ 1047 struct addrinfo *addrhead = NULL, *addr; 1031 1048 struct stat statbuf; 1032 1049 struct utsname sysinfo; 1033 1050 struct mntent mountent; 1051 struct sockaddr_in *addr4; 1052 struct sockaddr_in6 *addr6; 1034 1053 FILE * pmntfile; 1035 1054 … … 1063 1082 mountpoint = argv[2]; 1064 1083 } 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 } 1065 1092 mount_cifs_usage(); 1066 1093 exit(EX_USAGE); … … 1088 1115 exit(EX_USAGE); 1089 1116 case 'n': 1090 1091 1117 ++nomtab; 1118 break; 1092 1119 case 'b': 1093 1120 #ifdef MS_BIND … … 1123 1150 MOUNT_CIFS_VERSION_MINOR, 1124 1151 MOUNT_CIFS_VENDOR_SUFFIX); 1125 if(mountpassword) {1126 memset(mountpassword,0,64);1127 }1128 1152 exit (0); 1129 1153 case 'w': … … 1186 1210 case 'p': 1187 1211 if(mountpassword == NULL) 1188 mountpassword = (char *)calloc( 65,1);1212 mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); 1189 1213 if(mountpassword) { 1190 1214 got_password = 1; 1191 str ncpy(mountpassword,optarg,64);1215 strlcpy(mountpassword,optarg,MOUNT_PASSWD_SIZE+1); 1192 1216 } 1193 1217 break; … … 1196 1220 break; 1197 1221 case 't': 1222 break; 1223 case 'f': 1224 ++fakemnt; 1198 1225 break; 1199 1226 default: … … 1211 1238 if (getenv("PASSWD")) { 1212 1239 if(mountpassword == NULL) 1213 mountpassword = (char *)calloc( 65,1);1240 mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); 1214 1241 if(mountpassword) { 1215 str ncpy(mountpassword,getenv("PASSWD"),64);1242 strlcpy(mountpassword,getenv("PASSWD"),MOUNT_PASSWD_SIZE+1); 1216 1243 got_password = 1; 1217 1244 } … … 1226 1253 goto mount_exit; 1227 1254 } 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)) { 1230 1257 printf("No ip address specified and hostname not found\n"); 1231 1258 rc = EX_USAGE; … … 1274 1301 1275 1302 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(); 1277 1310 got_user = 1; 1278 1311 } 1279 1312 1280 1313 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); 1285 1317 if (!tmp_pass || !mountpassword) { 1286 1318 printf("Password not entered, exiting\n"); 1287 1319 exit(EX_USAGE); 1288 1320 } 1289 strncpy(mountpassword, tmp_pass, 64); 1290 1321 strlcpy(mountpassword, tmp_pass, MOUNT_PASSWD_SIZE+1); 1291 1322 got_password = 1; 1292 1323 } 1293 1324 /* FIXME launch daemon (handles dfs name resolution and credential change) 1294 1325 remember to clear parms and overwrite password field before launching */ 1295 mount_retry:1296 1326 if(orgoptions) { 1297 1327 optlen = strlen(orgoptions); … … 1308 1338 if(user_name) 1309 1339 optlen += strlen(user_name) + 6; 1310 if(ipaddr) 1311 optlen += strlen(ipaddr) + 4; 1340 optlen += MAX_ADDRESS_LEN + 4; 1312 1341 if(mountpassword) 1313 1342 optlen += strlen(mountpassword) + 6; 1314 if(options) { 1315 free(options); 1316 options = NULL; 1317 } 1318 options_size = optlen + 10 + 64; 1343 mount_retry: 1344 SAFE_FREE(options); 1345 options_size = optlen + 10 + DOMAIN_SIZE; 1319 1346 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 */); 1320 1347 … … 1324 1351 } 1325 1352 1326 options[0] = 0; 1327 strlcpy(options,"unc=",options_size); 1353 strlcpy(options, "unc=", options_size); 1328 1354 strlcat(options,share_name,options_size); 1329 1355 /* scan backwards and reverse direction of slash */ … … 1331 1357 if(temp > options + 6) 1332 1358 *temp = '\\'; 1333 if(ipaddr) {1334 strlcat(options,",ip=",options_size);1335 strlcat(options,ipaddr,options_size);1336 }1337 1338 1359 if(user_name) { 1339 1360 /* check for syntax like user=domain\user */ … … 1377 1398 replace_char(dev_name, '\\', '/', strlen(share_name)); 1378 1399 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)) { 1381 1428 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 } 1384 1436 break; 1385 1437 case ENODEV: … … 1396 1448 } 1397 1449 } 1398 default: 1399 printf("mount error %d = %s\n",errno,strerror(errno)); 1400 } 1450 } 1451 printf("mount error(%d): %s\n", errno, strerror(errno)); 1401 1452 printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n"); 1402 1453 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"); 1451 1468 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; 1459 1510 mount_exit: 1460 1511 if(mountpassword) { 1461 1512 int len = strlen(mountpassword); 1462 1513 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); 1484 1523 exit(rc); 1485 1524 }
Note:
See TracChangeset
for help on using the changeset viewer.