Overview
SHA1 Hash: | 9c952d247e5164a53ae2c24d5e0068d45e72e72e |
---|---|
Date: | 2007-07-31 22:59:31 |
User: | drh |
Comment: | Separate "nobody" and "anonymous" logins. |
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/login.c from [a6b6c1f3f9] to [8a96b84fb6].
@@ -21,10 +21,30 @@ ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code for generating the login and logout screens. +** +** Notes: +** +** There are two special-case user-ids: "anonymous" and "nobody". +** The capabilities of the nobody user are available to anyone, +** regardless of whether or not they are logged in. The capabilities +** of anonymous are only available after logging in, but the login +** screen displays the password for the anonymous login, so this +** should not prevent a human user from doing so. +** +** The nobody user has capabilities that you want spiders to have. +** The anonymous user has capabilities that you want people without +** logins to have. +** +** Of course, a sophisticated spider could easily circumvent the +** anonymous login requirement and walk the website. But that is +** not really the point. The anonymous login keeps search-engine +** crawlers and site download tools like wget from walking change +** logs and downloading diffs of very version of the archive that +** has ever existed, and things like that. */ #include "config.h" #include "login.h" #include <time.h> @@ -42,10 +62,11 @@ ** Generate the login page */ void login_page(void){ const char *zUsername, *zPasswd, *zGoto; const char *zNew1, *zNew2; + const char *zAnonPw; char *zErrMsg = ""; login_check_credentials(); zUsername = P("u"); zPasswd = P("p"); @@ -53,11 +74,11 @@ if( P("out")!=0 ){ const char *zCookieName = login_cookie_name(); cgi_set_cookie(zCookieName, "", 0, -86400); cgi_redirect(zGoto); } - if( !g.isAnon && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){ + if( g.okPassword && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){ if( db_int(1, "SELECT 0 FROM user" " WHERE uid=%d AND pw=%Q", g.userUid, zPasswd) ){ sleep(1); zErrMsg = @ <p><font color="red"> @@ -78,36 +99,39 @@ ); cgi_redirect("index"); return; } } - if( zUsername!=0 && zPasswd!=0 && strcmp(zUsername,"anonymous")!=0 ){ + if( zUsername!=0 && zPasswd!=0 ){ int uid = db_int(0, "SELECT uid FROM user" " WHERE login=%Q AND pw=%Q", zUsername, zPasswd); - if( uid<=0 ){ + if( uid<=0 || strcmp(zUsername,"nobody")==0 ){ sleep(1); zErrMsg = @ <p><font color="red"> @ You entered an unknown user or an incorrect password. @ </font></p> ; }else{ char *zCookie; const char *zCookieName = login_cookie_name(); - const char *zIpAddr = PD("REMOTE_ADDR","nil"); const char *zExpire = db_get("cookie-expire","8766"); - int expires; - - zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid); - expires = atoi(zExpire)*3600; - cgi_set_cookie(zCookieName, zCookie, 0, expires); - db_multi_exec( - "UPDATE user SET cookie=%Q, ipaddr=%Q, " - " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", - zCookie, zIpAddr, expires, uid - ); + int expires = atoi(zExpire)*3600; + const char *zIpAddr = PD("REMOTE_ADDR","nil"); + + if( strcmp(zUsername, "anonymous")==0 ){ + cgi_set_cookie(zCookieName, "anonymous", 0, expires); + }else{ + zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid); + cgi_set_cookie(zCookieName, zCookie, 0, expires); + db_multi_exec( + "UPDATE user SET cookie=%Q, ipaddr=%Q, " + " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", + zCookie, zIpAddr, expires, uid + ); + } cgi_redirect(zGoto); } } style_header("Login/Logout"); @ %s(zErrMsg) @@ -127,32 +151,40 @@ @ <tr> @ <td></td> @ <td><input type="submit" name="in" value="Login"></td> @ </tr> @ </table> - if( g.isAnon || g.zLogin==0 || g.zLogin[0]==0 ){ + if( g.zLogin==0 ){ @ <p>To login }else{ @ <p>You are current logged in as <b>%h(g.zLogin)</b></p> @ <p>To change your login to a different user } @ enter the user-id and password at the left and press the @ "Login" button. Your user name will be stored in a browser cookie. @ You must configure your web browser to accept cookies in order for @ the login to take.</p> - if( db_exists("SELECT uid FROM user WHERE login='anonymous'") ){ - @ <p>This server is configured to allow limited access to users - @ who are not logged in.</p> + if( g.zLogin==0 ){ + zAnonPw = db_text(0, "SELECT pw FROM user" + " WHERE login='anonymous'" + " AND cap!=''"); + if( zAnonPw ){ + @ <p>If you do not have a user-id, enter "<b>anonymous</b>" with a + @ password of "<b>%h(zAnonPw)</b>".</p> + }else{ + @ <p>A valid user-id and password is required. Anonymous access + @ is not allowed on this installation.</p> + } } - if( !g.isAnon ){ + if( g.zLogin ){ @ <br clear="both"><hr> @ <p>To log off the system (and delete your login cookie) @ press the following button:<br> @ <input type="submit" name="out" value="Logout"></p> } @ </form> - if( !g.isAnon ){ + if( g.okPassword ){ @ <br clear="both"><hr> @ <p>To change your password, enter your old password and your @ new password twice below then press the "Change Password" @ button.</p> @ <form action="login" method="POST"> @@ -184,11 +216,11 @@ const char *zCookie; const char *zRemoteAddr; const char *zCap = 0; /* Only run this check once. */ - if( g.zLogin!=0 ) return; + if( g.userUid!=0 ) return; /* If the HTTP connection is coming over 127.0.0.1 and if ** local login is disabled, then there is no need to check ** user credentials. @@ -198,45 +230,50 @@ && db_get_int("authenticate-localhost",1)==0 ){ uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'"); g.zLogin = db_text("?", "SELECT login FROM user WHERE uid=%d", uid); zCap = "s"; g.noPswd = 1; - g.isAnon = 0; } /* Check the login cookie to see if it matches a known valid user. */ - if( uid==0 ){ - if( (zCookie = P(login_cookie_name()))!=0 ){ + if( uid==0 && (zCookie = P(login_cookie_name()))!=0 ){ + if( isdigit(zCookie[0]) ){ uid = db_int(0, "SELECT uid FROM user" " WHERE uid=%d" " AND cookie=%Q" " AND ipaddr=%Q" " AND cexpire>julianday('now')", atoi(zCookie), zCookie, zRemoteAddr ); - }else{ + }else if( zCookie[0]=='a' ){ uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'"); } } if( uid==0 ){ - g.isAnon = 1; - g.zLogin = ""; - zCap = db_get("nologin-cap","onrj"); - }else if( zCap==0 ){ - Stmt s; - db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid); - db_step(&s); - g.zLogin = db_column_malloc(&s, 0); - zCap = db_column_malloc(&s, 1); - g.isAnon = 0; - db_finalize(&s); + uid = db_int(0, "SELECT uid FROM user WHERE login='nobody'"); + if( uid==0 ){ + uid = -1; + zCap = ""; + } + } + if( zCap==0 ){ + if( uid ){ + Stmt s; + db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid); + db_step(&s); + g.zLogin = db_column_malloc(&s, 0); + zCap = db_column_malloc(&s, 1); + db_finalize(&s); + } + if( zCap==0 ){ + zCap = ""; + } } g.userUid = uid; - login_set_capabilities(zCap); } /* ** Set the global capability flags based on a capability string.
Modified src/main.c from [fa34f0baa1] to [21f5fffa72].
@@ -74,11 +74,10 @@ char *urlUser; /* User id for http: */ char *urlPasswd; /* Password for http: */ char *urlCanonical; /* Canonical representation of the URL */ const char *zLogin; /* Login name. "" if not logged in. */ - int isAnon; /* True if logged in anoymously */ int noPswd; /* Logged in without password (on 127.0.0.1) */ int userUid; /* Integer user id */ /* Information used to populate the RCVFROM table */ int rcvid; /* The rcvid. 0 if not yet defined. */
Modified src/setup.c from [91d49b89a0] to [288da0d25b].
@@ -81,11 +81,11 @@ void setup_ulist(void){ Stmt s; style_footer(); login_check_credentials(); - if( !g.okWrite || g.isAnon ){ + if( !g.okSetup ){ login_needed(); return; } style_submenu_element("Add", "Add User", "setup_uedit"); @@ -371,24 +371,27 @@ @ formats, and change system defaults. But only the <b>Setup</b> user @ is able to change the repository to @ which this program is linked. @ </p></li> @ - if( zId==0 || strcmp(zId,"anonymous")==0 ){ - @ <li><p> - @ No login is required for user "<b>anonymous</b>". The capabilities - @ of this user are available to anyone without supplying a username or - @ password. To disable anonymous access, make sure there is no user - @ with an ID of <b>anonymous</b>. - @ </p></li> - @ - @ <li><p> - @ The password for the "<b>anonymous</b>" user is used for anonymous - @ access. The recommended value for the anonymous password - @ is "anonymous". - @ </p></li> - } + @ <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 the noloing user is ignore. + @ </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 no any + @ spider. + @ </p></li> @ </form> style_footer(); }
Modified src/style.c from [7b2fdcfed5] to [ed5f94f215].
@@ -76,11 +76,11 @@ @ <body bgcolor="white"> @ <hr size="1"> @ <table border="0" cellpadding="0" cellspacing="0" width="100%%"> @ <tr><td valign="top" align="left"> @ <big><big><b>%s(zTitle)</b></big></big><br> - if( g.zLogin==0 || g.zLogin[0]==0 ){ + if( g.zLogin==0 ){ @ <small>not logged in</small> zLogInOut = "Login"; }else{ @ <small>logged in as %h(g.zLogin)</small> }