diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 1338 |
1 files changed, 814 insertions, 524 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 855d8c08e3a4..3d72218bd962 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
41 | #include <keys/user-type.h> | 41 | #include <keys/user-type.h> |
42 | #include <net/ipv6.h> | 42 | #include <net/ipv6.h> |
43 | #include <linux/parser.h> | ||
44 | |||
43 | #include "cifspdu.h" | 45 | #include "cifspdu.h" |
44 | #include "cifsglob.h" | 46 | #include "cifsglob.h" |
45 | #include "cifsproto.h" | 47 | #include "cifsproto.h" |
@@ -63,6 +65,191 @@ extern mempool_t *cifs_req_poolp; | |||
63 | #define TLINK_ERROR_EXPIRE (1 * HZ) | 65 | #define TLINK_ERROR_EXPIRE (1 * HZ) |
64 | #define TLINK_IDLE_EXPIRE (600 * HZ) | 66 | #define TLINK_IDLE_EXPIRE (600 * HZ) |
65 | 67 | ||
68 | enum { | ||
69 | |||
70 | /* Mount options that take no arguments */ | ||
71 | Opt_user_xattr, Opt_nouser_xattr, | ||
72 | Opt_forceuid, Opt_noforceuid, | ||
73 | Opt_noblocksend, Opt_noautotune, | ||
74 | Opt_hard, Opt_soft, Opt_perm, Opt_noperm, | ||
75 | Opt_mapchars, Opt_nomapchars, Opt_sfu, | ||
76 | Opt_nosfu, Opt_nodfs, Opt_posixpaths, | ||
77 | Opt_noposixpaths, Opt_nounix, | ||
78 | Opt_nocase, | ||
79 | Opt_brl, Opt_nobrl, | ||
80 | Opt_forcemandatorylock, Opt_setuids, | ||
81 | Opt_nosetuids, Opt_dynperm, Opt_nodynperm, | ||
82 | Opt_nohard, Opt_nosoft, | ||
83 | Opt_nointr, Opt_intr, | ||
84 | Opt_nostrictsync, Opt_strictsync, | ||
85 | Opt_serverino, Opt_noserverino, | ||
86 | Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl, | ||
87 | Opt_acl, Opt_noacl, Opt_locallease, | ||
88 | Opt_sign, Opt_seal, Opt_direct, | ||
89 | Opt_strictcache, Opt_noac, | ||
90 | Opt_fsc, Opt_mfsymlinks, | ||
91 | Opt_multiuser, | ||
92 | |||
93 | /* Mount options which take numeric value */ | ||
94 | Opt_backupuid, Opt_backupgid, Opt_uid, | ||
95 | Opt_cruid, Opt_gid, Opt_file_mode, | ||
96 | Opt_dirmode, Opt_port, | ||
97 | Opt_rsize, Opt_wsize, Opt_actimeo, | ||
98 | |||
99 | /* Mount options which take string value */ | ||
100 | Opt_user, Opt_pass, Opt_ip, | ||
101 | Opt_unc, Opt_domain, | ||
102 | Opt_srcaddr, Opt_prefixpath, | ||
103 | Opt_iocharset, Opt_sockopt, | ||
104 | Opt_netbiosname, Opt_servern, | ||
105 | Opt_ver, Opt_sec, | ||
106 | |||
107 | /* Mount options to be ignored */ | ||
108 | Opt_ignore, | ||
109 | |||
110 | /* Options which could be blank */ | ||
111 | Opt_blank_pass, | ||
112 | |||
113 | Opt_err | ||
114 | }; | ||
115 | |||
116 | static const match_table_t cifs_mount_option_tokens = { | ||
117 | |||
118 | { Opt_user_xattr, "user_xattr" }, | ||
119 | { Opt_nouser_xattr, "nouser_xattr" }, | ||
120 | { Opt_forceuid, "forceuid" }, | ||
121 | { Opt_noforceuid, "noforceuid" }, | ||
122 | { Opt_noblocksend, "noblocksend" }, | ||
123 | { Opt_noautotune, "noautotune" }, | ||
124 | { Opt_hard, "hard" }, | ||
125 | { Opt_soft, "soft" }, | ||
126 | { Opt_perm, "perm" }, | ||
127 | { Opt_noperm, "noperm" }, | ||
128 | { Opt_mapchars, "mapchars" }, | ||
129 | { Opt_nomapchars, "nomapchars" }, | ||
130 | { Opt_sfu, "sfu" }, | ||
131 | { Opt_nosfu, "nosfu" }, | ||
132 | { Opt_nodfs, "nodfs" }, | ||
133 | { Opt_posixpaths, "posixpaths" }, | ||
134 | { Opt_noposixpaths, "noposixpaths" }, | ||
135 | { Opt_nounix, "nounix" }, | ||
136 | { Opt_nounix, "nolinux" }, | ||
137 | { Opt_nocase, "nocase" }, | ||
138 | { Opt_nocase, "ignorecase" }, | ||
139 | { Opt_brl, "brl" }, | ||
140 | { Opt_nobrl, "nobrl" }, | ||
141 | { Opt_nobrl, "nolock" }, | ||
142 | { Opt_forcemandatorylock, "forcemandatorylock" }, | ||
143 | { Opt_setuids, "setuids" }, | ||
144 | { Opt_nosetuids, "nosetuids" }, | ||
145 | { Opt_dynperm, "dynperm" }, | ||
146 | { Opt_nodynperm, "nodynperm" }, | ||
147 | { Opt_nohard, "nohard" }, | ||
148 | { Opt_nosoft, "nosoft" }, | ||
149 | { Opt_nointr, "nointr" }, | ||
150 | { Opt_intr, "intr" }, | ||
151 | { Opt_nostrictsync, "nostrictsync" }, | ||
152 | { Opt_strictsync, "strictsync" }, | ||
153 | { Opt_serverino, "serverino" }, | ||
154 | { Opt_noserverino, "noserverino" }, | ||
155 | { Opt_rwpidforward, "rwpidforward" }, | ||
156 | { Opt_cifsacl, "cifsacl" }, | ||
157 | { Opt_nocifsacl, "nocifsacl" }, | ||
158 | { Opt_acl, "acl" }, | ||
159 | { Opt_noacl, "noacl" }, | ||
160 | { Opt_locallease, "locallease" }, | ||
161 | { Opt_sign, "sign" }, | ||
162 | { Opt_seal, "seal" }, | ||
163 | { Opt_direct, "direct" }, | ||
164 | { Opt_direct, "forceddirectio" }, | ||
165 | { Opt_strictcache, "strictcache" }, | ||
166 | { Opt_noac, "noac" }, | ||
167 | { Opt_fsc, "fsc" }, | ||
168 | { Opt_mfsymlinks, "mfsymlinks" }, | ||
169 | { Opt_multiuser, "multiuser" }, | ||
170 | |||
171 | { Opt_backupuid, "backupuid=%s" }, | ||
172 | { Opt_backupgid, "backupgid=%s" }, | ||
173 | { Opt_uid, "uid=%s" }, | ||
174 | { Opt_cruid, "cruid=%s" }, | ||
175 | { Opt_gid, "gid=%s" }, | ||
176 | { Opt_file_mode, "file_mode=%s" }, | ||
177 | { Opt_dirmode, "dirmode=%s" }, | ||
178 | { Opt_dirmode, "dir_mode=%s" }, | ||
179 | { Opt_port, "port=%s" }, | ||
180 | { Opt_rsize, "rsize=%s" }, | ||
181 | { Opt_wsize, "wsize=%s" }, | ||
182 | { Opt_actimeo, "actimeo=%s" }, | ||
183 | |||
184 | { Opt_user, "user=%s" }, | ||
185 | { Opt_user, "username=%s" }, | ||
186 | { Opt_blank_pass, "pass=" }, | ||
187 | { Opt_pass, "pass=%s" }, | ||
188 | { Opt_pass, "password=%s" }, | ||
189 | { Opt_ip, "ip=%s" }, | ||
190 | { Opt_ip, "addr=%s" }, | ||
191 | { Opt_unc, "unc=%s" }, | ||
192 | { Opt_unc, "target=%s" }, | ||
193 | { Opt_unc, "path=%s" }, | ||
194 | { Opt_domain, "dom=%s" }, | ||
195 | { Opt_domain, "domain=%s" }, | ||
196 | { Opt_domain, "workgroup=%s" }, | ||
197 | { Opt_srcaddr, "srcaddr=%s" }, | ||
198 | { Opt_prefixpath, "prefixpath=%s" }, | ||
199 | { Opt_iocharset, "iocharset=%s" }, | ||
200 | { Opt_sockopt, "sockopt=%s" }, | ||
201 | { Opt_netbiosname, "netbiosname=%s" }, | ||
202 | { Opt_servern, "servern=%s" }, | ||
203 | { Opt_ver, "ver=%s" }, | ||
204 | { Opt_ver, "vers=%s" }, | ||
205 | { Opt_ver, "version=%s" }, | ||
206 | { Opt_sec, "sec=%s" }, | ||
207 | |||
208 | { Opt_ignore, "cred" }, | ||
209 | { Opt_ignore, "credentials" }, | ||
210 | { Opt_ignore, "guest" }, | ||
211 | { Opt_ignore, "rw" }, | ||
212 | { Opt_ignore, "ro" }, | ||
213 | { Opt_ignore, "suid" }, | ||
214 | { Opt_ignore, "nosuid" }, | ||
215 | { Opt_ignore, "exec" }, | ||
216 | { Opt_ignore, "noexec" }, | ||
217 | { Opt_ignore, "nodev" }, | ||
218 | { Opt_ignore, "noauto" }, | ||
219 | { Opt_ignore, "dev" }, | ||
220 | { Opt_ignore, "mand" }, | ||
221 | { Opt_ignore, "nomand" }, | ||
222 | { Opt_ignore, "_netdev" }, | ||
223 | |||
224 | { Opt_err, NULL } | ||
225 | }; | ||
226 | |||
227 | enum { | ||
228 | Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p, | ||
229 | Opt_sec_ntlmsspi, Opt_sec_ntlmssp, | ||
230 | Opt_ntlm, Opt_sec_ntlmi, Opt_sec_ntlmv2i, | ||
231 | Opt_sec_nontlm, Opt_sec_lanman, | ||
232 | Opt_sec_none, | ||
233 | |||
234 | Opt_sec_err | ||
235 | }; | ||
236 | |||
237 | static const match_table_t cifs_secflavor_tokens = { | ||
238 | { Opt_sec_krb5, "krb5" }, | ||
239 | { Opt_sec_krb5i, "krb5i" }, | ||
240 | { Opt_sec_krb5p, "krb5p" }, | ||
241 | { Opt_sec_ntlmsspi, "ntlmsspi" }, | ||
242 | { Opt_sec_ntlmssp, "ntlmssp" }, | ||
243 | { Opt_ntlm, "ntlm" }, | ||
244 | { Opt_sec_ntlmi, "ntlmi" }, | ||
245 | { Opt_sec_ntlmv2i, "ntlmv2i" }, | ||
246 | { Opt_sec_nontlm, "nontlm" }, | ||
247 | { Opt_sec_lanman, "lanman" }, | ||
248 | { Opt_sec_none, "none" }, | ||
249 | |||
250 | { Opt_sec_err, NULL } | ||
251 | }; | ||
252 | |||
66 | static int ip_connect(struct TCP_Server_Info *server); | 253 | static int ip_connect(struct TCP_Server_Info *server); |
67 | static int generic_ip_connect(struct TCP_Server_Info *server); | 254 | static int generic_ip_connect(struct TCP_Server_Info *server); |
68 | static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); | 255 | static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); |
@@ -920,13 +1107,79 @@ extract_hostname(const char *unc) | |||
920 | return dst; | 1107 | return dst; |
921 | } | 1108 | } |
922 | 1109 | ||
1110 | static int get_option_ul(substring_t args[], unsigned long *option) | ||
1111 | { | ||
1112 | int rc; | ||
1113 | char *string; | ||
1114 | |||
1115 | string = match_strdup(args); | ||
1116 | if (string == NULL) | ||
1117 | return -ENOMEM; | ||
1118 | rc = kstrtoul(string, 10, option); | ||
1119 | kfree(string); | ||
1120 | |||
1121 | return rc; | ||
1122 | } | ||
1123 | |||
1124 | |||
1125 | static int cifs_parse_security_flavors(char *value, | ||
1126 | struct smb_vol *vol) | ||
1127 | { | ||
1128 | |||
1129 | substring_t args[MAX_OPT_ARGS]; | ||
1130 | |||
1131 | switch (match_token(value, cifs_secflavor_tokens, args)) { | ||
1132 | case Opt_sec_krb5: | ||
1133 | vol->secFlg |= CIFSSEC_MAY_KRB5; | ||
1134 | break; | ||
1135 | case Opt_sec_krb5i: | ||
1136 | vol->secFlg |= CIFSSEC_MAY_KRB5 | CIFSSEC_MUST_SIGN; | ||
1137 | break; | ||
1138 | case Opt_sec_krb5p: | ||
1139 | /* vol->secFlg |= CIFSSEC_MUST_SEAL | CIFSSEC_MAY_KRB5; */ | ||
1140 | cERROR(1, "Krb5 cifs privacy not supported"); | ||
1141 | break; | ||
1142 | case Opt_sec_ntlmssp: | ||
1143 | vol->secFlg |= CIFSSEC_MAY_NTLMSSP; | ||
1144 | break; | ||
1145 | case Opt_sec_ntlmsspi: | ||
1146 | vol->secFlg |= CIFSSEC_MAY_NTLMSSP | CIFSSEC_MUST_SIGN; | ||
1147 | break; | ||
1148 | case Opt_ntlm: | ||
1149 | /* ntlm is default so can be turned off too */ | ||
1150 | vol->secFlg |= CIFSSEC_MAY_NTLM; | ||
1151 | break; | ||
1152 | case Opt_sec_ntlmi: | ||
1153 | vol->secFlg |= CIFSSEC_MAY_NTLM | CIFSSEC_MUST_SIGN; | ||
1154 | break; | ||
1155 | case Opt_sec_nontlm: | ||
1156 | vol->secFlg |= CIFSSEC_MAY_NTLMV2; | ||
1157 | break; | ||
1158 | case Opt_sec_ntlmv2i: | ||
1159 | vol->secFlg |= CIFSSEC_MAY_NTLMV2 | CIFSSEC_MUST_SIGN; | ||
1160 | break; | ||
1161 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | ||
1162 | case Opt_sec_lanman: | ||
1163 | vol->secFlg |= CIFSSEC_MAY_LANMAN; | ||
1164 | break; | ||
1165 | #endif | ||
1166 | case Opt_sec_none: | ||
1167 | vol->nullauth = 1; | ||
1168 | break; | ||
1169 | default: | ||
1170 | cERROR(1, "bad security option: %s", value); | ||
1171 | return 1; | ||
1172 | } | ||
1173 | |||
1174 | return 0; | ||
1175 | } | ||
1176 | |||
923 | static int | 1177 | static int |
924 | cifs_parse_mount_options(const char *mountdata, const char *devname, | 1178 | cifs_parse_mount_options(const char *mountdata, const char *devname, |
925 | struct smb_vol *vol) | 1179 | struct smb_vol *vol) |
926 | { | 1180 | { |
927 | char *value, *data, *end; | 1181 | char *data, *end; |
928 | char *mountdata_copy = NULL, *options; | 1182 | char *mountdata_copy = NULL, *options; |
929 | int err; | ||
930 | unsigned int temp_len, i, j; | 1183 | unsigned int temp_len, i, j; |
931 | char separator[2]; | 1184 | char separator[2]; |
932 | short int override_uid = -1; | 1185 | short int override_uid = -1; |
@@ -934,9 +1187,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
934 | bool uid_specified = false; | 1187 | bool uid_specified = false; |
935 | bool gid_specified = false; | 1188 | bool gid_specified = false; |
936 | char *nodename = utsname()->nodename; | 1189 | char *nodename = utsname()->nodename; |
1190 | char *string = NULL; | ||
1191 | char *tmp_end, *value; | ||
1192 | char delim; | ||
937 | 1193 | ||
938 | separator[0] = ','; | 1194 | separator[0] = ','; |
939 | separator[1] = 0; | 1195 | separator[1] = 0; |
1196 | delim = separator[0]; | ||
940 | 1197 | ||
941 | /* | 1198 | /* |
942 | * does not have to be perfect mapping since field is | 1199 | * does not have to be perfect mapping since field is |
@@ -975,6 +1232,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
975 | 1232 | ||
976 | options = mountdata_copy; | 1233 | options = mountdata_copy; |
977 | end = options + strlen(options); | 1234 | end = options + strlen(options); |
1235 | |||
978 | if (strncmp(options, "sep=", 4) == 0) { | 1236 | if (strncmp(options, "sep=", 4) == 0) { |
979 | if (options[4] != 0) { | 1237 | if (options[4] != 0) { |
980 | separator[0] = options[4]; | 1238 | separator[0] = options[4]; |
@@ -987,609 +1245,638 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
987 | vol->backupgid_specified = false; /* no backup intent for a group */ | 1245 | vol->backupgid_specified = false; /* no backup intent for a group */ |
988 | 1246 | ||
989 | while ((data = strsep(&options, separator)) != NULL) { | 1247 | while ((data = strsep(&options, separator)) != NULL) { |
1248 | substring_t args[MAX_OPT_ARGS]; | ||
1249 | unsigned long option; | ||
1250 | int token; | ||
1251 | |||
990 | if (!*data) | 1252 | if (!*data) |
991 | continue; | 1253 | continue; |
992 | if ((value = strchr(data, '=')) != NULL) | ||
993 | *value++ = '\0'; | ||
994 | 1254 | ||
995 | /* Have to parse this before we parse for "user" */ | 1255 | token = match_token(data, cifs_mount_option_tokens, args); |
996 | if (strnicmp(data, "user_xattr", 10) == 0) { | 1256 | |
1257 | switch (token) { | ||
1258 | |||
1259 | /* Ingnore the following */ | ||
1260 | case Opt_ignore: | ||
1261 | break; | ||
1262 | |||
1263 | /* Boolean values */ | ||
1264 | case Opt_user_xattr: | ||
997 | vol->no_xattr = 0; | 1265 | vol->no_xattr = 0; |
998 | } else if (strnicmp(data, "nouser_xattr", 12) == 0) { | 1266 | break; |
1267 | case Opt_nouser_xattr: | ||
999 | vol->no_xattr = 1; | 1268 | vol->no_xattr = 1; |
1000 | } else if (strnicmp(data, "user", 4) == 0) { | 1269 | break; |
1001 | if (!value) { | 1270 | case Opt_forceuid: |
1002 | printk(KERN_WARNING | ||
1003 | "CIFS: invalid or missing username\n"); | ||
1004 | goto cifs_parse_mount_err; | ||
1005 | } else if (!*value) { | ||
1006 | /* null user, ie anonymous, authentication */ | ||
1007 | vol->nullauth = 1; | ||
1008 | } | ||
1009 | if (strnlen(value, MAX_USERNAME_SIZE) < | ||
1010 | MAX_USERNAME_SIZE) { | ||
1011 | vol->username = kstrdup(value, GFP_KERNEL); | ||
1012 | if (!vol->username) { | ||
1013 | printk(KERN_WARNING "CIFS: no memory " | ||
1014 | "for username\n"); | ||
1015 | goto cifs_parse_mount_err; | ||
1016 | } | ||
1017 | } else { | ||
1018 | printk(KERN_WARNING "CIFS: username too long\n"); | ||
1019 | goto cifs_parse_mount_err; | ||
1020 | } | ||
1021 | } else if (strnicmp(data, "pass", 4) == 0) { | ||
1022 | if (!value) { | ||
1023 | vol->password = NULL; | ||
1024 | continue; | ||
1025 | } else if (value[0] == 0) { | ||
1026 | /* check if string begins with double comma | ||
1027 | since that would mean the password really | ||
1028 | does start with a comma, and would not | ||
1029 | indicate an empty string */ | ||
1030 | if (value[1] != separator[0]) { | ||
1031 | vol->password = NULL; | ||
1032 | continue; | ||
1033 | } | ||
1034 | } | ||
1035 | temp_len = strlen(value); | ||
1036 | /* removed password length check, NTLM passwords | ||
1037 | can be arbitrarily long */ | ||
1038 | |||
1039 | /* if comma in password, the string will be | ||
1040 | prematurely null terminated. Commas in password are | ||
1041 | specified across the cifs mount interface by a double | ||
1042 | comma ie ,, and a comma used as in other cases ie ',' | ||
1043 | as a parameter delimiter/separator is single and due | ||
1044 | to the strsep above is temporarily zeroed. */ | ||
1045 | |||
1046 | /* NB: password legally can have multiple commas and | ||
1047 | the only illegal character in a password is null */ | ||
1048 | |||
1049 | if ((value[temp_len] == 0) && | ||
1050 | (value + temp_len < end) && | ||
1051 | (value[temp_len+1] == separator[0])) { | ||
1052 | /* reinsert comma */ | ||
1053 | value[temp_len] = separator[0]; | ||
1054 | temp_len += 2; /* move after second comma */ | ||
1055 | while (value[temp_len] != 0) { | ||
1056 | if (value[temp_len] == separator[0]) { | ||
1057 | if (value[temp_len+1] == | ||
1058 | separator[0]) { | ||
1059 | /* skip second comma */ | ||
1060 | temp_len++; | ||
1061 | } else { | ||
1062 | /* single comma indicating start | ||
1063 | of next parm */ | ||
1064 | break; | ||
1065 | } | ||
1066 | } | ||
1067 | temp_len++; | ||
1068 | } | ||
1069 | if (value[temp_len] == 0) { | ||
1070 | options = NULL; | ||
1071 | } else { | ||
1072 | value[temp_len] = 0; | ||
1073 | /* point option to start of next parm */ | ||
1074 | options = value + temp_len + 1; | ||
1075 | } | ||
1076 | /* go from value to value + temp_len condensing | ||
1077 | double commas to singles. Note that this ends up | ||
1078 | allocating a few bytes too many, which is ok */ | ||
1079 | vol->password = kzalloc(temp_len, GFP_KERNEL); | ||
1080 | if (vol->password == NULL) { | ||
1081 | printk(KERN_WARNING "CIFS: no memory " | ||
1082 | "for password\n"); | ||
1083 | goto cifs_parse_mount_err; | ||
1084 | } | ||
1085 | for (i = 0, j = 0; i < temp_len; i++, j++) { | ||
1086 | vol->password[j] = value[i]; | ||
1087 | if (value[i] == separator[0] | ||
1088 | && value[i+1] == separator[0]) { | ||
1089 | /* skip second comma */ | ||
1090 | i++; | ||
1091 | } | ||
1092 | } | ||
1093 | vol->password[j] = 0; | ||
1094 | } else { | ||
1095 | vol->password = kzalloc(temp_len+1, GFP_KERNEL); | ||
1096 | if (vol->password == NULL) { | ||
1097 | printk(KERN_WARNING "CIFS: no memory " | ||
1098 | "for password\n"); | ||
1099 | goto cifs_parse_mount_err; | ||
1100 | } | ||
1101 | strcpy(vol->password, value); | ||
1102 | } | ||
1103 | } else if (!strnicmp(data, "ip", 2) || | ||
1104 | !strnicmp(data, "addr", 4)) { | ||
1105 | if (!value || !*value) { | ||
1106 | vol->UNCip = NULL; | ||
1107 | } else if (strnlen(value, INET6_ADDRSTRLEN) < | ||
1108 | INET6_ADDRSTRLEN) { | ||
1109 | vol->UNCip = kstrdup(value, GFP_KERNEL); | ||
1110 | if (!vol->UNCip) { | ||
1111 | printk(KERN_WARNING "CIFS: no memory " | ||
1112 | "for UNC IP\n"); | ||
1113 | goto cifs_parse_mount_err; | ||
1114 | } | ||
1115 | } else { | ||
1116 | printk(KERN_WARNING "CIFS: ip address " | ||
1117 | "too long\n"); | ||
1118 | goto cifs_parse_mount_err; | ||
1119 | } | ||
1120 | } else if (strnicmp(data, "sec", 3) == 0) { | ||
1121 | if (!value || !*value) { | ||
1122 | cERROR(1, "no security value specified"); | ||
1123 | continue; | ||
1124 | } else if (strnicmp(value, "krb5i", 5) == 0) { | ||
1125 | vol->secFlg |= CIFSSEC_MAY_KRB5 | | ||
1126 | CIFSSEC_MUST_SIGN; | ||
1127 | } else if (strnicmp(value, "krb5p", 5) == 0) { | ||
1128 | /* vol->secFlg |= CIFSSEC_MUST_SEAL | | ||
1129 | CIFSSEC_MAY_KRB5; */ | ||
1130 | cERROR(1, "Krb5 cifs privacy not supported"); | ||
1131 | goto cifs_parse_mount_err; | ||
1132 | } else if (strnicmp(value, "krb5", 4) == 0) { | ||
1133 | vol->secFlg |= CIFSSEC_MAY_KRB5; | ||
1134 | } else if (strnicmp(value, "ntlmsspi", 8) == 0) { | ||
1135 | vol->secFlg |= CIFSSEC_MAY_NTLMSSP | | ||
1136 | CIFSSEC_MUST_SIGN; | ||
1137 | } else if (strnicmp(value, "ntlmssp", 7) == 0) { | ||
1138 | vol->secFlg |= CIFSSEC_MAY_NTLMSSP; | ||
1139 | } else if (strnicmp(value, "ntlmv2i", 7) == 0) { | ||
1140 | vol->secFlg |= CIFSSEC_MAY_NTLMV2 | | ||
1141 | CIFSSEC_MUST_SIGN; | ||
1142 | } else if (strnicmp(value, "ntlmv2", 6) == 0) { | ||
1143 | vol->secFlg |= CIFSSEC_MAY_NTLMV2; | ||
1144 | } else if (strnicmp(value, "ntlmi", 5) == 0) { | ||
1145 | vol->secFlg |= CIFSSEC_MAY_NTLM | | ||
1146 | CIFSSEC_MUST_SIGN; | ||
1147 | } else if (strnicmp(value, "ntlm", 4) == 0) { | ||
1148 | /* ntlm is default so can be turned off too */ | ||
1149 | vol->secFlg |= CIFSSEC_MAY_NTLM; | ||
1150 | } else if (strnicmp(value, "nontlm", 6) == 0) { | ||
1151 | /* BB is there a better way to do this? */ | ||
1152 | vol->secFlg |= CIFSSEC_MAY_NTLMV2; | ||
1153 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | ||
1154 | } else if (strnicmp(value, "lanman", 6) == 0) { | ||
1155 | vol->secFlg |= CIFSSEC_MAY_LANMAN; | ||
1156 | #endif | ||
1157 | } else if (strnicmp(value, "none", 4) == 0) { | ||
1158 | vol->nullauth = 1; | ||
1159 | } else { | ||
1160 | cERROR(1, "bad security option: %s", value); | ||
1161 | goto cifs_parse_mount_err; | ||
1162 | } | ||
1163 | } else if (strnicmp(data, "vers", 3) == 0) { | ||
1164 | if (!value || !*value) { | ||
1165 | cERROR(1, "no protocol version specified" | ||
1166 | " after vers= mount option"); | ||
1167 | } else if ((strnicmp(value, "cifs", 4) == 0) || | ||
1168 | (strnicmp(value, "1", 1) == 0)) { | ||
1169 | /* this is the default */ | ||
1170 | continue; | ||
1171 | } | ||
1172 | } else if ((strnicmp(data, "unc", 3) == 0) | ||
1173 | || (strnicmp(data, "target", 6) == 0) | ||
1174 | || (strnicmp(data, "path", 4) == 0)) { | ||
1175 | if (!value || !*value) { | ||
1176 | printk(KERN_WARNING "CIFS: invalid path to " | ||
1177 | "network resource\n"); | ||
1178 | goto cifs_parse_mount_err; | ||
1179 | } | ||
1180 | if ((temp_len = strnlen(value, 300)) < 300) { | ||
1181 | vol->UNC = kmalloc(temp_len+1, GFP_KERNEL); | ||
1182 | if (vol->UNC == NULL) | ||
1183 | goto cifs_parse_mount_err; | ||
1184 | strcpy(vol->UNC, value); | ||
1185 | if (strncmp(vol->UNC, "//", 2) == 0) { | ||
1186 | vol->UNC[0] = '\\'; | ||
1187 | vol->UNC[1] = '\\'; | ||
1188 | } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { | ||
1189 | printk(KERN_WARNING | ||
1190 | "CIFS: UNC Path does not begin " | ||
1191 | "with // or \\\\ \n"); | ||
1192 | goto cifs_parse_mount_err; | ||
1193 | } | ||
1194 | } else { | ||
1195 | printk(KERN_WARNING "CIFS: UNC name too long\n"); | ||
1196 | goto cifs_parse_mount_err; | ||
1197 | } | ||
1198 | } else if ((strnicmp(data, "domain", 3) == 0) | ||
1199 | || (strnicmp(data, "workgroup", 5) == 0)) { | ||
1200 | if (!value || !*value) { | ||
1201 | printk(KERN_WARNING "CIFS: invalid domain name\n"); | ||
1202 | goto cifs_parse_mount_err; | ||
1203 | } | ||
1204 | /* BB are there cases in which a comma can be valid in | ||
1205 | a domain name and need special handling? */ | ||
1206 | if (strnlen(value, 256) < 256) { | ||
1207 | vol->domainname = kstrdup(value, GFP_KERNEL); | ||
1208 | if (!vol->domainname) { | ||
1209 | printk(KERN_WARNING "CIFS: no memory " | ||
1210 | "for domainname\n"); | ||
1211 | goto cifs_parse_mount_err; | ||
1212 | } | ||
1213 | cFYI(1, "Domain name set"); | ||
1214 | } else { | ||
1215 | printk(KERN_WARNING "CIFS: domain name too " | ||
1216 | "long\n"); | ||
1217 | goto cifs_parse_mount_err; | ||
1218 | } | ||
1219 | } else if (strnicmp(data, "srcaddr", 7) == 0) { | ||
1220 | vol->srcaddr.ss_family = AF_UNSPEC; | ||
1221 | |||
1222 | if (!value || !*value) { | ||
1223 | printk(KERN_WARNING "CIFS: srcaddr value" | ||
1224 | " not specified.\n"); | ||
1225 | goto cifs_parse_mount_err; | ||
1226 | } | ||
1227 | i = cifs_convert_address((struct sockaddr *)&vol->srcaddr, | ||
1228 | value, strlen(value)); | ||
1229 | if (i == 0) { | ||
1230 | printk(KERN_WARNING "CIFS: Could not parse" | ||
1231 | " srcaddr: %s\n", | ||
1232 | value); | ||
1233 | goto cifs_parse_mount_err; | ||
1234 | } | ||
1235 | } else if (strnicmp(data, "prefixpath", 10) == 0) { | ||
1236 | if (!value || !*value) { | ||
1237 | printk(KERN_WARNING | ||
1238 | "CIFS: invalid path prefix\n"); | ||
1239 | goto cifs_parse_mount_err; | ||
1240 | } | ||
1241 | if ((temp_len = strnlen(value, 1024)) < 1024) { | ||
1242 | if (value[0] != '/') | ||
1243 | temp_len++; /* missing leading slash */ | ||
1244 | vol->prepath = kmalloc(temp_len+1, GFP_KERNEL); | ||
1245 | if (vol->prepath == NULL) | ||
1246 | goto cifs_parse_mount_err; | ||
1247 | if (value[0] != '/') { | ||
1248 | vol->prepath[0] = '/'; | ||
1249 | strcpy(vol->prepath+1, value); | ||
1250 | } else | ||
1251 | strcpy(vol->prepath, value); | ||
1252 | cFYI(1, "prefix path %s", vol->prepath); | ||
1253 | } else { | ||
1254 | printk(KERN_WARNING "CIFS: prefix too long\n"); | ||
1255 | goto cifs_parse_mount_err; | ||
1256 | } | ||
1257 | } else if (strnicmp(data, "iocharset", 9) == 0) { | ||
1258 | if (!value || !*value) { | ||
1259 | printk(KERN_WARNING "CIFS: invalid iocharset " | ||
1260 | "specified\n"); | ||
1261 | goto cifs_parse_mount_err; | ||
1262 | } | ||
1263 | if (strnlen(value, 65) < 65) { | ||
1264 | if (strnicmp(value, "default", 7)) { | ||
1265 | vol->iocharset = kstrdup(value, | ||
1266 | GFP_KERNEL); | ||
1267 | |||
1268 | if (!vol->iocharset) { | ||
1269 | printk(KERN_WARNING "CIFS: no " | ||
1270 | "memory for" | ||
1271 | "charset\n"); | ||
1272 | goto cifs_parse_mount_err; | ||
1273 | } | ||
1274 | } | ||
1275 | /* if iocharset not set then load_nls_default | ||
1276 | is used by caller */ | ||
1277 | cFYI(1, "iocharset set to %s", value); | ||
1278 | } else { | ||
1279 | printk(KERN_WARNING "CIFS: iocharset name " | ||
1280 | "too long.\n"); | ||
1281 | goto cifs_parse_mount_err; | ||
1282 | } | ||
1283 | } else if (!strnicmp(data, "uid", 3) && value && *value) { | ||
1284 | vol->linux_uid = simple_strtoul(value, &value, 0); | ||
1285 | uid_specified = true; | ||
1286 | } else if (!strnicmp(data, "cruid", 5) && value && *value) { | ||
1287 | vol->cred_uid = simple_strtoul(value, &value, 0); | ||
1288 | } else if (!strnicmp(data, "forceuid", 8)) { | ||
1289 | override_uid = 1; | 1271 | override_uid = 1; |
1290 | } else if (!strnicmp(data, "noforceuid", 10)) { | 1272 | break; |
1273 | case Opt_noforceuid: | ||
1291 | override_uid = 0; | 1274 | override_uid = 0; |
1292 | } else if (!strnicmp(data, "gid", 3) && value && *value) { | 1275 | break; |
1293 | vol->linux_gid = simple_strtoul(value, &value, 0); | 1276 | case Opt_noblocksend: |
1294 | gid_specified = true; | ||
1295 | } else if (!strnicmp(data, "forcegid", 8)) { | ||
1296 | override_gid = 1; | ||
1297 | } else if (!strnicmp(data, "noforcegid", 10)) { | ||
1298 | override_gid = 0; | ||
1299 | } else if (strnicmp(data, "file_mode", 4) == 0) { | ||
1300 | if (value && *value) { | ||
1301 | vol->file_mode = | ||
1302 | simple_strtoul(value, &value, 0); | ||
1303 | } | ||
1304 | } else if (strnicmp(data, "dir_mode", 4) == 0) { | ||
1305 | if (value && *value) { | ||
1306 | vol->dir_mode = | ||
1307 | simple_strtoul(value, &value, 0); | ||
1308 | } | ||
1309 | } else if (strnicmp(data, "dirmode", 4) == 0) { | ||
1310 | if (value && *value) { | ||
1311 | vol->dir_mode = | ||
1312 | simple_strtoul(value, &value, 0); | ||
1313 | } | ||
1314 | } else if (strnicmp(data, "port", 4) == 0) { | ||
1315 | if (value && *value) { | ||
1316 | vol->port = | ||
1317 | simple_strtoul(value, &value, 0); | ||
1318 | } | ||
1319 | } else if (strnicmp(data, "rsize", 5) == 0) { | ||
1320 | if (value && *value) { | ||
1321 | vol->rsize = | ||
1322 | simple_strtoul(value, &value, 0); | ||
1323 | } | ||
1324 | } else if (strnicmp(data, "wsize", 5) == 0) { | ||
1325 | if (value && *value) { | ||
1326 | vol->wsize = | ||
1327 | simple_strtoul(value, &value, 0); | ||
1328 | } | ||
1329 | } else if (strnicmp(data, "sockopt", 5) == 0) { | ||
1330 | if (!value || !*value) { | ||
1331 | cERROR(1, "no socket option specified"); | ||
1332 | continue; | ||
1333 | } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) { | ||
1334 | vol->sockopt_tcp_nodelay = 1; | ||
1335 | } | ||
1336 | } else if (strnicmp(data, "netbiosname", 4) == 0) { | ||
1337 | if (!value || !*value || (*value == ' ')) { | ||
1338 | cFYI(1, "invalid (empty) netbiosname"); | ||
1339 | } else { | ||
1340 | memset(vol->source_rfc1001_name, 0x20, | ||
1341 | RFC1001_NAME_LEN); | ||
1342 | /* | ||
1343 | * FIXME: are there cases in which a comma can | ||
1344 | * be valid in workstation netbios name (and | ||
1345 | * need special handling)? | ||
1346 | */ | ||
1347 | for (i = 0; i < RFC1001_NAME_LEN; i++) { | ||
1348 | /* don't ucase netbiosname for user */ | ||
1349 | if (value[i] == 0) | ||
1350 | break; | ||
1351 | vol->source_rfc1001_name[i] = value[i]; | ||
1352 | } | ||
1353 | /* The string has 16th byte zero still from | ||
1354 | set at top of the function */ | ||
1355 | if (i == RFC1001_NAME_LEN && value[i] != 0) | ||
1356 | printk(KERN_WARNING "CIFS: netbiosname" | ||
1357 | " longer than 15 truncated.\n"); | ||
1358 | } | ||
1359 | } else if (strnicmp(data, "servern", 7) == 0) { | ||
1360 | /* servernetbiosname specified override *SMBSERVER */ | ||
1361 | if (!value || !*value || (*value == ' ')) { | ||
1362 | cFYI(1, "empty server netbiosname specified"); | ||
1363 | } else { | ||
1364 | /* last byte, type, is 0x20 for servr type */ | ||
1365 | memset(vol->target_rfc1001_name, 0x20, | ||
1366 | RFC1001_NAME_LEN_WITH_NULL); | ||
1367 | |||
1368 | for (i = 0; i < 15; i++) { | ||
1369 | /* BB are there cases in which a comma can be | ||
1370 | valid in this workstation netbios name | ||
1371 | (and need special handling)? */ | ||
1372 | |||
1373 | /* user or mount helper must uppercase | ||
1374 | the netbiosname */ | ||
1375 | if (value[i] == 0) | ||
1376 | break; | ||
1377 | else | ||
1378 | vol->target_rfc1001_name[i] = | ||
1379 | value[i]; | ||
1380 | } | ||
1381 | /* The string has 16th byte zero still from | ||
1382 | set at top of the function */ | ||
1383 | if (i == RFC1001_NAME_LEN && value[i] != 0) | ||
1384 | printk(KERN_WARNING "CIFS: server net" | ||
1385 | "biosname longer than 15 truncated.\n"); | ||
1386 | } | ||
1387 | } else if (strnicmp(data, "actimeo", 7) == 0) { | ||
1388 | if (value && *value) { | ||
1389 | vol->actimeo = HZ * simple_strtoul(value, | ||
1390 | &value, 0); | ||
1391 | if (vol->actimeo > CIFS_MAX_ACTIMEO) { | ||
1392 | cERROR(1, "CIFS: attribute cache" | ||
1393 | "timeout too large"); | ||
1394 | goto cifs_parse_mount_err; | ||
1395 | } | ||
1396 | } | ||
1397 | } else if (strnicmp(data, "credentials", 4) == 0) { | ||
1398 | /* ignore */ | ||
1399 | } else if (strnicmp(data, "version", 3) == 0) { | ||
1400 | /* ignore */ | ||
1401 | } else if (strnicmp(data, "guest", 5) == 0) { | ||
1402 | /* ignore */ | ||
1403 | } else if (strnicmp(data, "rw", 2) == 0 && strlen(data) == 2) { | ||
1404 | /* ignore */ | ||
1405 | } else if (strnicmp(data, "ro", 2) == 0) { | ||
1406 | /* ignore */ | ||
1407 | } else if (strnicmp(data, "noblocksend", 11) == 0) { | ||
1408 | vol->noblocksnd = 1; | 1277 | vol->noblocksnd = 1; |
1409 | } else if (strnicmp(data, "noautotune", 10) == 0) { | 1278 | break; |
1279 | case Opt_noautotune: | ||
1410 | vol->noautotune = 1; | 1280 | vol->noautotune = 1; |
1411 | } else if ((strnicmp(data, "suid", 4) == 0) || | 1281 | break; |
1412 | (strnicmp(data, "nosuid", 6) == 0) || | 1282 | case Opt_hard: |
1413 | (strnicmp(data, "exec", 4) == 0) || | ||
1414 | (strnicmp(data, "noexec", 6) == 0) || | ||
1415 | (strnicmp(data, "nodev", 5) == 0) || | ||
1416 | (strnicmp(data, "noauto", 6) == 0) || | ||
1417 | (strnicmp(data, "dev", 3) == 0)) { | ||
1418 | /* The mount tool or mount.cifs helper (if present) | ||
1419 | uses these opts to set flags, and the flags are read | ||
1420 | by the kernel vfs layer before we get here (ie | ||
1421 | before read super) so there is no point trying to | ||
1422 | parse these options again and set anything and it | ||
1423 | is ok to just ignore them */ | ||
1424 | continue; | ||
1425 | } else if (strnicmp(data, "hard", 4) == 0) { | ||
1426 | vol->retry = 1; | 1283 | vol->retry = 1; |
1427 | } else if (strnicmp(data, "soft", 4) == 0) { | 1284 | break; |
1285 | case Opt_soft: | ||
1428 | vol->retry = 0; | 1286 | vol->retry = 0; |
1429 | } else if (strnicmp(data, "perm", 4) == 0) { | 1287 | break; |
1288 | case Opt_perm: | ||
1430 | vol->noperm = 0; | 1289 | vol->noperm = 0; |
1431 | } else if (strnicmp(data, "noperm", 6) == 0) { | 1290 | break; |
1291 | case Opt_noperm: | ||
1432 | vol->noperm = 1; | 1292 | vol->noperm = 1; |
1433 | } else if (strnicmp(data, "mapchars", 8) == 0) { | 1293 | break; |
1294 | case Opt_mapchars: | ||
1434 | vol->remap = 1; | 1295 | vol->remap = 1; |
1435 | } else if (strnicmp(data, "nomapchars", 10) == 0) { | 1296 | break; |
1297 | case Opt_nomapchars: | ||
1436 | vol->remap = 0; | 1298 | vol->remap = 0; |
1437 | } else if (strnicmp(data, "sfu", 3) == 0) { | 1299 | break; |
1300 | case Opt_sfu: | ||
1438 | vol->sfu_emul = 1; | 1301 | vol->sfu_emul = 1; |
1439 | } else if (strnicmp(data, "nosfu", 5) == 0) { | 1302 | break; |
1303 | case Opt_nosfu: | ||
1440 | vol->sfu_emul = 0; | 1304 | vol->sfu_emul = 0; |
1441 | } else if (strnicmp(data, "nodfs", 5) == 0) { | 1305 | break; |
1306 | case Opt_nodfs: | ||
1442 | vol->nodfs = 1; | 1307 | vol->nodfs = 1; |
1443 | } else if (strnicmp(data, "posixpaths", 10) == 0) { | 1308 | break; |
1309 | case Opt_posixpaths: | ||
1444 | vol->posix_paths = 1; | 1310 | vol->posix_paths = 1; |
1445 | } else if (strnicmp(data, "noposixpaths", 12) == 0) { | 1311 | break; |
1312 | case Opt_noposixpaths: | ||
1446 | vol->posix_paths = 0; | 1313 | vol->posix_paths = 0; |
1447 | } else if (strnicmp(data, "nounix", 6) == 0) { | 1314 | break; |
1448 | vol->no_linux_ext = 1; | 1315 | case Opt_nounix: |
1449 | } else if (strnicmp(data, "nolinux", 7) == 0) { | ||
1450 | vol->no_linux_ext = 1; | 1316 | vol->no_linux_ext = 1; |
1451 | } else if ((strnicmp(data, "nocase", 6) == 0) || | 1317 | break; |
1452 | (strnicmp(data, "ignorecase", 10) == 0)) { | 1318 | case Opt_nocase: |
1453 | vol->nocase = 1; | 1319 | vol->nocase = 1; |
1454 | } else if (strnicmp(data, "mand", 4) == 0) { | 1320 | break; |
1455 | /* ignore */ | 1321 | case Opt_brl: |
1456 | } else if (strnicmp(data, "nomand", 6) == 0) { | ||
1457 | /* ignore */ | ||
1458 | } else if (strnicmp(data, "_netdev", 7) == 0) { | ||
1459 | /* ignore */ | ||
1460 | } else if (strnicmp(data, "brl", 3) == 0) { | ||
1461 | vol->nobrl = 0; | 1322 | vol->nobrl = 0; |
1462 | } else if ((strnicmp(data, "nobrl", 5) == 0) || | 1323 | break; |
1463 | (strnicmp(data, "nolock", 6) == 0)) { | 1324 | case Opt_nobrl: |
1464 | vol->nobrl = 1; | 1325 | vol->nobrl = 1; |
1465 | /* turn off mandatory locking in mode | 1326 | /* turn off mandatory locking in mode |
1466 | if remote locking is turned off since the | 1327 | * if remote locking is turned off since the |
1467 | local vfs will do advisory */ | 1328 | * local vfs will do advisory */ |
1468 | if (vol->file_mode == | 1329 | if (vol->file_mode == |
1469 | (S_IALLUGO & ~(S_ISUID | S_IXGRP))) | 1330 | (S_IALLUGO & ~(S_ISUID | S_IXGRP))) |
1470 | vol->file_mode = S_IALLUGO; | 1331 | vol->file_mode = S_IALLUGO; |
1471 | } else if (strnicmp(data, "forcemandatorylock", 9) == 0) { | 1332 | break; |
1472 | /* will take the shorter form "forcemand" as well */ | 1333 | case Opt_forcemandatorylock: |
1473 | /* This mount option will force use of mandatory | ||
1474 | (DOS/Windows style) byte range locks, instead of | ||
1475 | using posix advisory byte range locks, even if the | ||
1476 | Unix extensions are available and posix locks would | ||
1477 | be supported otherwise. If Unix extensions are not | ||
1478 | negotiated this has no effect since mandatory locks | ||
1479 | would be used (mandatory locks is all that those | ||
1480 | those servers support) */ | ||
1481 | vol->mand_lock = 1; | 1334 | vol->mand_lock = 1; |
1482 | } else if (strnicmp(data, "setuids", 7) == 0) { | 1335 | break; |
1336 | case Opt_setuids: | ||
1483 | vol->setuids = 1; | 1337 | vol->setuids = 1; |
1484 | } else if (strnicmp(data, "nosetuids", 9) == 0) { | 1338 | break; |
1339 | case Opt_nosetuids: | ||
1485 | vol->setuids = 0; | 1340 | vol->setuids = 0; |
1486 | } else if (strnicmp(data, "dynperm", 7) == 0) { | 1341 | break; |
1342 | case Opt_dynperm: | ||
1487 | vol->dynperm = true; | 1343 | vol->dynperm = true; |
1488 | } else if (strnicmp(data, "nodynperm", 9) == 0) { | 1344 | break; |
1345 | case Opt_nodynperm: | ||
1489 | vol->dynperm = false; | 1346 | vol->dynperm = false; |
1490 | } else if (strnicmp(data, "nohard", 6) == 0) { | 1347 | break; |
1348 | case Opt_nohard: | ||
1491 | vol->retry = 0; | 1349 | vol->retry = 0; |
1492 | } else if (strnicmp(data, "nosoft", 6) == 0) { | 1350 | break; |
1351 | case Opt_nosoft: | ||
1493 | vol->retry = 1; | 1352 | vol->retry = 1; |
1494 | } else if (strnicmp(data, "nointr", 6) == 0) { | 1353 | break; |
1354 | case Opt_nointr: | ||
1495 | vol->intr = 0; | 1355 | vol->intr = 0; |
1496 | } else if (strnicmp(data, "intr", 4) == 0) { | 1356 | break; |
1357 | case Opt_intr: | ||
1497 | vol->intr = 1; | 1358 | vol->intr = 1; |
1498 | } else if (strnicmp(data, "nostrictsync", 12) == 0) { | 1359 | break; |
1360 | case Opt_nostrictsync: | ||
1499 | vol->nostrictsync = 1; | 1361 | vol->nostrictsync = 1; |
1500 | } else if (strnicmp(data, "strictsync", 10) == 0) { | 1362 | break; |
1363 | case Opt_strictsync: | ||
1501 | vol->nostrictsync = 0; | 1364 | vol->nostrictsync = 0; |
1502 | } else if (strnicmp(data, "serverino", 7) == 0) { | 1365 | break; |
1366 | case Opt_serverino: | ||
1503 | vol->server_ino = 1; | 1367 | vol->server_ino = 1; |
1504 | } else if (strnicmp(data, "noserverino", 9) == 0) { | 1368 | break; |
1369 | case Opt_noserverino: | ||
1505 | vol->server_ino = 0; | 1370 | vol->server_ino = 0; |
1506 | } else if (strnicmp(data, "rwpidforward", 12) == 0) { | 1371 | break; |
1372 | case Opt_rwpidforward: | ||
1507 | vol->rwpidforward = 1; | 1373 | vol->rwpidforward = 1; |
1508 | } else if (strnicmp(data, "cifsacl", 7) == 0) { | 1374 | break; |
1375 | case Opt_cifsacl: | ||
1509 | vol->cifs_acl = 1; | 1376 | vol->cifs_acl = 1; |
1510 | } else if (strnicmp(data, "nocifsacl", 9) == 0) { | 1377 | break; |
1378 | case Opt_nocifsacl: | ||
1511 | vol->cifs_acl = 0; | 1379 | vol->cifs_acl = 0; |
1512 | } else if (strnicmp(data, "acl", 3) == 0) { | 1380 | break; |
1381 | case Opt_acl: | ||
1513 | vol->no_psx_acl = 0; | 1382 | vol->no_psx_acl = 0; |
1514 | } else if (strnicmp(data, "noacl", 5) == 0) { | 1383 | break; |
1384 | case Opt_noacl: | ||
1515 | vol->no_psx_acl = 1; | 1385 | vol->no_psx_acl = 1; |
1516 | } else if (strnicmp(data, "locallease", 6) == 0) { | 1386 | break; |
1387 | case Opt_locallease: | ||
1517 | vol->local_lease = 1; | 1388 | vol->local_lease = 1; |
1518 | } else if (strnicmp(data, "sign", 4) == 0) { | 1389 | break; |
1390 | case Opt_sign: | ||
1519 | vol->secFlg |= CIFSSEC_MUST_SIGN; | 1391 | vol->secFlg |= CIFSSEC_MUST_SIGN; |
1520 | } else if (strnicmp(data, "seal", 4) == 0) { | 1392 | break; |
1393 | case Opt_seal: | ||
1521 | /* we do not do the following in secFlags because seal | 1394 | /* we do not do the following in secFlags because seal |
1522 | is a per tree connection (mount) not a per socket | 1395 | * is a per tree connection (mount) not a per socket |
1523 | or per-smb connection option in the protocol */ | 1396 | * or per-smb connection option in the protocol |
1524 | /* vol->secFlg |= CIFSSEC_MUST_SEAL; */ | 1397 | * vol->secFlg |= CIFSSEC_MUST_SEAL; |
1398 | */ | ||
1525 | vol->seal = 1; | 1399 | vol->seal = 1; |
1526 | } else if (strnicmp(data, "direct", 6) == 0) { | 1400 | break; |
1527 | vol->direct_io = 1; | 1401 | case Opt_direct: |
1528 | } else if (strnicmp(data, "forcedirectio", 13) == 0) { | ||
1529 | vol->direct_io = 1; | 1402 | vol->direct_io = 1; |
1530 | } else if (strnicmp(data, "strictcache", 11) == 0) { | 1403 | break; |
1404 | case Opt_strictcache: | ||
1531 | vol->strict_io = 1; | 1405 | vol->strict_io = 1; |
1532 | } else if (strnicmp(data, "noac", 4) == 0) { | 1406 | break; |
1407 | case Opt_noac: | ||
1533 | printk(KERN_WARNING "CIFS: Mount option noac not " | 1408 | printk(KERN_WARNING "CIFS: Mount option noac not " |
1534 | "supported. Instead set " | 1409 | "supported. Instead set " |
1535 | "/proc/fs/cifs/LookupCacheEnabled to 0\n"); | 1410 | "/proc/fs/cifs/LookupCacheEnabled to 0\n"); |
1536 | } else if (strnicmp(data, "fsc", 3) == 0) { | 1411 | break; |
1412 | case Opt_fsc: | ||
1537 | #ifndef CONFIG_CIFS_FSCACHE | 1413 | #ifndef CONFIG_CIFS_FSCACHE |
1538 | cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE " | 1414 | cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE " |
1539 | "kernel config option set"); | 1415 | "kernel config option set"); |
1540 | goto cifs_parse_mount_err; | 1416 | goto cifs_parse_mount_err; |
1541 | #endif | 1417 | #endif |
1542 | vol->fsc = true; | 1418 | vol->fsc = true; |
1543 | } else if (strnicmp(data, "mfsymlinks", 10) == 0) { | 1419 | break; |
1420 | case Opt_mfsymlinks: | ||
1544 | vol->mfsymlinks = true; | 1421 | vol->mfsymlinks = true; |
1545 | } else if (strnicmp(data, "multiuser", 8) == 0) { | 1422 | break; |
1423 | case Opt_multiuser: | ||
1546 | vol->multiuser = true; | 1424 | vol->multiuser = true; |
1547 | } else if (!strnicmp(data, "backupuid", 9) && value && *value) { | 1425 | break; |
1548 | err = kstrtouint(value, 0, &vol->backupuid); | 1426 | |
1549 | if (err < 0) { | 1427 | /* Numeric Values */ |
1428 | case Opt_backupuid: | ||
1429 | if (get_option_ul(args, &option)) { | ||
1550 | cERROR(1, "%s: Invalid backupuid value", | 1430 | cERROR(1, "%s: Invalid backupuid value", |
1551 | __func__); | 1431 | __func__); |
1552 | goto cifs_parse_mount_err; | 1432 | goto cifs_parse_mount_err; |
1553 | } | 1433 | } |
1434 | vol->backupuid = option; | ||
1554 | vol->backupuid_specified = true; | 1435 | vol->backupuid_specified = true; |
1555 | } else if (!strnicmp(data, "backupgid", 9) && value && *value) { | 1436 | break; |
1556 | err = kstrtouint(value, 0, &vol->backupgid); | 1437 | case Opt_backupgid: |
1557 | if (err < 0) { | 1438 | if (get_option_ul(args, &option)) { |
1558 | cERROR(1, "%s: Invalid backupgid value", | 1439 | cERROR(1, "%s: Invalid backupgid value", |
1559 | __func__); | 1440 | __func__); |
1560 | goto cifs_parse_mount_err; | 1441 | goto cifs_parse_mount_err; |
1561 | } | 1442 | } |
1443 | vol->backupgid = option; | ||
1562 | vol->backupgid_specified = true; | 1444 | vol->backupgid_specified = true; |
1563 | } else | 1445 | break; |
1564 | printk(KERN_WARNING "CIFS: Unknown mount option %s\n", | 1446 | case Opt_uid: |
1565 | data); | 1447 | if (get_option_ul(args, &option)) { |
1566 | } | 1448 | cERROR(1, "%s: Invalid uid value", |
1567 | if (vol->UNC == NULL) { | 1449 | __func__); |
1568 | if (devname == NULL) { | 1450 | goto cifs_parse_mount_err; |
1569 | printk(KERN_WARNING "CIFS: Missing UNC name for mount " | 1451 | } |
1570 | "target\n"); | 1452 | vol->linux_uid = option; |
1571 | goto cifs_parse_mount_err; | 1453 | uid_specified = true; |
1572 | } | 1454 | break; |
1573 | if ((temp_len = strnlen(devname, 300)) < 300) { | 1455 | case Opt_cruid: |
1574 | vol->UNC = kmalloc(temp_len+1, GFP_KERNEL); | 1456 | if (get_option_ul(args, &option)) { |
1575 | if (vol->UNC == NULL) | 1457 | cERROR(1, "%s: Invalid cruid value", |
1458 | __func__); | ||
1459 | goto cifs_parse_mount_err; | ||
1460 | } | ||
1461 | vol->cred_uid = option; | ||
1462 | break; | ||
1463 | case Opt_gid: | ||
1464 | if (get_option_ul(args, &option)) { | ||
1465 | cERROR(1, "%s: Invalid gid value", | ||
1466 | __func__); | ||
1467 | goto cifs_parse_mount_err; | ||
1468 | } | ||
1469 | vol->linux_gid = option; | ||
1470 | gid_specified = true; | ||
1471 | break; | ||
1472 | case Opt_file_mode: | ||
1473 | if (get_option_ul(args, &option)) { | ||
1474 | cERROR(1, "%s: Invalid file_mode value", | ||
1475 | __func__); | ||
1476 | goto cifs_parse_mount_err; | ||
1477 | } | ||
1478 | vol->file_mode = option; | ||
1479 | break; | ||
1480 | case Opt_dirmode: | ||
1481 | if (get_option_ul(args, &option)) { | ||
1482 | cERROR(1, "%s: Invalid dir_mode value", | ||
1483 | __func__); | ||
1484 | goto cifs_parse_mount_err; | ||
1485 | } | ||
1486 | vol->dir_mode = option; | ||
1487 | break; | ||
1488 | case Opt_port: | ||
1489 | if (get_option_ul(args, &option)) { | ||
1490 | cERROR(1, "%s: Invalid port value", | ||
1491 | __func__); | ||
1492 | goto cifs_parse_mount_err; | ||
1493 | } | ||
1494 | vol->port = option; | ||
1495 | break; | ||
1496 | case Opt_rsize: | ||
1497 | if (get_option_ul(args, &option)) { | ||
1498 | cERROR(1, "%s: Invalid rsize value", | ||
1499 | __func__); | ||
1500 | goto cifs_parse_mount_err; | ||
1501 | } | ||
1502 | vol->rsize = option; | ||
1503 | break; | ||
1504 | case Opt_wsize: | ||
1505 | if (get_option_ul(args, &option)) { | ||
1506 | cERROR(1, "%s: Invalid wsize value", | ||
1507 | __func__); | ||
1508 | goto cifs_parse_mount_err; | ||
1509 | } | ||
1510 | vol->wsize = option; | ||
1511 | break; | ||
1512 | case Opt_actimeo: | ||
1513 | if (get_option_ul(args, &option)) { | ||
1514 | cERROR(1, "%s: Invalid actimeo value", | ||
1515 | __func__); | ||
1516 | goto cifs_parse_mount_err; | ||
1517 | } | ||
1518 | vol->actimeo = HZ * option; | ||
1519 | if (vol->actimeo > CIFS_MAX_ACTIMEO) { | ||
1520 | cERROR(1, "CIFS: attribute cache" | ||
1521 | "timeout too large"); | ||
1522 | goto cifs_parse_mount_err; | ||
1523 | } | ||
1524 | break; | ||
1525 | |||
1526 | /* String Arguments */ | ||
1527 | |||
1528 | case Opt_user: | ||
1529 | string = match_strdup(args); | ||
1530 | if (string == NULL) | ||
1531 | goto out_nomem; | ||
1532 | |||
1533 | if (!*string) { | ||
1534 | /* null user, ie. anonymous authentication */ | ||
1535 | vol->nullauth = 1; | ||
1536 | } else if (strnlen(string, MAX_USERNAME_SIZE) > | ||
1537 | MAX_USERNAME_SIZE) { | ||
1538 | printk(KERN_WARNING "CIFS: username too long\n"); | ||
1539 | goto cifs_parse_mount_err; | ||
1540 | } | ||
1541 | vol->username = kstrdup(string, GFP_KERNEL); | ||
1542 | if (!vol->username) { | ||
1543 | printk(KERN_WARNING "CIFS: no memory " | ||
1544 | "for username\n"); | ||
1545 | goto cifs_parse_mount_err; | ||
1546 | } | ||
1547 | break; | ||
1548 | case Opt_blank_pass: | ||
1549 | vol->password = NULL; | ||
1550 | break; | ||
1551 | case Opt_pass: | ||
1552 | /* passwords have to be handled differently | ||
1553 | * to allow the character used for deliminator | ||
1554 | * to be passed within them | ||
1555 | */ | ||
1556 | |||
1557 | /* Obtain the value string */ | ||
1558 | value = strchr(data, '='); | ||
1559 | if (value != NULL) | ||
1560 | *value++ = '\0'; | ||
1561 | |||
1562 | /* Set tmp_end to end of the string */ | ||
1563 | tmp_end = (char *) value + strlen(value); | ||
1564 | |||
1565 | /* Check if following character is the deliminator | ||
1566 | * If yes, we have encountered a double deliminator | ||
1567 | * reset the NULL character to the deliminator | ||
1568 | */ | ||
1569 | if (tmp_end < end && tmp_end[1] == delim) | ||
1570 | tmp_end[0] = delim; | ||
1571 | |||
1572 | /* Keep iterating until we get to a single deliminator | ||
1573 | * OR the end | ||
1574 | */ | ||
1575 | while ((tmp_end = strchr(tmp_end, delim)) != NULL && | ||
1576 | (tmp_end[1] == delim)) { | ||
1577 | tmp_end = (char *) &tmp_end[2]; | ||
1578 | } | ||
1579 | |||
1580 | /* Reset var options to point to next element */ | ||
1581 | if (tmp_end) { | ||
1582 | tmp_end[0] = '\0'; | ||
1583 | options = (char *) &tmp_end[1]; | ||
1584 | } else | ||
1585 | /* Reached the end of the mount option string */ | ||
1586 | options = end; | ||
1587 | |||
1588 | /* Now build new password string */ | ||
1589 | temp_len = strlen(value); | ||
1590 | vol->password = kzalloc(temp_len+1, GFP_KERNEL); | ||
1591 | if (vol->password == NULL) { | ||
1592 | printk(KERN_WARNING "CIFS: no memory " | ||
1593 | "for password\n"); | ||
1594 | goto cifs_parse_mount_err; | ||
1595 | } | ||
1596 | |||
1597 | for (i = 0, j = 0; i < temp_len; i++, j++) { | ||
1598 | vol->password[j] = value[i]; | ||
1599 | if ((value[i] == delim) && | ||
1600 | value[i+1] == delim) | ||
1601 | /* skip the second deliminator */ | ||
1602 | i++; | ||
1603 | } | ||
1604 | vol->password[j] = '\0'; | ||
1605 | break; | ||
1606 | case Opt_ip: | ||
1607 | string = match_strdup(args); | ||
1608 | if (string == NULL) | ||
1609 | goto out_nomem; | ||
1610 | |||
1611 | if (!*string) { | ||
1612 | vol->UNCip = NULL; | ||
1613 | } else if (strnlen(string, INET6_ADDRSTRLEN) > | ||
1614 | INET6_ADDRSTRLEN) { | ||
1615 | printk(KERN_WARNING "CIFS: ip address " | ||
1616 | "too long\n"); | ||
1617 | goto cifs_parse_mount_err; | ||
1618 | } | ||
1619 | vol->UNCip = kstrdup(string, GFP_KERNEL); | ||
1620 | if (!vol->UNCip) { | ||
1621 | printk(KERN_WARNING "CIFS: no memory " | ||
1622 | "for UNC IP\n"); | ||
1623 | goto cifs_parse_mount_err; | ||
1624 | } | ||
1625 | break; | ||
1626 | case Opt_unc: | ||
1627 | string = match_strdup(args); | ||
1628 | if (string == NULL) | ||
1629 | goto out_nomem; | ||
1630 | |||
1631 | if (!*string) { | ||
1632 | printk(KERN_WARNING "CIFS: invalid path to " | ||
1633 | "network resource\n"); | ||
1634 | goto cifs_parse_mount_err; | ||
1635 | } | ||
1636 | |||
1637 | temp_len = strnlen(string, 300); | ||
1638 | if (temp_len == 300) { | ||
1639 | printk(KERN_WARNING "CIFS: UNC name too long\n"); | ||
1576 | goto cifs_parse_mount_err; | 1640 | goto cifs_parse_mount_err; |
1577 | strcpy(vol->UNC, devname); | 1641 | } |
1578 | if (strncmp(vol->UNC, "//", 2) == 0) { | 1642 | |
1643 | if (strncmp(string, "//", 2) == 0) { | ||
1579 | vol->UNC[0] = '\\'; | 1644 | vol->UNC[0] = '\\'; |
1580 | vol->UNC[1] = '\\'; | 1645 | vol->UNC[1] = '\\'; |
1581 | } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { | 1646 | } else if (strncmp(string, "\\\\", 2) != 0) { |
1582 | printk(KERN_WARNING "CIFS: UNC Path does not " | 1647 | printk(KERN_WARNING "CIFS: UNC Path does not " |
1583 | "begin with // or \\\\ \n"); | 1648 | "begin with // or \\\\\n"); |
1584 | goto cifs_parse_mount_err; | 1649 | goto cifs_parse_mount_err; |
1585 | } | 1650 | } |
1586 | value = strpbrk(vol->UNC+2, "/\\"); | 1651 | |
1587 | if (value) | 1652 | vol->UNC = kmalloc(temp_len+1, GFP_KERNEL); |
1588 | *value = '\\'; | 1653 | if (vol->UNC == NULL) { |
1589 | } else { | 1654 | printk(KERN_WARNING "CIFS: no memory " |
1590 | printk(KERN_WARNING "CIFS: UNC name too long\n"); | 1655 | "for UNC\n"); |
1656 | goto cifs_parse_mount_err; | ||
1657 | } | ||
1658 | strcpy(vol->UNC, string); | ||
1659 | break; | ||
1660 | case Opt_domain: | ||
1661 | string = match_strdup(args); | ||
1662 | if (string == NULL) | ||
1663 | goto out_nomem; | ||
1664 | |||
1665 | if (!*string) { | ||
1666 | printk(KERN_WARNING "CIFS: invalid domain" | ||
1667 | " name\n"); | ||
1668 | goto cifs_parse_mount_err; | ||
1669 | } else if (strnlen(string, 256) == 256) { | ||
1670 | printk(KERN_WARNING "CIFS: domain name too" | ||
1671 | " long\n"); | ||
1672 | goto cifs_parse_mount_err; | ||
1673 | } | ||
1674 | |||
1675 | vol->domainname = kstrdup(string, GFP_KERNEL); | ||
1676 | if (!vol->domainname) { | ||
1677 | printk(KERN_WARNING "CIFS: no memory " | ||
1678 | "for domainname\n"); | ||
1679 | goto cifs_parse_mount_err; | ||
1680 | } | ||
1681 | cFYI(1, "Domain name set"); | ||
1682 | break; | ||
1683 | case Opt_srcaddr: | ||
1684 | string = match_strdup(args); | ||
1685 | if (string == NULL) | ||
1686 | goto out_nomem; | ||
1687 | |||
1688 | if (!*string) { | ||
1689 | printk(KERN_WARNING "CIFS: srcaddr value not" | ||
1690 | " specified\n"); | ||
1691 | goto cifs_parse_mount_err; | ||
1692 | } else if (!cifs_convert_address( | ||
1693 | (struct sockaddr *)&vol->srcaddr, | ||
1694 | string, strlen(string))) { | ||
1695 | printk(KERN_WARNING "CIFS: Could not parse" | ||
1696 | " srcaddr: %s\n", string); | ||
1697 | goto cifs_parse_mount_err; | ||
1698 | } | ||
1699 | break; | ||
1700 | case Opt_prefixpath: | ||
1701 | string = match_strdup(args); | ||
1702 | if (string == NULL) | ||
1703 | goto out_nomem; | ||
1704 | |||
1705 | if (!*string) { | ||
1706 | printk(KERN_WARNING "CIFS: Invalid path" | ||
1707 | " prefix\n"); | ||
1708 | goto cifs_parse_mount_err; | ||
1709 | } | ||
1710 | temp_len = strnlen(string, 1024); | ||
1711 | if (string[0] != '/') | ||
1712 | temp_len++; /* missing leading slash */ | ||
1713 | if (temp_len > 1024) { | ||
1714 | printk(KERN_WARNING "CIFS: prefix too long\n"); | ||
1715 | goto cifs_parse_mount_err; | ||
1716 | } | ||
1717 | |||
1718 | vol->prepath = kmalloc(temp_len+1, GFP_KERNEL); | ||
1719 | if (vol->prepath == NULL) { | ||
1720 | printk(KERN_WARNING "CIFS: no memory " | ||
1721 | "for path prefix\n"); | ||
1722 | goto cifs_parse_mount_err; | ||
1723 | } | ||
1724 | |||
1725 | if (string[0] != '/') { | ||
1726 | vol->prepath[0] = '/'; | ||
1727 | strcpy(vol->prepath+1, string); | ||
1728 | } else | ||
1729 | strcpy(vol->prepath, string); | ||
1730 | |||
1731 | break; | ||
1732 | case Opt_iocharset: | ||
1733 | string = match_strdup(args); | ||
1734 | if (string == NULL) | ||
1735 | goto out_nomem; | ||
1736 | |||
1737 | if (!*string) { | ||
1738 | printk(KERN_WARNING "CIFS: Invalid iocharset" | ||
1739 | " specified\n"); | ||
1740 | goto cifs_parse_mount_err; | ||
1741 | } else if (strnlen(string, 1024) >= 65) { | ||
1742 | printk(KERN_WARNING "CIFS: iocharset name " | ||
1743 | "too long.\n"); | ||
1744 | goto cifs_parse_mount_err; | ||
1745 | } | ||
1746 | |||
1747 | if (strnicmp(string, "default", 7) != 0) { | ||
1748 | vol->iocharset = kstrdup(string, | ||
1749 | GFP_KERNEL); | ||
1750 | if (!vol->iocharset) { | ||
1751 | printk(KERN_WARNING "CIFS: no memory" | ||
1752 | "for charset\n"); | ||
1753 | goto cifs_parse_mount_err; | ||
1754 | } | ||
1755 | } | ||
1756 | /* if iocharset not set then load_nls_default | ||
1757 | * is used by caller | ||
1758 | */ | ||
1759 | cFYI(1, "iocharset set to %s", string); | ||
1760 | break; | ||
1761 | case Opt_sockopt: | ||
1762 | string = match_strdup(args); | ||
1763 | if (string == NULL) | ||
1764 | goto out_nomem; | ||
1765 | |||
1766 | if (!*string) { | ||
1767 | printk(KERN_WARNING "CIFS: No socket option" | ||
1768 | " specified\n"); | ||
1769 | goto cifs_parse_mount_err; | ||
1770 | } | ||
1771 | if (strnicmp(string, "TCP_NODELAY", 11) == 0) | ||
1772 | vol->sockopt_tcp_nodelay = 1; | ||
1773 | break; | ||
1774 | case Opt_netbiosname: | ||
1775 | string = match_strdup(args); | ||
1776 | if (string == NULL) | ||
1777 | goto out_nomem; | ||
1778 | |||
1779 | if (!*string) { | ||
1780 | printk(KERN_WARNING "CIFS: Invalid (empty)" | ||
1781 | " netbiosname\n"); | ||
1782 | break; | ||
1783 | } | ||
1784 | |||
1785 | memset(vol->source_rfc1001_name, 0x20, | ||
1786 | RFC1001_NAME_LEN); | ||
1787 | /* | ||
1788 | * FIXME: are there cases in which a comma can | ||
1789 | * be valid in workstation netbios name (and | ||
1790 | * need special handling)? | ||
1791 | */ | ||
1792 | for (i = 0; i < RFC1001_NAME_LEN; i++) { | ||
1793 | /* don't ucase netbiosname for user */ | ||
1794 | if (string[i] == 0) | ||
1795 | break; | ||
1796 | vol->source_rfc1001_name[i] = string[i]; | ||
1797 | } | ||
1798 | /* The string has 16th byte zero still from | ||
1799 | * set at top of the function | ||
1800 | */ | ||
1801 | if (i == RFC1001_NAME_LEN && string[i] != 0) | ||
1802 | printk(KERN_WARNING "CIFS: netbiosname" | ||
1803 | " longer than 15 truncated.\n"); | ||
1804 | |||
1805 | break; | ||
1806 | case Opt_servern: | ||
1807 | /* servernetbiosname specified override *SMBSERVER */ | ||
1808 | string = match_strdup(args); | ||
1809 | if (string == NULL) | ||
1810 | goto out_nomem; | ||
1811 | |||
1812 | if (!*string) { | ||
1813 | printk(KERN_WARNING "CIFS: Empty server" | ||
1814 | " netbiosname specified\n"); | ||
1815 | break; | ||
1816 | } | ||
1817 | /* last byte, type, is 0x20 for servr type */ | ||
1818 | memset(vol->target_rfc1001_name, 0x20, | ||
1819 | RFC1001_NAME_LEN_WITH_NULL); | ||
1820 | |||
1821 | /* BB are there cases in which a comma can be | ||
1822 | valid in this workstation netbios name | ||
1823 | (and need special handling)? */ | ||
1824 | |||
1825 | /* user or mount helper must uppercase the | ||
1826 | netbios name */ | ||
1827 | for (i = 0; i < 15; i++) { | ||
1828 | if (string[i] == 0) | ||
1829 | break; | ||
1830 | vol->target_rfc1001_name[i] = string[i]; | ||
1831 | } | ||
1832 | /* The string has 16th byte zero still from | ||
1833 | set at top of the function */ | ||
1834 | if (i == RFC1001_NAME_LEN && string[i] != 0) | ||
1835 | printk(KERN_WARNING "CIFS: server net" | ||
1836 | "biosname longer than 15 truncated.\n"); | ||
1837 | break; | ||
1838 | case Opt_ver: | ||
1839 | string = match_strdup(args); | ||
1840 | if (string == NULL) | ||
1841 | goto out_nomem; | ||
1842 | |||
1843 | if (!*string) { | ||
1844 | cERROR(1, "no protocol version specified" | ||
1845 | " after vers= mount option"); | ||
1846 | goto cifs_parse_mount_err; | ||
1847 | } | ||
1848 | |||
1849 | if (strnicmp(string, "cifs", 4) == 0 || | ||
1850 | strnicmp(string, "1", 1) == 0) { | ||
1851 | /* This is the default */ | ||
1852 | break; | ||
1853 | } | ||
1854 | /* For all other value, error */ | ||
1855 | printk(KERN_WARNING "CIFS: Invalid version" | ||
1856 | " specified\n"); | ||
1591 | goto cifs_parse_mount_err; | 1857 | goto cifs_parse_mount_err; |
1858 | case Opt_sec: | ||
1859 | string = match_strdup(args); | ||
1860 | if (string == NULL) | ||
1861 | goto out_nomem; | ||
1862 | |||
1863 | if (!*string) { | ||
1864 | printk(KERN_WARNING "CIFS: no security flavor" | ||
1865 | " specified\n"); | ||
1866 | break; | ||
1867 | } | ||
1868 | |||
1869 | if (cifs_parse_security_flavors(string, vol) != 0) | ||
1870 | goto cifs_parse_mount_err; | ||
1871 | break; | ||
1872 | default: | ||
1873 | printk(KERN_WARNING "CIFS: Unknown mount option %s\n", | ||
1874 | data); | ||
1875 | break; | ||
1592 | } | 1876 | } |
1877 | /* Free up any allocated string */ | ||
1878 | kfree(string); | ||
1879 | string = NULL; | ||
1593 | } | 1880 | } |
1594 | 1881 | ||
1595 | #ifndef CONFIG_KEYS | 1882 | #ifndef CONFIG_KEYS |
@@ -1619,7 +1906,10 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1619 | kfree(mountdata_copy); | 1906 | kfree(mountdata_copy); |
1620 | return 0; | 1907 | return 0; |
1621 | 1908 | ||
1909 | out_nomem: | ||
1910 | printk(KERN_WARNING "Could not allocate temporary buffer\n"); | ||
1622 | cifs_parse_mount_err: | 1911 | cifs_parse_mount_err: |
1912 | kfree(string); | ||
1623 | kfree(mountdata_copy); | 1913 | kfree(mountdata_copy); |
1624 | return 1; | 1914 | return 1; |
1625 | } | 1915 | } |