Probably Jon's patch would allow an illegal group to be specified for a user.
3.5.1 is broken in the sense that the -g switch doesn't work, you can only use the user's main group. But it also allows you to set the root group by setting the main group of a user to root. Looks like Jon's patch allows this as well.
I wrote some code to check that a user is in the group specified after -g, disallowing root group and setting the group to any legal group for the user. I wrote a few extra Ns_ commands to do this, but it looks like the actual code maybe should be in nsmain.c, not in an external function. Lemme dig up the code.
#include <stdio.h>
#include <stdlib.h>
#include <grp.h>
#include <pwd.h>
int Ns_UserGroupCheck( char *user, char *group );
int Ns_GetUserGid(char *user);
int Ns_GetUid(char *user);
int Ns_GetGid(char *group);
char *Ns_GetUserName(int uid);
char *Ns_GetGroupName(int gid);
int
main (int argc, char **argv)
{
char *group;
char *user;
if ( ( (user = argv[1]) != NULL ) && ( (group = argv[2]) != NULL ) ) {
printf("check returned: %i\n", Ns_UserGroupCheck(user, group));
} else {
printf("usage: %s username groupname\n", argv[0]);
}
return 0;
}
/*
* Ns_UserGroupCheck checks:
* 1. user uid > 0, else return false
* 2. group gid > 0, else return false
* 5. user in group, else return false
* 6. return true.
*/
int
Ns_UserGroupCheck( char *user, char *group )
{
int gid, uid;
int ret;
char *grp;
struct group *grent;
char **members;
char *member;
int i = 0;
uid = Ns_GetUid(user);
if (uid > 0) {
// valid user
} else if (uid == 0) {
// root user
return 0;
} else if (uid == -1 && ( uid = atoi(user) ) && ( ( user = Ns_GetUserName(uid) ) != NULL ) ) {
// valid user
} else {
// invalid or root user
return uid;
}
gid = Ns_GetGid(group);
if (gid > 0) {
// valid group
} else if (gid == 0) {
// root group
return 0;
} else if (gid == -1 && ( gid = atoi(group) ) && ( ( group = Ns_GetGroupName(gid) ) != NULL ) ) {
// valid group
} else {
// invalid group or root group
return gid;
}
// valid user and group
// check if user in primary group
if ( gid == Ns_GetUserGid(user) ) {
return 1;
}
// check if user in additional group
grent = getgrnam(group);
members = grent->gr_mem;
while( members[i] ) {
printf ("member %i: %s\n", i, members[i]);
if (!strcmp(members[i], user)) {
return 1;
}
i++;
}
return -1;
}
int
Ns_GetUserGid(char *user)
{
struct passwd *pw;
int retcode;
//Ns_MutexLock(&lock);
pw = getpwnam(user);
if (pw == NULL) {
retcode = -1;
} else {
retcode = pw->pw_gid;
}
//Ns_MutexUnlock(&lock);
return retcode;
}
int
Ns_GetUid(char *user)
{
struct passwd *pw;
int retcode;
//Ns_MutexLock(&lock);
pw = getpwnam(user);
if (pw == NULL) {
retcode = -1;
} else {
retcode = pw->pw_uid;
}
//Ns_MutexUnlock(&lock);
return retcode;
}
char *
Ns_GetUserName(int uid)
{
struct passwd *pw;
char *pwname;
//Ns_MutexLock(&lock);
pw = getpwuid(uid);
if (pw == NULL) {
pwname = NULL;
} else {
pwname = pw->pw_name;
}
//Ns_MutexUnlock(&lock);
return pwname;
}
char *
Ns_GetGroupName(int gid)
{
struct group *grent;
char *grpname;
//Ns_MutexLock(&lock);
grent = getgrgid(gid);
if (grent == NULL) {
grpname = NULL;
} else {
grpname = grent->gr_name;
}
//Ns_MutexUnlock(&lock);
return grpname;
}
int
Ns_GetGid(char *group)
{
int retcode;
struct group *grent;
//Ns_MutexLock(&lock);
grent = getgrnam(group);
if (grent == NULL) {
retcode = -1;
} else {
retcode = grent->gr_gid;
}
//Ns_MutexUnlock(&lock);
return retcode;
}
You can compile and test without aolserver, I just commented out the Ns_Mutex locks to run it.
Problems is the code doesn't distinguish between invalid or root user/group, which would not matter in nsmain.c.