示例#1
0
struct passwd* getpwnam (const char* name)
{
  struct passwd* result;
  
  if (__getpwnam_r (name, &passwd, buf, 1024, &result) != 0)
    return NULL;
  return result;
}
示例#2
0
int
mtev_security_usergroup(const char *user, const char *group, mtev_boolean effective) {
  static long pwnam_buflen = 0;
  static long grnam_buflen = 0;
  uid_t uid = 0;
  gid_t gid = 0;

  if(pwnam_buflen == 0)
#ifdef _SC_GETPW_R_SIZE_MAX
    pwnam_buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
#else
    pwnam_buflen = 100; /* This shouldn't be used, so size is not important. */
#endif
  if(grnam_buflen == 0)
#ifdef _SC_GETGR_R_SIZE_MAX
    grnam_buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
#else
    grnam_buflen = 100;
#endif

  if(user) {
    if(isuinteger(user)) uid = atoi(user);
    else {
      struct passwd *pw, _pw;
      char *buf;
      if(NULL == (buf = alloca(pwnam_buflen))) BAIL("alloca failed\n");
      if(NULL == (pw = __getpwnam_r(user, &_pw, buf, pwnam_buflen)))
        BAIL("Cannot find user '%s'\n", user);
      uid = pw->pw_uid;
    }
  }

  if(group) {
    if(isuinteger(group)) gid = atoi(group);
    else {
      struct group *gr, _gr;
      char *buf;
      if(NULL == (buf = alloca(grnam_buflen))) BAIL("alloca failed\n");
      if(NULL == (gr = __getgrnam_r(group, &_gr, buf, grnam_buflen)))
        BAIL("Cannot find group '%s'\n", group);
      gid = gr->gr_gid;
    }
  }

  if(!user && !group) return 0;

#if defined(CAP_SUPPORTED) && defined(HAVE_SETPPRIV)
  if(!effective && getpflags(PRIV_AWARE)) {
    int rv;
    priv_set_t *set;
    set = priv_allocset();
    priv_addset(set, "proc_setid");
    rv = setppriv(PRIV_ON, PRIV_EFFECTIVE, set);
    priv_freeset(set);
    if(rv) BAIL("setppriv(proc_setid) failed");
  }
#endif

  if(group) {
    if(!effective && gid == 0) BAIL("Cannot use this function to setgid(0)\n");
    if((effective ? setegid(gid) : setgid(gid)) != 0)
      BAIL("setgid(%d) failed: %s\n", (int)gid, strerror(errno));
  }
  if(user) {
    if(!effective && uid == 0) BAIL("Cannot use this function to setuid(0)\n");
    if((effective ? seteuid(uid) : setuid(uid)) != 0) 
      BAIL("setgid(%d) failed: %s\n", (int)gid, strerror(errno));

    if(!effective) {
#if defined(CAP_SUPPORTED) && defined(HAVE_SETPPRIV)
      if(getpflags(PRIV_AWARE)) {
        int rv;
        priv_set_t *set;
        set = priv_allocset();
        priv_addset(set, "proc_setid");
        rv = setppriv(PRIV_OFF, PRIV_EFFECTIVE, set);
        if(rv) BAIL("setppriv(off, effective, proc_setid) failed");
        getppriv(PRIV_EFFECTIVE, set);
        rv = setppriv(PRIV_SET, PRIV_PERMITTED, set);
        if(rv) BAIL("setppriv(effective -> permitted) failed");
        priv_freeset(set);
      }
#endif

      if(setuid(0) == 0) BAIL("setuid(0) worked, and it shouldn't have.\n");
      if(setgid(0) == 0) BAIL("setgid(0) worked, and it shouldn't have.\n");
    }
  }

  return 0;
}