Changeset 165 for branches/samba-3.0/source/client/mount.cifs.c
- Timestamp:
- Mar 11, 2009, 9:14:55 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.0/source/client/mount.cifs.c
r140 r165 40 40 #include <fcntl.h> 41 41 #include <limits.h> 42 #include "mount.h" 42 43 43 44 #define MOUNT_CIFS_VERSION_MAJOR "1" 44 #define MOUNT_CIFS_VERSION_MINOR "1 0"45 #define MOUNT_CIFS_VERSION_MINOR "12" 45 46 46 47 #ifndef MOUNT_CIFS_VENDOR_SUFFIX … … 65 66 #endif 66 67 68 #define MAX_UNC_LEN 1024 69 67 70 #define CONST_DISCARD(type, ptr) ((type) ((void *) (ptr))) 68 71 … … 76 79 static int got_uid = 0; 77 80 static int got_gid = 0; 78 static int free_share_name = 0;79 81 static char * user_name = NULL; 80 82 static char * mountpassword = NULL; … … 87 89 /* like strncpy but does not 0 fill the buffer and always null 88 90 * terminates. bufsize is the size of the destination buffer */ 89 s ize_t strlcpy(char *d, const char *s, size_t bufsize)91 static size_t strlcpy(char *d, const char *s, size_t bufsize) 90 92 { 91 93 size_t len = strlen(s); … … 101 103 * terminates. bufsize is the length of the buffer, which should 102 104 * be one more than the maximum resulting string length */ 103 s ize_t strlcat(char *d, const char *s, size_t bufsize)105 static size_t strlcat(char *d, const char *s, size_t bufsize) 104 106 { 105 107 size_t len1 = strlen(d); … … 159 161 mountpassword = NULL; 160 162 } 161 exit( 1);163 exit(EX_USAGE); 162 164 } 163 165 … … 220 222 memset(mountpassword,0,64); 221 223 } 222 exit( 1);224 exit(EX_USAGE); 223 225 } else { 224 226 got_user = 1; … … 246 248 memset(mountpassword,0,64); 247 249 } 248 exit( 1);250 exit(EX_USAGE); 249 251 } else { 250 252 if(mountpassword == NULL) { … … 276 278 memset(mountpassword,0,64); 277 279 } 278 exit( 1);280 exit(EX_USAGE); 279 281 } else { 280 282 if(domain_name == NULL) { … … 313 315 if (mountpassword == NULL) { 314 316 printf("malloc failed\n"); 315 exit( 1);317 exit(EX_SYSERR); 316 318 } 317 319 … … 321 323 printf("mount.cifs failed. %s attempting to open password file %s\n", 322 324 strerror(errno),filename); 323 exit( 1);325 exit(EX_SYSERR); 324 326 } 325 327 } … … 333 335 if(filename != NULL) 334 336 close(file_descript); 335 exit( 1);337 exit(EX_SYSERR); 336 338 } else if(rc == 0) { 337 339 if(mountpassword[0] == 0) { … … 477 479 } else if (strncmp(data, "sec", 3) == 0) { 478 480 if (value) { 479 if (!strcmp(value, "none")) 481 if (!strncmp(value, "none", 4) || 482 !strncmp(value, "krb5", 4)) 480 483 got_password = 1; 481 484 } … … 552 555 if (!(pw = getpwnam(value))) { 553 556 printf("bad user name \"%s\"\n", value); 554 exit( 1);557 exit(EX_USAGE); 555 558 } 556 559 snprintf(user, sizeof(user), "%u", pw->pw_uid); … … 568 571 if (!(gr = getgrnam(value))) { 569 572 printf("bad group name \"%s\"\n", value); 570 exit( 1);573 exit(EX_USAGE); 571 574 } 572 575 snprintf(group, sizeof(group), "%u", gr->gr_gid); … … 663 666 if (out == NULL) { 664 667 perror("malloc"); 665 exit( 1);668 exit(EX_SYSERR); 666 669 } 667 670 … … 688 691 if (out == NULL) { 689 692 perror("malloc"); 690 exit( 1);693 exit(EX_SYSERR); 691 694 } 692 695 … … 704 707 if (out == NULL) { 705 708 perror("malloc"); 706 exit( 1);709 exit(EX_SYSERR); 707 710 } 708 711 … … 842 845 } 843 846 847 /* replace all occurances of "from" in a string with "to" */ 848 static void replace_char(char *string, char from, char to, int maxlen) 849 { 850 char *lastchar = string + maxlen; 851 while (string) { 852 string = strchr(string, from); 853 if (string) { 854 *string = to; 855 if (string >= lastchar) 856 return; 857 } 858 } 859 } 860 844 861 /* Note that caller frees the returned buffer if necessary */ 845 862 static char * parse_server(char ** punc_name) 846 863 { 847 864 char * unc_name = *punc_name; 848 int length = strnlen(unc_name, 1024);865 int length = strnlen(unc_name, MAX_UNC_LEN); 849 866 char * share; 850 867 char * ipaddress_string = NULL; … … 852 869 struct in_addr server_ipaddr; 853 870 854 if(length > 1023) {871 if(length > (MAX_UNC_LEN - 1)) { 855 872 printf("mount error: UNC name too long"); 856 873 return NULL; … … 871 888 share = strchr(unc_name,':'); 872 889 if(share) { 873 free_share_name = 1;874 890 *punc_name = (char *)malloc(length+3); 875 891 if(*punc_name == NULL) { … … 879 895 return NULL; 880 896 } 881 882 897 *share = '/'; 883 898 strncpy((*punc_name)+2,unc_name,length); 899 free(unc_name); 884 900 unc_name = *punc_name; 885 901 unc_name[length+2] = 0; … … 895 911 unc_name[1] = '/'; 896 912 unc_name += 2; 897 if ((share = strchr(unc_name, '/')) || 898 (share = strchr(unc_name,'\\'))) { 913 914 /* allow for either delimiter between host and sharename */ 915 if ((share = strpbrk(unc_name, "/\\"))) { 899 916 *share = 0; /* temporarily terminate the string */ 900 917 share += 1; … … 902 919 host_entry = gethostbyname(unc_name); 903 920 } 904 *(share - 1) = '/'; /* put the slash back */ 905 if ((prefixpath = strchr(share, '/'))) { 921 *(share - 1) = '/'; /* put delimiter back */ 922 923 /* we don't convert the prefixpath delimiters since '\\' is a valid char in posix paths */ 924 if ((prefixpath = strpbrk(share, "/\\"))) { 906 925 *prefixpath = 0; /* permanently terminate the string */ 907 926 if (!strlen(++prefixpath)) … … 968 987 }; 969 988 989 /* convert a string to uppercase. return false if the string 990 * wasn't ASCII. Return success on a NULL ptr */ 991 static int 992 uppercase_string(char *string) 993 { 994 if (!string) 995 return 1; 996 997 while (*string) { 998 /* check for unicode */ 999 if ((unsigned char) string[0] & 0x80) 1000 return 0; 1001 *string = toupper((unsigned char) *string); 1002 string++; 1003 } 1004 1005 return 1; 1006 } 1007 970 1008 int main(int argc, char ** argv) 971 1009 { … … 980 1018 char * resolved_path = NULL; 981 1019 char * temp; 1020 char * dev_name; 982 1021 int rc; 983 1022 int rsize = 0; … … 1003 1042 } else { 1004 1043 mount_cifs_usage(); 1005 exit( 1);1044 exit(EX_USAGE); 1006 1045 } 1007 1046 … … 1016 1055 #endif */ 1017 1056 if(argc > 2) { 1018 share_name = argv[1]; 1057 dev_name = argv[1]; 1058 share_name = strndup(argv[1], MAX_UNC_LEN); 1059 if (share_name == NULL) { 1060 fprintf(stderr, "%s: %s", argv[0], strerror(ENOMEM)); 1061 exit(EX_SYSERR); 1062 } 1019 1063 mountpoint = argv[2]; 1064 } else { 1065 mount_cifs_usage(); 1066 exit(EX_USAGE); 1020 1067 } 1021 1068 … … 1039 1086 case 'h': /* help */ 1040 1087 mount_cifs_usage (); 1041 exit( 1);1088 exit(EX_USAGE); 1042 1089 case 'n': 1043 1090 ++nomtab; … … 1096 1143 if (*ep) { 1097 1144 printf("bad uid value \"%s\"\n", optarg); 1098 exit( 1);1145 exit(EX_USAGE); 1099 1146 } 1100 1147 } else { … … 1103 1150 if (!(pw = getpwnam(optarg))) { 1104 1151 printf("bad user name \"%s\"\n", optarg); 1105 exit( 1);1152 exit(EX_USAGE); 1106 1153 } 1107 1154 uid = pw->pw_uid; … … 1116 1163 if (*ep) { 1117 1164 printf("bad gid value \"%s\"\n", optarg); 1118 exit( 1);1165 exit(EX_USAGE); 1119 1166 } 1120 1167 } else { … … 1123 1170 if (!(gr = getgrnam(optarg))) { 1124 1171 printf("bad user name \"%s\"\n", optarg); 1125 exit( 1);1172 exit(EX_USAGE); 1126 1173 } 1127 1174 gid = gr->gr_gid; … … 1153 1200 printf("unknown mount option %c\n",c); 1154 1201 mount_cifs_usage(); 1155 exit( 1);1156 } 1157 } 1158 1159 if((argc < 3) || ( share_name == NULL) || (mountpoint == NULL)) {1202 exit(EX_USAGE); 1203 } 1204 } 1205 1206 if((argc < 3) || (dev_name == NULL) || (mountpoint == NULL)) { 1160 1207 mount_cifs_usage(); 1161 exit( 1);1208 exit(EX_USAGE); 1162 1209 } 1163 1210 … … 1176 1223 1177 1224 if (orgoptions && parse_options(&orgoptions, &flags)) { 1178 rc = -1;1225 rc = EX_USAGE; 1179 1226 goto mount_exit; 1180 1227 } … … 1182 1229 if((ipaddr == NULL) && (got_ip == 0)) { 1183 1230 printf("No ip address specified and hostname not found\n"); 1184 rc = -1;1231 rc = EX_USAGE; 1185 1232 goto mount_exit; 1186 1233 } … … 1197 1244 if(chdir(mountpoint)) { 1198 1245 printf("mount error: can not change directory into mount target %s\n",mountpoint); 1199 rc = -1;1246 rc = EX_USAGE; 1200 1247 goto mount_exit; 1201 1248 } … … 1203 1250 if(stat (".", &statbuf)) { 1204 1251 printf("mount error: mount point %s does not exist\n",mountpoint); 1205 rc = -1;1252 rc = EX_USAGE; 1206 1253 goto mount_exit; 1207 1254 } … … 1209 1256 if (S_ISDIR(statbuf.st_mode) == 0) { 1210 1257 printf("mount error: mount point %s is not a directory\n",mountpoint); 1211 rc = -1;1258 rc = EX_USAGE; 1212 1259 goto mount_exit; 1213 1260 } … … 1222 1269 } else { 1223 1270 printf("mount error: permission denied or not superuser and mount.cifs not installed SUID\n"); 1224 return -1;1271 exit(EX_USAGE); 1225 1272 } 1226 1273 } … … 1237 1284 mountpassword = (char *)calloc(65,1); 1238 1285 if (!tmp_pass || !mountpassword) { 1239 printf("Password not entered, exiting .\n");1240 return -1;1286 printf("Password not entered, exiting\n"); 1287 exit(EX_USAGE); 1241 1288 } 1242 1289 strncpy(mountpassword, tmp_pass, 64); … … 1257 1304 printf("No server share name specified\n"); 1258 1305 printf("\nMounting the DFS root for server not implemented yet\n"); 1259 exit( 1);1306 exit(EX_USAGE); 1260 1307 } 1261 1308 if(user_name) … … 1274 1321 if(options == NULL) { 1275 1322 printf("Could not allocate memory for mount options\n"); 1276 return -1;1323 exit(EX_SYSERR); 1277 1324 } 1278 1325 … … 1326 1373 if(verboseflag) 1327 1374 printf("\nmount.cifs kernel mount options %s \n",options); 1328 if(mount(share_name, mountpoint, "cifs", flags, options)) { 1375 1376 /* convert all '\\' to '/' in share portion so that /proc/mounts looks pretty */ 1377 replace_char(dev_name, '\\', '/', strlen(share_name)); 1378 1379 if(mount(dev_name, mountpoint, "cifs", flags, options)) { 1329 1380 /* remember to kill daemon on error */ 1330 char * tmp;1331 1332 1381 switch (errno) { 1333 1382 case 0: … … 1340 1389 if(retry == 0) { 1341 1390 retry = 1; 1342 tmp = share_name; 1343 while (*tmp && !(((unsigned char)tmp[0]) & 0x80)) { 1344 *tmp = toupper((unsigned char)*tmp); 1345 tmp++; 1346 } 1347 if(!*tmp) { 1391 if (uppercase_string(dev_name) && 1392 uppercase_string(share_name) && 1393 uppercase_string(prefixpath)) { 1348 1394 printf("retrying with upper case share name\n"); 1349 1395 goto mount_retry; … … 1354 1400 } 1355 1401 printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n"); 1356 rc = -1; 1357 goto mount_exit; 1402 rc = EX_FAIL; 1358 1403 } else { 1404 atexit(unlock_mtab); 1405 rc = lock_mtab(); 1406 if (rc) { 1407 printf("cannot lock mtab"); 1408 goto mount_exit; 1409 } 1359 1410 pmntfile = setmntent(MOUNTED, "a+"); 1360 if(pmntfile) { 1361 mountent.mnt_fsname = share_name; 1362 mountent.mnt_dir = mountpoint; 1363 mountent.mnt_type = CONST_DISCARD(char *,"cifs"); 1364 mountent.mnt_opts = (char *)malloc(220); 1365 if(mountent.mnt_opts) { 1366 char * mount_user = getusername(); 1367 memset(mountent.mnt_opts,0,200); 1368 if(flags & MS_RDONLY) 1369 strlcat(mountent.mnt_opts,"ro",220); 1370 else 1371 strlcat(mountent.mnt_opts,"rw",220); 1372 if(flags & MS_MANDLOCK) 1373 strlcat(mountent.mnt_opts,",mand",220); 1374 if(flags & MS_NOEXEC) 1375 strlcat(mountent.mnt_opts,",noexec",220); 1376 if(flags & MS_NOSUID) 1377 strlcat(mountent.mnt_opts,",nosuid",220); 1378 if(flags & MS_NODEV) 1379 strlcat(mountent.mnt_opts,",nodev",220); 1380 if(flags & MS_SYNCHRONOUS) 1381 strlcat(mountent.mnt_opts,",synch",220); 1382 if(mount_user) { 1383 if(getuid() != 0) { 1384 strlcat(mountent.mnt_opts,",user=",220); 1385 strlcat(mountent.mnt_opts,mount_user,220); 1386 } 1387 /* free(mount_user); do not free static mem */ 1388 } 1389 } 1390 mountent.mnt_freq = 0; 1391 mountent.mnt_passno = 0; 1392 rc = addmntent(pmntfile,&mountent); 1393 endmntent(pmntfile); 1394 if(mountent.mnt_opts) { 1395 free(mountent.mnt_opts); 1396 mountent.mnt_opts = NULL; 1397 } 1398 } else { 1399 printf("could not update mount table\n"); 1400 } 1401 } 1402 rc = 0; 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); 1451 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 } 1403 1459 mount_exit: 1404 1460 if(mountpassword) { … … 1425 1481 } 1426 1482 1427 if(free_share_name) { 1428 free(share_name); 1429 share_name = NULL; 1430 } 1431 return rc; 1483 free(share_name); 1484 exit(rc); 1432 1485 }
Note:
See TracChangeset
for help on using the changeset viewer.