Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | More checking of user permissions on the Security Audit page. |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
564e42dfe577d60983345042dea1d358 |
| User & Date: | drh 2017-07-01 22:17:46.843 |
Context
|
2017-07-01
| ||
| 22:38 | Add the cgi_referer() utility function. Use it to cause the setup_uedit page to always go back to the page it came from. check-in: 59a51b8267 user: drh tags: trunk | |
| 22:17 | More checking of user permissions on the Security Audit page. check-in: 564e42dfe5 user: drh tags: trunk | |
| 19:36 | Update the change log to mention recent enhancements. check-in: 8fe2f97ea1 user: drh tags: trunk | |
Changes
Changes to src/security_audit.c.
| ︙ | ︙ | |||
185 186 187 188 189 190 191 |
}else{
@ <li><p>
@ Anonymous users can create or edit wiki, but moderator
@ approval is required before the edits become permanent.
}
}
| | > | | > > > > > > > > > > > > > > > > > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | > | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
}else{
@ <li><p>
@ Anonymous users can create or edit wiki, but moderator
@ approval is required before the edits become permanent.
}
}
/* Administrative privilege should only be provided to
** specific individuals, not to entire classes of people.
** And not too many people should have administrator privilege.
*/
z = db_text(0, "SELECT group_concat(login,' AND ') FROM user"
" WHERE cap GLOB '*[as]*'"
" AND login in ('anonymous','nobody','reader','developer')");
if( z && z[0] ){
@ <li><p>
@ Adminstrative privilege is granted to an entire class of users
@ (%h(z)). Ideally, the Write-Unver privilege should only be
@ granted to specific individuals.
}
n = db_int(0,"SELECT count(*) FROM user WHERE cap GLOB '*[as]*'");
if( n==0 ){
@ <li><p>
@ No users have administrator privilege.
}else{
z = db_text(0,
"SELECT group_concat("
"printf('<a href=''setup_uedit?id=%%d''>%%s</a>',uid,login),"
"', ')"
" FROM user"
" WHERE cap GLOB '*[as]*'"
);
@ <li><p>
@ Users with administrator privilege are: %s(z)
fossil_free(z);
if( n>3 ){
@ <p><b>Caution</b>:
@ Administrator privilege is granted to
@ <a href='setup_ulist?with=as'>%d(n) users</a>.
@ Ideally, administator privilege ('s' or 'a') should only
@ be granted to one or two users.
}
}
/* The push-unversioned privilege should only be provided to
** specific individuals, not to entire classes of people.
** And no too many people should have this privilege.
*/
z = db_text(0,
"SELECT group_concat("
"printf('<a href=''setup_uedit?id=%%d''>%%s</a>',uid,login),"
"' and ')"
" FROM user"
" WHERE cap GLOB '*y*'"
" AND login in ('anonymous','nobody','reader','developer')"
);
if( z && z[0] ){
@ <li><p>
@ The "Write-Unver" privilege is granted to an entire class of users
@ (%s(z)). Ideally, the Write-Unver privilege should only be
@ granted to specific individuals.
fossil_free(z);
}
n = db_int(0,"SELECT count(*) FROM user WHERE cap GLOB '*y*'");
if( n>3 ){
@ <li><p>
}else if( n>0 ){
z = db_text(0,
"SELECT group_concat("
"printf('<a href=''setup_uedit?id=%%d''>%%s</a>',uid,login),', ')"
" FROM user WHERE cap GLOB '*y*'"
);
@ <li><p>
@ Users with "Write-Unver" privilege: %s(z)
fossil_free(z);
if( n>3 ){
@ <p><b>Caution:</b>
@ The "Write-Unver" privilege ('y') is granted to an excessive
@ number of users (%d(n)).
@ Ideally, the Write-Unver privilege should only
@ be granted to one or two users.
}
}
/* Notify if REMOTE_USER or HTTP_AUTHENTICATION is used for login.
*/
if( db_get_boolean("remote_user_ok", 0) ){
@ <li><p>
@ This repository trusts that the REMOTE_USER environment variable set
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
}
/*
** WEBPAGE: setup_ulist
**
** Show a list of users. Clicking on any user jumps to the edit
** screen for that user. Requires Admin privileges.
*/
void setup_ulist(void){
Stmt s;
double rNow;
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
| > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > > | | | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
}
/*
** WEBPAGE: setup_ulist
**
** Show a list of users. Clicking on any user jumps to the edit
** screen for that user. Requires Admin privileges.
**
** Query parameters:
**
** with=CAP Only show users that have one or more capabilities in CAP.
*/
void setup_ulist(void){
Stmt s;
double rNow;
const char *zWith = P("with");
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
if( zWith==0 || zWith[0]==0 ){
style_submenu_element("Add", "setup_uedit");
style_submenu_element("Log", "access_log");
style_submenu_element("Help", "setup_ulist_notes");
style_header("User List");
@ <table border=1 cellpadding=2 cellspacing=0 class='userTable'>
@ <thead><tr>
@ <th>UID <th>Category
@ <th>Capabilities (<a href='%R/setup_ucap_list'>key</a>)
@ <th>Info <th>Last Change</tr></thead>
@ <tbody>
db_prepare(&s,
"SELECT uid, login, cap, date(mtime,'unixepoch')"
" FROM user"
" WHERE login IN ('anonymous','nobody','developer','reader')"
" ORDER BY login"
);
while( db_step(&s)==SQLITE_ROW ){
int uid = db_column_int(&s, 0);
const char *zLogin = db_column_text(&s, 1);
const char *zCap = db_column_text(&s, 2);
const char *zDate = db_column_text(&s, 4);
@ <tr>
@ <td><a href='setup_uedit?id=%d(uid)'>%d(uid)</a>
@ <td><a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a>
@ <td>%h(zCap)
if( fossil_strcmp(zLogin,"anonymous")==0 ){
@ <td>All logged-in users
}else if( fossil_strcmp(zLogin,"developer")==0 ){
@ <td>Users with '<b>v</b>' capability
}else if( fossil_strcmp(zLogin,"nobody")==0 ){
@ <td>All users without login
}else if( fossil_strcmp(zLogin,"reader")==0 ){
@ <td>Users with '<b>u</b>' capability
}else{
@ <td>
}
if( zDate && zDate[0] ){
@ <td>%h(zDate)
}else{
@ <td>
}
@ </tr>
}
db_finalize(&s);
}else{
style_header("Users With Capabilities \"%h\"", zWith);
}
@ </tbody></table>
@ <div class='section'>Users</div>
@ <table border=1 cellpadding=2 cellspacing=0 class='userTable' id='userlist'>
@ <thead><tr>
@ <th>ID<th>Login Name<th>Caps<th>Info<th>Date<th>Expire<th>Last Login</tr></thead>
@ <tbody>
db_multi_exec(
"CREATE TEMP TABLE lastAccess(uname TEXT PRIMARY KEY, atime REAL) WITHOUT ROWID;"
);
if( db_table_exists("repository","accesslog") ){
db_multi_exec(
"INSERT INTO lastAccess(uname, atime)"
" SELECT uname, max(mtime) FROM ("
" SELECT uname, mtime FROM accesslog WHERE success"
" UNION ALL"
" SELECT login AS uname, rcvfrom.mtime AS mtime FROM rcvfrom JOIN user USING(uid))"
" GROUP BY 1;"
);
}
if( zWith && zWith[0] ){
zWith = mprintf(" AND cap GLOB '*[%q]*'", zWith);
}else{
zWith = "";
}
db_prepare(&s,
"SELECT uid, login, cap, info, date(mtime,'unixepoch'), lower(login) AS sortkey, "
" CASE WHEN info LIKE '%%expires 20%%'"
" THEN substr(info,instr(lower(info),'expires')+8,10)"
" END AS exp,"
"atime"
" FROM user LEFT JOIN lastAccess ON login=uname"
" WHERE login NOT IN ('anonymous','nobody','developer','reader') %s"
" ORDER BY sortkey", zWith/*safe-for-%s*/
);
rNow = db_double(0.0, "SELECT julianday('now');");
while( db_step(&s)==SQLITE_ROW ){
int uid = db_column_int(&s, 0);
const char *zLogin = db_column_text(&s, 1);
const char *zCap = db_column_text(&s, 2);
const char *zInfo = db_column_text(&s, 3);
|
| ︙ | ︙ | |||
423 424 425 426 427 428 429 |
if( zId && !g.perm.Setup && uid>0 ){
char *zOldCaps;
zOldCaps = db_text(0, "SELECT cap FROM user WHERE uid=%d",uid);
higherUser = zOldCaps && strchr(zOldCaps,'s');
}
if( P("can") ){
| > | | 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
if( zId && !g.perm.Setup && uid>0 ){
char *zOldCaps;
zOldCaps = db_text(0, "SELECT cap FROM user WHERE uid=%d",uid);
higherUser = zOldCaps && strchr(zOldCaps,'s');
}
if( P("can") ){
/* User pressed the cancel button */
cgi_redirect("setup_ulist");
return;
}
/* If we have all the necessary information, write the new or
** modified user record. After writing the user record, redirect
** to the page that displays a list of users.
*/
|
| ︙ | ︙ |