Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

513 lines
9.3 KiB
C

static char sccsid[] = "@(#)46 1.7 src/bos/usr/bin/usrck/usrgroups.c, cmdsadm, bos411, 9428A410j 6/15/90 23:44:04";
/*
* COMPONENT_NAME: (CMDSADM) security: system administration
*
* FUNCTIONS: rm_group, ck_group, ck_pgrp, ck_groups, ck_admgroups,
* ck_sugroups, fix_groups, fix_admgroups, fix_sugroups
*
* ORIGINS: 27
*
* IBM CONFIDENTIAL -- (IBM Confidential Restricted when
* combined with the aggregated modules for this product)
* SOURCE MATERIALS
* (C) COPYRIGHT International Business Machines Corp. 1989
* All Rights Reserved
*
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
#include <sys/types.h>
#include <sys/audit.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <usersec.h>
#include <pwd.h>
#include "usrck_msg.h"
#include "usrck.h"
/*
* Global data
*/
extern int verbose;
extern int fixit;
extern struct groups *groups;
extern int ngroups;
extern int yp_grp_entries;
extern int grpcmp (const void *, const void *);
/*
* NAME: rm_group
*
* FUNCTION: Remove a group from a double-null terminated list
*
* EXECUTION ENVIRONMENT:
*
* User process. Local to this file.
*
* NOTES:
* Removes a group from a double-null terminate list of groups
* by copying all of the groups afterwards forward to this
* point.
*
* RETURNS: NONE
*/
static void
rm_group (groups)
char *groups;
{
char *old,
*new;
/*
* Point old at where the current group is and point
* new at the start of the next group in the list.
*/
new = old = groups;
while (*new++)
;
/*
* Copy from the new location backwards until a double
* null is seen. Then paste an extra null on to double
* null terminate the new string.
*/
while (*new)
while (*old++ = *new++)
;
*old = '\0';
}
/*
* NAME: ck_group
*
* FUNCTION: Check for the existence of a group by name
*
* EXECUTION ENVIRONMENT:
*
* User process. Local to this file.
*
* NOTES:
* Binary search of the group table for the named group
*
* RETURNS: Index of group entry, or -1 on failure
*/
static int
ck_group (group)
char *group;
{
int high;
int low;
int test;
int i;
low = 0;
high = ngroups - 1;
test = (low + high) / 2;
while (low <= high) {
if (i = strcmp (group, groups[test].grp_name)) {
if (i > 0)
low = test + 1;
else
high = test - 1;
test = (low + high) / 2;
} else {
if (! groups[test].grp_valid)
return -1;
else
return test;
}
}
return -1;
}
/*
* NAME: ck_pgrp
*
* FUNCTION: Check for existence of primary group
*
* EXECUTION ENVIRONMENT:
*
* User process.
*
* NOTES:
* Checks the list of groups for the existence of this
* users primary group.
*
* RETURNS: Zero if the group exists, non-zero otherwise
*/
int
ck_pgrp (struct users *user)
{
char gid[10];
int i;
/*
* Locate the user's primary group in the groups table.
* Report an error if one doesn't exist.
*/
for (i = 0;i < ngroups;i++)
if (groups[i].grp_gid == user->usr_gid)
return 0;
if (yp_grp_entries) {
sprintf (gid, "%lu", user->usr_gid);
msg2 (MSGSTR (M_ASSYPGRP, DEF_ASSYPGRP),
user->usr_name, gid);
return 0;
} else {
msg2 (MSGSTR (M_NOPGRP, DEF_NOPGRP),
user->usr_name, user->usr_gid);
return -1;
}
}
/*
* NAME: ck_groups
*
* FUNCTION: Check a users concurrent groupset for validity
*
* EXECUTION ENVIRONMENT:
*
* User process.
*
* NOTES:
* Each member in the user's concurrent group set is checked
* for existence.
*
* RETURNS: Zero if all groups exist, non-zero otherwise.
*/
int
ck_groups (char *name)
{
char *groups;
int errors = 0;
/*
* See if the user has a concurrent group set
*/
if (getuserattr (name, S_GROUPS, (void *) &groups, 0) || ! groups)
return 0;
/*
* Check each member of the concurrent group set for existence
* and count how many don't exist. This will be returned as
* the error code.
*/
while (*groups) {
if (ck_group (groups) < 0) {
if (yp_grp_entries) {
msg2 (MSGSTR (M_ASSYPGRP, DEF_ASSYPGRP),
name, groups);
} else {
errors++;
msg2 (MSGSTR (M_NOGROUP, DEF_NOGROUP),
name, groups);
}
}
while (*groups++)
;
}
return errors;
}
/*
* NAME: ck_admgroups
*
* FUNCTION: Check a users administrative groupset for validity
*
* EXECUTION ENVIRONMENT:
*
* User process.
*
* NOTES:
* Each member in the user's administrative group set is checked
* for existence.
*
* RETURNS: Zero if all groups exist, non-zero otherwise.
*/
int
ck_admgroups (struct users *user)
{
char *groups;
char *name = user->usr_name;
int errors = 0;
/*
* See if the user has an administrative group set
*/
if (getuserattr (name, S_ADMGROUPS, (void *) &groups, 0)
|| ! groups)
return 0;
/*
* Check each member of the administrative group set for existence
* and count how many don't exist. This will be returned as
* the error code.
*/
while (*groups) {
if (ck_group (groups) < 0) {
if (yp_grp_entries) {
msg2 (MSGSTR (M_ASSYPGRP, DEF_ASSYPGRP),
name, groups);
} else {
errors++;
msg2 (MSGSTR (M_NOADMGRP, DEF_NOADMGRP),
name, groups);
}
}
while (*groups++)
;
}
return errors;
}
/*
* NAME: ck_sugroups
*
* FUNCTION: Check a users switch-user groupset for validity
*
* EXECUTION ENVIRONMENT:
*
* User process.
*
* NOTES:
* Each member in the user's switch-user group set is checked
* for existence.
*
* RETURNS: Zero if all groups exist, non-zero otherwise.
*/
int
ck_sugroups (struct users *user)
{
char *groups;
char *name = user->usr_name;
int errors = 0;
/*
* See if the user has a switch-user group set
*/
if (getuserattr (name, S_SUGROUPS, (void *) &groups, SEC_LIST)
|| ! groups)
return 0;
/*
* Check each member of the switch-user group set for existence
* and count how many don't exist. This will be returned as
* the error code.
*/
while (*groups) {
if (strcmp (groups, "ALL") != 0 && ck_group (groups) < 0) {
if (yp_grp_entries) {
msg2 (MSGSTR (M_ASSYPGRP, DEF_ASSYPGRP),
name, groups);
} else {
errors++;
msg2 (MSGSTR (M_NOSUGRP, DEF_NOSUGRP),
name, groups);
}
}
while (*groups++)
;
}
return errors;
}
/*
* NAME: fix_groups
*
* FUNCTION: Fix a users concurrent groupset
*
* EXECUTION ENVIRONMENT:
*
* User process.
*
* NOTES:
* Each member in the user's concurrent group set is checked
* for existence and non-existent groups are removed.
*
* RETURNS: NONE
*/
void
fix_groups (char *name)
{
char *groups;
char *cp;
char buf[MAXATTRSIZ];
/*
* Get the users concurrent group set
*/
if (getuserattr (name, S_GROUPS, (void *) &groups, 0) || ! groups)
return;
for (cp = buf;groups[0] || groups[1];*cp++ = *groups++)
;
*cp = 0;
groups = buf;
/*
* Check each member of the concurrent group set for existence
* and remove those that don't exist.
*/
while (*groups) {
if (ck_group (groups) < 0) {
if (yp_grp_entries)
msg2 (MSGSTR (M_ASSYPGRP, DEF_ASSYPGRP),
name, groups);
else
rm_group (groups);
} else
while (*groups++)
;
}
if (putuserattr (name, S_GROUPS, (void *) buf, 0))
fprintf (stderr, MSGSTR (M_BADPUT, DEF_BADPUT), name, S_GROUPS);
}
/*
* NAME: fix_admgroups
*
* FUNCTION: Fix a users administrative groupset
*
* EXECUTION ENVIRONMENT:
*
* User process.
*
* NOTES:
* Each member in the user's administrative group set is checked
* for existence and non-existent groups are removed.
*
* RETURNS: Zero if all groups exist, non-zero otherwise.
*/
void
fix_admgroups (char *name)
{
char *groups;
char *cp;
char buf[MAXATTRSIZ];
/*
* Get the user's administrative groupset
*/
if (getuserattr (name, S_ADMGROUPS, (void *) &groups, 0) || ! groups)
return;
for (cp = buf;groups[0] || groups[1];*cp++ = *groups++)
;
*cp = 0;
groups = buf;
/*
* Check each member of the administrative group set for existence
* and remove those that don't exist.
*/
while (*groups) {
if (ck_group (groups) < 0) {
if (yp_grp_entries)
msg2 (MSGSTR (M_ASSYPGRP, DEF_ASSYPGRP),
name, groups);
else
rm_group (groups);
} else
while (*groups++)
;
}
if (putuserattr (name, S_ADMGROUPS, (void *) buf, 0))
fprintf (stderr, MSGSTR (M_BADPUT, DEF_BADPUT),
name, S_ADMGROUPS);
}
/*
* NAME: fix_sugroups
*
* FUNCTION: Fix a users switch-user groupset
*
* EXECUTION ENVIRONMENT:
*
* User process.
*
* NOTES:
* Each member in the user's switch-user group set is checked
* for existence and all non-existent groups are removed.
*
* RETURNS: Zero if all groups exist, non-zero otherwise.
*/
void
fix_sugroups (char *name)
{
char *groups;
char *cp;
char buf[MAXATTRSIZ];
/*
* Get the users switch-user group set
*/
if (getuserattr (name, S_SUGROUPS, (void *) &groups, SEC_LIST)
|| ! groups)
return;
for (cp = buf;groups[0] || groups[1];*cp++ = *groups++)
;
*cp = 0;
groups = buf;
/*
* Check each member of the switch-user group set for existence
* and remove those that don't exist.
*/
while (*groups) {
if (strcmp (groups, "ALL") != 0 && ck_group (groups) < 0) {
if (yp_grp_entries)
msg2 (MSGSTR (M_ASSYPGRP, DEF_ASSYPGRP),
name, groups);
else
rm_group (groups);
} else
while (*groups++)
;
}
if (putuserattr (name, S_SUGROUPS, (void *) buf, SEC_LIST))
fprintf (stderr, MSGSTR (M_BADPUT, DEF_BADPUT),
name, S_SUGROUPS);
}