Forum OpenACS Development: Re: AOL 3.5 and APM

Collapse
11: Re: AOL 3.5 and APM (response to 1)
Posted by Tom Jackson on

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.