nfs4proc.c (07f9479a40cc778bc1462ada11f95b01360ae4ff) | nfs4proc.c (68d93184352f2e723f135b0a9bad93b58f9d120b) |
---|---|
1/* 2 * Server-side procedures for NFSv4. 3 * 4 * Copyright (c) 2002 The Regents of the University of Michigan. 5 * All rights reserved. 6 * 7 * Kendrick Smith <kmsmith@umich.edu> 8 * Andy Adamson <andros@umich.edu> --- 389 unchanged lines hidden (view full) --- 398static __be32 399nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 400 struct nfsd4_putfh *putfh) 401{ 402 fh_put(&cstate->current_fh); 403 cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; 404 memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, 405 putfh->pf_fhlen); | 1/* 2 * Server-side procedures for NFSv4. 3 * 4 * Copyright (c) 2002 The Regents of the University of Michigan. 5 * All rights reserved. 6 * 7 * Kendrick Smith <kmsmith@umich.edu> 8 * Andy Adamson <andros@umich.edu> --- 389 unchanged lines hidden (view full) --- 398static __be32 399nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 400 struct nfsd4_putfh *putfh) 401{ 402 fh_put(&cstate->current_fh); 403 cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; 404 memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, 405 putfh->pf_fhlen); |
406 return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP); | 406 return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS); |
407} 408 409static __be32 410nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 411 void *arg) 412{ 413 __be32 status; 414 --- 342 unchanged lines hidden (view full) --- 757 struct nfsd4_secinfo *secinfo) 758{ 759 struct svc_fh resfh; 760 struct svc_export *exp; 761 struct dentry *dentry; 762 __be32 err; 763 764 fh_init(&resfh, NFS4_FHSIZE); | 407} 408 409static __be32 410nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 411 void *arg) 412{ 413 __be32 status; 414 --- 342 unchanged lines hidden (view full) --- 757 struct nfsd4_secinfo *secinfo) 758{ 759 struct svc_fh resfh; 760 struct svc_export *exp; 761 struct dentry *dentry; 762 __be32 err; 763 764 fh_init(&resfh, NFS4_FHSIZE); |
765 err = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, NFSD_MAY_EXEC); 766 if (err) 767 return err; |
|
765 err = nfsd_lookup_dentry(rqstp, &cstate->current_fh, 766 secinfo->si_name, secinfo->si_namelen, 767 &exp, &dentry); 768 if (err) 769 return err; 770 if (dentry->d_inode == NULL) { 771 exp_put(exp); 772 err = nfserr_noent; --- 208 unchanged lines hidden (view full) --- 981} 982 983typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, 984 void *); 985enum nfsd4_op_flags { 986 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ 987 ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ 988 ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ | 768 err = nfsd_lookup_dentry(rqstp, &cstate->current_fh, 769 secinfo->si_name, secinfo->si_namelen, 770 &exp, &dentry); 771 if (err) 772 return err; 773 if (dentry->d_inode == NULL) { 774 exp_put(exp); 775 err = nfserr_noent; --- 208 unchanged lines hidden (view full) --- 984} 985 986typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, 987 void *); 988enum nfsd4_op_flags { 989 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ 990 ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ 991 ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ |
992 /* For rfc 5661 section 2.6.3.1.1: */ 993 OP_HANDLES_WRONGSEC = 1 << 3, 994 OP_IS_PUTFH_LIKE = 1 << 4, |
|
989}; 990 991struct nfsd4_operation { 992 nfsd4op_func op_func; 993 u32 op_flags; 994 char *op_name; 995}; 996 --- 29 unchanged lines hidden (view full) --- 1026 return nfserr_op_not_in_session; 1027 if (op->opnum == OP_SEQUENCE) 1028 return nfs_ok; 1029 if (args->opcnt != 1) 1030 return nfserr_not_only_op; 1031 return nfs_ok; 1032} 1033 | 995}; 996 997struct nfsd4_operation { 998 nfsd4op_func op_func; 999 u32 op_flags; 1000 char *op_name; 1001}; 1002 --- 29 unchanged lines hidden (view full) --- 1032 return nfserr_op_not_in_session; 1033 if (op->opnum == OP_SEQUENCE) 1034 return nfs_ok; 1035 if (args->opcnt != 1) 1036 return nfserr_not_only_op; 1037 return nfs_ok; 1038} 1039 |
1040static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op) 1041{ 1042 return &nfsd4_ops[op->opnum]; 1043} 1044 1045static bool need_wrongsec_check(struct svc_rqst *rqstp) 1046{ 1047 struct nfsd4_compoundres *resp = rqstp->rq_resp; 1048 struct nfsd4_compoundargs *argp = rqstp->rq_argp; 1049 struct nfsd4_op *this = &argp->ops[resp->opcnt - 1]; 1050 struct nfsd4_op *next = &argp->ops[resp->opcnt]; 1051 struct nfsd4_operation *thisd; 1052 struct nfsd4_operation *nextd; 1053 1054 thisd = OPDESC(this); 1055 /* 1056 * Most ops check wronsec on our own; only the putfh-like ops 1057 * have special rules. 1058 */ 1059 if (!(thisd->op_flags & OP_IS_PUTFH_LIKE)) 1060 return false; 1061 /* 1062 * rfc 5661 2.6.3.1.1.6: don't bother erroring out a 1063 * put-filehandle operation if we're not going to use the 1064 * result: 1065 */ 1066 if (argp->opcnt == resp->opcnt) 1067 return false; 1068 1069 nextd = OPDESC(next); 1070 /* 1071 * Rest of 2.6.3.1.1: certain operations will return WRONGSEC 1072 * errors themselves as necessary; others should check for them 1073 * now: 1074 */ 1075 return !(nextd->op_flags & OP_HANDLES_WRONGSEC); 1076} 1077 |
|
1034/* 1035 * COMPOUND call. 1036 */ 1037static __be32 1038nfsd4_proc_compound(struct svc_rqst *rqstp, 1039 struct nfsd4_compoundargs *args, 1040 struct nfsd4_compoundres *resp) 1041{ --- 61 unchanged lines hidden (view full) --- 1103 slack_bytes = (char *)resp->end - (char *)resp->p; 1104 if (slack_bytes < COMPOUND_SLACK_SPACE 1105 + COMPOUND_ERR_SLACK_SPACE) { 1106 BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE); 1107 op->status = nfserr_resource; 1108 goto encode_op; 1109 } 1110 | 1078/* 1079 * COMPOUND call. 1080 */ 1081static __be32 1082nfsd4_proc_compound(struct svc_rqst *rqstp, 1083 struct nfsd4_compoundargs *args, 1084 struct nfsd4_compoundres *resp) 1085{ --- 61 unchanged lines hidden (view full) --- 1147 slack_bytes = (char *)resp->end - (char *)resp->p; 1148 if (slack_bytes < COMPOUND_SLACK_SPACE 1149 + COMPOUND_ERR_SLACK_SPACE) { 1150 BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE); 1151 op->status = nfserr_resource; 1152 goto encode_op; 1153 } 1154 |
1111 opdesc = &nfsd4_ops[op->opnum]; | 1155 opdesc = OPDESC(op); |
1112 1113 if (!cstate->current_fh.fh_dentry) { 1114 if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { 1115 op->status = nfserr_nofilehandle; 1116 goto encode_op; 1117 } 1118 } else if (cstate->current_fh.fh_export->ex_fslocs.migrated && 1119 !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { 1120 op->status = nfserr_moved; 1121 goto encode_op; 1122 } 1123 1124 if (opdesc->op_func) 1125 op->status = opdesc->op_func(rqstp, cstate, &op->u); 1126 else 1127 BUG_ON(op->status == nfs_ok); 1128 | 1156 1157 if (!cstate->current_fh.fh_dentry) { 1158 if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { 1159 op->status = nfserr_nofilehandle; 1160 goto encode_op; 1161 } 1162 } else if (cstate->current_fh.fh_export->ex_fslocs.migrated && 1163 !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { 1164 op->status = nfserr_moved; 1165 goto encode_op; 1166 } 1167 1168 if (opdesc->op_func) 1169 op->status = opdesc->op_func(rqstp, cstate, &op->u); 1170 else 1171 BUG_ON(op->status == nfs_ok); 1172 |
1173 if (!op->status && need_wrongsec_check(rqstp)) 1174 op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp); 1175 |
|
1129encode_op: 1130 /* Only from SEQUENCE */ 1131 if (resp->cstate.status == nfserr_replay_cache) { 1132 dprintk("%s NFS4.1 replay from cache\n", __func__); 1133 status = op->status; 1134 goto out; 1135 } 1136 if (op->status == nfserr_replay_me) { --- 75 unchanged lines hidden (view full) --- 1212 .op_name = "OP_LOCKT", 1213 }, 1214 [OP_LOCKU] = { 1215 .op_func = (nfsd4op_func)nfsd4_locku, 1216 .op_name = "OP_LOCKU", 1217 }, 1218 [OP_LOOKUP] = { 1219 .op_func = (nfsd4op_func)nfsd4_lookup, | 1176encode_op: 1177 /* Only from SEQUENCE */ 1178 if (resp->cstate.status == nfserr_replay_cache) { 1179 dprintk("%s NFS4.1 replay from cache\n", __func__); 1180 status = op->status; 1181 goto out; 1182 } 1183 if (op->status == nfserr_replay_me) { --- 75 unchanged lines hidden (view full) --- 1259 .op_name = "OP_LOCKT", 1260 }, 1261 [OP_LOCKU] = { 1262 .op_func = (nfsd4op_func)nfsd4_locku, 1263 .op_name = "OP_LOCKU", 1264 }, 1265 [OP_LOOKUP] = { 1266 .op_func = (nfsd4op_func)nfsd4_lookup, |
1267 .op_flags = OP_HANDLES_WRONGSEC, |
|
1220 .op_name = "OP_LOOKUP", 1221 }, 1222 [OP_LOOKUPP] = { 1223 .op_func = (nfsd4op_func)nfsd4_lookupp, | 1268 .op_name = "OP_LOOKUP", 1269 }, 1270 [OP_LOOKUPP] = { 1271 .op_func = (nfsd4op_func)nfsd4_lookupp, |
1272 .op_flags = OP_HANDLES_WRONGSEC, |
|
1224 .op_name = "OP_LOOKUPP", 1225 }, 1226 [OP_NVERIFY] = { 1227 .op_func = (nfsd4op_func)nfsd4_nverify, 1228 .op_name = "OP_NVERIFY", 1229 }, 1230 [OP_OPEN] = { 1231 .op_func = (nfsd4op_func)nfsd4_open, | 1273 .op_name = "OP_LOOKUPP", 1274 }, 1275 [OP_NVERIFY] = { 1276 .op_func = (nfsd4op_func)nfsd4_nverify, 1277 .op_name = "OP_NVERIFY", 1278 }, 1279 [OP_OPEN] = { 1280 .op_func = (nfsd4op_func)nfsd4_open, |
1281 .op_flags = OP_HANDLES_WRONGSEC, |
|
1232 .op_name = "OP_OPEN", 1233 }, 1234 [OP_OPEN_CONFIRM] = { 1235 .op_func = (nfsd4op_func)nfsd4_open_confirm, 1236 .op_name = "OP_OPEN_CONFIRM", 1237 }, 1238 [OP_OPEN_DOWNGRADE] = { 1239 .op_func = (nfsd4op_func)nfsd4_open_downgrade, 1240 .op_name = "OP_OPEN_DOWNGRADE", 1241 }, 1242 [OP_PUTFH] = { 1243 .op_func = (nfsd4op_func)nfsd4_putfh, | 1282 .op_name = "OP_OPEN", 1283 }, 1284 [OP_OPEN_CONFIRM] = { 1285 .op_func = (nfsd4op_func)nfsd4_open_confirm, 1286 .op_name = "OP_OPEN_CONFIRM", 1287 }, 1288 [OP_OPEN_DOWNGRADE] = { 1289 .op_func = (nfsd4op_func)nfsd4_open_downgrade, 1290 .op_name = "OP_OPEN_DOWNGRADE", 1291 }, 1292 [OP_PUTFH] = { 1293 .op_func = (nfsd4op_func)nfsd4_putfh, |
1244 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1294 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1295 | OP_IS_PUTFH_LIKE, |
1245 .op_name = "OP_PUTFH", 1246 }, 1247 [OP_PUTPUBFH] = { 1248 .op_func = (nfsd4op_func)nfsd4_putrootfh, | 1296 .op_name = "OP_PUTFH", 1297 }, 1298 [OP_PUTPUBFH] = { 1299 .op_func = (nfsd4op_func)nfsd4_putrootfh, |
1249 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1300 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1301 | OP_IS_PUTFH_LIKE, |
1250 .op_name = "OP_PUTPUBFH", 1251 }, 1252 [OP_PUTROOTFH] = { 1253 .op_func = (nfsd4op_func)nfsd4_putrootfh, | 1302 .op_name = "OP_PUTPUBFH", 1303 }, 1304 [OP_PUTROOTFH] = { 1305 .op_func = (nfsd4op_func)nfsd4_putrootfh, |
1254 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1306 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1307 | OP_IS_PUTFH_LIKE, |
1255 .op_name = "OP_PUTROOTFH", 1256 }, 1257 [OP_READ] = { 1258 .op_func = (nfsd4op_func)nfsd4_read, 1259 .op_name = "OP_READ", 1260 }, 1261 [OP_READDIR] = { 1262 .op_func = (nfsd4op_func)nfsd4_readdir, --- 13 unchanged lines hidden (view full) --- 1276 }, 1277 [OP_RENEW] = { 1278 .op_func = (nfsd4op_func)nfsd4_renew, 1279 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1280 .op_name = "OP_RENEW", 1281 }, 1282 [OP_RESTOREFH] = { 1283 .op_func = (nfsd4op_func)nfsd4_restorefh, | 1308 .op_name = "OP_PUTROOTFH", 1309 }, 1310 [OP_READ] = { 1311 .op_func = (nfsd4op_func)nfsd4_read, 1312 .op_name = "OP_READ", 1313 }, 1314 [OP_READDIR] = { 1315 .op_func = (nfsd4op_func)nfsd4_readdir, --- 13 unchanged lines hidden (view full) --- 1329 }, 1330 [OP_RENEW] = { 1331 .op_func = (nfsd4op_func)nfsd4_renew, 1332 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1333 .op_name = "OP_RENEW", 1334 }, 1335 [OP_RESTOREFH] = { 1336 .op_func = (nfsd4op_func)nfsd4_restorefh, |
1284 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1337 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1338 | OP_IS_PUTFH_LIKE, |
1285 .op_name = "OP_RESTOREFH", 1286 }, 1287 [OP_SAVEFH] = { 1288 .op_func = (nfsd4op_func)nfsd4_savefh, | 1339 .op_name = "OP_RESTOREFH", 1340 }, 1341 [OP_SAVEFH] = { 1342 .op_func = (nfsd4op_func)nfsd4_savefh, |
1343 .op_flags = OP_HANDLES_WRONGSEC, |
|
1289 .op_name = "OP_SAVEFH", 1290 }, 1291 [OP_SECINFO] = { 1292 .op_func = (nfsd4op_func)nfsd4_secinfo, | 1344 .op_name = "OP_SAVEFH", 1345 }, 1346 [OP_SECINFO] = { 1347 .op_func = (nfsd4op_func)nfsd4_secinfo, |
1348 .op_flags = OP_HANDLES_WRONGSEC, |
|
1293 .op_name = "OP_SECINFO", 1294 }, 1295 [OP_SETATTR] = { 1296 .op_func = (nfsd4op_func)nfsd4_setattr, 1297 .op_name = "OP_SETATTR", 1298 }, 1299 [OP_SETCLIENTID] = { 1300 .op_func = (nfsd4op_func)nfsd4_setclientid, --- 47 unchanged lines hidden (view full) --- 1348 }, 1349 [OP_RECLAIM_COMPLETE] = { 1350 .op_func = (nfsd4op_func)nfsd4_reclaim_complete, 1351 .op_flags = ALLOWED_WITHOUT_FH, 1352 .op_name = "OP_RECLAIM_COMPLETE", 1353 }, 1354 [OP_SECINFO_NO_NAME] = { 1355 .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, | 1349 .op_name = "OP_SECINFO", 1350 }, 1351 [OP_SETATTR] = { 1352 .op_func = (nfsd4op_func)nfsd4_setattr, 1353 .op_name = "OP_SETATTR", 1354 }, 1355 [OP_SETCLIENTID] = { 1356 .op_func = (nfsd4op_func)nfsd4_setclientid, --- 47 unchanged lines hidden (view full) --- 1404 }, 1405 [OP_RECLAIM_COMPLETE] = { 1406 .op_func = (nfsd4op_func)nfsd4_reclaim_complete, 1407 .op_flags = ALLOWED_WITHOUT_FH, 1408 .op_name = "OP_RECLAIM_COMPLETE", 1409 }, 1410 [OP_SECINFO_NO_NAME] = { 1411 .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, |
1412 .op_flags = OP_HANDLES_WRONGSEC, |
|
1356 .op_name = "OP_SECINFO_NO_NAME", 1357 }, 1358}; 1359 1360static const char *nfsd4_op_name(unsigned opnum) 1361{ 1362 if (opnum < ARRAY_SIZE(nfsd4_ops)) 1363 return nfsd4_ops[opnum].op_name; --- 49 unchanged lines hidden --- | 1413 .op_name = "OP_SECINFO_NO_NAME", 1414 }, 1415}; 1416 1417static const char *nfsd4_op_name(unsigned opnum) 1418{ 1419 if (opnum < ARRAY_SIZE(nfsd4_ops)) 1420 return nfsd4_ops[opnum].op_name; --- 49 unchanged lines hidden --- |