aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-03-15 19:12:25 -0400
committerSage Weil <sage@newdream.net>2010-03-23 10:46:47 -0400
commit0a990e7093566ceb07e38951e1a01686923d4f09 (patch)
tree4f02c6f7a5c1033b4a81363e6e996d6237bda8e1 /fs
parent5b3dbb44ab40660a080d03585bd35f45b2890c49 (diff)
ceph: clean up service ticket decoding
Previously we would decode state directly into our current ticket_handler. This is problematic if for some reason we fail to decode, because we end up with half new state and half old state. We are probably already in bad shape if we get an update we can't decode, but we may as well be tidy anyway. Decode into new_* temporaries and update the ticket_handler only on success. Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs')
-rw-r--r--fs/ceph/auth_x.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c
index 33d3ad4dc456..8d8a84964763 100644
--- a/fs/ceph/auth_x.c
+++ b/fs/ceph/auth_x.c
@@ -156,7 +156,11 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
156 struct timespec validity; 156 struct timespec validity;
157 struct ceph_crypto_key old_key; 157 struct ceph_crypto_key old_key;
158 void *tp, *tpend; 158 void *tp, *tpend;
159 struct ceph_timespec new_validity;
160 struct ceph_crypto_key new_session_key;
159 struct ceph_buffer *new_ticket_blob; 161 struct ceph_buffer *new_ticket_blob;
162 unsigned long new_expires, new_renew_after;
163 u64 new_secret_id;
160 164
161 ceph_decode_need(&p, end, sizeof(u32) + 1, bad); 165 ceph_decode_need(&p, end, sizeof(u32) + 1, bad);
162 166
@@ -189,16 +193,16 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
189 goto bad; 193 goto bad;
190 194
191 memcpy(&old_key, &th->session_key, sizeof(old_key)); 195 memcpy(&old_key, &th->session_key, sizeof(old_key));
192 ret = ceph_crypto_key_decode(&th->session_key, &dp, dend); 196 ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
193 if (ret) 197 if (ret)
194 goto out; 198 goto out;
195 199
196 ceph_decode_copy(&dp, &th->validity, sizeof(th->validity)); 200 ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
197 ceph_decode_timespec(&validity, &th->validity); 201 ceph_decode_timespec(&validity, &new_validity);
198 th->expires = get_seconds() + validity.tv_sec; 202 new_expires = get_seconds() + validity.tv_sec;
199 th->renew_after = th->expires - (validity.tv_sec / 4); 203 new_renew_after = new_expires - (validity.tv_sec / 4);
200 dout(" expires=%lu renew_after=%lu\n", th->expires, 204 dout(" expires=%lu renew_after=%lu\n", new_expires,
201 th->renew_after); 205 new_renew_after);
202 206
203 /* ticket blob for service */ 207 /* ticket blob for service */
204 ceph_decode_8_safe(&p, end, is_enc, bad); 208 ceph_decode_8_safe(&p, end, is_enc, bad);
@@ -223,13 +227,21 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
223 dout(" ticket blob is %d bytes\n", dlen); 227 dout(" ticket blob is %d bytes\n", dlen);
224 ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); 228 ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
225 struct_v = ceph_decode_8(&tp); 229 struct_v = ceph_decode_8(&tp);
226 th->secret_id = ceph_decode_64(&tp); 230 new_secret_id = ceph_decode_64(&tp);
227 ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); 231 ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
228 if (ret) 232 if (ret)
229 goto out; 233 goto out;
234
235 /* all is well, update our ticket */
236 ceph_crypto_key_destroy(&th->session_key);
230 if (th->ticket_blob) 237 if (th->ticket_blob)
231 ceph_buffer_put(th->ticket_blob); 238 ceph_buffer_put(th->ticket_blob);
239 th->session_key = new_session_key;
232 th->ticket_blob = new_ticket_blob; 240 th->ticket_blob = new_ticket_blob;
241 th->validity = new_validity;
242 th->secret_id = new_secret_id;
243 th->expires = new_expires;
244 th->renew_after = new_renew_after;
233 dout(" got ticket service %d (%s) secret_id %lld len %d\n", 245 dout(" got ticket service %d (%s) secret_id %lld len %d\n",
234 type, ceph_entity_type_name(type), th->secret_id, 246 type, ceph_entity_type_name(type), th->secret_id,
235 (int)th->ticket_blob->vec.iov_len); 247 (int)th->ticket_blob->vec.iov_len);