Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Create a separate "Log Menu" page that shows all of the available log files. |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
b28badb7411b90b2203a81212216bc5d |
| User & Date: | drh 2024-03-29 12:41:47.123 |
Context
|
2024-03-29
| ||
| 13:04 | Improved error message for when the error log is unavailable. check-in: e6b06b5d11 user: drh tags: trunk | |
| 12:41 | Create a separate "Log Menu" page that shows all of the available log files. check-in: b28badb741 user: drh tags: trunk | |
| 11:27 | Update the backtrace output formatting to the log file so that it is easy to copy/paste the backtrace hex addresses into an "addr2line" command-line in order to get symbolic names. check-in: daaf9ee79c user: drh tags: trunk | |
Changes
Changes to src/security_audit.c.
| ︙ | ︙ | |||
749 750 751 752 753 754 755 | @ <input type="submit" name="cancel" value="Cancel"> @ </form> style_finish_page(); } /* | | | | < < | 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 |
@ <input type="submit" name="cancel" value="Cancel">
@ </form>
style_finish_page();
}
/*
** The maximum number of bytes of the error log to show by default.
*/
#define MXSHOWLOG 500000
/*
** WEBPAGE: errorlog
**
** Show the content of the error log. Only the administrator can view
** this page.
*/
void errorlog_page(void){
i64 szFile;
FILE *in;
char z[10000];
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_header("Server Error Log");
style_submenu_element("Test", "%R/test-warning");
style_submenu_element("Refresh", "%R/errorlog");
style_submenu_element("Log-Menu", "%R/setup-logmenu");
if( g.zErrlog==0 || fossil_strcmp(g.zErrlog,"-")==0 ){
@ <p>To create a server error log:
@ <ol>
@ <li><p>
@ If the server is running as CGI, then create a line in the CGI file
@ like this:
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
47 48 49 50 51 52 53 |
void setup_menu_entry(
const char *zTitle,
const char *zLink,
const char *zDesc
){
@ <tr><td valign="top" align="right">
if( zLink && zLink[0] ){
| | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
void setup_menu_entry(
const char *zTitle,
const char *zLink,
const char *zDesc
){
@ <tr><td valign="top" align="right">
if( zLink && zLink[0] ){
@ <a href="%s(zLink)"><nobr>%h(zTitle)</nobr></a>
}else{
@ %h(zTitle)
}
@ </td><td width="5"></td><td valign="top">%h(zDesc)</td></tr>
}
|
| ︙ | ︙ | |||
158 159 160 161 162 163 164 |
setup_menu_entry("Web-Cache", "cachestat",
"View the status of the expensive-page cache");
}
setup_menu_entry("Logo", "setup_logo",
"Change the logo and background images for the server");
setup_menu_entry("Shunned", "shun",
"Show artifacts that are shunned by this repository");
| < < | < < | < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
setup_menu_entry("Web-Cache", "cachestat",
"View the status of the expensive-page cache");
}
setup_menu_entry("Logo", "setup_logo",
"Change the logo and background images for the server");
setup_menu_entry("Shunned", "shun",
"Show artifacts that are shunned by this repository");
setup_menu_entry("Log Files", "setup-logmenu",
"A menu of available log files");
setup_menu_entry("Unversioned Files", "uvlist?byage=1",
"Show all unversioned files held");
setup_menu_entry("Stats", "stat",
"Repository Status Reports");
setup_menu_entry("Sitemap", "sitemap",
"Links to miscellaneous pages");
if( setup_user ){
setup_menu_entry("SQL", "admin_sql",
"Enter raw SQL commands");
setup_menu_entry("TH1", "admin_th1",
"Enter raw TH1 commands");
}
@ </table>
style_finish_page();
}
/*
** WEBPAGE: setup-logmenu
**
** Show a menu of available log renderings accessible to an administrator,
** together with a succinct explanation of each.
**
** This page is only accessible by administrators.
*/
void setup_logmenu_page(void){
Blob desc;
blob_init(&desc, 0, 0);
/* Administrator access only */
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_header("Log Menu");
@ <table border="0" cellspacing="3">
setup_menu_entry("Admin Log", "admin_log",
"The admin log records configuration changes to the repository.\n"
"The admin log is stored in the \"admin_log\" table of the repository.\n"
);
setup_menu_entry("Artifact Log", "rcvfromlist",
"The artifact log records when new content is added to the repository.\n"
"The time and date and origin of the new content is entered into the\n"
"Log. The artifact log is always on and is stored in the \"rcvfrom\"\n"
"table of the repository.\n"
);
blob_appendf(&desc,
"The error log is a separate text file to which warning and error\n"
"messages are appended. A single error log can and often is shared\n"
"across multiple repositories.\n"
);
if( g.zErrlog==0 || fossil_strcmp(g.zErrlog,"-")==0 ){
blob_appendf(&desc,"The error log is disabled for this repository.");
}else{
blob_appendf(&desc,"In this repository, the error log is in the file"
"named \"%s\".", g.zErrlog);
}
setup_menu_entry("Error Log", "errorlog", blob_str(&desc));
blob_reset(&desc);
setup_menu_entry("User Log", "user_log",
"The user log is a record of login attempts. The user log is stored\n"
"in the \"accesslog\" table of the respository.\n"
);
@ </table>
style_finish_page();
}
/*
** Generate a checkbox for an attribute.
*/
void onoff_attribute(
const char *zLabel, /* The text label on the checkbox */
const char *zVar, /* The corresponding row in the CONFIG table */
const char *zQParm, /* The query parameter */
|
| ︙ | ︙ | |||
1960 1961 1962 1963 1964 1965 1966 |
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_set_current_feature("setup");
style_header("Admin Log");
| | < < | 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 |
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_set_current_feature("setup");
style_header("Admin Log");
style_submenu_element("Log-Menu", "setup-logmenu");
create_admin_log_table();
limit = atoi(PD("n","200"));
ofst = atoi(PD("x","0"));
fLogEnabled = db_get_boolean("admin-log", 0);
@ <div>Admin logging is %s(fLogEnabled?"on":"off").
@ (Change this on the <a href="setup_settings">settings</a> page.)</div>
|
| ︙ | ︙ |
Changes to src/shun.c.
| ︙ | ︙ | |||
372 373 374 375 376 377 378 |
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_header("Artifact Receipts");
| | < < | 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_header("Artifact Receipts");
style_submenu_element("Log-Menu", "setup-logmenu");
if( showAll ){
ofst = 0;
}else{
style_submenu_element("All", "rcvfromlist?all=1");
}
if( ofst>0 ){
style_submenu_element("Newer", "rcvfromlist?ofst=%d",
|
| ︙ | ︙ |
Changes to src/user.c.
| ︙ | ︙ | |||
665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 |
iVerify = atoi(g.argv[3]);
prompt_for_password(g.argv[2], &answer, iVerify);
fossil_print("[%s]\n", blob_str(&answer));
}
/*
** WEBPAGE: access_log
**
** Show login attempts, including timestamp and IP address.
** Requires Admin privileges.
**
** Query parameters:
**
** y=N 1: success only. 2: failure only. 3: both (default: 3)
** n=N Number of entries to show (default: 200)
** o=N Skip this many entries (default: 0)
*/
| > | | | | | | | < < | | | | | | | | | 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 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 |
iVerify = atoi(g.argv[3]);
prompt_for_password(g.argv[2], &answer, iVerify);
fossil_print("[%s]\n", blob_str(&answer));
}
/*
** WEBPAGE: access_log
** WEBPAGE: user_log
**
** Show login attempts, including timestamp and IP address.
** Requires Admin privileges.
**
** Query parameters:
**
** y=N 1: success only. 2: failure only. 3: both (default: 3)
** n=N Number of entries to show (default: 200)
** o=N Skip this many entries (default: 0)
*/
void user_log_page(void){
int y = atoi(PD("y","3"));
int n = atoi(PD("n","200"));
int skip = atoi(PD("o","0"));
const char *zUser = P("u");
Blob sql;
Stmt q;
int cnt = 0;
int rc;
int fLogEnabled;
login_check_credentials();
if( !g.perm.Admin ){ login_needed(0); return; }
create_accesslog_table();
if( P("delall") && P("delallbtn") ){
db_multi_exec("DELETE FROM accesslog");
cgi_redirectf("%R/user_log?y=%d&n=%d&o=%o", y, n, skip);
return;
}
if( P("delanon") && P("delanonbtn") ){
db_multi_exec("DELETE FROM accesslog WHERE uname='anonymous'");
cgi_redirectf("%R/user_log?y=%d&n=%d&o=%o", y, n, skip);
return;
}
if( P("delfail") && P("delfailbtn") ){
db_multi_exec("DELETE FROM accesslog WHERE NOT success");
cgi_redirectf("%R/user_log?y=%d&n=%d&o=%o", y, n, skip);
return;
}
if( P("delold") && P("deloldbtn") ){
db_multi_exec("DELETE FROM accesslog WHERE rowid in"
"(SELECT rowid FROM accesslog ORDER BY rowid DESC"
" LIMIT -1 OFFSET 200)");
cgi_redirectf("%R/user_log?y=%d&n=%d", y, n);
return;
}
style_header("User Log");
style_submenu_element("Log-Menu", "setup-logmenu");
blob_zero(&sql);
blob_append_sql(&sql,
"SELECT uname, ipaddr, datetime(mtime,toLocal()), success"
" FROM accesslog"
);
if( zUser ){
blob_append_sql(&sql, " WHERE uname=%Q", zUser);
n = 1000000000;
skip = 0;
}else if( y==1 ){
blob_append(&sql, " WHERE success", -1);
}else if( y==2 ){
blob_append(&sql, " WHERE NOT success", -1);
}
blob_append_sql(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip);
if( skip ){
style_submenu_element("Newer", "%R/user_log?o=%d&n=%d&y=%d",
skip>=n ? skip-n : 0, n, y);
}
rc = db_prepare_ignore_error(&q, "%s", blob_sql_text(&sql));
fLogEnabled = db_get_boolean("access-log", 0);
@ <div align="center">User logging is %s(fLogEnabled?"on":"off").
@ (Change this on the <a href="setup_settings">settings</a> page.)</div>
@ <table border="1" cellpadding="5" class="sortable" align="center" \
@ data-column-types='Ttt' data-init-sort='1'>
@ <thead><tr><th width="33%%">Date</th><th width="34%%">User</th>
@ <th width="33%%">IP Address</th></tr></thead><tbody>
while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
const char *zIP = db_column_text(&q, 1);
const char *zDate = db_column_text(&q, 2);
int bSuccess = db_column_int(&q, 3);
cnt++;
if( cnt>n ){
style_submenu_element("Older", "%R/user_log?o=%d&n=%d&y=%d",
skip+n, n, y);
break;
}
if( bSuccess ){
@ <tr>
}else{
@ <tr bgcolor="#ffacc0">
}
@ <td>%s(zDate)</td><td>%h(zName)</td><td>%h(zIP)</td></tr>
}
if( skip>0 || cnt>n ){
style_submenu_element("All", "%R/user_log?n=10000000");
}
@ </tbody></table>
db_finalize(&q);
@ <hr>
@ <form method="post" action="%R/user_log">
@ <label><input type="checkbox" name="delold">
@ Delete all but the most recent 200 entries</input></label>
@ <input type="submit" name="deloldbtn" value="Delete"></input>
@ </form>
@ <form method="post" action="%R/user_log">
@ <label><input type="checkbox" name="delanon">
@ Delete all entries for user "anonymous"</input></label>
@ <input type="submit" name="delanonbtn" value="Delete"></input>
@ </form>
@ <form method="post" action="%R/user_log">
@ <label><input type="checkbox" name="delfail">
@ Delete all failed login attempts</input></label>
@ <input type="submit" name="delfailbtn" value="Delete"></input>
@ </form>
@ <form method="post" action="%R/user_log">
@ <label><input type="checkbox" name="delall">
@ Delete all entries</input></label>
@ <input type="submit" name="delallbtn" value="Delete"></input>
@ </form>
style_table_sorter();
style_finish_page();
}
|