Overview
SHA1 Hash: | 1f1d96529c64ef5e9afda16af7d405aade92cb3d |
---|---|
Date: | 2008-08-03 16:47:43 |
User: | drh |
Comment: | Users unconditionally inherit capabilities of "anonymous". New capability "v" means to inherit capabilities of user "developer". Login is prohibited if the password is empty. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/admin.c from [3d7573884c] to [8499f27819].
@@ -108,10 +108,10 @@ } admin_prepare_submenu(); style_header("Admin"); @ <h2>Links:</h2> @ <ul> - @ <li><a href='%s(g.zBaseURL)/admin/setup'>Fossil WWW Setup</a></li> + @ <li><a href='%s(g.zBaseURL)/setup'>Fossil WWW Setup</a></li> @ <li><a href='%s(g.zBaseURL)/admin/sql'>Run SQL queries</a></li> @ </ul> style_footer(); }
Modified src/db.c from [2755f169fc] to [1ccbb50ea2].
@@ -789,13 +789,15 @@ "INSERT INTO user(login, pw, cap, info)" "VALUES(%Q,'','s','')", zUser ); db_multi_exec( "INSERT INTO user(login,pw,cap,info)" - " VALUES('anonymous','anonymous','hjkorw','Anon');" + " VALUES('anonymous','anonymous','aghknw','Anon');" "INSERT INTO user(login,pw,cap,info)" " VALUES('nobody','','jor','Nobody');" + "INSERT INTO user(login,pw,cap,info)" + " VALUES('developer','','deipt','Dev');" ); user_select(); if (makeInitialVersion){ blob_zero(&manifest);
Modified src/login.c from [86fb4c3fd8] to [0807191c83].
@@ -113,11 +113,11 @@ ); cgi_redirect(zGoto); return; } } - if( zUsername!=0 && zPasswd!=0 ){ + if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){ int uid = db_int(0, "SELECT uid FROM user" " WHERE login=%Q AND pw=%Q", zUsername, zPasswd); if( uid<=0 || strcmp(zUsername,"nobody")==0 ){ sleep(1); @@ -300,13 +300,15 @@ g.userUid = uid; if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){ g.zLogin = 0; } if( uid && g.zLogin ){ + /* All logged-in users inherit privileges from "nobody" */ zNcap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'"); login_set_capabilities(zNcap); - if( db_get_int("inherit-anon",0) ){ + if( strcmp(g.zLogin, "anonymous")!=0 ){ + /* All logged-in users inherit privileges from "anonymous" */ zAcap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'"); login_set_capabilities(zAcap); } } login_set_capabilities(zCap); @@ -314,10 +316,11 @@ /* ** Set the global capability flags based on a capability string. */ void login_set_capabilities(const char *zCap){ + static char *zDev = 0; int i; for(i=0; zCap[i]; i++){ switch( zCap[i] ){ case 's': g.okSetup = 1; case 'a': g.okAdmin = g.okRdTkt = g.okWrTkt = @@ -343,10 +346,20 @@ case 'n': g.okNewTkt = 1; break; case 'w': g.okWrTkt = g.okRdTkt = g.okNewTkt = g.okApndTkt = 1; break; case 'c': g.okApndTkt = 1; break; case 't': g.okTktFmt = 1; break; + + /* The "v" privileges is a little different. It recursively + ** inherits all privileges of the user named "developer" */ + case 'v': { + if( zDev==0 ){ + zDev = db_text("", "SELECT cap FROM user WHERE login='developer'"); + login_set_capabilities(zDev); + } + break; + } } } } /* @@ -359,27 +372,35 @@ int rc = 1; if( nCap<0 ) nCap = strlen(zCap); for(i=0; i<nCap && rc && zCap[i]; i++){ switch( zCap[i] ){ case 'a': rc = g.okAdmin; break; + /* case 'b': */ case 'c': rc = g.okApndTkt; break; case 'd': rc = g.okDelete; break; case 'e': rc = g.okRdAddr; break; case 'f': rc = g.okNewWiki; break; case 'g': rc = g.okClone; break; case 'h': rc = g.okHistory; break; case 'i': rc = g.okWrite; break; case 'j': rc = g.okRdWiki; break; case 'k': rc = g.okWrWiki; break; + /* case 'l': */ case 'm': rc = g.okApndWiki; break; case 'n': rc = g.okNewTkt; break; case 'o': rc = g.okRead; break; case 'p': rc = g.okPassword; break; + /* case 'q': */ case 'r': rc = g.okRdTkt; break; case 's': rc = g.okSetup; break; case 't': rc = g.okTktFmt; break; + /* case 'u': */ + /* case 'v': */ case 'w': rc = g.okWrTkt; break; + /* case 'x': */ + /* case 'y': */ + /* case 'z': */ default: rc = 0; break; } } return rc; }
Modified src/my_page.c from [52bd9eb48f] to [98c9467776].
@@ -27,12 +27,12 @@ */ #include <assert.h> #include "config.h" #include "my_page.h" -/** -Renders a logout button. +/* +** Renders a logout button. */ static void mypage_logout_button() { if( g.zLogin ){ @ <br clear="both"/><hr/> @@ -43,12 +43,12 @@ @ <input type="submit" name="out" value="Logout"/></p> @ </form> } } -/** -Renders a password changer. +/* +** Renders a password changer. */ static void mypage_password_changer() { if( g.okPassword ){ @ <br clear="both"/><hr/> @@ -71,12 +71,12 @@ @ </form> } } -/** -Default page rendered for /my. +/* +** Default page rendered for /my. */ static void mypage_page_default() { int uid = g.userUid; char * sql = mprintf( "SELECT login,cap,info FROM user WHERE uid=%d",
Modified src/setup.c from [7115d9c001] to [1c7a1834ca].
@@ -152,34 +152,50 @@ @ <li value="15"><b>Check-Out</b>: Check out versions</li> @ <li value="16"><b>Password</b>: Change your own password</li> @ <li value="18"><b>Read-Tkt</b>: View tickets</li> @ <li value="19"><b>Setup:</b> Setup and configure this website</li> @ <li value="20"><b>Tkt-Report:</b> Create new bug summary reports</li> + @ <li value="22"><b>Developer:</b> Inherit privileges of user "developer"</li> @ <li value="23"><b>Write-Tkt</b>: Edit tickets</li> @ </ol> @ </p></li> @ @ <li><p> - @ Every user, logged in or not, has the privileges of <b>nobody</b>. + @ Every user, logged in or not, inherits the privileges of <b>nobody</b>. @ Any human can login as <b>anonymous</b> since the password is @ clearly displayed on the login page for them to type. The purpose @ of requiring anonymous to log in is to prevent access by spiders. + @ Every logged-in user inherits the privileges of <b>anonymous</b>. @ </p></li> @ @ </ol> @ </td></tr></table> style_footer(); } /* +** Return true if zPw is a valid password string. A valid +** password string is: +** +** (1) A zero-length string, or +** (2) a string that contains a character other than '*'. +*/ +static int isValidPwString(const char *zPw){ + if( zPw==0 ) return 0; + if( zPw[0]==0 ) return 1; + while( zPw[0]=='*' ){ zPw++; } + return zPw[0]!=0; +} + +/* ** WEBPAGE: /setup_uedit */ void user_edit(void){ - const char *zId, *zLogin, *zInfo, *zCap; + const char *zId, *zLogin, *zInfo, *zCap, *zPw; char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap; char *oak, *oad, *oac, *oaf, *oam, *oah, *oag, *oae; - char *oat; + char *oat, *oav; int doWrite; int uid; int higherUser = 0; /* True if user being edited is SETUP and the */ /* user doing the editing is ADMIN. Disallow editing */ @@ -208,12 +224,10 @@ ** modified user record. After writing the user record, redirect ** to the page that displays a list of users. */ doWrite = cgi_all("login","info","pw") && !higherUser; if( doWrite ){ - const char *zPw; - const char *zLogin; char zCap[50]; int i = 0; int aa = P("aa")!=0; int ad = P("ad")!=0; int ae = P("ae")!=0; @@ -230,10 +244,11 @@ int af = P("af")!=0; int am = P("am")!=0; int ah = P("ah")!=0; int ag = P("ag")!=0; int at = P("at")!=0; + int av = P("av")!=0; if( aa ){ zCap[i++] = 'a'; } if( ac ){ zCap[i++] = 'c'; } if( ad ){ zCap[i++] = 'd'; } if( ae ){ zCap[i++] = 'e'; } if( af ){ zCap[i++] = 'f'; } @@ -247,15 +262,16 @@ if( ao ){ zCap[i++] = 'o'; } if( ap ){ zCap[i++] = 'p'; } if( ar ){ zCap[i++] = 'r'; } if( as ){ zCap[i++] = 's'; } if( at ){ zCap[i++] = 't'; } + if( av ){ zCap[i++] = 'v'; } if( aw ){ zCap[i++] = 'w'; } zCap[i] = 0; zPw = P("pw"); - if( zPw==0 || zPw[0]==0 ){ + if( !isValidPwString(zPw) ){ zPw = db_text(0, "SELECT pw FROM user WHERE uid=%d", uid); } zLogin = P("login"); if( uid>0 && db_exists("SELECT 1 FROM user WHERE login=%Q AND uid!=%d", zLogin, uid) @@ -280,16 +296,18 @@ /* Load the existing information about the user, if any */ zLogin = ""; zInfo = ""; zCap = ""; + zPw = ""; oaa = oac = oad = oae = oaf = oag = oah = oai = oaj = oak = oam = - oan = oao = oap = oar = oas = oat = oaw = ""; + oan = oao = oap = oar = oas = oat = oav = oaw = ""; if( uid ){ zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid); zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid); zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid); + zPw = db_text("", "SELECT pw FROM user WHERE uid=%d", uid); if( strchr(zCap, 'a') ) oaa = " checked"; if( strchr(zCap, 'c') ) oac = " checked"; if( strchr(zCap, 'd') ) oad = " checked"; if( strchr(zCap, 'e') ) oae = " checked"; if( strchr(zCap, 'f') ) oaf = " checked"; @@ -303,10 +321,11 @@ if( strchr(zCap, 'o') ) oao = " checked"; if( strchr(zCap, 'p') ) oap = " checked"; if( strchr(zCap, 'r') ) oar = " checked"; if( strchr(zCap, 's') ) oas = " checked"; if( strchr(zCap, 't') ) oat = " checked"; + if( strchr(zCap, 'v') ) oav = " checked"; if( strchr(zCap, 'w') ) oaw = " checked"; } /* Begin generating the page */ @@ -346,10 +365,11 @@ @ <input type="checkbox" name="ae"%s(oad)>Email</input><br> @ <input type="checkbox" name="ap"%s(oap)>Password</input><br> @ <input type="checkbox" name="ai"%s(oai)>Check-In</input><br> @ <input type="checkbox" name="ao"%s(oao)>Check-Out</input><br> @ <input type="checkbox" name="ah"%s(oah)>History</input><br> + @ <input type="checkbox" name="av"%s(oav)>Developer</input><br> @ <input type="checkbox" name="ag"%s(oag)>Clone</input><br> @ <input type="checkbox" name="aj"%s(oaj)>Read Wiki</input><br> @ <input type="checkbox" name="af"%s(oaf)>New Wiki</input><br> @ <input type="checkbox" name="am"%s(oam)>Append Wiki</input><br> @ <input type="checkbox" name="ak"%s(oak)>Write Wiki</input><br> @@ -360,21 +380,30 @@ @ <input type="checkbox" name="at"%s(oat)>Tkt Report</input> @ </td> @ </tr> @ <tr> @ <td align="right">Password:</td> - @ <td><input type="password" name="pw" value=""></td> + if( strcmp(zLogin, "anonymous")==0 ){ + /* User the password for "anonymous" as cleartext */ + @ <td><input type="text" name="pw" value="%h(zPw)"></td> + }else if( zPw[0] ){ + /* Obscure the password for all other users */ + @ <td><input type="password" name="pw" value="**********"></td> + }else{ + /* Show an empty password as an empty input field */ + @ <td><input type="password" name="pw" value=""></td> + } @ </tr> if( !higherUser ){ @ <tr> @ <td> </td> @ <td><input type="submit" name="submit" value="Apply Changes"> @ </tr> } @ </table></td></tr></table> - @ <p><b>Notes:</b></p> - @ <ol> + @ <h2>Privileges And Capabilities:</h2> + @ <ul> if( higherUser ){ @ <li><p><font color="blue"><b> @ User %h(zLogin) has Setup privileges and you only have Admin privileges @ so you are not permitted to make changes to %h(zLogin). @ </b></font></p></li> @@ -402,10 +431,15 @@ @ user "nobody" to avoid problems with spiders trying to walk every @ historical version of every baseline and file. @ </p></li> @ @ <li><p> + @ The <b>Developer</b> privilege causes all privileges of the user + @ named "developer" to be inherited by this user. + @ </p></li> + @ + @ <li><p> @ The <b>Check-in</b> privilege allows remote users to "push". @ The <b>Check-out</b> privilege allows remote users to "pull". @ The <b>Clone</b> privilege allows remote users to "clone". @ </li><p> @ @@ -418,39 +452,58 @@ @ ticket report formats. @ </p></li> @ @ <li><p> @ Users with the <b>Password</b> privilege are allowed to change their - @ own password. Recommended ON for most users but OFF for "anonynmous" - @ and "nobody". + @ own password. Recommended ON for most users but OFF for special + @ users "developer, "anonynmous", and "nobody". @ </p></li> @ @ <li><p> @ The <b>EMail</b> privilege allows the display of sensitive information @ such as the email address of users and contact information on tickets. @ Recommended OFF for "anonymous" and for "nobody". @ </p></li> @ @ <li><p> + @ Login is prohibited if the password is an empty string. + @ </p></li> + @ </ul> + @ + @ <h2>Special Logins</h2> + @ + @ <ul> + @ <li><p> @ No login is required for user "<b>nobody</b>". The capabilities - @ of this user are available to anyone without supplying a username or - @ password. To disable nobody access, make sure there is no user - @ with an ID of <b>nobody</b> or that the nobody user has no - @ capabilities enabled. The password for nobody is ignore. To - @ avoid problems with spiders overloading the server, it is suggested - @ that the 'h' (History) capability be turned off for user nobody. + @ of the <b>nobody</b> user are inherited by all users, regardless of + @ whether or not they are logged in. To disable universal access + @ to the repository, make sure no user named "<b>nobody</b>" exists or + @ that the <b>nobody</b> user has no capabilities enabled. + @ The password for <b>nobody</b> is ignore. To avoid problems with + @ spiders overloading the server, it is recommended + @ that the 'h' (History) capability be turned off for the <b>nobody</b> + @ user. @ </p></li> @ @ <li><p> @ Login is required for user "<b>anonymous</b>" but the password @ is displayed on the login screen beside the password entry box @ so anybody who can read should be able to login as anonymous. @ On the other hand, spiders and web-crawlers will typically not @ be able to login. Set the capabilities of the anonymous user @ to things that you want any human to be able to do, but not any - @ spider. + @ spider. Every other logged-in user inherits the privileges of + @ <b>anonymous</b>. @ </p></li> + @ + @ <li><p> + @ The "<b>developer</b>" user is intended as a template for trusted users + @ with check-in privileges. When adding new trusted users, simply + @ select the <b>Developer</b> privilege to cause the new user to inherit + @ all privileges of the "developer" user. + @ </li></p> + @ </ul> @ </form> style_footer(); }