diff options
-rw-r--r-- | mk/bsd.pkg.install.mk | 41 | ||||
-rw-r--r-- | mk/install/deinstall | 53 | ||||
-rw-r--r-- | mk/install/header | 7 | ||||
-rw-r--r-- | mk/install/install | 112 | ||||
-rw-r--r-- | mk/install/usergroup | 359 |
5 files changed, 419 insertions, 153 deletions
diff --git a/mk/bsd.pkg.install.mk b/mk/bsd.pkg.install.mk index 67cc65f58b7..90569408004 100644 --- a/mk/bsd.pkg.install.mk +++ b/mk/bsd.pkg.install.mk @@ -1,4 +1,4 @@ -# $NetBSD: bsd.pkg.install.mk,v 1.73 2005/01/28 06:30:58 jlam Exp $ +# $NetBSD: bsd.pkg.install.mk,v 1.74 2005/01/28 07:37:55 jlam Exp $ # # This Makefile fragment is included by bsd.pkg.mk to use the common # INSTALL/DEINSTALL scripts. To use this Makefile fragment, simply: @@ -104,14 +104,12 @@ FILES_SUBST+= PKG_REFCOUNT_DBDIR=${_PKG_REFCOUNT_DBDIR:Q} # # Only the group is required; the groupid is optional. # +PKG_GROUPS?= # empty PKG_USERS?= # empty _PKG_USER_HOME?= /nonexistent _PKG_USER_SHELL?= ${NOLOGIN} -PKG_GROUPS?= # empty -FILES_SUBST+= PKG_USERS=${PKG_USERS:Q} FILES_SUBST+= PKG_USER_HOME=${_PKG_USER_HOME} FILES_SUBST+= PKG_USER_SHELL=${_PKG_USER_SHELL} -FILES_SUBST+= PKG_GROUPS=${PKG_GROUPS:Q} # Interix is very Special in that users are groups cannot have the # same name. Interix.mk tries to work around this by overriding @@ -131,6 +129,41 @@ BROKEN:= "User and group '${user:C/:.*//}' cannot have the same name on Interix DEPENDS+= ${_USER_DEPENDS} .endif +INSTALL_USERGROUP_FILE= ${WRKDIR}/.install-usergroup +INSTALL_UNPACK_TMPL+= ${INSTALL_USERGROUP_FILE} + +${INSTALL_USERGROUP_FILE}: ../../mk/install/usergroup + ${_PKG_SILENT}${_PKG_DEBUG}{ \ + ${ECHO} "# start of install-usergroup"; \ + ${ECHO} "#"; \ + ${ECHO} "# Generate a +USERGROUP script that reference counts users"; \ + ${ECHO} "# and groups that are required for the proper functioning"; \ + ${ECHO} "# of the package."; \ + ${ECHO} "#"; \ + ${ECHO} "case \$${STAGE} in"; \ + ${ECHO} "PRE-INSTALL)"; \ + ${ECHO} " \$${CAT} > ./+USERGROUP << 'EOF_USERGROUP'"; \ + ${SED} ${FILES_SUBST_SED} ../../mk/install/usergroup; \ + ${ECHO} ""; \ + eval set -- ${PKG_GROUPS} ; \ + while ${TEST} $$# -gt 0; do \ + i="$$1"; shift; \ + ${ECHO} "# GROUP: $$i"; \ + done; \ + eval set -- ${PKG_USERS} ; \ + while ${TEST} $$# -gt 0; do \ + i="$$1"; shift; \ + ${ECHO} "# USER: $$i"; \ + done; \ + ${ECHO} "EOF_USERGROUP"; \ + ${ECHO} " \$${CHMOD} +x ./+USERGROUP"; \ + ${ECHO} " ;;"; \ + ${ECHO} "esac"; \ + ${ECHO} ""; \ + ${ECHO} "# end of install-usergroup"; \ + } > ${.TARGET}.tmp; \ + ${MV} -f ${.TARGET}.tmp ${.TARGET} + # SPECIAL_PERMS are lists that look like: # file user group mode # At post-install time, file (it may be a directory) is changed to be diff --git a/mk/install/deinstall b/mk/install/deinstall index a6126b711de..ebef22dd6de 100644 --- a/mk/install/deinstall +++ b/mk/install/deinstall @@ -1,25 +1,6 @@ # start of deinstall # -# $NetBSD: deinstall,v 1.30 2005/01/28 06:30:59 jlam Exp $ - -eval set -- ${PKG_USERS} -for userset; do - user=` - IFS=":" - set -- ${userset} - ${ECHO} "$1" - ` - ALL_USERS="${ALL_USERS} \"${user}\"" -done -eval set -- ${PKG_GROUPS} -for groupset; do - group=` - IFS=":" - set -- ${groupset} - ${ECHO} "$1" - ` - ALL_GROUPS="${ALL_GROUPS} \"${group}\"" -done +# $NetBSD: deinstall,v 1.31 2005/01/28 07:37:55 jlam Exp $ eval set -- ${CONF_FILES} ${SUPPORT_FILES} while [ $# -gt 0 ]; do @@ -115,35 +96,15 @@ POST-DEINSTALL) case ${_PKG_CONFIG} in YES) ${TEST} -x ./+DIRS && ./+DIRS REMOVE ${PKG_METADATA_DIR} ;; esac + case ${_PKG_CREATE_USERGROUP} in + YES) ${TEST} -x ./+USERGROUP && ./+USERGROUP REMOVE ${PKG_METADATA_DIR} ;; + esac - if [ -n "${ALL_USERS}" -o -n "${ALL_GROUPS}" -o \ - -n "${modified_files}" -o -n "${existing_dirs}" ]; then + if [ -n "${modified_files}" ]; then ${CAT} << EOF =========================================================================== If you won't be using ${PKGNAME} any longer, you may want to remove EOF - if [ -n "${ALL_USERS}" ]; then - ${ECHO} "" - allusersmsg=" * the following users" - sep=": " - eval set -- ${ALL_USERS} - for user; do - allusersmsg="${allusersmsg}${sep}${user}" - sep=", " - done - ${ECHO} "${allusersmsg}" - fi - if [ -n "${ALL_GROUPS}" ]; then - ${ECHO} "" - allgroupsmsg=" * the following groups" - sep=": " - eval set -- ${ALL_GROUPS} - for group; do - allgroupsmsg="${allgroupsmsg}${sep}${group}" - sep=", " - done - ${ECHO} "${allgroupsmsg}" - fi if [ -n "${modified_files}" ]; then ${CAT} << EOF @@ -166,7 +127,9 @@ EOF =========================================================================== EOF fi - ${TEST} -x ./+DIRS && ./+DIRS CHECK-REMOVE + + ${TEST} -x ./+USERGROUP && ./+USERGROUP CHECK-REMOVE ${PKG_METADATA_DIR} + ${TEST} -x ./+DIRS && ./+DIRS CHECK-REMOVE ${PKG_METADATA_DIR} ;; esac diff --git a/mk/install/header b/mk/install/header index 6c5c41b3863..7152fae2c00 100644 --- a/mk/install/header +++ b/mk/install/header @@ -2,7 +2,7 @@ # # start of header # -# $NetBSD: header,v 1.28 2005/01/28 06:30:59 jlam Exp $ +# $NetBSD: header,v 1.29 2005/01/28 07:37:55 jlam Exp $ PKGNAME=$1 STAGE=$2 @@ -62,9 +62,6 @@ ${LOCALBASE}/*) VIEW="${PKG_PREFIX#${LOCALBASE}/}" ;; *) VIEW="" ;; esac -PKG_USERS="@PKG_USERS@" -PKG_GROUPS="@PKG_GROUPS@" - SPECIAL_PERMS="@SPECIAL_PERMS@" CONF_FILES="@CONF_FILES@" @@ -90,8 +87,6 @@ esac PKG_REGISTER_SHELLS="@PKG_REGISTER_SHELLS@" PKG_SHELL="@PKG_SHELL@" -ALL_USERS= -ALL_GROUPS= ALL_FILES= VIEW_FILES= diff --git a/mk/install/install b/mk/install/install index 940f8004868..7ab2557bd08 100644 --- a/mk/install/install +++ b/mk/install/install @@ -1,106 +1,22 @@ # start of install # -# $NetBSD: install,v 1.34 2005/01/28 06:30:59 jlam Exp $ +# $NetBSD: install,v 1.35 2005/01/28 07:37:55 jlam Exp $ case ${STAGE} in PRE-INSTALL) - msginit - _pkg_exit=0 - if [ -n "${PKG_GROUPS}" ]; then - _print_group_header=1 - eval set -- ${PKG_GROUPS} - for groupset; do - save_IFS="${IFS}"; IFS=":" - set -- ${groupset} - group="$1"; groupid="$2" - IFS="${save_IFS}" - - # We need to check that ${PKG_GROUP} exists before - # adding the user. Do it with chgrp to be able to - # use NIS. - # - ${TOUCH} /tmp/grouptest.$$ - if ${CHGRP} ${group} /tmp/grouptest.$$ >/dev/null 2>&1; then - ${ECHO} "Group '${group}' already exists." - elif [ "${_PKG_CREATE_USERGROUP}" = "NO" ]; then - if [ ${_print_group_header} -gt 0 ]; then - _print_group_header=0 - msgadd "" - msgadd "The following groups need to be created for ${PKGNAME}:" - msgadd "" - fi - if [ -z "${groupid}" ]; then - groupid_str= - else - groupid_str=" (${groupid})" - fi - msgadd "#${group}${groupid_str}" - _pkg_exit=1 - else - groupid_option= - if [ -n "${groupid}" ]; then - groupid_option="-g" - fi - ${ECHO} "Creating group: ${group}" - ${GROUPADD} ${groupid_option} ${groupid} "${group}" - fi - ${RM} -f /tmp/grouptest.$$ - done - fi - if [ -n "${PKG_USERS}" ]; then - _print_user_header=1 - eval set -- ${PKG_USERS} - for userset; do - save_IFS="${IFS}"; IFS=":" - set -- ${userset} - user="$1"; group="$2"; userid="$3" - descr="${4:-${PKGBASE} ${user} user}" - home="${5:-@PKG_USER_HOME@}" - shell="${6:-@PKG_USER_SHELL@}" - IFS="${save_IFS}" - - # Use `id' to be able to use NIS. - if ${ID} "${user}" >/dev/null 2>&1; then - ${ECHO} "User '${user}' already exists." - elif [ "${_PKG_CREATE_USERGROUP}" = "NO" ]; then - if [ ${_print_user_header} -gt 0 ]; then - _print_user_header=0 - msgadd "" - msgadd "The following users need to be created for ${PKGNAME}:" - msgadd "" - fi - if [ -z "${userid}" ]; then - userid_str= - else - userid_str=" (${userid})" - fi - msgadd "#${user}${userid_str}: ${group}, ${home}, ${shell}" - _pkg_exit=1 - else - userid_option= - if [ -n "${userid}" ]; then - userid_option="-u" - fi - ${ECHO} "Creating user: ${user}" - ${USERADD} -c "${descr}" \ - ${userid_option} ${userid} \ - -g "${group}" \ - -d "${home}" \ - -s "${shell}" \ - "${user}" - fi - done - fi - if ! msgempty; then - ${ECHO} "===========================================================================" - msgprint - ${ECHO} "" - ${ECHO} "===========================================================================" - fi - if [ ${_pkg_exit} -gt 0 ]; then - exit ${_pkg_exit} + # + # Require that necessary users and groups exist or else fail the + # installation of the package. + # + case ${_PKG_CREATE_USERGROUP} in + YES) ${TEST} -x ./+USERGROUP && ./+USERGROUP ADD ${PKG_METADATA_DIR} ;; + esac + if ${TEST} -x ./+USERGROUP && ./+USERGROUP CHECK-ADD ${PKG_METADATA_DIR}; then + : + else + exit 1 fi - + # # Create package directories at pre-install time. # if [ "${PKG_INSTALLATION_TYPE}" = "pkgviews" -a \ @@ -126,7 +42,7 @@ POST-INSTALL) # # Note any missing package directories. # - ${TEST} -x ./+DIRS && ./+DIRS CHECK-ADD + ${TEST} -x ./+DIRS && ./+DIRS CHECK-ADD ${PKG_METADATA_DIR} msginit if [ "${_PKG_CONFIG}" = "YES" ]; then diff --git a/mk/install/usergroup b/mk/install/usergroup new file mode 100644 index 00000000000..32dacfb5abf --- /dev/null +++ b/mk/install/usergroup @@ -0,0 +1,359 @@ +#!@SH@ +# +# +USERGROUP - users and groups management script +# +# Usage: ./+USERGROUP ADD|REMOVE [metadatadir] +# ./+USERGROUP CHECK-ADD|CHECK-REMOVE [metadatadir] +# +# This script supports two actions, ADD and REMOVE, that will add or +# remove the users and groups needed by the package associated with +# <metadatadir>. The CHECK-ADD action will check whether any users or +# groups needed by the package are missing, and print an informative +# message noting those users and groups. The CHECK-REMOVE action will +# check whether any users and groups needed by the package still exist, +# and print an informative message noting those users and groups. The +# CHECK-ADD and CHECK-REMOVE actions return non-zero if they detect +# either missing or existing users/groups, respectively. +# +# Lines starting with "# USER: " or "# GROUP: " are data read by this +# script that name the users and groups that this package requires to +# exist to function correctly, e.g. +# +# # USER: foo:foogrp::The Foomister +# # GROUP: foogrp +# +# The USER lines are of the form: +# +# user:group[:[userid][:[descr][:[home][:shell]]]] +# +# Only the user and group are required; everything else is optional, +# but the colons must be in the right places when specifying optional +# bits. +# +# The GROUP lines are of the form: +# +# group[:groupid] +# +# Only the group is required; the groupid is optional. +# +CAT="@CAT@" +CHGRP="@CHGRP@" +ECHO="@ECHO@" +GREP="@GREP@" +GROUPADD="@GROUPADD@" +ID="@ID@" +MKDIR="@MKDIR@" +PWD_CMD="@PWD_CMD@" +RM="@RM@" +RMDIR="@RMDIR@" +SED="@SED@" +SORT="@SORT@" +TEST="@TEST@" +USERADD="@USERADD@" + +SELF=$0 +ACTION=$1 +PKG_METADATA_DIR="${2-`${PWD_CMD}`}" +PKG_REFCOUNT_DBDIR="@PKG_REFCOUNT_DBDIR@" +: ${PKGNAME=${PKG_METADATA_DIR##*/}} +: ${PKGBASE=${PKGNAME%-[0-9]*}} + +PKG_REFCOUNT_USERS_DBDIR="${PKG_REFCOUNT_DBDIR}/users" +PKG_REFCOUNT_GROUPS_DBDIR="${PKG_REFCOUNT_DBDIR}/groups" + +PKG_USER_HOME="@PKG_USER_HOME@" +PKG_USER_SHELL="@PKG_USER_SHELL@" + +group_exists() +{ + case $group in + "") return 2 ;; + esac + # Check using chgrp to work properly in an NIS environment. + testfile="./grouptest.tmp.$$" + ${ECHO} > $testfile + if ${CHGRP} $group $testfile >/dev/null 2>&1; then + ${RM} -f $testfile + return 0 + fi + ${RM} -f $testfile + return 1 +} + +user_exists() +{ + case $user in + "") return 2 ;; + esac + # Check using id to work properly in an NIS environment. + if ${ID} $user >/dev/null 2>&1; then + return 0 + fi + return 1 +} + +exitcode=0 +case $ACTION in +ADD) + ${SED} -n "/^\# GROUP: /{s/^\# GROUP: //;p;}" ${SELF} | ${SORT} -u | + { while read line; do + SAVEIFS="$IFS"; IFS=":" + set -- $line + group="$1"; groupid="$2" + IFS="$SAVEIFS" + case $group in + "") continue ;; + esac + shadow_dir="${PKG_REFCOUNT_GROUPS_DBDIR}/$group" + preexist="$shadow_dir/+PREEXISTING" + token="$shadow_dir/${PKGNAME}" + if ${TEST} ! -d "$shadow_dir"; then + ${MKDIR} $shadow_dir + group_exists $group && + ${ECHO} "${PKGNAME}" > $preexist + fi + group_exists $group || + { ${ECHO} "Creating group: $group"; + case $groupid in + "") ${GROUPADD} $group ;; + *) ${GROUPADD} -g $groupid $group ;; + esac; } + if ${TEST} -f "$token" && \ + ${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then + : + else + ${ECHO} "${PKG_METADATA_DIR}" >> $token + fi + done; } + ${SED} -n "/^\# USER: /{s/^\# USER: //;p;}" ${SELF} | ${SORT} -u | + { while read line; do + SAVEIFS="$IFS"; IFS=":" + set -- $line + user="$1"; group="$2"; userid="$3" + descr="$4"; home="$5" shell="$6" + IFS="$SAVEIFS" + case $user in + "") continue ;; + esac + : ${descr:="${PKGBASE} $user user"} + : ${home:="${PKG_USER_HOME}"} + : ${shell:="${PKG_USER_SHELL}"} + shadow_dir="${PKG_REFCOUNT_USERS_DBDIR}/$user" + preexist="$shadow_dir/+PREEXISTING" + token="$shadow_dir/${PKGNAME}" + if ${TEST} ! -d "$shadow_dir"; then + ${MKDIR} $shadow_dir + user_exists $user && + ${ECHO} "${PKGNAME}" > $preexist + fi + { user_exists $user && group_exists $group; } || + { ${ECHO} "Creating user: $user"; + case $userid in + "") ${USERADD} -c "$descr" -d "$home" -s "$shell" \ + -g $group $user ;; + *) ${USERADD} -c "$descr" -d "$home" -s "$shell" \ + -g $group -u $userid $user ;; + esac; } + if ${TEST} -f "$token" && \ + ${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then + : + else + ${ECHO} "${PKG_METADATA_DIR}" >> $token + fi + done; } + ;; + +REMOVE) + ${SED} -n "/^\# USER: /{s/^\# USER: //;p;}" ${SELF} | ${SORT} -u | + { while read line; do + SAVEIFS="$IFS"; IFS=":" + set -- $line + user="$1"; group="$2"; userid="$3" + descr="$4"; home="$5" shell="$6" + IFS="$SAVEIFS" + case $user in + "") continue ;; + esac + shadow_dir="${PKG_REFCOUNT_USERS_DBDIR}/$user" + preexist="$shadow_dir/+PREEXISTING" + token="$shadow_dir/${PKGNAME}" + tokentmp="$token.tmp.$$" + if ${TEST} -f "$token" && \ + ${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then + ${CAT} "$token" | ${GREP} -v "^${PKG_METADATA_DIR}$" > $tokentmp + case `${CAT} $tokentmp | ${SED} -n "$="` in + "") + ${RM} -f $preexist $token $token.tmp.* + ${RMDIR} -p $shadow_dir 2>/dev/null || ${TRUE} + ;; + *) + ${MV} -f $tokentmp $token + ;; + esac + fi + done; } + ${SED} -n "/^\# GROUP: /{s/^\# GROUP: //;p;}" ${SELF} | ${SORT} -u | + { while read line; do + SAVEIFS="$IFS"; IFS=":" + set -- $line + group="$1"; groupid="$2" + IFS="$SAVEIFS" + case $group in + "") continue ;; + esac + shadow_dir="${PKG_REFCOUNT_GROUPS_DBDIR}/$group" + preexist="$shadow_dir/+PREEXISTING" + token="$shadow_dir/${PKGNAME}" + tokentmp="$token.tmp.$$" + if ${TEST} -f "$token" && \ + ${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then + ${CAT} "$token" | ${GREP} -v "^${PKG_METADATA_DIR}$" > $tokentmp + case `${CAT} $tokentmp | ${SED} -n "$="` in + "") + ${RM} -f $preexist $token $token.tmp.* + ${RMDIR} -p $shadow_dir 2>/dev/null || ${TRUE} + ;; + *) + ${MV} -f $tokentmp $token + ;; + esac + fi + done; } + ;; + +CHECK-ADD) + ${SED} -n "/^\# GROUP: /{s/^\# GROUP: //;p;}" ${SELF} | ${SORT} -u | + { while read line; do + SAVEIFS="$IFS"; IFS=":" + set -- $line + group="$1"; groupid="$2" + IFS="$SAVEIFS" + case $group in + "") continue ;; + *) group_exists $group && continue ;; + esac + case "$printed_header" in + yes) ;; + *) printed_header=yes + ${ECHO} "===========================================================================" + ${ECHO} "The following groups need to be created for ${PKGNAME}:" + ${ECHO} "" + ;; + esac + case $groupid in + "") ${ECHO} " $group" ;; + *) ${ECHO} " $group ($groupid)" ;; + esac + done + case "$printed_header" in + yes) ${ECHO} "" + ${ECHO} "===========================================================================" + exit 1 + ;; + esac; } + ${TEST} $? -eq 0 || exitcode=1 + ${SED} -n "/^\# USER: /{s/^\# USER: //;p;}" ${SELF} | ${SORT} -u | + { while read line; do + SAVEIFS="$IFS"; IFS=":" + set -- $line + user="$1"; group="$2"; userid="$3" + descr="$4"; home="$5" shell="$6" + IFS="$SAVEIFS" + case $user in + "") continue ;; + *) user_exists $user && continue ;; + esac + case "$printed_header" in + yes) ;; + *) printed_header=yes + ${ECHO} "===========================================================================" + ${ECHO} "The following users need to be created for ${PKGNAME}:" + ${ECHO} "" + ;; + esac + : ${home:="${PKG_USER_HOME}"} + : ${shell:="${PKG_USER_SHELL}"} + case $userid in + "") ${ECHO} " $user: $group, $home, $shell" ;; + *) ${ECHO} " $user ($userid): $group, $home, $shell" ;; + esac + done + case "$printed_header" in + yes) ${ECHO} "" + ${ECHO} "===========================================================================" + exit 1 + ;; + esac; } + ${TEST} $? -eq 0 || exitcode=1 + ;; + +CHECK-REMOVE) + ${SED} -n "/^\# USER: /{s/^\# USER: //;p;}" ${SELF} | ${SORT} -u | + { while read line; do + SAVEIFS="$IFS"; IFS=":" + set -- $line + user="$1"; group="$2"; userid="$3" + descr="$4"; home="$5" shell="$6" + IFS="$SAVEIFS" + case $user in + "") continue ;; + *) user_exists $user || continue ;; + esac + shadow_dir="${PKG_REFCOUNT_USERS_DBDIR}/$user" + ${TEST} -d "$shadow_dir" && continue # refcount isn't zero + case "$printed_header" in + yes) ;; + *) printed_header=yes + ${ECHO} "===========================================================================" + ${ECHO} "The following users are no longer being used by ${PKGNAME}," + ${ECHO} "and they can be removed if no other packages are using them:" + ${ECHO} "" + ;; + esac + ${ECHO} " ${user}" + done + case "$printed_header" in + yes) ${ECHO} "" + ${ECHO} "===========================================================================" + exit 1 + ;; + esac; } + ${TEST} $? -eq 0 || exitcode=1 + ${SED} -n "/^\# GROUP: /{s/^\# GROUP: //;p;}" ${SELF} | ${SORT} -u | + { while read line; do + SAVEIFS="$IFS"; IFS=":" + set -- $line + group="$1"; groupid="$2" + IFS="$SAVEIFS" + case $group in + "") continue ;; + *) group_exists $group || continue ;; + esac + shadow_dir="${PKG_REFCOUNT_GROUPS_DBDIR}/$group" + ${TEST} -d "$shadow_dir" && continue # refcount isn't zero + case "$printed_header" in + yes) ;; + *) printed_header=yes + ${ECHO} "===========================================================================" + ${ECHO} "The following groups are no longer being used by ${PKGNAME}," + ${ECHO} "and they can be removed if no other packages are using them:" + ${ECHO} "" + ;; + esac + ${ECHO} " $group" + done + case "$printed_header" in + yes) ${ECHO} "" + ${ECHO} "===========================================================================" + exit 1 + ;; + esac; } + ${TEST} $? -eq 0 || exitcode=1 + ;; + +*) + ${ECHO} "Usage: ./+USERGROUP ADD|REMOVE [metadatadir]" + ${ECHO} " ./+USERGROUP CHECK-ADD|CHECK-REMOVE" + ;; +esac +exit $exitcode |