From b4b963a130f0828e380144622cfd670b9cac4448 Mon Sep 17 00:00:00 2001 From: Kimmo Suominen Date: Mon, 9 Nov 2020 11:43:46 +0200 Subject: [PATCH 1/2] vidoas: Allow specifying file to edit. Add manual page and license. - Add functionality to edit a file specified on the command line. - Add `-n` option for running prerequisite checks without editing the configuration file. - Install vidoas in `@PREFIX@/sbin` as it is really more of a system maintenance command (run by administrators; requires root privileges for editing the default **doas(1)** configuation file). - Add a manual page (in section `8`). - Release the code under the same MIT-like license as **doas(1)** itself. --- Makefile | 19 ++++++--- vidoas | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- vidoas.8 | 70 +++++++++++++++++++++++++++++++++ 3 files changed, 197 insertions(+), 9 deletions(-) create mode 100644 vidoas.8 diff --git a/Makefile b/Makefile index 47b81bb..068799a 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,9 @@ ifeq ($(UNAME_S),Darwin) MANDIR=$(DESTDIR)$(PREFIX)/share/man endif -all: $(BIN) doas.1.final doas.conf.5.final vidoas.final +FINALS=doas.1.final doas.conf.5.final vidoas.final vidoas.8.final + +all: $(BIN) $(FINALS) $(BIN): $(OBJECTS) $(CC) -o $(BIN) $(OBJECTS) $(LDFLAGS) @@ -64,22 +66,26 @@ y.tab.o: parse.y $(YACC) parse.y $(CC) $(CPPFLAGS) $(CFLAGS) -c y.tab.c -install: $(BIN) doas.1.final doas.conf.5.final vidoas.final +install: $(BIN) $(FINALS) mkdir -p $(DESTDIR)$(PREFIX)/bin cp $(BIN) $(DESTDIR)$(PREFIX)/bin/ chmod 4755 $(DESTDIR)$(PREFIX)/bin/$(BIN) - cp vidoas.final $(DESTDIR)$(PREFIX)/bin/vidoas - chmod 755 $(DESTDIR)$(PREFIX)/bin/vidoas + mkdir -p $(DESTDIR)$(PREFIX)/sbin + cp vidoas.final $(DESTDIR)$(PREFIX)/sbin/vidoas + chmod 755 $(DESTDIR)$(PREFIX)/sbin/vidoas mkdir -p $(MANDIR)/man1 cp doas.1.final $(MANDIR)/man1/doas.1 mkdir -p $(MANDIR)/man5 cp doas.conf.5.final $(MANDIR)/man5/doas.conf.5 + mkdir -p $(MANDIR)/man8 + cp vidoas.8.final $(MANDIR)/man8/vidoas.8 uninstall: rm -f $(DESTDIR)$(PREFIX)/bin/doas - rm -f $(DESTDIR)$(PREFIX)/bin/vidoas + rm -f $(DESTDIR)$(PREFIX)/sbin/vidoas rm -f $(MANDIR)/man1/doas.1 rm -f $(MANDIR)/man5/doas.conf.5 + rm -f $(MANDIR)/man8/vidoas.8 clean: rm -f $(BIN) $(OBJECTS) y.tab.c @@ -90,5 +96,6 @@ clean: doas.1.final: doas.1 doas.conf.5.final: doas.conf.5 vidoas.final: vidoas -doas.1.final doas.conf.5.final vidoas.final: +vidoas.8.final: vidoas.8 +$(FINALS): $(CAT) $^ | $(SED) 's,@DOAS_CONF@,$(DOAS_CONF),g' > $@ diff --git a/vidoas b/vidoas index c9b6514..3031b63 100755 --- a/vidoas +++ b/vidoas @@ -1,4 +1,20 @@ #!/bin/sh + +# Copyright (c) 2020 Kimmo Suominen +# +# 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. + # Edit a temporary copy of the doas.conf file and check it for syntax # errors before installing it as the actual doas.conf file. @@ -12,7 +28,6 @@ PROG="${0##*/}" umask 022 DOAS_CONF=@DOAS_CONF@ -doas_lock_file="${DOAS_CONF}.lck" die() { @@ -37,6 +52,20 @@ get_intr() ' } +owner_of() +{ + local file + file="${1}" + + if stat --version >/dev/null 2>&1 + then + stat -c '%U' "${file}" + else + stat -f '%Su' "${file}" + fi \ + | awk '{print $1; exit}' +} + set_trap_rm() { local file file_list @@ -51,6 +80,82 @@ set_trap_rm() fi } +usage() +{ + cat <&2; exit 1;; + esac +done +shift $((${OPTIND} - 1)) + +case ${#} in +0) ;; +1) DOAS_CONF="${1}";; +*) usage 1>&2; exit 1;; +esac + +case ${noop} in +0) noop=false;; +1) noop=true;; +*) noop=true; exec >/dev/null 2>&1;; +esac + +case "${DOAS_CONF}" in +-*) + warn "Invalid filename: ${DOAS_CONF}" + die "Try using './${DOAS_CONF}' instead" + ;; +esac + +doas_conf_dir="$(dirname "${DOAS_CONF}")" +doas_conf_base="$(basename "${DOAS_CONF}")" +DOAS_CONF="${doas_conf_dir}/${doas_conf_base}" +doas_lock_file="${DOAS_CONF}.lck" + +# These checks are only for producing nicer diagnostic messages to the +# user. They are not relied on by the rest of the code. + +if [ ! -e "${doas_conf_dir}" ] +then + die "${doas_conf_dir} does not exist" +fi + +if [ ! -d "${doas_conf_dir}" ] +then + die "${doas_conf_dir} is not a directory" +fi + +if [ ! -w "${doas_conf_dir}" ] +then + owner="$(owner_of "${doas_conf_dir}")" + warn "${doas_conf_dir} is not writable" + die "You probably need to run ${PROG} as ${owner:-root}" +fi + tmp_doas="$(mktemp "${DOAS_CONF}.XXXXXXXXXX")" \ || die "You probably need to run ${PROG} as root" set_trap_rm "${tmp_doas}" @@ -65,7 +170,7 @@ set_trap_rm "${tmp_doas}" "${tmp_test_ln}" if ln "${tmp_doas}" "${tmp_test_ln}" 2>/dev/null then - die 'ln(1) is not safe for lock files, bailing' + die 'ln(1) is not safe for creating lock files, bailing' fi # If a doas.conf file exists, copy it into the temporary file for @@ -77,10 +182,16 @@ then then cp "${DOAS_CONF}" "${tmp_doas}" else - die "Cannot read ${DOAS_CONF}" + die "${DOAS_CONF} is not readable" fi fi +if ${noop} +then + warn 'OK: Prerequisite checks passed' + exit 0 +fi + # Link the temporary file to the lock file. if ln "${tmp_doas}" "${doas_lock_file}" diff --git a/vidoas.8 b/vidoas.8 new file mode 100644 index 0000000..0a9a3f9 --- /dev/null +++ b/vidoas.8 @@ -0,0 +1,70 @@ +.\" +.\" Copyright (c) 2020 Kimmo Suominen +.\" +.\" 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. +.\" +.Dd November 9, 2020 +.Dt VIDOAS 1 +.Os +.Sh NAME +.Nm vidoas +.Nd edit a doas configuration file +.Sh SYNOPSIS +.Nm +.Op Fl n +.Op Ar file +.Nm +.Fl h +.Sh DESCRIPTION +The +.Nm +utility opens an editor on a temporary copy of a +.Xr doas 1 +configuration file and checks it for syntax errors before installing it +as the actual configuration file. +.Pp +The options are as follows: +.Bl -tag -width EDITOR +.It Fl h +Show a usage message. +.It Fl n +Do not edit the file, just perform prerequisite checks. +If this switch is repeated, all output will be suppressed and the check +result is only indicated by the exit status. +.El +.Sh EXIT STATUS +.Ex -std +.Sh ENVIRONMENT +.Bl -tag -width EDITOR +.It Ev EDITOR +The editor command used for editing the configuration file. +If the +.Ev EDITOR +environment variable is null or not set, the +.Xr vi 1 +editor program will be used. +.El +.Sh FILES +.Bl -tag -width EDITOR +.It Pa @DOAS_CONF@ +The default configuration file to edit, when no +.Ar file +argument is specified. +.El +.Sh SEE ALSO +.Xr doas 1 , +.Xr doas.conf 5 +.Sh AUTHORS +.An Kimmo Suominen Aq Mt kim@netbsd.org From f807ff888d0383b5437f9857318261c135612cd6 Mon Sep 17 00:00:00 2001 From: Kimmo Suominen Date: Mon, 9 Nov 2020 11:54:04 +0200 Subject: [PATCH 2/2] Account correctly for the -h option --- vidoas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vidoas b/vidoas index 3031b63..3d95278 100755 --- a/vidoas +++ b/vidoas @@ -102,11 +102,11 @@ EOF noop=0 -while getopts n opt +while getopts hn opt do case "${opt}" in - n) noop=$((${noop} + 1));; h) usage; exit 0;; + n) noop=$((${noop} + 1));; *) usage 1>&2; exit 1;; esac done