Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch sub-repos Excluding Merge-Ins
This is equivalent to a diff from 13ceb46e49 to e8b15ad642
2011-03-28
| ||
22:47 | Merge the sub-repo capability into trunk. check-in: ab4882588e user: drh tags: trunk | |
22:29 | A new approach to sub-repos in which a specific user for the subrepo is specified in the CONFIG table entry. Closed-Leaf check-in: e8b15ad642 user: drh tags: sub-repos | |
21:46 | Fixes to the capability reduction on subrepositories. check-in: 4b545a8a02 user: drh tags: sub-repos | |
18:08 | Allow for the creation of "sub-repositories" that can be accessed through the web interface using the same login credentials as the parent repository. check-in: 97d0118794 user: drh tags: sub-repos | |
07:40 | Use "password" instead of "passwd" because it's complete and proper, and plays nicely w/ Emacs "send-invisible" capabilities that keep typed text from echoing on screen. check-in: 13ceb46e49 user: bharder tags: trunk | |
2011-03-27
| ||
21:55 | Changes to makeheaders so that it does not move static inline procedures into header files. Changed suggested by Yoran Heling. This has zero impact on Fossil which does not use "inline" anywhere. check-in: 99532f33af user: drh tags: trunk | |
Changes to src/login.c.
498 498 } 499 499 500 500 /* Set the capabilities */ 501 501 login_set_capabilities(zCap); 502 502 login_set_anon_nobody_capabilities(); 503 503 } 504 504 505 +/* 506 +** Memory of settings 507 +*/ 508 +static int login_anon_once = 1; 509 + 505 510 /* 506 511 ** Add the default privileges of users "nobody" and "anonymous" as appropriate 507 512 ** for the user g.zLogin. 508 513 */ 509 514 void login_set_anon_nobody_capabilities(void){ 510 - static int once = 1; 511 - if( g.zLogin && once ){ 515 + if( g.zLogin && login_anon_once ){ 512 516 const char *zCap; 513 517 /* All logged-in users inherit privileges from "nobody" */ 514 518 zCap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'"); 515 519 login_set_capabilities(zCap); 516 520 if( fossil_strcmp(g.zLogin, "nobody")!=0 ){ 517 521 /* All logged-in users inherit privileges from "anonymous" */ 518 522 zCap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'"); 519 523 login_set_capabilities(zCap); 520 524 } 521 - once = 0; 525 + login_anon_once = 0; 522 526 } 523 527 } 524 528 525 529 /* 526 530 ** Set the global capability flags based on a capability string. 527 531 */ 528 532 void login_set_capabilities(const char *zCap){ ................................................................................ 615 619 /* case 'q': */ 616 620 case 'r': rc = g.okRdTkt; break; 617 621 case 's': rc = g.okSetup; break; 618 622 case 't': rc = g.okTktFmt; break; 619 623 /* case 'u': READER */ 620 624 /* case 'v': DEVELOPER */ 621 625 case 'w': rc = g.okWrTkt; break; 622 - /* case 'x': */ 626 + case 'x': rc = g.okPrivate; break; 623 627 /* case 'y': */ 624 628 case 'z': rc = g.okZip; break; 625 629 default: rc = 0; break; 626 630 } 627 631 } 628 632 return rc; 629 633 } 634 + 635 +/* 636 +** Change the login to zUser. 637 +*/ 638 +void login_as_user(const char *zUser){ 639 + char *zCap = ""; /* New capabilities */ 640 + 641 + /* Turn off all capabilities from prior logins */ 642 + g.okSetup = 0; 643 + g.okAdmin = 0; 644 + g.okDelete = 0; 645 + g.okPassword = 0; 646 + g.okQuery = 0; 647 + g.okWrite = 0; 648 + g.okRead = 0; 649 + g.okHistory = 0; 650 + g.okClone = 0; 651 + g.okRdWiki = 0; 652 + g.okNewWiki = 0; 653 + g.okApndWiki = 0; 654 + g.okWrWiki = 0; 655 + g.okRdTkt = 0; 656 + g.okNewTkt = 0; 657 + g.okApndTkt = 0; 658 + g.okWrTkt = 0; 659 + g.okAttach = 0; 660 + g.okTktFmt = 0; 661 + g.okRdAddr = 0; 662 + g.okZip = 0; 663 + g.okPrivate = 0; 664 + 665 + /* Set the global variables recording the userid and login. The 666 + ** "nobody" user is a special case in that g.zLogin==0. 667 + */ 668 + g.userUid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUser); 669 + if( g.userUid==0 ){ 670 + zUser = 0; 671 + g.userUid = db_int(0, "SELECT uid FROM user WHERE login='nobody'"); 672 + } 673 + if( g.userUid ){ 674 + zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", g.userUid); 675 + } 676 + if( fossil_strcmp(zUser,"nobody")==0 ) zUser = 0; 677 + g.zLogin = fossil_strdup(zUser); 678 + 679 + /* Set the capabilities */ 680 + login_set_capabilities(zCap); 681 + login_anon_once = 1; 682 + login_set_anon_nobody_capabilities(); 683 +} 630 684 631 685 /* 632 686 ** Call this routine when the credential check fails. It causes 633 687 ** a redirect to the "login" page. 634 688 */ 635 689 void login_needed(void){ 636 690 const char *zUrl = PD("REQUEST_URI", "index");
Changes to src/main.c.
966 966 if( zPathInfo==0 || zPathInfo[0]==0 967 967 || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ 968 968 fossil_redirect_home(); 969 969 }else{ 970 970 zPath = mprintf("%s", zPathInfo); 971 971 } 972 972 973 - /* Remove the leading "/" at the beginning of the path. 973 + /* Make g.zPath point to the first element of the path. Make 974 + ** g.zExtra point to everything past that point. 974 975 */ 975 - g.zPath = &zPath[1]; 976 - for(i=1; zPath[i] && zPath[i]!='/'; i++){} 977 - if( zPath[i]=='/' ){ 978 - zPath[i] = 0; 979 - g.zExtra = &zPath[i+1]; 980 - }else{ 981 - g.zExtra = 0; 976 + while(1){ 977 + char *zAltRepo = 0; 978 + g.zPath = &zPath[1]; 979 + for(i=1; zPath[i] && zPath[i]!='/'; i++){} 980 + if( zPath[i]=='/' ){ 981 + zPath[i] = 0; 982 + g.zExtra = &zPath[i+1]; 983 + 984 + /* Look for sub-repositories. A sub-repository is another repository 985 + ** that accepts the login credentials of the current repository. A 986 + ** subrepository is identified by a CONFIG table entry "subrepo:NAME" 987 + ** where NAME is the first component of the path. The value of the 988 + ** the CONFIG entries is the string "USER:FILENAME" where USER is the 989 + ** USER name to log in as in the subrepository and FILENAME is the 990 + ** repository filename. 991 + */ 992 + zAltRepo = db_text(0, "SELECT value FROM config WHERE name='subrepo:%q'", 993 + g.zPath); 994 + if( zAltRepo ){ 995 + int nHost; 996 + int jj; 997 + char *zUser = zAltRepo; 998 + login_check_credentials(); 999 + for(jj=0; zAltRepo[jj] && zAltRepo[jj]!=':'; jj++){} 1000 + if( zAltRepo[jj]==':' ){ 1001 + zAltRepo[jj] = 0; 1002 + zAltRepo += jj+1; 1003 + }else{ 1004 + zUser = "nobody"; 1005 + } 1006 + if( zAltRepo[0]!='/' ){ 1007 + zAltRepo = mprintf("%s/../%s", g.zRepositoryName, zAltRepo); 1008 + file_simplify_name(zAltRepo, -1); 1009 + } 1010 + db_close(1); 1011 + db_open_repository(zAltRepo); 1012 + login_as_user(zUser); 1013 + g.okPassword = 0; 1014 + zPath += i; 1015 + nHost = g.zTop - g.zBaseURL; 1016 + g.zBaseURL = mprintf("%z/%s", g.zBaseURL, g.zPath); 1017 + g.zTop = g.zBaseURL + nHost; 1018 + continue; 1019 + } 1020 + }else{ 1021 + g.zExtra = 0; 1022 + } 1023 + break; 982 1024 } 983 1025 if( g.zExtra ){ 984 1026 /* CGI parameters get this treatment elsewhere, but places like getfile 985 1027 ** will use g.zExtra directly. 986 1028 */ 987 1029 dehttpize(g.zExtra); 988 1030 cgi_set_parameter_nocopy("name", g.zExtra);