commit - 444134c06cbc0ad8b7366aba187ea98566b758a5
commit + 4267117b60d80255740be96d5077585dc6fca353
blob - d0ea33ff297130b499703d8f068c954783abcdb3
blob + 92b8b6e1ead43b0bcc59c1e691a49c49be6c0698
--- Makefile
+++ Makefile
SRCS+=bridge.c tunnel.c media.c sysctl.c passwd.c pfsync.c carp.c
SRCS+=trunk.c who.c more.c stringlist.c utils.c sqlite3.c ppp.c prompt.c
SRCS+=nopt.c pflow.c wg.c nameserver.c ndp.c umb.c utf8.c cmdargs.c ctlargs.c
-SRCS+=helpcommands.c makeargv.c
+SRCS+=helpcommands.c makeargv.c syslog.c
CLEANFILES+=compile.c
LDADD=-lutil -ledit -ltermcap -lsqlite3 -L/usr/local/lib #-static
blob - 2c6b28c32e26056d4f1939cbe118d5492a29d10d
blob + 226fed59c36b42ba4f74c649eff6bb1d3647f4ee
--- commands.c
+++ commands.c
static int setenvcmd(int, char **);
static int unsetenvcmd(int, char **);
static int shell(int, char*[]);
+static int syslog_cmd(int, char *[], char *);
static int ping(int, char*[]);
static int ping6(int, char*[]);
static int traceroute(int, char*[]);
sshhelp[] = "SSH connection to remote host",
telnethelp[] = "Telnet connection to remote host",
crontabhelp[] = "Configure scheduled background jobs",
+ sysloghelp[] = "Configure system logging",
quithelp[] = "Close current connection",
exithelp[] = "Leave configuration mode and return to privileged mode",
verbosehelp[] = "Set verbose diagnostics",
{ "motd", motdhelp, CMPL(t) (char **)ctl_motd, ssctl, ctlhandler, 1, 1, 0, 1 },
{ "crontab", crontabhelp, CMPL(t) (char **)ctl_crontab, ssctl, ctlhandler, 1, 1, 0, 1 },
{ "scheduler", crontabhelp, CMPL(t) (char **)ctl_crontab, ssctl, ctlhandler, 1, 1, 0, 1 },
+ { "syslog", sysloghelp, CMPL0 NULL, 0, syslog_cmd, 1, 1, 1, 0 },
{ "inet", inethelp, CMPL(t) (char **)ctl_inet, ssctl, ctlhandler, 1, 1, 0, 1 },
{ "ping", pinghelp, CMPL0 0, 0, ping, 0, 0, 0, 0 },
{ "ping6", ping6help, CMPL0 0, 0, ping6, 0, 0, 0, 0 },
child = -1;
return 1;
+}
+
+/*
+ * syslog command.
+ */
+static int
+syslog_cmd(int argc, char *argv[], char *unused)
+{
+ int set = 1;
+
+ if (argc < 1) {
+ printf("%% Invalid arguments\n");
+ return 1;
+ }
+
+ if (NO_ARG(argv[0])) {
+ set = 0;
+ argc--;
+ argv++;
+ }
+
+ if (argc == 1) {
+ if (set) {
+ if (syslog_is_enabled())
+ return 0;
+ syslog_enable();
+ } else {
+ if (syslog_is_disabled())
+ return 0;
+ syslog_disable();
+ }
+
+ printf("%% system logging will be %s as soon as the "
+ "\"syslog reload\" command is run\n",
+ set ? "enabled" : "disabled");
+ return 0;
+ }
+
+ if (isprefix(argv[1], "reload")) {
+ if (argc != 2) {
+ printf("%% Invalid arguments\n");
+ return 1;
+ }
+ syslog_reload();
+ return 0;
+ }
+
+ if (isprefix(argv[1], "udp-af")) {
+ if (set) {
+ if (argc != 3) {
+ printf("%% Invalid arguments\n");
+ return 1;
+ }
+ if (isprefix(argv[2], "inet4"))
+ syslog_udp_af_v4();
+ else if (isprefix(argv[2], "inet6"))
+ syslog_udp_af_v6();
+ else {
+ printf("%% invalid UDP address family %s\n",
+ argv[2]);
+ return 1;
+ }
+ } else {
+ if (argc != 2) {
+ printf("%% Invalid arguments\n");
+ return 1;
+ }
+ syslog_udp_af_disable();
+ }
+ } else {
+ printf("%% Invalid arguments\n");
+ return 1;
+ }
+
+ return 0;
}
/*
blob - 84ff64c42be556f8392417b7ba5f35c45332fff5
blob + d00bceecd642cedddf69c7a9abf21417dd5da150
--- conf.c
+++ conf.c
int default_llpriority(char *);
int islateif(char *);
int isdefaultroute(struct sockaddr *, struct sockaddr *);
-int scantext(char *, char *);
int ipv6ll_db_compare(struct sockaddr_in6 *, struct sockaddr_in6 *,
char *);
fprintf(output, "!\n");
conf_nameserver(output);
+
+ fprintf(output, "!\n");
+ conf_syslog(output);
return(0);
}
blob - 98be4c1f2a50bf22257eacd7a22db984d21c26e7
blob + 7863546b0296f84a69797ca438c9405e737071d8
--- externs.h
+++ externs.h
int conf_routes(FILE *, char *, int, int, int);
int conf_dhcrelay(char *, char *, int);
int dhcpleased_has_address(char *, const char *, const char *);
+int scantext(char *, char *);
/* show.c */
void p_rttables(int, u_int, int);
#define HALT "/sbin/halt"
#define SU "/usr/bin/su"
#define DOAS "/usr/bin/doas"
+#define RCCTL "/usr/sbin/rcctl"
#define SAVESCRIPT "/usr/local/bin/save.sh"
#ifndef DHCPLEASES
#define DHCPLEASES "/var/db/dhcpd.leases"
/* ctlargs.c */
int pr_prot1(int, char **);
char **step_optreq(char **, char **, int, char **, int);
+
+/* syslog.c */
+void syslog_enable(void);
+int syslog_is_enabled(void);
+void syslog_disable(void);
+int syslog_is_disabled(void);
+void syslog_udp_af_disable(void);
+void syslog_udp_af_v4(void);
+void syslog_udp_af_v6(void);
+void syslog_reload(void);
+void syslog_stop(void);
+void conf_syslog(FILE *);
blob - 746039c12f247f72374cc49c9792c96bcbe0ed52
blob + dfc6b3e3aefb2ff0426854de58f389e220ce5f16
--- main.c
+++ main.c
printf("%% database pppoeipaddrmode creation failed\n");
if (db_create_table_flag_x("pin") < 0)
printf("%% database pin creation failed\n");
+ if (db_create_table_flag_x("syslog") < 0)
+ printf("%% database syslog table creation failed\n");
if (iflag) {
/*
blob - /dev/null
blob + 50a0ccf832a0ce794a40f59bf5f1bbe304fe99cc (mode 644)
--- /dev/null
+++ syslog.c
+/*
+ * Copyright (c) 2023 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "stringlist.h"
+#include "externs.h"
+
+void
+syslog_enable(void)
+{
+ /* prevent duplicate rows */
+ if (db_delete_flag_x_ctl("ctl", "syslog", 0) < 0)
+ printf("%% database deletion failure: ctl syslog\n");
+
+ if (db_insert_flag_x("ctl", "syslog", 0, DB_X_ENABLE, "") < 0)
+ printf("%% database insert failure: ctl syslog enable\n");
+}
+
+int
+syslog_is_enabled(void)
+{
+ int dbflag;
+
+ dbflag = db_select_flag_x_dbflag_rtable("ctl", "syslog", 0);
+ return (dbflag < 0 || dbflag == DB_X_ENABLE);
+}
+
+void
+syslog_disable(void)
+{
+ /* prevent duplicate rows */
+ if (db_delete_flag_x_ctl("ctl", "syslog", 0) < 0)
+ printf("%% database deletion failure: ctl syslog\n");
+
+ if (db_insert_flag_x("ctl", "syslog", 0, DB_X_DISABLE_ALWAYS, "") < 0)
+ printf("%% database insert failure: ctl syslog disable\n");
+}
+
+int
+syslog_is_disabled(void)
+{
+ int dbflag;
+
+ dbflag = db_select_flag_x_dbflag_rtable("ctl", "syslog", 0);
+ return (dbflag == DB_X_DISABLE_ALWAYS);
+}
+
+void
+syslog_udp_af_disable(void)
+{
+ if (db_delete_flag_x_ctl("syslog", "udp-af", 0) < 0)
+ printf("%% database delete failure syslog udp-af\n");
+}
+
+void
+syslog_udp_af_v4(void)
+{
+ syslog_udp_af_disable(); /* prevent duplicate rows */
+
+ if (db_insert_flag_x("syslog", "udp-af", 0, 0, "-4") < 0)
+ printf("%% database insert failure: syslog udp-af v4\n");
+}
+
+void
+syslog_udp_af_v6(void)
+{
+ syslog_udp_af_disable(); /* prevent duplicate rows */
+
+ if (db_insert_flag_x("syslog", "udp-af", 0, 0, "-6") < 0)
+ printf("%% database insert failure: syslog udp-af v6\n");
+}
+
+void
+conf_syslog(FILE *output)
+{
+ int dbflag;
+ StringList *data;
+ int reload = 0;
+
+ dbflag = db_select_flag_x_dbflag_rtable("ctl", "syslog", 0);
+ if (dbflag < 0)
+ dbflag = DB_X_ENABLE;
+
+ switch (dbflag) {
+ case DB_X_ENABLE:
+ /* syslogd is enabled unless explicitly disabled */
+ break;
+ case DB_X_DISABLE_ALWAYS:
+ fprintf(output, "no syslog\n");
+ reload = 1;
+ break;
+ default:
+ printf("%% bad ctl syslog flag 0x%x in database\n", dbflag);
+ return;
+ }
+
+ data = sl_init();
+ if (db_select_flag_x_ctl(data, "syslog", "udp-af") < 0) {
+ printf("%% database select failure: syslog udp-af\n");
+ goto done;
+ }
+ if (data->sl_cur) {
+ fprintf(output, "syslog udp-af %s\n", data->sl_str[0]);
+ reload = 1;
+ }
+
+ if (reload)
+ fprintf(output, "syslog reload\n");
+done:
+ sl_free(data, 1);
+}
+
+static int
+run_rcctl(char *argv[], int outfd)
+{
+ int ret;
+
+ ret = cmdargs_output(RCCTL, argv, outfd, -1);
+ if (ret < 0)
+ printf("%% could not run %s\n", RCCTL);
+ return ret;
+}
+
+void
+syslog_stop(void)
+{
+ char *stop_argv[] = { RCCTL, "stop", "syslogd", NULL };
+
+ printf("%% stopping syslogd\n");
+ run_rcctl(stop_argv, -1);
+}
+
+static void
+syslog_start(void)
+{
+ char *start_argv[] = { RCCTL, "start", "syslogd", NULL };
+
+ printf("%% starting syslogd\n");
+ run_rcctl(start_argv, -1);
+}
+
+static int
+daemon_has_status(char *name, char *status)
+{
+ char *argv[] = { RCCTL, "ls", status, NULL };
+ char outpath[PATH_MAX];
+ char text[128];
+ int fd = -1, found = 0, len;
+
+ len = snprintf(text, sizeof(text), "%s\n", name);
+ if (len < 0) {
+ printf("%% snprintf: %s\n", strerror(errno));
+ return 0;
+ }
+ if ((size_t)len >= sizeof(text)) {
+ printf("%% daemon name too long: %s\n", name);
+ return 0;
+ }
+
+ strlcpy(outpath, "/tmp/nsh-XXXXXX", sizeof(outpath));
+ fd = mkstemp(outpath);
+ if (fd == -1) {
+ printf("%% mkstemp: %s\n", strerror(errno));
+ return 0;
+ }
+
+ /* rcctl will exit with code 1 if a daemon is matching */
+ if (run_rcctl(argv, fd) == 1 && scantext(outpath, text))
+ found = 1;
+
+ unlink(outpath);
+ close(fd);
+ return found;
+}
+
+void
+syslog_reload(void)
+{
+ char *setflags_argv[] = { RCCTL, "set", "syslogd", "flags", "", NULL };
+ char *reload_argv[] = { RCCTL, "reload", "syslogd", NULL };
+ char *enable_argv[] = { RCCTL, "enable", "syslogd", NULL };
+ char *disable_argv[] = { RCCTL, "disable", "syslogd", NULL };
+ StringList *data, *flags;
+ char *s = NULL;
+ int i;
+ size_t len = 0;
+
+ if (syslog_is_disabled()) {
+ run_rcctl(disable_argv, -1);
+ if (daemon_has_status("syslogd", "rogue"))
+ syslog_stop();
+ return;
+ }
+
+ data = sl_init();
+ flags = sl_init();
+
+ if (db_select_flag_x_ctl(data, "syslog", "udp-af") < 0) {
+ printf("%% database select failure: syslog udp-af\n");
+ goto done;
+ }
+ if (data->sl_cur) {
+ s = strdup(data->sl_str[0]);
+ if (s == NULL) {
+ printf("%% strdup: %s\n", strerror(errno));
+ goto done;
+ }
+ sl_add(flags, s);
+ }
+
+ for (i = 0; i < flags->sl_cur; i++)
+ len += strlen(flags->sl_str[i]) + 1;
+
+ if (len) {
+ size_t sz = len + 1;
+
+ s = calloc(sz, 1);
+ if (s == NULL) {
+ printf("%% strdup: %s\n", strerror(errno));
+ goto done;
+ }
+ for (i = 0; i < flags->sl_cur; i++) {
+ if (strlcat(s, flags->sl_str[i], sz) >= sz) {
+ printf("%% flags too long\n");
+ goto done;
+ }
+ if (strlcat(s, " ", sz) >= sz) {
+ printf("%% flags too long\n");
+ goto done;
+ }
+ }
+
+ setflags_argv[4] = s;
+ }
+
+ if (run_rcctl(enable_argv, -1) != 0) {
+ printf("%% could not enable syslogd\n");
+ goto done;
+ }
+
+ printf("%% setting syslogd flags: %s\n", setflags_argv[4]);
+ if (run_rcctl(setflags_argv, -1) != 0) {
+ printf("%% could not set syslogd flags\n");
+ goto done;
+ }
+
+ if (daemon_has_status("syslogd", "failed")) {
+ syslog_start();
+ } else {
+ printf("%% reloading syslogd\n");
+ run_rcctl(reload_argv, -1);
+ }
+done:
+ sl_free(data, 1);
+ sl_free(flags, 1);
+ free(s);
+}