Saturday, November 01, 2008

Utility to Add/Del/Mod Configuration File

In UNIX, root (or administrator) can delegrate some of the commands to non-privilege users to carry out system administrative tasks by using sudo or RBAC (available only in Solaris

Configuation files like /etc/passwd and /etc/group have equivalent utilities (useradd, usermod, userdel, groupadd, groupmod, groupdel) to handle them properly. However, other configuration files have to rely on vi to do the editing. If someone is given the sudo to vi any file, he/she can sudo vi /etc/sudoers to temporarily include him/her to run any command.

Below script is a 'proof-of-concept' script that you may be able to allow sudo to run to add/del/mod entry in any ascii configuration file. Therefore, no need to allow vi in the sudo. BTW, only pre-defined files can be modified.

#! /bin/sh


usage()
{
        echo "Usage: $0 <config-file> add <line#> <new-data>"
        echo "       if line# > total # of lines, append new-data to end of file"
        echo "Usage: $0 <config-file> del <line#>"
        echo "Usage: $0 <config-file> mod <line#> <new-data>"
}


if [ $# -lt 3 -o $# -gt 4 ]; then
        usage
        exit 1
fi
config="$1"
action="$2"
lineno="$3"


if [ ! -f $config ]; then
        echo "Error. \"$config\" does not exist"
        exit 2
fi


#
# only allow to edit the following files in the list
#
allow="hosts defaultrouter services"
found=0
for cfg in $allow
do
        if [ `basename $config` = "$cfg" ]; then
                found=1
                break
        fi
done
if [ $found -eq 0 ]; then
        echo "Error. You can only edit \"$allow\" files"
        exit 2
fi


#
# lineno <= total
#
total=`wc -l $config | awk '{print $1}'`
if [ $lineno -gt $total ]; then
        lineno=$total
fi


#
# case - add/del/mod
#
case $action in
add)
        newdata="$4"
ex -s "$config" << EOF
${lineno}a
$newdata
.
wq!
EOF
        ;;

del)
ex -s "$config" << EOF
${lineno}d
wq!
EOF
        ;;

mod)
        newdata="$4"
ex -s "$config" << EOF
${lineno}c
$newdata
.
wq!
EOF
        ;;

*)
        usage
        exit 1
        ;;
esac

In order to accomplish the above task, we need to work with primitive command like ex. It may not be easy to find out what are the commands to feed to "ex". In UNIX Power Tool 3rd Ed Chapter 20, it showed that you can use diff -e to find out all the "ex" commands. Here is an illustration. Suppose you want to add 10.0.11.3 monitor to line 5 in the 'hosts' file, all you have to do is to a diff between the new and original file.

$ cat /etc/hosts
127.0.0.1      localhost
10.0.1.11      master loghost
10.0.11.1      gateway
10.0.11.2      storage
10.0.11.12     peter
10.0.11.13     bruce
10.0.11.14     elvis
10.0.11.15     alan
10.0.11.16     chris
10.0.11.17     andy
10.0.11.18     tony
10.0.11.19     cliff
10.0.11.20     richard

$ cat /tmp/hosts.modified
127.0.0.1      localhost
10.0.1.11      master loghost
10.0.11.1      gateway
10.0.11.2      storage
10.0.11.3      monitor
10.0.11.12     peter
10.0.11.13     bruce
10.0.11.14     elvis
10.0.11.15     alan
10.0.11.16     chris
10.0.11.17     andy
10.0.11.18     tony
10.0.11.19     cliff
10.0.11.20     richard

$ diff -e /etc/hosts /tmp/hosts.modified
5a
10.0.11.3      monitor
.
In this example, all you need to program in your script to include 10.0.11.3 monitor using ex will be:
ex -s /etc/hosts << EOF
5a
10.9.8.7   mon
.
wq!
EOF

You may want to program in the script to backup the configuration file before any modification.

Labels: , ,

0 Comments:

Post a Comment

<< Home