Bug 12512

Summary: usermod/useradd/groupadd fail to check validity of gid number
Product: [Retired] Red Hat Linux Reporter: Karl DeBisschop <kdebisschop>
Component: shadow-utilsAssignee: Bernhard Rosenkraenzer <bero>
Status: CLOSED RAWHIDE QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 6.2   
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2000-06-19 15:32:08 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Karl DeBisschop 2000-06-19 15:20:55 UTC
groupmod can create illegal groups
usermod can add users to illegal groups

if you add yourself to an illegal group, you will not be able to login
again, at least with some versions of login.

This seems to be a bug - these utilities should protect against simple
errors like this (in my case, I added an extra zero to the group number,
resulting in an out of reange group). Possibly login should be
considered to have a bug - some implementations log you in with only the
primary group, while others permit no login - but I cannot vouch for
security implications of either approach)

the attached code does a simple check of the validity of the group file
for a given user, using the installed version of initgroups on the build
machine. Perhaps a better approach would be to fork a trail `su` -- but
some sort of check should probably be done, and checking int value will
break if ported to a system with a larger gid range.

#define VERSION "$ Revision 0.1$"

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <getopt.h>

void print_version(char *cmd);
void print_usage(char *cmd);

int main (int argc, char **argv)
{
        char *username;
        struct passwd *pw;
        gid_t gid;
        int c;
  int option_index = 0;
  static struct option long_options[] =
  { 
    {"help",    no_argument,      0,'h'},
    {"version", no_argument,      0,'V'},
    {"user",    required_argument,0,'u'},
    {0,0,0,0}
        };


        while (1) {

                c =
getopt_long(argc,argv,"+hVu:",long_options,&option_index);

                if (c==-1 || c==EOF)
                        break;

                switch (c) {
                case '?': /* print short usage statement if args not
parsable */
                        printf("%s: Unknown argument:
%s\n\n",argv[0],optarg);
                        exit(1);
                case 'h': /* help */
                        print_usage(argv[0]);
                        exit(0);
                case 'V': /* version */
                        print_version(argv[0]);
                        exit(0);
                case 'u': /* hostname */
                        username = malloc(strlen(optarg));
                        if (username==NULL)
                                exit(1);
                        strcpy(username,optarg);
                        break;
                }
        }

        if (username==NULL) {
                print_usage(argv[0]);
                exit(1);
        }

        if (strspn(username,"0123456789")==strlen(username))
                pw=getpwuid((uid_t)atoi(username));
        else
                pw=getpwnam(username);

        if (pw==NULL) {
                printf("%s: invalid username %s\n",argv[0],username);
                exit(1);
        }

        strcpy(username,pw->pw_name);
        gid=pw->pw_gid;

        c=initgroups(username,gid);
        printf("%d\n",c);

        return c;
}

void print_usage(char *cmd)
{
        printf("Usage: %s -u <user>\n",cmd);
}

void print_version(char *cmd)
{
        char version[20];
        sscanf(VERSION,"$ Revision %[^$]$",&version);
        printf("%s %s\n",cmd,version);
}

Comment 1 Karl DeBisschop 2000-06-19 15:32:06 UTC
double checking, the downstream problem is NOT with login, it's with `su`

It shows up if you try and ssh to the host with the corrupt group file, but you
can still login at the console.

Also, shouldn't grpck also report this as a problem with the group file?

Comment 2 Bernhard Rosenkraenzer 2000-10-24 11:03:04 UTC
usermod and friends have been fixed in rawhide.