Fossil SCM

Fixed a bug in /json/user/save which could cause the fossil-internally-defined version of the 'name' param to be used, overwriting a user's name with 'user/save'. The name now _must_ come from the request payload, to avoid this ambiguity.

stephan 2012-03-17 01:49 trunk
Commit 7e25293c5e72a078706771b2ad1ab4c35269c417
1 file changed +39 -17
+39 -17
--- src/json_user.c
+++ src/json_user.c
@@ -198,16 +198,17 @@
198198
char const tgtHasSetup = zCap && (NULL!=strchr(zCap, 's'));
199199
char tgtHadSetup = 0;
200200
Blob sql = empty_blob;
201201
Stmt q = empty_Stmt;
202202
203
+#if 0
203204
if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
204205
return json_set_err( FSL_JSON_E_DENIED,
205206
"Password change requires 'a', 's', "
206207
"or 'p' permissions.");
207208
}
208
-
209
+#endif
209210
if(uid<=0 && (!zName||!*zName)){
210211
return json_set_err(FSL_JSON_E_MISSING_ARGS,
211212
"One of 'uid' or 'name' is required.");
212213
}else if(uid>0){
213214
zNameFree = db_text(NULL, "SELECT login FROM user WHERE uid=%d",uid);
@@ -278,33 +279,39 @@
278279
blob_append(&sql, "UPDATE user SET",-1 );
279280
blob_append(&sql, " mtime=cast(strftime('%s') AS INTEGER)", -1);
280281
281282
if((uid>0) && zNameNew){
282283
/* Check for name change... */
283
- if( (!g.perm.Admin && !g.perm.Setup)
284
- && zNameNew && (zName != zNameNew)
285
- && (0!=strcmp(zNameNew,zName))){
286
- json_set_err( FSL_JSON_E_DENIED,
287
- "Modifying user names requires 'a' or 's' privileges.");
288
- goto error;
289
- }
290
- forceLogout = cson_value_true()
284
+ if(0!=strcmp(zName,zNameNew)){
285
+ if( (!g.perm.Admin && !g.perm.Setup)
286
+ && (zName != zNameNew)){
287
+ json_set_err( FSL_JSON_E_DENIED,
288
+ "Modifying user names requires 'a' or 's' privileges.");
289
+ goto error;
290
+ }
291
+ forceLogout = cson_value_true()
291292
/* reminders: 1) does not allocate.
292
- 2) we do this because changing a name
293
- invalidates any login token because the old name
294
- is part of the token hash.
293
+ 2) we do this because changing a name
294
+ invalidates any login token because the old name
295
+ is part of the token hash.
295296
*/;
296
- blob_appendf(&sql, ", login=%Q", zNameNew);
297
- ++gotFields;
297
+ blob_appendf(&sql, ", login=%Q", zNameNew);
298
+ ++gotFields;
299
+ }
298300
}
299301
300302
if( zCap ){
301303
blob_appendf(&sql, ", cap=%Q", zCap);
302304
++gotFields;
303305
}
304306
#define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */
305
- if( zPW ){
307
+ if( zPW && *zPW ){
308
+ if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
309
+ return json_set_err( FSL_JSON_E_DENIED,
310
+ "Password change requires 'a', 's', "
311
+ "or 'p' permissions.");
312
+ }
306313
#if !TRY_LOGIN_GROUP
307314
char * zPWHash = NULL;
308315
++gotFields;
309316
zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL);
310317
blob_appendf(&sql, ", pw=%Q", zPWHash);
@@ -389,22 +396,37 @@
389396
static cson_value * json_user_save(){
390397
/* try to get user info from GET/CLI args and construct
391398
a JSON form of it... */
392399
cson_object * u = cson_new_object();
393400
char const * str = NULL;
401
+ cson_value * tmpV = NULL;
394402
char b = -1;
395403
int i = -1;
396404
int uid = -1;
397405
cson_value * payload = NULL;
398406
#define PROP(LK) str = json_find_option_cstr(LK,NULL,NULL); \
399407
if(str){ cson_object_set(u, LK, json_new_string(str)); } (void)0
400
- PROP("name");
401408
PROP("password");
402409
PROP("info");
403410
PROP("capabilities");
404411
#undef PROP
405
-
412
+ if(g.isHTTP){
413
+ tmpV = json_req_payload_get("name");
414
+ }
415
+ if(!tmpV && !g.isHTTP){
416
+ /* only do this in CLI mode, to avoid the fossil-internal "name"
417
+ param from become a user's name. Been there, done that
418
+ (renamed my account to "user/save").
419
+ */
420
+ str = json_find_option_cstr("name",NULL,NULL);
421
+ if(str){
422
+ tmpV = json_new_string(str);
423
+ }
424
+ }
425
+ if(tmpV){
426
+ cson_object_set(u, "name", tmpV);
427
+ }
406428
#define PROP(LK,DFLT) b = json_find_option_bool(LK,NULL,NULL,DFLT); \
407429
if(DFLT!=b){ cson_object_set(u, LK, cson_value_new_bool(b)); } (void)0
408430
PROP("forceLogout",-1);
409431
#undef PROP
410432
411433
--- src/json_user.c
+++ src/json_user.c
@@ -198,16 +198,17 @@
198 char const tgtHasSetup = zCap && (NULL!=strchr(zCap, 's'));
199 char tgtHadSetup = 0;
200 Blob sql = empty_blob;
201 Stmt q = empty_Stmt;
202
 
203 if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
204 return json_set_err( FSL_JSON_E_DENIED,
205 "Password change requires 'a', 's', "
206 "or 'p' permissions.");
207 }
208
209 if(uid<=0 && (!zName||!*zName)){
210 return json_set_err(FSL_JSON_E_MISSING_ARGS,
211 "One of 'uid' or 'name' is required.");
212 }else if(uid>0){
213 zNameFree = db_text(NULL, "SELECT login FROM user WHERE uid=%d",uid);
@@ -278,33 +279,39 @@
278 blob_append(&sql, "UPDATE user SET",-1 );
279 blob_append(&sql, " mtime=cast(strftime('%s') AS INTEGER)", -1);
280
281 if((uid>0) && zNameNew){
282 /* Check for name change... */
283 if( (!g.perm.Admin && !g.perm.Setup)
284 && zNameNew && (zName != zNameNew)
285 && (0!=strcmp(zNameNew,zName))){
286 json_set_err( FSL_JSON_E_DENIED,
287 "Modifying user names requires 'a' or 's' privileges.");
288 goto error;
289 }
290 forceLogout = cson_value_true()
291 /* reminders: 1) does not allocate.
292 2) we do this because changing a name
293 invalidates any login token because the old name
294 is part of the token hash.
295 */;
296 blob_appendf(&sql, ", login=%Q", zNameNew);
297 ++gotFields;
 
298 }
299
300 if( zCap ){
301 blob_appendf(&sql, ", cap=%Q", zCap);
302 ++gotFields;
303 }
304 #define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */
305 if( zPW ){
 
 
 
 
 
306 #if !TRY_LOGIN_GROUP
307 char * zPWHash = NULL;
308 ++gotFields;
309 zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL);
310 blob_appendf(&sql, ", pw=%Q", zPWHash);
@@ -389,22 +396,37 @@
389 static cson_value * json_user_save(){
390 /* try to get user info from GET/CLI args and construct
391 a JSON form of it... */
392 cson_object * u = cson_new_object();
393 char const * str = NULL;
 
394 char b = -1;
395 int i = -1;
396 int uid = -1;
397 cson_value * payload = NULL;
398 #define PROP(LK) str = json_find_option_cstr(LK,NULL,NULL); \
399 if(str){ cson_object_set(u, LK, json_new_string(str)); } (void)0
400 PROP("name");
401 PROP("password");
402 PROP("info");
403 PROP("capabilities");
404 #undef PROP
405
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
406 #define PROP(LK,DFLT) b = json_find_option_bool(LK,NULL,NULL,DFLT); \
407 if(DFLT!=b){ cson_object_set(u, LK, cson_value_new_bool(b)); } (void)0
408 PROP("forceLogout",-1);
409 #undef PROP
410
411
--- src/json_user.c
+++ src/json_user.c
@@ -198,16 +198,17 @@
198 char const tgtHasSetup = zCap && (NULL!=strchr(zCap, 's'));
199 char tgtHadSetup = 0;
200 Blob sql = empty_blob;
201 Stmt q = empty_Stmt;
202
203 #if 0
204 if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
205 return json_set_err( FSL_JSON_E_DENIED,
206 "Password change requires 'a', 's', "
207 "or 'p' permissions.");
208 }
209 #endif
210 if(uid<=0 && (!zName||!*zName)){
211 return json_set_err(FSL_JSON_E_MISSING_ARGS,
212 "One of 'uid' or 'name' is required.");
213 }else if(uid>0){
214 zNameFree = db_text(NULL, "SELECT login FROM user WHERE uid=%d",uid);
@@ -278,33 +279,39 @@
279 blob_append(&sql, "UPDATE user SET",-1 );
280 blob_append(&sql, " mtime=cast(strftime('%s') AS INTEGER)", -1);
281
282 if((uid>0) && zNameNew){
283 /* Check for name change... */
284 if(0!=strcmp(zName,zNameNew)){
285 if( (!g.perm.Admin && !g.perm.Setup)
286 && (zName != zNameNew)){
287 json_set_err( FSL_JSON_E_DENIED,
288 "Modifying user names requires 'a' or 's' privileges.");
289 goto error;
290 }
291 forceLogout = cson_value_true()
292 /* reminders: 1) does not allocate.
293 2) we do this because changing a name
294 invalidates any login token because the old name
295 is part of the token hash.
296 */;
297 blob_appendf(&sql, ", login=%Q", zNameNew);
298 ++gotFields;
299 }
300 }
301
302 if( zCap ){
303 blob_appendf(&sql, ", cap=%Q", zCap);
304 ++gotFields;
305 }
306 #define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */
307 if( zPW && *zPW ){
308 if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
309 return json_set_err( FSL_JSON_E_DENIED,
310 "Password change requires 'a', 's', "
311 "or 'p' permissions.");
312 }
313 #if !TRY_LOGIN_GROUP
314 char * zPWHash = NULL;
315 ++gotFields;
316 zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL);
317 blob_appendf(&sql, ", pw=%Q", zPWHash);
@@ -389,22 +396,37 @@
396 static cson_value * json_user_save(){
397 /* try to get user info from GET/CLI args and construct
398 a JSON form of it... */
399 cson_object * u = cson_new_object();
400 char const * str = NULL;
401 cson_value * tmpV = NULL;
402 char b = -1;
403 int i = -1;
404 int uid = -1;
405 cson_value * payload = NULL;
406 #define PROP(LK) str = json_find_option_cstr(LK,NULL,NULL); \
407 if(str){ cson_object_set(u, LK, json_new_string(str)); } (void)0
 
408 PROP("password");
409 PROP("info");
410 PROP("capabilities");
411 #undef PROP
412 if(g.isHTTP){
413 tmpV = json_req_payload_get("name");
414 }
415 if(!tmpV && !g.isHTTP){
416 /* only do this in CLI mode, to avoid the fossil-internal "name"
417 param from become a user's name. Been there, done that
418 (renamed my account to "user/save").
419 */
420 str = json_find_option_cstr("name",NULL,NULL);
421 if(str){
422 tmpV = json_new_string(str);
423 }
424 }
425 if(tmpV){
426 cson_object_set(u, "name", tmpV);
427 }
428 #define PROP(LK,DFLT) b = json_find_option_bool(LK,NULL,NULL,DFLT); \
429 if(DFLT!=b){ cson_object_set(u, LK, cson_value_new_bool(b)); } (void)0
430 PROP("forceLogout",-1);
431 #undef PROP
432
433

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button