f93cf255d4
Closes #238 Update all files to list SPDX license shortname. Most files are BSD 3 clause license. The exceptions are: serge@sl ~/src/shadow$ git grep SPDX-License | grep -v BSD-3-Clause contrib/atudel:# SPDX-License-Identifier: BSD-4-Clause lib/tcbfuncs.c: * SPDX-License-Identifier: 0BSD libmisc/salt.c: * SPDX-License-Identifier: Unlicense src/login_nopam.c: * SPDX-License-Identifier: Unlicense src/nologin.c: * SPDX-License-Identifier: BSD-2-Clause src/vipw.c: * SPDX-License-Identifier: GPL-2.0-or-later Signed-off-by: Serge Hallyn <serge@hallyn.com>
466 lines
12 KiB
Bash
466 lines
12 KiB
Bash
#!/bin/sh
|
|
# This is a shell archive (produced by GNU sharutils 4.2.1).
|
|
# To extract the files from this archive, save it to some FILE, remove
|
|
# everything before the `!/bin/sh' line above, then type `sh FILE'.
|
|
#
|
|
# Made on 2000-05-25 14:41 CDT by <gk4@gnu.austin.ibm.com>.
|
|
# Source directory was `/home/gk4/src/groupmem'.
|
|
#
|
|
# Existing files will *not* be overwritten unless `-c' is specified.
|
|
#
|
|
# This shar contains:
|
|
# length mode name
|
|
# ------ ---------- ------------------------------------------
|
|
# 1960 -rw-r--r-- Makefile
|
|
# 6348 -rw-r--r-- groupmems.c
|
|
# 3372 -rw------- groupmems.8
|
|
#
|
|
save_IFS="${IFS}"
|
|
IFS="${IFS}:"
|
|
gettext_dir=FAILED
|
|
locale_dir=FAILED
|
|
first_param="$1"
|
|
for dir in $PATH
|
|
do
|
|
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
|
|
&& ($dir/gettext --version >/dev/null 2>&1)
|
|
then
|
|
set `$dir/gettext --version 2>&1`
|
|
if test "$3" = GNU
|
|
then
|
|
gettext_dir=$dir
|
|
fi
|
|
fi
|
|
if test "$locale_dir" = FAILED && test -f $dir/shar \
|
|
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
|
|
then
|
|
locale_dir=`$dir/shar --print-text-domain-dir`
|
|
fi
|
|
done
|
|
IFS="$save_IFS"
|
|
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
|
|
then
|
|
echo=echo
|
|
else
|
|
TEXTDOMAINDIR=$locale_dir
|
|
export TEXTDOMAINDIR
|
|
TEXTDOMAIN=sharutils
|
|
export TEXTDOMAIN
|
|
echo="$gettext_dir/gettext -s"
|
|
fi
|
|
if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then
|
|
shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
|
|
elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then
|
|
shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
|
|
elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then
|
|
shar_touch='touch -am $3$4$5$6$2 "$8"'
|
|
else
|
|
shar_touch=:
|
|
echo
|
|
$echo 'WARNING: not restoring timestamps. Consider getting and'
|
|
$echo "installing GNU \`touch', distributed in GNU File Utilities..."
|
|
echo
|
|
fi
|
|
rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch
|
|
#
|
|
if mkdir _sh10937; then
|
|
$echo 'x -' 'creating lock directory'
|
|
else
|
|
$echo 'failed to create lock directory'
|
|
exit 1
|
|
fi
|
|
# ============= Makefile ==============
|
|
if test -f 'Makefile' && test "$first_param" != -c; then
|
|
$echo 'x -' SKIPPING 'Makefile' '(file already exists)'
|
|
else
|
|
$echo 'x -' extracting 'Makefile' '(text)'
|
|
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
|
|
/*
|
|
# SPDX-FileCopyrightText: 2000, International Business Machines, Inc.
|
|
# SPDX-FileCopyrightText: 2000, George Kraft IV, gk4@us.ibm.com
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
X
|
|
all: groupmems
|
|
X
|
|
groupmems: groupmems.c
|
|
X cc -g -o groupmems groupmems.c -L. -lshadow
|
|
X
|
|
install: groupmems
|
|
X -/usr/sbin/groupadd groups
|
|
X install -o root -g groups -m 4770 groupmems /usr/bin
|
|
X
|
|
install.man: groupmems.8
|
|
X install -o root -g root -m 644 groupmems.8 /usr/man/man8
|
|
X
|
|
SHAR_EOF
|
|
(set 20 00 05 25 14 40 28 'Makefile'; eval "$shar_touch") &&
|
|
chmod 0644 'Makefile' ||
|
|
$echo 'restore of' 'Makefile' 'failed'
|
|
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
|
|
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
|
|
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|
|
|| $echo 'Makefile:' 'MD5 check failed'
|
|
b46cf7ef8d59149093c011ced3f3103c Makefile
|
|
SHAR_EOF
|
|
else
|
|
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`"
|
|
test 1960 -eq "$shar_count" ||
|
|
$echo 'Makefile:' 'original size' '1960,' 'current size' "$shar_count!"
|
|
fi
|
|
fi
|
|
# ============= groupmems.c ==============
|
|
if test -f 'groupmems.c' && test "$first_param" != -c; then
|
|
$echo 'x -' SKIPPING 'groupmems.c' '(file already exists)'
|
|
else
|
|
$echo 'x -' extracting 'groupmems.c' '(text)'
|
|
sed 's/^X//' << 'SHAR_EOF' > 'groupmems.c' &&
|
|
/*
|
|
X * SPDX-FileCopyrightText: 2000, International Business Machines, Inc.
|
|
X * SPDX-FileCopyrightText: 2000, George Kraft IV, gk4@us.ibm.com
|
|
X * SPDX-License-Identifier: BSD-3-Clause
|
|
X */
|
|
/*
|
|
**
|
|
** Utility "groupmem" adds and deletes members from a user's group.
|
|
**
|
|
** Setup (as "root"):
|
|
**
|
|
** groupadd -r groups
|
|
** chmod 2770 groupmems
|
|
** chown root.groups groupmems
|
|
** groupmems -g groups -a gk4
|
|
**
|
|
** Usage (as "gk4"):
|
|
**
|
|
** groupmems -a olive
|
|
** groupmems -a jordan
|
|
** groupmems -a meghan
|
|
** groupmems -a morgan
|
|
** groupmems -a jake
|
|
** groupmems -l
|
|
** groupmems -d jake
|
|
** groupmems -l
|
|
*/
|
|
X
|
|
#include <stdio.h>
|
|
#include <pwd.h>
|
|
#include <grp.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include "defines.h"
|
|
#include "groupio.h"
|
|
X
|
|
/* Exit Status Values */
|
|
X
|
|
#define EXIT_SUCCESS 0 /* success */
|
|
#define EXIT_USAGE 1 /* invalid command syntax */
|
|
#define EXIT_GROUP_FILE 2 /* group file access problems */
|
|
#define EXIT_NOT_ROOT 3 /* not superuser */
|
|
#define EXIT_NOT_EROOT 4 /* not effective superuser */
|
|
#define EXIT_NOT_PRIMARY 5 /* not primary owner of group */
|
|
#define EXIT_NOT_MEMBER 6 /* member of group does not exist */
|
|
#define EXIT_MEMBER_EXISTS 7 /* member of group already exists */
|
|
X
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
X
|
|
/* Globals */
|
|
X
|
|
extern int optind;
|
|
extern char *optarg;
|
|
static char *adduser = NULL;
|
|
static char *deluser = NULL;
|
|
static char *thisgroup = NULL;
|
|
static int purge = FALSE;
|
|
static int list = FALSE;
|
|
static int exclusive = 0;
|
|
X
|
|
static int isroot(void) {
|
|
X return getuid() ? FALSE : TRUE;
|
|
}
|
|
X
|
|
static int isgroup(void) {
|
|
X gid_t g = getgid();
|
|
X struct group *grp = getgrgid(g);
|
|
X
|
|
X return TRUE;
|
|
}
|
|
X
|
|
static char *whoami(void) {
|
|
X struct group *grp = getgrgid(getgid());
|
|
X struct passwd *usr = getpwuid(getuid());
|
|
X
|
|
X if (0 == strcmp(usr->pw_name, grp->gr_name)) {
|
|
X return (char *)strdup(usr->pw_name);
|
|
X } else {
|
|
X return NULL;
|
|
X }
|
|
}
|
|
X
|
|
static void
|
|
addtogroup(char *user, char **members) {
|
|
X int i;
|
|
X char **pmembers;
|
|
X
|
|
X for (i = 0; NULL != members[i]; i++ ) {
|
|
X if (0 == strcmp(user, members[i])) {
|
|
X fprintf(stderr, "Member already exists\n");
|
|
X exit(EXIT_MEMBER_EXISTS);
|
|
X }
|
|
X }
|
|
X
|
|
X if (0 == i) {
|
|
X pmembers = (char **)calloc(2, sizeof(char *));
|
|
X } else {
|
|
X pmembers = (char **)realloc(members, sizeof(char *)*(i+1));
|
|
X }
|
|
X
|
|
X *members = *pmembers;
|
|
X members[i] = user;
|
|
X members[i+1] = NULL;
|
|
}
|
|
X
|
|
static void
|
|
rmfromgroup(char *user, char **members) {
|
|
X int i;
|
|
X int found = FALSE;
|
|
X
|
|
X i = 0;
|
|
X while (!found && NULL != members[i]) {
|
|
X if (0 == strcmp(user, members[i])) {
|
|
X found = TRUE;
|
|
X } else {
|
|
X i++;
|
|
X }
|
|
X }
|
|
X
|
|
X while (found && NULL != members[i]) {
|
|
X members[i] = members[++i];
|
|
X }
|
|
X
|
|
X if (!found) {
|
|
X fprintf(stderr, "Member to remove could not be found\n");
|
|
X exit(EXIT_NOT_MEMBER);
|
|
X }
|
|
}
|
|
X
|
|
static void
|
|
nomembers(char **members) {
|
|
X int i;
|
|
X
|
|
X for (i = 0; NULL != members[i]; i++ ) {
|
|
X members[i] = NULL;
|
|
X }
|
|
}
|
|
X
|
|
static void
|
|
members(char **members) {
|
|
X int i;
|
|
X
|
|
X for (i = 0; NULL != members[i]; i++ ) {
|
|
X printf("%s ", members[i]);
|
|
X
|
|
X if (NULL == members[i+1]) {
|
|
X printf("\n");
|
|
X } else {
|
|
X printf(" ");
|
|
X }
|
|
X }
|
|
}
|
|
X
|
|
static void usage(void) {
|
|
X fprintf(stderr, "usage: groupmems -a username | -d username | -D | -l [-g groupname]\n");
|
|
X exit(EXIT_USAGE);
|
|
}
|
|
X
|
|
main(int argc, char **argv) {
|
|
X int arg, i;
|
|
X char *name;
|
|
X struct group *grp;
|
|
X
|
|
X while ((arg = getopt(argc, argv, "a:d:g:Dl")) != EOF) {
|
|
X switch (arg) {
|
|
X case 'a':
|
|
X adduser = strdup(optarg);
|
|
X ++exclusive;
|
|
X break;
|
|
X case 'd':
|
|
X deluser = strdup(optarg);
|
|
X ++exclusive;
|
|
X break;
|
|
X case 'g':
|
|
X thisgroup = strdup(optarg);
|
|
X break;
|
|
X case 'D':
|
|
X purge = TRUE;
|
|
X ++exclusive;
|
|
X break;
|
|
X case 'l':
|
|
X list = TRUE;
|
|
X ++exclusive;
|
|
X break;
|
|
X default:
|
|
X usage();
|
|
X }
|
|
X }
|
|
X
|
|
X if (exclusive > 1 || optind < argc) {
|
|
X usage();
|
|
X }
|
|
X
|
|
X if (!isroot() && NULL != thisgroup) {
|
|
X fprintf(stderr, "Only root can add members to different groups\n");
|
|
X exit(EXIT_NOT_ROOT);
|
|
X } else if (isroot() && NULL != thisgroup) {
|
|
X name = thisgroup;
|
|
X } else if (!isgroup()) {
|
|
X fprintf(stderr, "Group access is required\n");
|
|
X exit(EXIT_NOT_EROOT);
|
|
X } else if (NULL == (name = whoami())) {
|
|
X fprintf(stderr, "Not primary owner of current group\n");
|
|
X exit(EXIT_NOT_PRIMARY);
|
|
X }
|
|
X
|
|
X if (!gr_lock()) {
|
|
X fprintf(stderr, "Unable to lock group file\n");
|
|
X exit(EXIT_GROUP_FILE);
|
|
X }
|
|
X
|
|
X if (!gr_open(O_RDWR)) {
|
|
X fprintf(stderr, "Unable to open group file\n");
|
|
X exit(EXIT_GROUP_FILE);
|
|
X }
|
|
X
|
|
X grp = (struct group *)gr_locate(name);
|
|
X
|
|
X if (NULL != adduser) {
|
|
X addtogroup(adduser, grp->gr_mem);
|
|
X gr_update(grp);
|
|
X } else if (NULL != deluser) {
|
|
X rmfromgroup(deluser, grp->gr_mem);
|
|
X gr_update(grp);
|
|
X } else if (purge) {
|
|
X nomembers(grp->gr_mem);
|
|
X gr_update(grp);
|
|
X } else if (list) {
|
|
X members(grp->gr_mem);
|
|
X }
|
|
X
|
|
X if (!gr_close()) {
|
|
X fprintf(stderr, "Cannot close group file\n");
|
|
X exit(EXIT_GROUP_FILE);
|
|
X }
|
|
X
|
|
X gr_unlock();
|
|
X
|
|
X exit(EXIT_SUCCESS);
|
|
}
|
|
X
|
|
/* EOF */
|
|
SHAR_EOF
|
|
(set 20 00 05 25 14 36 38 'groupmems.c'; eval "$shar_touch") &&
|
|
chmod 0644 'groupmems.c' ||
|
|
$echo 'restore of' 'groupmems.c' 'failed'
|
|
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
|
|
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
|
|
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|
|
|| $echo 'groupmems.c:' 'MD5 check failed'
|
|
f0dd68f8d762d89d24d3ce1f4141f981 groupmems.c
|
|
SHAR_EOF
|
|
else
|
|
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.c'`"
|
|
test 6348 -eq "$shar_count" ||
|
|
$echo 'groupmems.c:' 'original size' '6348,' 'current size' "$shar_count!"
|
|
fi
|
|
fi
|
|
# ============= groupmems.8 ==============
|
|
if test -f 'groupmems.8' && test "$first_param" != -c; then
|
|
$echo 'x -' SKIPPING 'groupmems.8' '(file already exists)'
|
|
else
|
|
$echo 'x -' extracting 'groupmems.8' '(text)'
|
|
sed 's/^X//' << 'SHAR_EOF' > 'groupmems.8' &&
|
|
X.\"
|
|
X.\" SPDX-FileCopyrightText: 2000, International Business Machines, Inc.
|
|
X.\" SPDX-FileCopyrightText: 2000, George Kraft IV, gk4@us.ibm.com
|
|
X.\" SPDX-License-Identifier: BSD-3-Clause
|
|
X.\"
|
|
X.\" $Id$
|
|
X.\"
|
|
X.TH GROUPMEMS 8
|
|
X.SH NAME
|
|
groupmems \- Administer members of a user's primary group
|
|
X.SH SYNOPSIS
|
|
X.B groupmems
|
|
\fB-a\fI user_name \fR |
|
|
\fB-d\fI user_name \fR |
|
|
\fB-l\fR |
|
|
\fB-D\fR |
|
|
[\fB-g\fI group_name \fR]
|
|
X.SH DESCRIPTION
|
|
The \fBgroupmems\fR utility allows a user to administer their own
|
|
group membership list without the requirement of superuser privileges.
|
|
The \fBgroupmems\fR utility is for systems that configure its users to
|
|
be in their own name sake primary group (i.e., guest / guest).
|
|
X.P
|
|
Only the superuser, as administrator, can use \fBgroupmems\fR to alter
|
|
the memberships of other groups.
|
|
X.IP "\fB-a \fIuser_name\fR"
|
|
Add a new user to the group membership list.
|
|
X.IP "\fB-d \fIuser_name\fR"
|
|
Delete a user from the group membership list.
|
|
X.IP "\fB-l\fR"
|
|
List the group membership list.
|
|
X.IP "\fB-D\fR"
|
|
Delete all users from the group membership list.
|
|
X.IP "\fB-g \fIgroup_name\fR"
|
|
The superuser can specify which group membership list to modify.
|
|
X.SH SETUP
|
|
The \fBgroupmems\fR executable should be in mode \fB2770\fR as user \fBroot\fR
|
|
and in group \fBgroups\fR. The system administrator can add users to
|
|
group groups to allow or disallow them using the \fBgroupmems\fR utility
|
|
to manager their own group membership list.
|
|
X.P
|
|
X $ groupadd -r groups
|
|
X.br
|
|
X $ chmod 2770 groupmems
|
|
X.br
|
|
X $ chown root.groups groupmems
|
|
X.br
|
|
X $ groupmems -g groups -a gk4
|
|
X.SH FILES
|
|
/etc/group
|
|
X.br
|
|
/etc/gshadow
|
|
X.SH SEE ALSO
|
|
X.BR chfn (1),
|
|
X.BR chsh (1),
|
|
X.BR useradd (8),
|
|
X.BR userdel (8),
|
|
X.BR usermod (8),
|
|
X.BR passwd (1),
|
|
X.BR groupadd (8),
|
|
X.BR groupdel (8)
|
|
X.SH AUTHOR
|
|
George Kraft IV (gk4@us.ibm.com)
|
|
X.\" EOF
|
|
SHAR_EOF
|
|
(set 20 00 05 25 14 38 23 'groupmems.8'; eval "$shar_touch") &&
|
|
chmod 0600 'groupmems.8' ||
|
|
$echo 'restore of' 'groupmems.8' 'failed'
|
|
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
|
|
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
|
|
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|
|
|| $echo 'groupmems.8:' 'MD5 check failed'
|
|
181e6cd3a3c9d3df320197fa2cde2b4a groupmems.8
|
|
SHAR_EOF
|
|
else
|
|
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.8'`"
|
|
test 3372 -eq "$shar_count" ||
|
|
$echo 'groupmems.8:' 'original size' '3372,' 'current size' "$shar_count!"
|
|
fi
|
|
fi
|
|
rm -fr _sh10937
|
|
exit 0
|