Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Update the sub-repository capability so that it is able to restrict permissions on the sub-repository to a subset of the login permissions. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | sub-repos |
| Files: | files | file ages | folders |
| SHA1: |
c477b2470f552fe46bf269ba2cc722d3 |
| User & Date: | drh 2011-03-28 21:27:37.154 |
Context
|
2011-03-28
| ||
| 21:46 | Fixes to the capability reduction on subrepositories. check-in: 4b545a8a02 user: drh tags: sub-repos | |
| 21:27 | Update the sub-repository capability so that it is able to restrict permissions on the sub-repository to a subset of the login permissions. check-in: c477b2470f 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 | |
Changes
Changes to src/login.c.
| ︙ | ︙ | |||
498 499 500 501 502 503 504 505 506 507 508 509 |
}
/* Set the capabilities */
login_set_capabilities(zCap);
login_set_anon_nobody_capabilities();
}
/*
** Add the default privileges of users "nobody" and "anonymous" as appropriate
** for the user g.zLogin.
*/
void login_set_anon_nobody_capabilities(void){
| > > > > > > < | | > > > | 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 |
}
/* Set the capabilities */
login_set_capabilities(zCap);
login_set_anon_nobody_capabilities();
}
/*
** Memory of settings
*/
static int login_anon_once = 1;
static char login_settings[26];
/*
** Add the default privileges of users "nobody" and "anonymous" as appropriate
** for the user g.zLogin.
*/
void login_set_anon_nobody_capabilities(void){
if( g.zLogin && login_anon_once ){
const char *zCap;
/* All logged-in users inherit privileges from "nobody" */
zCap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'");
login_set_capabilities(zCap);
if( fossil_strcmp(g.zLogin, "nobody")!=0 ){
/* All logged-in users inherit privileges from "anonymous" */
zCap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'");
login_set_capabilities(zCap);
}
login_anon_once = 0;
}
}
/*
** Set the global capability flags based on a capability string.
*/
void login_set_capabilities(const char *zCap){
static char *zDev = 0;
static char *zUser = 0;
int i;
for(i=0; zCap[i]; i++){
int c = zCap[i];
if( c<'a' || c>'z' ) continue;
login_settings[c-'a'] = 1;
switch( zCap[i] ){
case 's': g.okSetup = 1; /* Fall thru into Admin */
case 'a': g.okAdmin = g.okRdTkt = g.okWrTkt = g.okZip =
g.okRdWiki = g.okWrWiki = g.okNewWiki =
g.okApndWiki = g.okHistory = g.okClone =
g.okNewTkt = g.okPassword = g.okRdAddr =
g.okTktFmt = g.okAttach = g.okApndTkt = 1;
|
| ︙ | ︙ | |||
615 616 617 618 619 620 621 |
/* case 'q': */
case 'r': rc = g.okRdTkt; break;
case 's': rc = g.okSetup; break;
case 't': rc = g.okTktFmt; break;
/* case 'u': READER */
/* case 'v': DEVELOPER */
case 'w': rc = g.okWrTkt; break;
| | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 |
/* case 'q': */
case 'r': rc = g.okRdTkt; break;
case 's': rc = g.okSetup; break;
case 't': rc = g.okTktFmt; break;
/* case 'u': READER */
/* case 'v': DEVELOPER */
case 'w': rc = g.okWrTkt; break;
case 'x': rc = g.okPrivate; break;
/* case 'y': */
case 'z': rc = g.okZip; break;
default: rc = 0; break;
}
}
return rc;
}
/*
** For every character in zCap between 'a' and 'z' set a byte in seen[].
*/
static void setCap(const char *zCap, char *seen){
int c;
if( zCap ){
while( (c = *(zCap++))!=0 ){
if( c>='a' && c<='z' ) seen[c-'a'] = 1;
}
}
}
/*
** Remove privileges such that previleges are restricted to the
** set given in the argument.
*/
void login_restrict_capabilities(const char *zAllowed){
char zNew[30];
char seen[26];
int nNew = 0;
int i;
/* Compute the intersection of current settings with zAllowed[] and
** store the result in zNew[]
*/
memset(seen, 0, sizeof(seen));
setCap(zAllowed, seen);
if( seen['v'-'a'] ){
char *z = db_text(0, "SELECT cap FROM user WHERE login='developer'");
setCap(z, seen);
fossil_free(z);
}
if( seen['u'-'a'] ){
char *z = db_text(0, "SELECT cap FROM user WHERE login='reader'");
setCap(z, seen);
fossil_free(z);
}
seen['u'-'a'] = 0;
seen['v'-'a'] = 0;
for(i=0; i<sizeof(seen); i++){
if( seen[i] && login_settings[i] ) zNew[nNew++] = i+'a';
}
zNew[nNew] = 0;
/* Turn off all capabilities */
g.okSetup = 0;
g.okAdmin = 0;
g.okDelete = 0;
g.okPassword = 0;
g.okQuery = 0;
g.okWrite = 0;
g.okRead = 0;
g.okHistory = 0;
g.okClone = 0;
g.okRdWiki = 0;
g.okNewWiki = 0;
g.okApndWiki = 0;
g.okWrWiki = 0;
g.okRdTkt = 0;
g.okNewTkt = 0;
g.okApndTkt = 0;
g.okWrTkt = 0;
g.okAttach = 0;
g.okTktFmt = 0;
g.okRdAddr = 0;
g.okZip = 0;
g.okPrivate = 0;
memset(login_settings, 0, sizeof(login_settings));
/* Set the reduced capabilities */
login_set_capabilities(zNew);
login_anon_once = 1;
login_set_anon_nobody_capabilities();
}
/*
** Call this routine when the credential check fails. It causes
** a redirect to the "login" page.
*/
void login_needed(void){
const char *zUrl = PD("REQUEST_URI", "index");
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
981 982 983 984 985 986 987 |
zPath[i] = 0;
g.zExtra = &zPath[i+1];
/* Look for sub-repositories. A sub-repository is another repository
** that accepts the login credentials of the current repository. A
** subrepository is identified by a CONFIG table entry "subrepo:NAME"
** where NAME is the first component of the path. The value of the
| | > > > > > > > > > > > | | | 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 |
zPath[i] = 0;
g.zExtra = &zPath[i+1];
/* Look for sub-repositories. A sub-repository is another repository
** that accepts the login credentials of the current repository. A
** subrepository is identified by a CONFIG table entry "subrepo:NAME"
** where NAME is the first component of the path. The value of the
** the CONFIG entries is the string "CAP:FILENAME" where CAP is the
** maximum capability string and FILENAME is the new repository
** filename.
*/
zAltRepo = db_text(0, "SELECT value FROM config WHERE name='subrepo:%q'",
g.zPath);
if( zAltRepo ){
int nHost;
int jj;
char *zInheritCap = zAltRepo;
login_check_credentials();
for(jj=0; zAltRepo[jj] && zAltRepo[jj]!=':'; jj++){}
if( zAltRepo[jj]==':' ){
zAltRepo[jj] = 0;
zAltRepo += jj+1;
}else{
zInheritCap = "";
}
if( zAltRepo[0]!='/' ){
zAltRepo = mprintf("%s/../%s", g.zRepositoryName, zAltRepo);
file_simplify_name(zAltRepo, -1);
}
db_close(1);
db_open_repository(zAltRepo);
login_restrict_capabilities(zInheritCap);
zPath += i;
nHost = g.zTop - g.zBaseURL;
g.zBaseURL = mprintf("%z/%s", g.zBaseURL, g.zPath);
g.zTop = g.zBaseURL + nHost;
continue;
}
}else{
|
| ︙ | ︙ |