Fossil SCM
Make sure that "nobody" and "anonymous" privileges by users who attempt to sync with higher privileges.
Commit
60212796377638c9444935d8e80a9cdac819a0ed
Parent
7343126617842a3…
2 files changed
+38
-18
+12
-2
+38
-18
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -296,12 +296,10 @@ | ||
| 296 | 296 | void login_check_credentials(void){ |
| 297 | 297 | int uid = 0; /* User id */ |
| 298 | 298 | const char *zCookie; /* Text of the login cookie */ |
| 299 | 299 | const char *zRemoteAddr; /* IP address of the requestor */ |
| 300 | 300 | const char *zCap = 0; /* Capability string */ |
| 301 | - const char *zNcap; /* Capabilities of user "nobody" */ | |
| 302 | - const char *zAcap; /* Capabllities of user "anonymous" */ | |
| 303 | 301 | |
| 304 | 302 | /* Only run this check once. */ |
| 305 | 303 | if( g.userUid!=0 ) return; |
| 306 | 304 | |
| 307 | 305 | |
| @@ -362,47 +360,69 @@ | ||
| 362 | 360 | blob_reset(&b); |
| 363 | 361 | } |
| 364 | 362 | sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "%.10s", zCookie); |
| 365 | 363 | } |
| 366 | 364 | |
| 365 | + /* If no user found yet, try to log in as "nobody" */ | |
| 367 | 366 | if( uid==0 ){ |
| 368 | 367 | uid = db_int(0, "SELECT uid FROM user WHERE login='nobody'"); |
| 369 | 368 | if( uid==0 ){ |
| 369 | + /* If there is no user "nobody", then make one up - with no privileges */ | |
| 370 | 370 | uid = -1; |
| 371 | 371 | zCap = ""; |
| 372 | 372 | } |
| 373 | 373 | strcpy(g.zCsrfToken, "none"); |
| 374 | 374 | } |
| 375 | - if( zCap==0 ){ | |
| 376 | - if( uid ){ | |
| 377 | - Stmt s; | |
| 378 | - db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid); | |
| 379 | - if( db_step(&s)==SQLITE_ROW ){ | |
| 380 | - g.zLogin = db_column_malloc(&s, 0); | |
| 381 | - zCap = db_column_malloc(&s, 1); | |
| 382 | - } | |
| 383 | - db_finalize(&s); | |
| 384 | - } | |
| 375 | + | |
| 376 | + /* At this point, we know that uid!=0. Find the privileges associated | |
| 377 | + ** with user uid. | |
| 378 | + */ | |
| 379 | + assert( uid!=0 ); | |
| 380 | + if( zCap==0 ){ | |
| 381 | + Stmt s; | |
| 382 | + db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid); | |
| 383 | + if( db_step(&s)==SQLITE_ROW ){ | |
| 384 | + g.zLogin = db_column_malloc(&s, 0); | |
| 385 | + zCap = db_column_malloc(&s, 1); | |
| 386 | + } | |
| 387 | + db_finalize(&s); | |
| 385 | 388 | if( zCap==0 ){ |
| 386 | 389 | zCap = ""; |
| 387 | 390 | } |
| 388 | 391 | } |
| 392 | + | |
| 393 | + /* Set the global variables recording the userid and login. The | |
| 394 | + ** "nobody" user is a special case in that g.zLogin==0. | |
| 395 | + */ | |
| 389 | 396 | g.userUid = uid; |
| 390 | 397 | if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){ |
| 391 | 398 | g.zLogin = 0; |
| 392 | 399 | } |
| 393 | - if( uid && g.zLogin ){ | |
| 400 | + | |
| 401 | + /* Set the capabilities */ | |
| 402 | + login_set_capabilities(zCap); | |
| 403 | + login_set_anon_nobody_capabilities(); | |
| 404 | +} | |
| 405 | + | |
| 406 | +/* | |
| 407 | +** Add the default privileges of users "nobody" and "anonymous" as appropriate | |
| 408 | +** for the user g.zLogin. | |
| 409 | +*/ | |
| 410 | +void login_set_anon_nobody_capabilities(void){ | |
| 411 | + static int once = 1; | |
| 412 | + if( g.zLogin && once ){ | |
| 413 | + const char *zCap; | |
| 394 | 414 | /* All logged-in users inherit privileges from "nobody" */ |
| 395 | - zNcap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'"); | |
| 396 | - login_set_capabilities(zNcap); | |
| 415 | + zCap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'"); | |
| 416 | + login_set_capabilities(zCap); | |
| 397 | 417 | if( strcmp(g.zLogin, "anonymous")!=0 ){ |
| 398 | 418 | /* All logged-in users inherit privileges from "anonymous" */ |
| 399 | - zAcap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'"); | |
| 400 | - login_set_capabilities(zAcap); | |
| 419 | + zCap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'"); | |
| 420 | + login_set_capabilities(zCap); | |
| 401 | 421 | } |
| 422 | + once = 0; | |
| 402 | 423 | } |
| 403 | - login_set_capabilities(zCap); | |
| 404 | 424 | } |
| 405 | 425 | |
| 406 | 426 | /* |
| 407 | 427 | ** Set the global capability flags based on a capability string. |
| 408 | 428 | */ |
| 409 | 429 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -296,12 +296,10 @@ | |
| 296 | void login_check_credentials(void){ |
| 297 | int uid = 0; /* User id */ |
| 298 | const char *zCookie; /* Text of the login cookie */ |
| 299 | const char *zRemoteAddr; /* IP address of the requestor */ |
| 300 | const char *zCap = 0; /* Capability string */ |
| 301 | const char *zNcap; /* Capabilities of user "nobody" */ |
| 302 | const char *zAcap; /* Capabllities of user "anonymous" */ |
| 303 | |
| 304 | /* Only run this check once. */ |
| 305 | if( g.userUid!=0 ) return; |
| 306 | |
| 307 | |
| @@ -362,47 +360,69 @@ | |
| 362 | blob_reset(&b); |
| 363 | } |
| 364 | sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "%.10s", zCookie); |
| 365 | } |
| 366 | |
| 367 | if( uid==0 ){ |
| 368 | uid = db_int(0, "SELECT uid FROM user WHERE login='nobody'"); |
| 369 | if( uid==0 ){ |
| 370 | uid = -1; |
| 371 | zCap = ""; |
| 372 | } |
| 373 | strcpy(g.zCsrfToken, "none"); |
| 374 | } |
| 375 | if( zCap==0 ){ |
| 376 | if( uid ){ |
| 377 | Stmt s; |
| 378 | db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid); |
| 379 | if( db_step(&s)==SQLITE_ROW ){ |
| 380 | g.zLogin = db_column_malloc(&s, 0); |
| 381 | zCap = db_column_malloc(&s, 1); |
| 382 | } |
| 383 | db_finalize(&s); |
| 384 | } |
| 385 | if( zCap==0 ){ |
| 386 | zCap = ""; |
| 387 | } |
| 388 | } |
| 389 | g.userUid = uid; |
| 390 | if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){ |
| 391 | g.zLogin = 0; |
| 392 | } |
| 393 | if( uid && g.zLogin ){ |
| 394 | /* All logged-in users inherit privileges from "nobody" */ |
| 395 | zNcap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'"); |
| 396 | login_set_capabilities(zNcap); |
| 397 | if( strcmp(g.zLogin, "anonymous")!=0 ){ |
| 398 | /* All logged-in users inherit privileges from "anonymous" */ |
| 399 | zAcap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'"); |
| 400 | login_set_capabilities(zAcap); |
| 401 | } |
| 402 | } |
| 403 | login_set_capabilities(zCap); |
| 404 | } |
| 405 | |
| 406 | /* |
| 407 | ** Set the global capability flags based on a capability string. |
| 408 | */ |
| 409 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -296,12 +296,10 @@ | |
| 296 | void login_check_credentials(void){ |
| 297 | int uid = 0; /* User id */ |
| 298 | const char *zCookie; /* Text of the login cookie */ |
| 299 | const char *zRemoteAddr; /* IP address of the requestor */ |
| 300 | const char *zCap = 0; /* Capability string */ |
| 301 | |
| 302 | /* Only run this check once. */ |
| 303 | if( g.userUid!=0 ) return; |
| 304 | |
| 305 | |
| @@ -362,47 +360,69 @@ | |
| 360 | blob_reset(&b); |
| 361 | } |
| 362 | sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "%.10s", zCookie); |
| 363 | } |
| 364 | |
| 365 | /* If no user found yet, try to log in as "nobody" */ |
| 366 | if( uid==0 ){ |
| 367 | uid = db_int(0, "SELECT uid FROM user WHERE login='nobody'"); |
| 368 | if( uid==0 ){ |
| 369 | /* If there is no user "nobody", then make one up - with no privileges */ |
| 370 | uid = -1; |
| 371 | zCap = ""; |
| 372 | } |
| 373 | strcpy(g.zCsrfToken, "none"); |
| 374 | } |
| 375 | |
| 376 | /* At this point, we know that uid!=0. Find the privileges associated |
| 377 | ** with user uid. |
| 378 | */ |
| 379 | assert( uid!=0 ); |
| 380 | if( zCap==0 ){ |
| 381 | Stmt s; |
| 382 | db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid); |
| 383 | if( db_step(&s)==SQLITE_ROW ){ |
| 384 | g.zLogin = db_column_malloc(&s, 0); |
| 385 | zCap = db_column_malloc(&s, 1); |
| 386 | } |
| 387 | db_finalize(&s); |
| 388 | if( zCap==0 ){ |
| 389 | zCap = ""; |
| 390 | } |
| 391 | } |
| 392 | |
| 393 | /* Set the global variables recording the userid and login. The |
| 394 | ** "nobody" user is a special case in that g.zLogin==0. |
| 395 | */ |
| 396 | g.userUid = uid; |
| 397 | if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){ |
| 398 | g.zLogin = 0; |
| 399 | } |
| 400 | |
| 401 | /* Set the capabilities */ |
| 402 | login_set_capabilities(zCap); |
| 403 | login_set_anon_nobody_capabilities(); |
| 404 | } |
| 405 | |
| 406 | /* |
| 407 | ** Add the default privileges of users "nobody" and "anonymous" as appropriate |
| 408 | ** for the user g.zLogin. |
| 409 | */ |
| 410 | void login_set_anon_nobody_capabilities(void){ |
| 411 | static int once = 1; |
| 412 | if( g.zLogin && once ){ |
| 413 | const char *zCap; |
| 414 | /* All logged-in users inherit privileges from "nobody" */ |
| 415 | zCap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'"); |
| 416 | login_set_capabilities(zCap); |
| 417 | if( strcmp(g.zLogin, "anonymous")!=0 ){ |
| 418 | /* All logged-in users inherit privileges from "anonymous" */ |
| 419 | zCap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'"); |
| 420 | login_set_capabilities(zCap); |
| 421 | } |
| 422 | once = 0; |
| 423 | } |
| 424 | } |
| 425 | |
| 426 | /* |
| 427 | ** Set the global capability flags based on a capability string. |
| 428 | */ |
| 429 |
+12
-2
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -382,13 +382,18 @@ | ||
| 382 | 382 | ** Signature generation on the client side is handled by the |
| 383 | 383 | ** http_exchange() routine. |
| 384 | 384 | */ |
| 385 | 385 | void check_login(Blob *pLogin, Blob *pNonce, Blob *pSig){ |
| 386 | 386 | Stmt q; |
| 387 | - int rc; | |
| 387 | + int rc = -1; | |
| 388 | 388 | |
| 389 | - db_prepare(&q, "SELECT pw, cap, uid FROM user WHERE login=%B", pLogin); | |
| 389 | + db_prepare(&q, | |
| 390 | + "SELECT pw, cap, uid FROM user" | |
| 391 | + " WHERE login=%B" | |
| 392 | + " AND length(pw)>0", | |
| 393 | + pLogin | |
| 394 | + ); | |
| 390 | 395 | if( db_step(&q)==SQLITE_ROW ){ |
| 391 | 396 | Blob pw, combined, hash; |
| 392 | 397 | blob_zero(&pw); |
| 393 | 398 | db_ephemeral_blob(&q, 0, &pw); |
| 394 | 399 | blob_zero(&combined); |
| @@ -407,10 +412,15 @@ | ||
| 407 | 412 | g.zLogin = mprintf("%b", pLogin); |
| 408 | 413 | g.zNonce = mprintf("%b", pNonce); |
| 409 | 414 | } |
| 410 | 415 | } |
| 411 | 416 | db_finalize(&q); |
| 417 | + | |
| 418 | + if( rc==0 ){ | |
| 419 | + /* If the login was successful. */ | |
| 420 | + login_set_anon_nobody_capabilities(); | |
| 421 | + } | |
| 412 | 422 | } |
| 413 | 423 | |
| 414 | 424 | /* |
| 415 | 425 | ** Send the content of all files in the unsent table. |
| 416 | 426 | ** |
| 417 | 427 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -382,13 +382,18 @@ | |
| 382 | ** Signature generation on the client side is handled by the |
| 383 | ** http_exchange() routine. |
| 384 | */ |
| 385 | void check_login(Blob *pLogin, Blob *pNonce, Blob *pSig){ |
| 386 | Stmt q; |
| 387 | int rc; |
| 388 | |
| 389 | db_prepare(&q, "SELECT pw, cap, uid FROM user WHERE login=%B", pLogin); |
| 390 | if( db_step(&q)==SQLITE_ROW ){ |
| 391 | Blob pw, combined, hash; |
| 392 | blob_zero(&pw); |
| 393 | db_ephemeral_blob(&q, 0, &pw); |
| 394 | blob_zero(&combined); |
| @@ -407,10 +412,15 @@ | |
| 407 | g.zLogin = mprintf("%b", pLogin); |
| 408 | g.zNonce = mprintf("%b", pNonce); |
| 409 | } |
| 410 | } |
| 411 | db_finalize(&q); |
| 412 | } |
| 413 | |
| 414 | /* |
| 415 | ** Send the content of all files in the unsent table. |
| 416 | ** |
| 417 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -382,13 +382,18 @@ | |
| 382 | ** Signature generation on the client side is handled by the |
| 383 | ** http_exchange() routine. |
| 384 | */ |
| 385 | void check_login(Blob *pLogin, Blob *pNonce, Blob *pSig){ |
| 386 | Stmt q; |
| 387 | int rc = -1; |
| 388 | |
| 389 | db_prepare(&q, |
| 390 | "SELECT pw, cap, uid FROM user" |
| 391 | " WHERE login=%B" |
| 392 | " AND length(pw)>0", |
| 393 | pLogin |
| 394 | ); |
| 395 | if( db_step(&q)==SQLITE_ROW ){ |
| 396 | Blob pw, combined, hash; |
| 397 | blob_zero(&pw); |
| 398 | db_ephemeral_blob(&q, 0, &pw); |
| 399 | blob_zero(&combined); |
| @@ -407,10 +412,15 @@ | |
| 412 | g.zLogin = mprintf("%b", pLogin); |
| 413 | g.zNonce = mprintf("%b", pNonce); |
| 414 | } |
| 415 | } |
| 416 | db_finalize(&q); |
| 417 | |
| 418 | if( rc==0 ){ |
| 419 | /* If the login was successful. */ |
| 420 | login_set_anon_nobody_capabilities(); |
| 421 | } |
| 422 | } |
| 423 | |
| 424 | /* |
| 425 | ** Send the content of all files in the unsent table. |
| 426 | ** |
| 427 |