summaryrefslogtreecommitdiff
path: root/mk/install
diff options
context:
space:
mode:
authorjlam <jlam>2006-04-23 00:00:43 +0000
committerjlam <jlam>2006-04-23 00:00:43 +0000
commit1681e974bb6b92327674323cc6ecfcdc2381500b (patch)
tree83da8d716a011e9b725796b5b60577a3a8a6b2b3 /mk/install
parentc878f580a26a805c3150c575cfcc1dbc3d81d495 (diff)
downloadpkgsrc-1681e974bb6b92327674323cc6ecfcdc2381500b.tar.gz
Add two new capabilities to the pkginstall framework:
(1) Allow specifying the numeric UID and GID for users and groups in /etc/mk.conf by setting PKG_UID.<user> and PKG_GID.<group> to those values. If these values are specified, then the +USERGROUP script will verify that existing users and groups match the requested UIDs and GIDs for the package, and otherwise create them with these UIDs and GIDs. For example: PKG_UID.courier= 10001 PKG_GID.mail= 6 In this example, the courier-authlib binary package will be created to use uid 10001 for the "courier" user and gid 6 for the "mail" group. (2) Allow a package to request that users and groups be created prior to configuring or building a package by setting USERGROUP_PHASE to "configure" or "build". Because the reason for this is typically to hardcode the UIDs and GIDs of requested users and groups directly into the package's executables, these hardcoded values will be automatically determined and put into the +USERGROUP script. For example: USERGROUP_PHASE= configure PKG_GROUPS= qmail nofiles PKG_USERS+= qmaill:nofiles PKG_USERS+= qmailq:qmail In this example, the users and groups are created before the configure phase when building qmail, and the qmail binary package's +INSTALL script will try to create (or verify) users and groups with the same UIDs and GIDs that were used during the build. As part of these changes, the format for PKG_USERS and PKG_GROUPS has changed -- the optional parts of the corresponding entries are no longer used and cannot be specified. Instead, the following variables should be set: PKG_GID.<group> is the group's numeric GID. PKG_UID.<user> is the user's numeric UID. PKG_GECOS.<user> is the user's description. PKG_HOME.<user> is the user's home directory. PKG_SHELL.<user> is the user's login shell. A separate commit will follow which will fix all packages that set PKG_USERS and PKG_GROUPS to use the new syntax and variables.
Diffstat (limited to 'mk/install')
-rw-r--r--mk/install/bsd.pkginstall.mk117
-rw-r--r--mk/install/usergroup78
-rwxr-xr-xmk/install/usergroup-check126
-rw-r--r--mk/install/usergroupfuncs79
-rw-r--r--mk/install/usergroupfuncs.DragonFly70
-rw-r--r--mk/install/usergroupfuncs.FreeBSD70
6 files changed, 470 insertions, 70 deletions
diff --git a/mk/install/bsd.pkginstall.mk b/mk/install/bsd.pkginstall.mk
index bb38461922b..d26962e8046 100644
--- a/mk/install/bsd.pkginstall.mk
+++ b/mk/install/bsd.pkginstall.mk
@@ -1,4 +1,4 @@
-# $NetBSD: bsd.pkginstall.mk,v 1.46 2006/04/16 04:27:17 jlam Exp $
+# $NetBSD: bsd.pkginstall.mk,v 1.47 2006/04/23 00:00:43 jlam Exp $
#
# This Makefile fragment is included by bsd.pkg.mk and implements the
# common INSTALL/DEINSTALL scripts framework. To use the pkginstall
@@ -111,21 +111,41 @@ FILES_SUBST+= PKG_INSTALLATION_TYPE=${PKG_INSTALLATION_TYPE:Q}
# PKG_USERS represents the users to create for the package. It is a
# space-separated list of elements of the form
#
-# user:group[:[userid][:[descr][:[home][:shell]]]]
+# user:group
#
-# Only the user and group are required; everything else is optional,
-# but the colons must be in the right places when specifying optional
-# bits. Note that if the description contains spaces, they must
-# be escaped as usual, e.g.
+# The following variables are optional and specify further details of
+# the user accounts listed in PKG_USERS:
+#
+# PKG_UID.<user> is the hardcoded numeric UID for <user>.
+# PKG_GECOS.<user> is <user>'s description, as well as contact info.
+# PKG_HOME.<user> is the home directory for <user>.
+# PKG_SHELL.<user> is the login shell for <user>.
#
-# foo:foogrp::The\ Foomister
#
# PKG_GROUPS represents the groups to create for the package. It is a
# space-separated list of elements of the form
#
-# group[:groupid]
+# group
+#
+# The following variables are optional and specify further details of
+# the user accounts listed in PKG_GROUPS:
+#
+# PKG_GID.<group> is the hardcoded numeric GID for <group>.
+#
+# For example:
+#
+# PKG_GROUPS+= mail
+# PKG_USERS+= courier:mail
+#
+# PKG_GECOS.courier= Courier authlib and mail user
#
-# Only the group is required; the groupid is optional.
+# USERGROUP_PHASE is set to the phase just before which users and
+# groups need to be created. Valid values are "configure" and
+# "build". If not defined, then by default users and groups
+# are created prior to installation by the pre-install-script
+# target. If this is defined, then the numeric UIDs and GIDs
+# of users and groups required by this package are hardcoded
+# into the +INSTALL script.
#
PKG_GROUPS?= # empty
PKG_USERS?= # empty
@@ -162,19 +182,43 @@ _INSTALL_USERGROUP_DATAFILE= ${_PKGINSTALL_DIR}/usergroup-data
_INSTALL_UNPACK_TMPL+= ${_INSTALL_USERGROUP_FILE}
_INSTALL_DATA_TMPL+= ${_INSTALL_USERGROUP_DATAFILE}
+.for _group_ in ${PKG_GROUPS}
+. if defined(USERGROUP_PHASE)
+# Determine the numeric GID of each group.
+USE_TOOLS+= perl
+PKG_GID.${_group_}_cmd= \
+ if ${TEST} ! -x ${PERL5}; then ${ECHO} ""; exit 0; fi; \
+ ${PERL5} -le 'print scalar getgrnam shift' ${_group_}
+PKG_GID.${_group_}?= ${PKG_GID.${_group_}_cmd:sh:M*}
+. endif
+_PKG_GROUPS+= ${_group_}:${PKG_GID.${_group_}}
+.endfor
+
+.for _entry_ in ${PKG_USERS}
+. if defined(USERGROUP_PHASE)
+# Determine the numeric UID of each user.
+USE_TOOLS+= perl
+PKG_UID.${_entry_:C/\:.*//}_cmd= \
+ if ${TEST} ! -x ${PERL5}; then ${ECHO} ""; exit 0; fi; \
+ ${PERL5} -le 'print scalar getpwnam shift' ${_entry_:C/\:.*//}
+PKG_UID.${_entry_:C/\:.*//}?= ${PKG_UID.${_entry_:C/\:.*//}_cmd:sh:M*}
+. endif
+_PKG_USERS+= ${_user_::=${_entry_:C/\:.*//}}${_entry_}:${PKG_UID.${_user_}}:${PKG_GECOS.${_user_}:Q}:${PKG_HOME.${_user_}:Q}:${PKG_SHELL.${_user_}:Q}
+.endfor
+
${_INSTALL_USERGROUP_DATAFILE}:
${_PKG_SILENT}${_PKG_DEBUG}${MKDIR} ${.TARGET:H}
${_PKG_SILENT}${_PKG_DEBUG}${RM} -f ${.TARGET} ${.TARGET}.tmp
${_PKG_SILENT}${_PKG_DEBUG}${TOUCH} ${TOUCH_ARGS} ${.TARGET}.tmp
${_PKG_SILENT}${_PKG_DEBUG} \
- set -- dummy ${PKG_GROUPS}; shift; \
+ set -- dummy ${_PKG_GROUPS:C/\:*$//}; shift; \
exec 1>>${.TARGET}.tmp; \
while ${TEST} $$# -gt 0; do \
i="$$1"; shift; \
${ECHO} "# GROUP: $$i"; \
done
${_PKG_SILENT}${_PKG_DEBUG} \
- set -- dummy ${PKG_USERS}; shift; \
+ set -- dummy ${_PKG_USERS:C/\:*$//}; shift; \
exec 1>>${.TARGET}.tmp; \
while ${TEST} $$# -gt 0; do \
i="$$1"; shift; \
@@ -196,6 +240,57 @@ ${_INSTALL_USERGROUP_FILE}: \
${TOUCH} ${TOUCH_ARGS} ${.TARGET}; \
fi
+_INSTALL_USERGROUP_UNPACKER= ${_PKGINSTALL_DIR}/usergroup-unpack
+
+${_INSTALL_USERGROUP_UNPACKER}: \
+ ${_INSTALL_USERGROUP_FILE} \
+ ${_INSTALL_USERGROUP_DATAFILE}
+ ${_PKG_SILENT}${_PKG_DEBUG}${MKDIR} ${.TARGET:H}
+ ${_PKG_SILENT}${_PKG_DEBUG} \
+ exec 1>${.TARGET}.tmp; \
+ ${ECHO} "#!${SH}"; \
+ ${ECHO} ""; \
+ ${ECHO} "CAT="${CAT:Q}; \
+ ${ECHO} "CHMOD="${CHMOD:Q}; \
+ ${ECHO} "SED="${SED:Q}; \
+ ${ECHO} ""; \
+ ${ECHO} "SELF=\$$0"; \
+ ${ECHO} "STAGE=UNPACK"; \
+ ${ECHO} ""; \
+ ${CAT} ${_INSTALL_USERGROUP_FILE} \
+ ${_INSTALL_USERGROUP_DATAFILE}
+ ${_PKG_SILENT}${_PKG_DEBUG}${MV} -f ${.TARGET}.tmp ${.TARGET}
+ ${_PKG_SILENT}${_PKG_DEBUG}${CHMOD} +x ${.TARGET}
+
+.if defined(USERGROUP_PHASE)
+. if !empty(USERGROUP_PHASE:M*configure)
+pre-configure: create-usergroup
+. elif !empty(USERGROUP_PHASE:M*build)
+pre-build: create-usergroup
+. endif
+.endif
+
+_INSTALL_USERGROUP_CHECK= \
+ ${SETENV} PERL5=${PERL5:Q} \
+ ${SH} ${PKGSRCDIR}/mk/install/usergroup-check
+
+.PHONY: create-usergroup
+create-usergroup: ${_INSTALL_USERGROUP_UNPACKER}
+ ${_PKG_SILENT}${_PKG_DEBUG} \
+ if ${_INSTALL_USERGROUP_CHECK} -g ${_PKG_GROUPS:C/\:*$//} && \
+ ${_INSTALL_USERGROUP_CHECK} -u ${_PKG_USERS:C/\:*$//}; then \
+ exit 0; \
+ fi; \
+ cd ${_PKGINSTALL_DIR} && \
+ ${SH} ${_INSTALL_USERGROUP_UNPACKER} && \
+ ${TEST} -f ./+USERGROUP && \
+ ./+USERGROUP ADD ${_PKG_DBDIR}/${PKGNAME} && \
+ ./+USERGROUP CHECK-ADD ${_PKG_DBDIR}/${PKGNAME} && \
+ ${RM} -f ${_INSTALL_USERGROUP_FILE:Q} \
+ ${_INSTALL_USERGROUP_DATAFILE:Q} \
+ ${_INSTALL_USERGROUP_UNPACKER:Q} \
+ ./+USERGROUP
+
# 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/usergroup b/mk/install/usergroup
index c9fca96e048..958e2aa5575 100644
--- a/mk/install/usergroup
+++ b/mk/install/usergroup
@@ -1,4 +1,4 @@
-# $NetBSD: usergroup,v 1.14 2006/03/19 23:58:14 jlam Exp $
+# $NetBSD: usergroup,v 1.15 2006/04/23 00:00:44 jlam Exp $
#
# Generate a +USERGROUP script that reference-counts users and groups
# that are required for the proper functioning of the package.
@@ -44,11 +44,13 @@ UNPACK,|UNPACK,+USERGROUP)
#
# Only the group is required; the groupid is optional.
#
+AWK="@AWK@"
CAT="@CAT@"
CHGRP="@CHGRP@"
+CHOWN="@CHOWN@"
ECHO="@ECHO@"
GREP="@GREP@"
-ID="@ID@"
+LS="@LS@"
MKDIR="@MKDIR@"
PWD_CMD="@PWD_CMD@"
RM="@RM@"
@@ -77,36 +79,6 @@ case "${PKG_CREATE_USERGROUP:-@PKG_CREATE_USERGROUP@}" in
;;
esac
-group_exists()
-{
- _group="$1"
- 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()
-{
- _user="$1"
- 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
-}
-
listwrap()
{
_length=$1
@@ -150,7 +122,7 @@ ADD)
token="$shadow_dir/${PKGNAME}"
if ${TEST} ! -d "$shadow_dir"; then
${MKDIR} $shadow_dir
- group_exists $group &&
+ group_exists $group $groupid &&
${ECHO} "${PKGNAME}" > $preexist
fi
if ${TEST} -f "$token" && \
@@ -161,11 +133,11 @@ ADD)
fi
case ${_PKG_CREATE_USERGROUP} in
yes)
- if group_exists $group; then
- :
- else
- addgroup "$group" "$groupid"
- fi
+ group_exists $group $groupid
+ case $? in
+ 0) ;;
+ 1) addgroup "$group" "$groupid" ;;
+ esac
;;
esac
done; }
@@ -187,7 +159,7 @@ ADD)
token="$shadow_dir/${PKGNAME}"
if ${TEST} ! -d "$shadow_dir"; then
${MKDIR} $shadow_dir
- user_exists $user &&
+ user_exists $user $userid &&
${ECHO} "${PKGNAME}" > $preexist
fi
if ${TEST} -f "$token" && \
@@ -198,12 +170,14 @@ ADD)
fi
case ${_PKG_CREATE_USERGROUP} in
yes)
- if user_exists $user && group_exists $group; then
- :
- else
- adduser "$user" "$group" "$userid" \
+ group_exists $group || continue
+ user_exists $user $userid
+ case $? in
+ 0) ;;
+ 1) adduser "$user" "$group" "$userid" \
"$descr" "$home" "$shell"
- fi
+ ;;
+ esac
;;
esac
done; }
@@ -276,7 +250,7 @@ CHECK-ADD)
IFS="$SAVEIFS"
case $group in
"") continue ;;
- *) group_exists $group && continue ;;
+ *) group_exists $group $groupid && continue ;;
esac
case "$printed_header" in
yes) ;;
@@ -288,7 +262,7 @@ CHECK-ADD)
esac
case $groupid in
"") ${ECHO} " $group" ;;
- *) ${ECHO} " $group ($groupid)" ;;
+ *) ${ECHO} " $group (gid = $groupid)" ;;
esac
done
case "$printed_header" in
@@ -307,7 +281,7 @@ CHECK-ADD)
IFS="$SAVEIFS"
case $user in
"") continue ;;
- *) user_exists $user && continue ;;
+ *) user_exists $user $userid && continue ;;
esac
case "$printed_header" in
yes) ;;
@@ -317,11 +291,11 @@ CHECK-ADD)
${ECHO} ""
;;
esac
- : ${home:="${PKG_USER_HOME}"}
- : ${shell:="${PKG_USER_SHELL}"}
+ : ${home:="@PKG_USER_HOME@"}
+ : ${shell:="@PKG_USER_SHELL@"}
case $userid in
"") ${ECHO} " $user: $group, $home, $shell" ;;
- *) ${ECHO} " $user ($userid): $group, $home, $shell" ;;
+ *) ${ECHO} " $user (uid = $userid): $group, $home, $shell" ;;
esac
done
case "$printed_header" in
@@ -343,7 +317,7 @@ CHECK-REMOVE)
IFS="$SAVEIFS"
case $user in
"") continue ;;
- *) user_exists $user || continue ;;
+ *) user_exists $user $userid || continue ;;
esac
shadow_dir="${PKG_REFCOUNT_USERS_DBDIR}/$user"
${TEST} ! -d "$shadow_dir" || continue # refcount isn't zero
@@ -370,7 +344,7 @@ CHECK-REMOVE)
IFS="$SAVEIFS"
case $group in
"") continue ;;
- *) group_exists $group || continue ;;
+ *) group_exists $group $groupid || continue ;;
esac
shadow_dir="${PKG_REFCOUNT_GROUPS_DBDIR}/$group"
${TEST} ! -d "$shadow_dir" || continue # refcount isn't zero
diff --git a/mk/install/usergroup-check b/mk/install/usergroup-check
new file mode 100755
index 00000000000..0dd318d6eb3
--- /dev/null
+++ b/mk/install/usergroup-check
@@ -0,0 +1,126 @@
+#!/bin/sh
+#
+# $NetBSD: usergroup-check,v 1.1 2006/04/23 00:00:44 jlam Exp $
+#
+# Copyright (c) 2006 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the NetBSD
+# Foundation, Inc. and its contributors.
+# 4. Neither the name of The NetBSD Foundation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+######################################################################
+#
+# NAME
+# usergroup-check -- verify that users/groups match numeric IDs
+#
+# SYNOPSIS
+# usergroup-check -g [group_entry ...]
+# usergroup-check -u [user_entry ...]
+#
+# DESCRIPTION
+# usergroup-check checks for the existence of users and groups
+# and verifies that they match the requested numeric IDs if
+# given. The group_entry format matches that of /etc/group and
+# the user_entry format matches that of /etc/passwd, though the
+# field contents may be empty.
+#
+# usergroup-check exits 0 if the users and groups exist and match
+# the numeric IDs, and >0 otherwise.
+#
+# OPTIONS
+# The following command line arguments are supported.
+#
+# -g Indicates that the subsequent arguments are group entries.
+#
+# -u Indicates that the subsequent arguments are user entries.
+#
+######################################################################
+
+: ${PERL5=perl}
+
+self="${0##*/}"
+
+usage() {
+ echo 1>&2 "usage: $self -g [group_entry ...]"
+ echo 1>&2 " $self -u [user_entry ...]"
+}
+
+if test $# -lt 1; then
+ usage; exit 1
+fi
+
+check=
+case "$1" in
+-g) check=groups ;;
+-u) check=users ;;
+*) usage; exit 1 ;;
+esac
+shift
+
+missing_groups=
+missing_users=
+
+case $check in
+groups)
+ while test $# -gt 0; do
+ entry="$1"; shift
+ ( SAVEIFS="$IFS"; IFS=":"
+ set -- $entry; group="$1"; groupid="$2"
+ IFS="$SAVEIFS"
+ gid=`${PERL5} -le 'print scalar getgrnam shift' $group`
+ test -n "$gid" || exit 1
+ case "$groupid" in
+ ""|$gid) exit 0 ;;
+ *) exit 1 ;;
+ esac ) || missing_groups="$missing_groups $i"
+ done
+ ;;
+
+users)
+ missing_users=
+ while test $# -gt 0; do
+ entry="$1"; shift
+ ( SAVEIFS="$IFS"; IFS=":"
+ set -- $entry; user="$1"; userid="$3"
+ IFS="$SAVEIFS"
+ gid=`${PERL5} -le 'print scalar getpwnam shift' $user`
+ test -n "$gid" || exit 1
+ case "$userid" in
+ ""|$gid) exit 0 ;;
+ *) exit 1 ;;
+ esac ) || missing_users="$missing_users $i"
+ done
+ ;;
+esac
+
+test -z "$missing_groups" -a -z "$missing_users" || exit 1
+exit 0
diff --git a/mk/install/usergroupfuncs b/mk/install/usergroupfuncs
index 364ca4f2a69..bbea62ff70c 100644
--- a/mk/install/usergroupfuncs
+++ b/mk/install/usergroupfuncs
@@ -1,15 +1,84 @@
-# $NetBSD: usergroupfuncs,v 1.3 2005/10/28 20:05:46 jlam Exp $
+# $NetBSD: usergroupfuncs,v 1.4 2006/04/23 00:00:44 jlam Exp $
#
-# Default implementation of adduser() and addgroup() shell functions
-# for adding users and groups. This implementation assumes there are
-# NetBSD/Solaris-compatible versions of useradd(8) and groupadd(8)
-# available through ${USERADD} and ${GROUPADD}, respectively.
+# Default implementations of user_exists() and group_exists() shell
+# functions for checking the existence of users and groups, and of
+# adduser() and addgroup() shell functions for adding users and groups.
+# Assume there are NetBSD/Solaris-compatible versions of useradd(8) and
+# groupadd(8) available through ${USERADD} and ${GROUPADD}, respectively.
#
# Platform-specific replacements for this file should be located at:
#
# pkgsrc/mk/install/usergroupfuncs.${OPSYS}
#
+# group_exists group groupid
+# Returns 0 if $group exists and has gid $groupid
+# Returns 1 if neither $group nor $groupid exist
+# Returns 2 if $group or $groupid exist but don't match
+# Returns 3 for all errors
+#
+group_exists()
+{
+ _group="$1"; _groupid="$2"
+ ${TEST} -n "$_group" || return 3
+
+ # Check using chgrp to work properly in an NSS/NIS environment.
+ _testfile="./grouptest.tmp.$$"
+ ${ECHO} > $_testfile
+ if ${CHGRP} $_group $_testfile >/dev/null 2>&1; then
+ # $_group exists
+ _id=`${LS} -ln $_testfile 2>/dev/null | ${AWK} '{ print $4 }'`
+ ${TEST} -n "$_groupid" || _groupid=$_id
+ if ${TEST} "$_groupid" = "$_id"; then
+ ${RM} -f $_testfile; return 0
+ fi
+ ${RM} -f $_testfile; return 2
+ elif ${CHGRP} $_groupid $_testfile >/dev/null 2>&1; then
+ _name=`${LS} -l $_testfile 2>/dev/null | ${AWK} '{ print $4 }'`
+ if ${TEST} "$_name" != "$_groupid"; then
+ # $_group doesn't exist, but $_groupid exists
+ ${RM} -f $_testfile; return 2
+ fi
+ # neither $_group nor $_groupid exist
+ ${RM} -f $_testfile; return 1
+ fi
+ ${RM} -f $_testfile; return 3
+}
+
+# user_exists user userid
+# Returns 0 if $user exists and has uid $userid
+# Returns 1 if neither $user nor $userid exist
+# Returns 2 if $user or $userid exist but don't match
+# Returns 3 for all errors
+#
+user_exists()
+{
+ _user="$1"; _userid="$2"
+ ${TEST} -n "$_user" || return 3
+
+ # Check using chown to work properly in an NSS/NIS environment.
+ _testfile="./usertest.tmp.$$"
+ ${ECHO} > $_testfile
+ if ${CHOWN} $_user $_testfile >/dev/null 2>&1; then
+ # $_user exists
+ _id=`${LS} -ln $_testfile 2>/dev/null | ${AWK} '{ print $3 }'`
+ ${TEST} -n "$_userid" || _userid=$_id
+ if ${TEST} "$_userid" = "$_id"; then
+ ${RM} -f $_testfile; return 0
+ fi
+ ${RM} -f $_testfile; return 2
+ elif ${CHOWN} $_userid $_testfile >/dev/null 2>&1; then
+ _name=`${LS} -l $_testfile 2>/dev/null | ${AWK} '{ print $3 }'`
+ if ${TEST} "$_name" != "$_userid"; then
+ # $_user doesn't exist, but $_userid exists
+ ${RM} -f $_testfile; return 2
+ fi
+ # neither $_user nor $_userid exist
+ ${RM} -f $_testfile; return 1
+ fi
+ ${RM} -f $_testfile; return 3
+}
+
# adduser user group [userid] [descr] [home] [shell]
adduser()
{
diff --git a/mk/install/usergroupfuncs.DragonFly b/mk/install/usergroupfuncs.DragonFly
index 193be31b42b..91da004c73f 100644
--- a/mk/install/usergroupfuncs.DragonFly
+++ b/mk/install/usergroupfuncs.DragonFly
@@ -1,8 +1,76 @@
-# $NetBSD: usergroupfuncs.DragonFly,v 1.1 2005/10/28 20:09:38 joerg Exp $
+# $NetBSD: usergroupfuncs.DragonFly,v 1.2 2006/04/23 00:00:44 jlam Exp $
#
# Platform-specific adduser and addgroup functionality
# on top of pw(8).
+# group_exists group groupid
+# Returns 0 if $group exists and has gid $groupid
+# Returns 1 if neither $group nor $groupid exist
+# Returns 2 if $group or $groupid exist but don't match
+# Returns 3 for all errors
+#
+group_exists()
+{
+ _group="$1"; _groupid="$2"
+ ${TEST} -n "$_group" || return 3
+
+ # Check using chgrp to work properly in an NSS/NIS environment.
+ _testfile="./grouptest.tmp.$$"
+ ${ECHO} > $_testfile
+ if ${CHGRP} $_group $_testfile >/dev/null 2>&1; then
+ # $_group exists
+ _id=`${LS} -ln $_testfile 2>/dev/null | ${AWK} '{ print $4 }'`
+ ${TEST} -n "$_groupid" || _groupid=$_id
+ if ${TEST} "$_groupid" = "$_id"; then
+ ${RM} -f $_testfile; return 0
+ fi
+ ${RM} -f $_testfile; return 2
+ elif ${CHGRP} $_groupid $_testfile >/dev/null 2>&1; then
+ _name=`${LS} -l $_testfile 2>/dev/null | ${AWK} '{ print $4 }'`
+ if ${TEST} "$_name" != "$_groupid"; then
+ # $_group doesn't exist, but $_groupid exists
+ ${RM} -f $_testfile; return 2
+ fi
+ # neither $_group nor $_groupid exist
+ ${RM} -f $_testfile; return 1
+ fi
+ ${RM} -f $_testfile; return 3
+}
+
+# user_exists user userid
+# Returns 0 if $user exists and has uid $userid
+# Returns 1 if neither $user nor $userid exist
+# Returns 2 if $user or $userid exist but don't match
+# Returns 3 for all errors
+#
+user_exists()
+{
+ _user="$1"; _userid="$2"
+ ${TEST} -n "$_user" || return 3
+
+ # Check using chown to work properly in an NSS/NIS environment.
+ _testfile="./usertest.tmp.$$"
+ ${ECHO} > $_testfile
+ if ${CHOWN} $_user $_testfile >/dev/null 2>&1; then
+ # $_user exists
+ _id=`${LS} -ln $_testfile 2>/dev/null | ${AWK} '{ print $3 }'`
+ ${TEST} -n "$_userid" || _userid=$_id
+ if ${TEST} "$_userid" = "$_id"; then
+ ${RM} -f $_testfile; return 0
+ fi
+ ${RM} -f $_testfile; return 2
+ elif ${CHOWN} $_userid $_testfile >/dev/null 2>&1; then
+ _name=`${LS} -l $_testfile 2>/dev/null | ${AWK} '{ print $3 }'`
+ if ${TEST} "$_name" != "$_userid"; then
+ # $_user doesn't exist, but $_userid exists
+ ${RM} -f $_testfile; return 2
+ fi
+ # neither $_user nor $_userid exist
+ ${RM} -f $_testfile; return 1
+ fi
+ ${RM} -f $_testfile; return 3
+}
+
# adduser user group [userid] [descr] [home] [shell]
adduser()
{
diff --git a/mk/install/usergroupfuncs.FreeBSD b/mk/install/usergroupfuncs.FreeBSD
index e5b0ee0e465..069339008de 100644
--- a/mk/install/usergroupfuncs.FreeBSD
+++ b/mk/install/usergroupfuncs.FreeBSD
@@ -1,8 +1,76 @@
-# $NetBSD: usergroupfuncs.FreeBSD,v 1.1 2005/11/06 19:45:08 joerg Exp $
+# $NetBSD: usergroupfuncs.FreeBSD,v 1.2 2006/04/23 00:00:44 jlam Exp $
#
# Platform-specific adduser and addgroup functionality
# on top of pw(8).
+# group_exists group groupid
+# Returns 0 if $group exists and has gid $groupid
+# Returns 1 if neither $group nor $groupid exist
+# Returns 2 if $group or $groupid exist but don't match
+# Returns 3 for all errors
+#
+group_exists()
+{
+ _group="$1"; _groupid="$2"
+ ${TEST} -n "$_group" || return 3
+
+ # Check using chgrp to work properly in an NSS/NIS environment.
+ _testfile="./grouptest.tmp.$$"
+ ${ECHO} > $_testfile
+ if ${CHGRP} $_group $_testfile >/dev/null 2>&1; then
+ # $_group exists
+ _id=`${LS} -ln $_testfile 2>/dev/null | ${AWK} '{ print $4 }'`
+ ${TEST} -n "$_groupid" || _groupid=$_id
+ if ${TEST} "$_groupid" = "$_id"; then
+ ${RM} -f $_testfile; return 0
+ fi
+ ${RM} -f $_testfile; return 2
+ elif ${CHGRP} $_groupid $_testfile >/dev/null 2>&1; then
+ _name=`${LS} -l $_testfile 2>/dev/null | ${AWK} '{ print $4 }'`
+ if ${TEST} "$_name" != "$_groupid"; then
+ # $_group doesn't exist, but $_groupid exists
+ ${RM} -f $_testfile; return 2
+ fi
+ # neither $_group nor $_groupid exist
+ ${RM} -f $_testfile; return 1
+ fi
+ ${RM} -f $_testfile; return 3
+}
+
+# user_exists user userid
+# Returns 0 if $user exists and has uid $userid
+# Returns 1 if neither $user nor $userid exist
+# Returns 2 if $user or $userid exist but don't match
+# Returns 3 for all errors
+#
+user_exists()
+{
+ _user="$1"; _userid="$2"
+ ${TEST} -n "$_user" || return 3
+
+ # Check using chown to work properly in an NSS/NIS environment.
+ _testfile="./usertest.tmp.$$"
+ ${ECHO} > $_testfile
+ if ${CHOWN} $_user $_testfile >/dev/null 2>&1; then
+ # $_user exists
+ _id=`${LS} -ln $_testfile 2>/dev/null | ${AWK} '{ print $3 }'`
+ ${TEST} -n "$_userid" || _userid=$_id
+ if ${TEST} "$_userid" = "$_id"; then
+ ${RM} -f $_testfile; return 0
+ fi
+ ${RM} -f $_testfile; return 2
+ elif ${CHOWN} $_userid $_testfile >/dev/null 2>&1; then
+ _name=`${LS} -l $_testfile 2>/dev/null | ${AWK} '{ print $3 }'`
+ if ${TEST} "$_name" != "$_userid"; then
+ # $_user doesn't exist, but $_userid exists
+ ${RM} -f $_testfile; return 2
+ fi
+ # neither $_user nor $_userid exist
+ ${RM} -f $_testfile; return 1
+ fi
+ ${RM} -f $_testfile; return 3
+}
+
# adduser user group [userid] [descr] [home] [shell]
adduser()
{