diff --git a/Makefile b/Makefile index 3fdd1b0..f163826 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ ifeq ($(UNAME_S),Darwin) MANDIR=$(DESTDIR)$(PREFIX)/share/man endif -FINALS=doas.1.final doas.conf.5.final vidoas.final vidoas.8.final +FINALS=doas.1.final doas.conf.5.final vidoas.final vidoas.8.final all: $(BIN) $(FINALS) @@ -72,19 +72,24 @@ install: $(BIN) $(FINALS) chmod 4755 $(DESTDIR)$(PREFIX)/bin/$(BIN) cp vidoas.final $(DESTDIR)$(PREFIX)/bin/vidoas chmod 755 $(DESTDIR)$(PREFIX)/bin/vidoas + cp doasedit $(DESTDIR)$(PREFIX)/bin/doasedit + chmod 755 $(DESTDIR)$(PREFIX)/bin/doasedit 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 + cp doasedit.8 $(MANDIR)/man8/doasedit.8 uninstall: rm -f $(DESTDIR)$(PREFIX)/bin/doas rm -f $(DESTDIR)$(PREFIX)/bin/vidoas + rm -f $(DESTDIR)$(PREFIX)/bin/doasedit rm -f $(MANDIR)/man1/doas.1 rm -f $(MANDIR)/man5/doas.conf.5 rm -f $(MANDIR)/man8/vidoas.8 + rm -f $(MANDIR)/man8/doasedit.8 clean: rm -f $(BIN) $(OBJECTS) y.tab.c diff --git a/README.md b/README.md index 0d59b68..3815912 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,11 @@ Create a new file in the root user's home: doas touch /root/new-file +Edit a text file which requires admin access without running the text editor +as the root user: + + doasedit /path/to/text/file + On Linux versions of doas prior to 6.3p1 required commands with arguments to be prefixed by a double-dash (--). From 6.3p1 and onward the double-dash is no longer required. Here we remove a directory owned by root: doas -- rm -rf old-directory diff --git a/doasedit b/doasedit new file mode 100755 index 0000000..f8f8e81 --- /dev/null +++ b/doasedit @@ -0,0 +1,86 @@ +#!/bin/sh +# Copy an existing text file to a temporary location. Then +# Edit the file. +# Attempt to then transfer the temporary file back to the original +# location if the temprary file has been altered. +# Conclude with a little clean-up. +# Try to avoid deleting any changes. + +if [ $# -lt 1 ] +then + echo "usage: $0 text-file" + exit 1 +fi + +if [ ! -f "$1" ] +then + echo "File does not exist or is a special file/link." + exit 2 +fi + +if [ -L "$1" ] +then + echo "File is a symbolic link. Refusing to edit." + exit 2 +fi + +if [ ! -r "$1" ] +then + echo "This user is unable to read the specified file." + exit 3 +fi + +temp_file=$(mktemp --tmpdir doasedit.XXXXXXXX) +if [ ! $? ] +then + echo "Could not create temporary file." + exit 4 +fi + +cp "$1" "$temp_file" +if [ ! $? ] +then + echo "Unable to copy file $1" + exit 5 +fi + +"${EDITOR:-vi}" "$temp_file" +if [ ! $? ] +then + echo "Could not run editor $EDITOR" + echo "Please make sure EDITOR variable is set." + rm -f "$temp_file" + exit 6 +fi + +# Check to see if the file has been changed. +cmp -s "$1" "$temp_file" +status=$? +if [ $status -eq 0 ] +then + echo "File unchanged. Not writing back to original location." + rm -f "$temp_file" + exit 0 +fi + +# At this point the file has been changed. Make sure it still exists. +if [ -f "$temp_file" ] +then + doas cp "$temp_file" "$1" + cmp -s "$temp_file" "$1" + status=$? + # If file fails to copy, do not do clean-up + while [ $status -ne 0 ] + do + echo "Copying file back to $1 failed. Press Ctrl-C to abort or Enter to try again." + read abc + doas cp "$temp_file" "$1" + cmp -s "$temp_file" "$1" + status=$? + done +fi + +# Clean up +rm -f "$temp_file" +exit 0 + diff --git a/doasedit.8 b/doasedit.8 new file mode 100644 index 0000000..511ecdb --- /dev/null +++ b/doasedit.8 @@ -0,0 +1,53 @@ +.\" +.\" Copyright (c) 2021 Jesse Smith +.\" +.\" 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 September 13, 2021 +.Dt DOASEDIT 1 +.Os +.Sh NAME +.Nm doasedit +.Nd edit a text file and then write the file back to its original location with admin access +.Sh SYNOPSIS +.Nm +.Op Ar file +.Sh DESCRIPTION +The +.Nm +utility opens an editor on a temporary copy of a +text file. Once the file has been altered, it is written +back to the original location, using doas for elevated access. +This is intended for use in editing configuration files where +the user may need to be root to edit a file, but does not wish +to run their text editor as the super user. +.Pp +The doasedit utility accepts one argument, the file to +be edited. The text editor used during the editing process +is set using the EDITOR environment variable. +.El +.Sh EXIT STATUS +.Ex -std +.Sh ENVIRONMENT +.Bl -tag -width EDITOR +.It Ev EDITOR +The editor command used for editing the target text file. +If no EDITOR variable is set, then the command vi is used. +.El +.Sh SEE ALSO +.Xr doas 1 , +.Xr doas.conf 5 +.Sh AUTHORS +.An Jesse Smith Aq Mt jessefrgsmith@yahoo.ca