Example #1
0
/*
 * Set local connection credentials into given hash structure
 */
int
__pmServerSetLocalCreds(int fd, __pmHashCtl *attrs)
{
#if defined(HAVE_STRUCT_UCRED)		/* Linux */
    struct ucred ucred;
    __pmSockLen length = sizeof(ucred);

    if (__pmGetSockOpt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &length) < 0)
	return -oserror();
    return SetCredentialAttrs(attrs, ucred.pid, ucred.uid, ucred.gid);

#elif defined(HAVE_GETPEEREID)		/* MacOSX */
    uid_t uid;
    gid_t gid;

    if (getpeereid(__pmFD(fd), &uid, &gid) < 0)
	return -oserror();
    return SetCredentialAttrs(attrs, 0, uid, gid);

#elif defined(HAVE_GETPEERUCRED)	/* Solaris */
    unsigned int uid, gid, pid;
    ucred_t *ucred = NULL;

    if (getpeerucred(__pmFD(fd), &ucred) < 0)
	return -oserror();
    pid = ucred_getpid(ucred);
    uid = ucred_geteuid(ucred);
    gid = ucred_getegid(ucred);
    ucred_free(ucred);
    return SetCredentialAttrs(attrs, pid, uid, gid);

#else
    return -EOPNOTSUPP;
#endif
}
// Calls from the door function to check that the client credentials
// match this process. Returns 0 if credentials okay, otherwise -1.
static int check_credentials() {
  ucred_t *cred_info = NULL;
  int ret = -1; // deny by default

  // get client credentials
  if (door_ucred(&cred_info) == -1) {
    return -1; // unable to get them, deny
  }

  // get our euid/eguid (probably could cache these)
  uid_t euid = geteuid();
  gid_t egid = getegid();

  // get euid/egid from ucred_free
  uid_t ucred_euid = ucred_geteuid(cred_info);
  gid_t ucred_egid = ucred_getegid(cred_info);

  // check that the effective uid/gid matches
  if (ucred_euid == euid && ucred_egid == egid) {
    ret =  0;  // allow
  }

  ucred_free(cred_info);
  return ret;
}
Example #3
0
/*
 * call-seq:
 *   basicsocket.getpeereid => [euid, egid]
 *
 * Returns the user and group on the peer of the UNIX socket.
 * The result is a two element array which contains the effective uid and the effective gid.
 *
 *   Socket.unix_server_loop("/tmp/sock") {|s|
 *     begin
 *       euid, egid = s.getpeereid
 *
 *       # Check the connected client is myself or not.
 *       next if euid != Process.uid
 *
 *       # do something about my resource.
 *
 *     ensure
 *       s.close
 *     end
 *   }
 *
 */
static VALUE
bsock_getpeereid(VALUE self)
{
UNRUBBY_SOCKET_HACK;
#if defined(HAVE_GETPEEREID)
    rb_io_t *fptr;
    uid_t euid;
    gid_t egid;
    GetOpenFile(self, fptr);
    if (getpeereid(fptr->fd, &euid, &egid) == -1)
	rb_sys_fail("getpeereid");
    return rb_assoc_new(UIDT2NUM(euid), GIDT2NUM(egid));
#elif defined(SO_PEERCRED) /* GNU/Linux */
    rb_io_t *fptr;
    struct ucred cred;
    socklen_t len = sizeof(cred);
    GetOpenFile(self, fptr);
    if (getsockopt(fptr->fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1)
	rb_sys_fail("getsockopt(SO_PEERCRED)");
    return rb_assoc_new(UIDT2NUM(cred.uid), GIDT2NUM(cred.gid));
#elif defined(HAVE_GETPEERUCRED) /* Solaris */
    rb_io_t *fptr;
    ucred_t *uc = NULL;
    VALUE ret;
    GetOpenFile(self, fptr);
    if (getpeerucred(fptr->fd, &uc) == -1)
	rb_sys_fail("getpeerucred");
    ret = rb_assoc_new(UIDT2NUM(ucred_geteuid(uc)), GIDT2NUM(ucred_getegid(uc)));
    ucred_free(uc);
    return ret;
#endif
}
Example #4
0
int getpeereid(int sock, uid_t *euid, gid_t *egid)
{
    int rc = -1;

#ifdef HAVE_GETPEERUCRED
    ucred_t *cred;

    rc = getpeerucred(sock, &cred);
    if (rc == 0) {
	if (euid) *euid = ucred_geteuid(cred);
	if (egid) *egid = ucred_getegid(cred);
	ucred_free(cred);
    }
#elif 0 // defined(SO_PEERCRED)
    struct ucred cred;
    socklen_t len = sizeof(struct ucred);

    rc = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cred, &len);
    if (rc == 0) {
	if (euid) *euid = cred.uid;
	if (egid) *egid = cred.gid;
    }
#else
//#warning "Need getpeereid(), getpeerucred(), or getsockopt(SO_PEERCRED) support"
    if (euid) *euid = 65534; /* nobody */
    if (egid) *egid = 65534; /* nogroup */
#endif
    return rc;
}
Example #5
0
int
auth_recv (m_msg_t m, uid_t *uid, gid_t *gid)
{
    ucred_t *ucred = NULL;
    uid_t    uid_tmp;
    gid_t    gid_tmp;
    int      rc = -1;

    if (getpeerucred (m->sd, &ucred) < 0) {
        log_msg (LOG_ERR, "Failed to get peer ucred: %s", strerror (errno));
    }
    else if ((uid_tmp = ucred_geteuid (ucred)) < 0) {
        log_msg (LOG_ERR, "Failed to get peer UID: %s", strerror (errno));
    }
    else if ((gid_tmp = ucred_getegid (ucred)) < 0) {
        log_msg (LOG_ERR, "Failed to get peer GID: %s", strerror (errno));
    }
    else {
        *uid = uid_tmp;
        *gid = gid_tmp;
        rc = 0;
    }

    if (ucred) {
        ucred_free (ucred);
    }
    return (rc);
}
Example #6
0
/*
 * picld_wait is called when a picl_wait request is received
 */
static void
picld_wait(picl_service_t *in)
{
	picl_retwait_t	ret;
	int		err;
	ucred_t	*puc = NULL;
	uid_t uid;

	ret.cnum = in->req_wait.cnum;
	if (door_ucred(&puc) != 0)
		ret.retcode = PICL_FAILURE;
	else {
		uid = ucred_geteuid(puc);
		if (enter_picld_wait(uid) == PICL_FAILURE)
			ret.retcode = PICL_FAILURE;
		else {
			err = xptree_refresh_notify(in->req_wait.secs);
			ret.retcode = err;
			exit_picld_wait(uid);
		}
		ucred_free(puc);
	}
	(void) rw_unlock(&init_lk);
	(void) door_return((char *)&ret, sizeof (picl_retwait_t), NULL, 0);
}
Example #7
0
/**
 * pfl_socket_getpeercred - Retrieve credentials of process on other end
 *	of a UNIX domain socket.
 * @s: socket file descriptor.
 * @uid: value-result user ID.
 * @gid: value-result group ID.
 */
int
pfl_socket_getpeercred(int s, uid_t *uid, gid_t *gid)
{
#ifdef HAVE_GETPEEREID
	if (getpeereid(s, uid, gid) == -1)
		return (errno);
#elif defined(HAVE_GETPEERUCRED)
	ucred_t *ucr;

	if (getpeerucred(s, &ucr) == -1)
		return (errno);
	*uid = ucred_geteuid(ucr);
	*gid = ucred_getegid(ucr);
	ucred_free(ucr);
#else
	struct ucred ucr;
	socklen_t len;

	len = sizeof(ucr);
	if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &ucr, &len))
		return (errno);
	*uid = ucr.uid;
	*gid = ucr.gid;
#endif
	return (0);
}
Example #8
0
/*
 * Get other side's uid for UNIX socket.
 *
 * Standardise on getpeereid() from BSDs.
 */
int getpeereid(int fd, uid_t *uid_p, gid_t *gid_p)
{
#ifdef SO_PEERCRED
	struct ucred cred;
	socklen_t len = sizeof(cred);
	if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) >= 0) {
		*uid_p = cred.uid;
		*gid_p = cred.gid;
		return 0;
	}
#else /* !SO_PEERCRED */
#ifdef HAVE_GETPEERUCRED
	ucred_t *cred = NULL;
	if (getpeerucred(fd, &cred) >= 0) {
		*uid_p = ucred_geteuid(cred);
		*gid_p = ucred_getegid(cred);
		ucred_free(cred);
		if ((int)*uid_p == -1 || (int)*gid_p == -1)
			return -1;
		return 0;
	}
#else
	errno = ENOSYS;
#endif /* HAVE_GETPEERUCRED */
#endif /* !SO_PEERCRED */
	return -1;
}
Example #9
0
int
get_peer_label(int fd, char **slabel)
{
	if (is_system_labeled()) {
		ucred_t *uc = NULL;
		m_label_t *sl;
		char *pslabel = NULL; /* peer's slabel */

		if ((fd < 0) || (slabel == NULL)) {
			errno = EINVAL;
			return (-1);
		}

		if (getpeerucred(fd, &uc) == -1)
			return (-1);

		sl = ucred_getlabel(uc);
		if (label_to_str(sl, &pslabel, M_INTERNAL, DEF_NAMES) != 0)
			syslog(LOG_WARNING, "label_to_str(): %m");
		ucred_free(uc);

		if (pslabel != NULL) {
			syslog(LOG_DEBUG, "get_peer_label(%d, %s): becomes %s",
				fd, (*slabel ? *slabel : "NULL"), pslabel);
			if (*slabel != NULL)
				free(*slabel);
			*slabel = strdup(pslabel);
		}
	}

	return (0);
}
Example #10
0
static void
N2N_check_priv(
	void			*buf,
	char			*dc_str)
{
	nss_pheader_t		*phdr = (nss_pheader_t *)buf;
	ucred_t			*uc = NULL;
	const priv_set_t	*eset;
	zoneid_t		zoneid;
	int			errnum;
	char			*me = "N2N_check_priv";

	if (door_ucred(&uc) != 0) {
		errnum = errno;
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
		(me, "door_ucred: %s\n", strerror(errno));

		NSCD_RETURN_STATUS(phdr, NSS_ERROR, errnum);
	}

	eset = ucred_getprivset(uc, PRIV_EFFECTIVE);
	zoneid = ucred_getzoneid(uc);

	if ((zoneid != GLOBAL_ZONEID && zoneid != getzoneid()) ||
	    eset != NULL ? !priv_ismember(eset, PRIV_SYS_ADMIN) :
	    ucred_geteuid(uc) != 0) {

		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ALERT)
		(me, "%s call failed(cred): caller pid %d, uid %d, "
		    "euid %d, zoneid %d\n", dc_str, ucred_getpid(uc),
		    ucred_getruid(uc), ucred_geteuid(uc), zoneid);
		ucred_free(uc);

		NSCD_RETURN_STATUS(phdr, NSS_ERROR, EACCES);
	}

	_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
	(me, "nscd received %s cmd from pid %d, uid %d, "
	    "euid %d, zoneid %d\n", dc_str, ucred_getpid(uc),
	    ucred_getruid(uc), ucred_geteuid(uc), zoneid);

	ucred_free(uc);

	NSCD_RETURN_STATUS_SUCCESS(phdr);
}
Example #11
0
/*
 * Check to see if the door client's euid is 0 or if it has required_priv
 * privilege. Return 0 if yes, -1 otherwise.
 * Supported values for required_priv are:
 *    - NSCD_ALL_PRIV: for all zones privileges
 *    - NSCD_READ_PRIV: for PRIV_FILE_DAC_READ privilege
 */
int
_nscd_check_client_priv(int required_priv)
{
	int			rc = 0;
	ucred_t			*uc = NULL;
	const priv_set_t	*eset;
	char			*me = "_nscd_check_client_read_priv";
	priv_set_t		*zs;	/* zone */

	if (door_ucred(&uc) != 0) {
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
		(me, "door_ucred: %s\n", strerror(errno));
		return (-1);
	}

	if (ucred_geteuid(uc) == 0) {
		ucred_free(uc);
		return (0);
	}

	eset = ucred_getprivset(uc, PRIV_EFFECTIVE);
	switch (required_priv) {
		case NSCD_ALL_PRIV:
			zs = priv_str_to_set("zone", ",", NULL);
			if (!priv_isequalset(eset, zs)) {
				_NSCD_LOG(NSCD_LOG_FRONT_END,
				    NSCD_LOG_LEVEL_ERROR)
				(me, "missing all zones privileges\n");
				rc = -1;
			}
			priv_freeset(zs);
			break;
		case NSCD_READ_PRIV:
			if (!priv_ismember(eset, PRIV_FILE_DAC_READ))
				rc = -1;
			break;
		default:
			_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
			(me, "unknown required_priv: %d\n", required_priv);
			rc = -1;
			break;
	}
	ucred_free(uc);
	return (rc);
}
Example #12
0
File: cred.c Project: gpg/payproc
/* Retrieve the credentials from the peer using the connect file
   descriptor FD.  Returns 0 on success or -1 on error.  */
int
credentials_from_socket (int fd, pid_t *r_pid, uid_t *r_uid, gid_t *r_gid)
{
  int rc = -1;

#ifdef HAVE_SO_PEERCRED
  {
    struct ucred cr;
    socklen_t cl = sizeof cr;

    if (!getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl))
      {
         *r_pid = cr.pid;
         *r_uid = cr.uid;
         *r_gid = cr.gid;
         rc = 0;
      }
  }
#elif defined (HAVE_GETPEERUCRED)
  {
    ucred_t *ucred = NULL;

    if (getpeerucred (fd, &ucred) != -1)
      {
	*r_pid = ucred_getpid (ucred);
        *r_uid = ucred_geteuid (ucred);
        *r_gid = ucred_getegid (ucred);
        rc = 0;
	ucred_free (ucred);
      }
  }
#elif defined (HAVE_LOCAL_PEEREID)
  {
    struct unpcbid unp;
    socklen_t unpl = sizeof unp;

    if (getsockopt (fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1)
      {
	*r_pid = unp.unp_pid;
	*r_uid = unp.unp_euid;
	*r_gid = unp.unp_egid;
	rc = 0;
      }
  }
#elif defined(HAVE_GETPEEREID)
  {
    if (getpeereid (fd, r_uid, r_gid) != -1)
      {
	r_pid = (pid_t)(-1);
	rc = 0;
      }
  }
#endif

  return rc;
}
Example #13
0
/*
 * vs_stats_check_auth
 *
 * Returns: 0 caller authorized to reset stats
 *         -1 caller not authorized to reset stats
 */
static int
vs_stats_check_auth()
{
	ucred_t *uc = NULL;
	uid_t uid;
	struct passwd *pw;

	if (door_ucred(&uc) != 0)
		return (-1);

	if (((uid = ucred_getsuid(uc)) == (uid_t)-1) ||
	    ((pw = getpwuid(uid)) == NULL) ||
	    (chkauthattr(VS_VALUE_AUTH, pw->pw_name) != 1)) {
		ucred_free(uc);
		return (-1);
	}

	ucred_free(uc);
	return (0);
}
Example #14
0
int main (void)
{
  ucred_t *cred ;
  uid_t uid ;
  gid_t gid ;
  int s = 0 ;
  getpeerucred(s, &cred) ;
  uid = ucred_geteuid(cred) ;
  gid = ucred_getegid(cred) ;
  ucred_free(cred) ;
  return 0 ;
}
Example #15
0
void
_nscd_APP_check_cred(
	void		*buf,
	pid_t		*pidp,
	char		*dc_str,
	int		log_comp,
	int		log_level)
{
	nss_pheader_t	*phdr = (nss_pheader_t *)buf;
	ucred_t		*uc = NULL;
	uid_t		ruid;
	uid_t		euid;
	pid_t		pid;
	int		errnum;
	char		*me = "_nscd_APP_check_cred";

	if (door_ucred(&uc) != 0) {
		errnum = errno;
		_NSCD_LOG(log_comp, NSCD_LOG_LEVEL_ERROR)
		(me, "door_ucred: %s\n", strerror(errno));

		NSCD_RETURN_STATUS(phdr, NSS_ERROR, errnum);
	}

	NSCD_SET_STATUS_SUCCESS(phdr);
	pid = ucred_getpid(uc);
	if (NSS_PACKED_CRED_CHECK(buf, ruid = ucred_getruid(uc),
	    euid = ucred_geteuid(uc))) {
		if (pidp != NULL) {
			if (*pidp == (pid_t)-1)
				*pidp = pid;
			else if (*pidp != pid) {
				NSCD_SET_STATUS(phdr, NSS_ERROR, EACCES);
			}
		}
	} else {
		NSCD_SET_STATUS(phdr, NSS_ERROR, EACCES);
	}

	ucred_free(uc);

	if (NSCD_STATUS_IS_NOT_OK(phdr)) {
		_NSCD_LOG(log_comp, log_level)
		(me, "%s call failed: caller pid %d (input pid = %d), ruid %d, "
		    "euid %d, header ruid %d, header euid %d\n", dc_str,
		    pid, (pidp != NULL) ? *pidp : -1, ruid, euid,
		    ((nss_pheader_t *)(buf))->p_ruid,
		    ((nss_pheader_t *)(buf))->p_euid);
	}
}
Example #16
0
/*ARGSUSED*/
void
_nscd_peruser_getadmin(
	void		*buf,
	int		buf_size)
{
	void		*result_mn = NSCD_N2N_DOOR_DATA(void, buf);
	int		errnum = 0;
	int		ret;
	uid_t		uid;
	nss_pheader_t	*phdr = (nss_pheader_t *)buf;
	char		*me = "_nscd_peruser_getadmin";
	ucred_t		*uc = NULL;
	child_t		*ch;

	/* get door client's credential information */
	if (door_ucred(&uc) != 0) {
		errnum = errno;
		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "door_ucred failed: %s\n", strerror(errnum));

		NSCD_RETURN_N2N_STATUS(phdr, NSS_NSCD_PRIV, errnum,
		    NSCD_DOOR_UCRED_ERROR);
	}

	/* get door client's effective uid */
	uid = ucred_geteuid(uc);
	ucred_free(uc);
	uc = NULL;

	_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
	(me, "per user get admin ... (uid = %d)\n", uid);

	/* is the per-user nscd running ? if not, no one to serve */
	ch = get_cslot(uid, 1);
	if (ch == NULL) {
		NSCD_RETURN_N2N_STATUS(phdr, NSS_NSCD_PRIV, 0,
		    NSCD_SELF_CRED_NO_CHILD_SLOT);
	}

	ret = _nscd_doorcall_fd(ch->child_door, NSCD_GETADMIN,
	    NULL, sizeof (nscd_admin_t), result_mn,
	    sizeof (nscd_admin_t), phdr);

	if (ret == NSS_SUCCESS) {
		phdr->data_len = sizeof (nscd_admin_t);
		return;
	}
}
Example #17
0
int
getpeereid(int s, uid_t *euid, gid_t *gid)
{
	ucred_t *ucred = NULL;

	if (getpeerucred(s, &ucred) == -1)
		return (-1);
	if ((*euid = ucred_geteuid(ucred)) == -1)
		return (-1);
	if ((*gid = ucred_getrgid(ucred)) == -1)
		return (-1);

	ucred_free(ucred);

	return (0);
}
Example #18
0
File: auth.c Project: Feechka/UOBP
static int
retrievePeerCredentials (PeerCredentials *credentials, int fd) {
  *credentials = NULL;
  if (getpeerucred(fd, credentials) == -1) {
    logSystemError("getpeerucred");
    return 0;
  }

#ifdef HAVE_GETZONEID
  if (ucred_getzoneid(*credentials) != getzoneid()) {
    ucred_free(*credentials);
    return 0;
  }
#endif /* HAVE_GETZONEID */

  return 1;
}
Example #19
0
uid_t
_nscd_get_client_euid()
{
	ucred_t	*uc = NULL;
	uid_t	id;
	char	*me = "get_client_euid";

	if (door_ucred(&uc) != 0) {
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
		(me, "door_ucred: %s\n", strerror(errno));
		return ((uid_t)-1);
	}

	id = ucred_geteuid(uc);
	ucred_free(uc);
	return (id);
}
Example #20
0
ucred_t *
ucred_get(pid_t pid)
{
	ucred_t *uc;

	uc = _ucred_alloc();

	if (uc == NULL)
		return (NULL);

	if (syscall(SYS_ucredsys, UCREDSYS_UCREDGET, pid, uc) != 0) {
		ucred_free(uc);
		return (NULL);
	}

	return (uc);
}
Example #21
0
static int ctrls_get_creds_peerucred(int sockfd, uid_t *uid, gid_t *gid) {
  ucred_t *cred = NULL;

  if (getpeerucred(sockfd, &cred) < 0) {
    int xerrno = errno;

    pr_trace_msg(trace_channel, 7, "error obtaining credentials using "
      "getpeerucred(3) on fd %d: %s", sockfd, strerror(xerrno));

    errno = xerrno;
    return -1;
  }

  if (uid)
    *uid = ucred_getruid(cred);

  if (gid)
    *gid = ucred_getrgid(cred);

  ucred_free(cred);
  return 0;
}
Example #22
0
/**
 * Create a connection handle by accepting on a listen socket.  This
 * function may block if the listen socket has no connection ready.
 *
 * @param access function to use to check if access is allowed
 * @param access_cls closure for access
 * @param lsock listen socket
 * @return the connection handle, NULL on error
 */
struct GNUNET_CONNECTION_Handle *
GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access,
                                      void *access_cls,
                                      struct GNUNET_NETWORK_Handle *lsock)
{
  struct GNUNET_CONNECTION_Handle *connection;
  char addr[128];
  socklen_t addrlen;
  struct GNUNET_NETWORK_Handle *sock;
  int aret;
  struct sockaddr_in *v4;
  struct sockaddr_in6 *v6;
  struct sockaddr *sa;
  void *uaddr;
  struct GNUNET_CONNECTION_Credentials *gcp;
  struct GNUNET_CONNECTION_Credentials gc;
#ifdef SO_PEERCRED
  struct ucred uc;
  socklen_t olen;
#endif

  addrlen = sizeof (addr);
  sock =
      GNUNET_NETWORK_socket_accept (lsock, (struct sockaddr *) &addr, &addrlen);
  if (NULL == sock)
  {
    LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept");
    return NULL;
  }
  if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t)))
  {
    GNUNET_break (0);
    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
    return NULL;
  }

  sa = (struct sockaddr *) addr;
  v6 = (struct sockaddr_in6 *) addr;
  if ((AF_INET6 == sa->sa_family) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)))
  {
    /* convert to V4 address */
    v4 = GNUNET_malloc (sizeof (struct sockaddr_in));
    memset (v4, 0, sizeof (struct sockaddr_in));
    v4->sin_family = AF_INET;
#if HAVE_SOCKADDR_IN_SIN_LEN
    v4->sin_len = (u_char) sizeof (struct sockaddr_in);
#endif
    memcpy (&v4->sin_addr,
            &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) -
                                       sizeof (struct in_addr)],
            sizeof (struct in_addr));
    v4->sin_port = v6->sin6_port;
    uaddr = v4;
    addrlen = sizeof (struct sockaddr_in);
  }
  else
  {
    uaddr = GNUNET_malloc (addrlen);
    memcpy (uaddr, addr, addrlen);
  }
  gcp = NULL;
  gc.uid = 0;
  gc.gid = 0;
  if (AF_UNIX == sa->sa_family)
  {
#if HAVE_GETPEEREID
    /* most BSDs */
    if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock), &gc.uid, &gc.gid))
      gcp = &gc;
#else
#ifdef SO_PEERCRED
    /* largely traditional GNU/Linux */
    olen = sizeof (uc);
    if ((0 ==
         getsockopt (GNUNET_NETWORK_get_fd (sock), SOL_SOCKET, SO_PEERCRED, &uc,
                     &olen)) && (olen == sizeof (uc)))
    {
      gc.uid = uc.uid;
      gc.gid = uc.gid;
      gcp = &gc;
    }
#else
#if HAVE_GETPEERUCRED
    /* this is for Solaris 10 */
    ucred_t *uc;

    uc = NULL;
    if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc))
    {
      gc.uid = ucred_geteuid (uc);
      gc.gid = ucred_getegid (uc);
      gcp = &gc;
    }
    ucred_free (uc);
#endif
#endif
#endif
  }

  if ((NULL != access) &&
      (GNUNET_YES != (aret = access (access_cls, gcp, uaddr, addrlen))))
  {
    if (GNUNET_NO == aret)
      LOG (GNUNET_ERROR_TYPE_INFO, _("Access denied to `%s'\n"),
           GNUNET_a2s (uaddr, addrlen));
    GNUNET_break (GNUNET_OK ==
                  GNUNET_NETWORK_socket_shutdown (sock, SHUT_RDWR));
    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
    GNUNET_free (uaddr);
    return NULL;
  }
  connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
  connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
  connection->addr = uaddr;
  connection->addrlen = addrlen;
  connection->sock = sock;
  LOG (GNUNET_ERROR_TYPE_INFO, 
       _("Accepting connection from `%s': %p\n"),
       GNUNET_a2s (uaddr, addrlen), connection);
  return connection;
}
Example #23
0
/* ARGSUSED */
void
ipmgmt_handler(void *cookie, char *argp, size_t argsz, door_desc_t *dp,
    uint_t n_desc)
{
	ipmgmt_door_info_t	*infop = NULL;
	ipmgmt_retval_t		retval;
	int			i;
	uint_t			err;
	ucred_t			*cred = NULL;

	for (i = 0; i_ipmgmt_door_info_tbl[i].idi_cmd != 0; i++) {
		if (i_ipmgmt_door_info_tbl[i].idi_cmd ==
		    ((ipmgmt_arg_t *)(void *)argp)->ia_cmd) {
			infop = &i_ipmgmt_door_info_tbl[i];
			break;
		}
	}

	if (infop == NULL) {
		ipmgmt_log(LOG_ERR, "Invalid door command specified");
		err = EINVAL;
		goto fail;
	}

	/* check for solaris.network.interface.config authorization */
	if (infop->idi_set) {
		uid_t		uid;
		struct passwd	pwd;
		char		buf[1024];

		if (door_ucred(&cred) != 0) {
			err = errno;
			ipmgmt_log(LOG_ERR, "Could not get user credentials.");
			goto fail;
		}
		uid = ucred_getruid(cred);
		if ((int)uid < 0) {
			err = errno;
			ipmgmt_log(LOG_ERR, "Could not get user id.");
			goto fail;
		}
		if (getpwuid_r(uid, &pwd, buf, sizeof (buf)) ==
		    NULL) {
			err = errno;
			ipmgmt_log(LOG_ERR, "Could not get password entry.");
			goto fail;
		}
		if (chkauthattr(NETWORK_INTERFACE_CONFIG_AUTH,
		    pwd.pw_name) != 1) {
			err = EPERM;
			ipmgmt_log(LOG_ERR, "Not authorized for operation.");
			goto fail;
		}
		ucred_free(cred);
	}

	/* individual handlers take care of calling door_return */
	infop->idi_handler((void *)argp);
	return;
fail:
	ucred_free(cred);
	retval.ir_err = err;
	(void) door_return((char *)&retval, sizeof (retval), NULL, 0);
}
Example #24
0
int lutil_getpeereid( int s, uid_t *euid, gid_t *egid
#ifdef LDAP_PF_LOCAL_SENDMSG
	, struct berval *peerbv
#endif
	)
{
#ifdef LDAP_PF_LOCAL
#if defined( HAVE_GETPEERUCRED )
	ucred_t *uc = NULL;
	if( getpeerucred( s, &uc ) == 0 )  {
		*euid = ucred_geteuid( uc );
		*egid = ucred_getegid( uc );
		ucred_free( uc );
		return 0;
	}

#elif defined( SO_PEERCRED )
	struct ucred peercred;
	ber_socklen_t peercredlen = sizeof peercred;

	if(( getsockopt( s, SOL_SOCKET, SO_PEERCRED,
		(void *)&peercred, &peercredlen ) == 0 )
		&& ( peercredlen == sizeof peercred ))
	{
		*euid = peercred.uid;
		*egid = peercred.gid;
		return 0;
	}

#elif defined( LOCAL_PEERCRED )
	struct xucred peercred;
	ber_socklen_t peercredlen = sizeof peercred;

	if(( getsockopt( s, LOCAL_PEERCRED, 1,
		(void *)&peercred, &peercredlen ) == 0 )
		&& ( peercred.cr_version == XUCRED_VERSION ))
	{
		*euid = peercred.cr_uid;
		*egid = peercred.cr_gid;
		return 0;
	}
#elif defined( LDAP_PF_LOCAL_SENDMSG ) && defined( MSG_WAITALL )
	int err, fd;
	struct iovec iov;
	struct msghdr msg = {0};
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
# ifndef CMSG_SPACE
# define CMSG_SPACE(len)	(_CMSG_ALIGN(sizeof(struct cmsghdr)) + _CMSG_ALIGN(len))
# endif
# ifndef CMSG_LEN
# define CMSG_LEN(len)		(_CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
# endif
	struct {
		struct cmsghdr cm;
		int fd;
	} control_st;
	struct cmsghdr *cmsg;
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
	struct stat st;
	struct sockaddr_un lname, rname;
	ber_socklen_t llen, rlen;

	rlen = sizeof(rname);
	llen = sizeof(lname);
	memset( &lname, 0, sizeof( lname ));
	getsockname(s, (struct sockaddr *)&lname, &llen);

	iov.iov_base = peerbv->bv_val;
	iov.iov_len = peerbv->bv_len;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	peerbv->bv_len = 0;

# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
	msg.msg_control = &control_st;
	msg.msg_controllen = sizeof( struct cmsghdr ) + sizeof( int );	/* no padding! */

	cmsg = CMSG_FIRSTHDR( &msg );
# else
	msg.msg_accrights = (char *)&fd;
	msg.msg_accrightslen = sizeof(fd);
# endif

	/*
	 * AIX returns a bogus file descriptor if recvmsg() is
	 * called with MSG_PEEK (is this a bug?). Hence we need
	 * to receive the Abandon PDU.
	 */
	err = recvmsg( s, &msg, MSG_WAITALL );
	if( err >= 0 &&
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
	    cmsg->cmsg_len == CMSG_LEN( sizeof(int) ) &&
	    cmsg->cmsg_level == SOL_SOCKET &&
	    cmsg->cmsg_type == SCM_RIGHTS
# else
		msg.msg_accrightslen == sizeof(int)
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL*/
	) {
		int mode = S_IFIFO|S_ISUID|S_IRWXU;

		/* We must receive a valid descriptor, it must be a pipe,
		 * it must only be accessible by its owner, and it must
		 * have the name of our socket written on it.
		 */
		peerbv->bv_len = err;
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
		fd = (*(int *)CMSG_DATA( cmsg ));
# endif
		err = fstat( fd, &st );
		if ( err == 0 )
			rlen = read(fd, &rname, rlen);
		close(fd);
		if( err == 0 && st.st_mode == mode &&
			llen == rlen && !memcmp(&lname, &rname, llen))
		{
			*euid = st.st_uid;
			*egid = st.st_gid;
			return 0;
		}
	}
#elif defined(SOCKCREDSIZE)
	struct msghdr msg;
	ber_socklen_t crmsgsize;
	void *crmsg;
	struct cmsghdr *cmp;
	struct sockcred *sc;

	memset(&msg, 0, sizeof msg);
	crmsgsize = CMSG_SPACE(SOCKCREDSIZE(NGROUPS));
	if (crmsgsize == 0) goto sc_err;
	crmsg = malloc(crmsgsize);
	if (crmsg == NULL) goto sc_err;
	memset(crmsg, 0, crmsgsize);
	
	msg.msg_control = crmsg;
	msg.msg_controllen = crmsgsize;
	
	if (recvmsg(s, &msg, 0) < 0) {
		free(crmsg);
		goto sc_err;
	}	

	if (msg.msg_controllen == 0 || (msg.msg_flags & MSG_CTRUNC) != 0) {
		free(crmsg);
		goto sc_err;
	}	
	
	cmp = CMSG_FIRSTHDR(&msg);
	if (cmp->cmsg_level != SOL_SOCKET || cmp->cmsg_type != SCM_CREDS) {
		printf("nocreds\n");
		goto sc_err;
	}	
	
	sc = (struct sockcred *)(void *)CMSG_DATA(cmp);
	
	*euid = sc->sc_euid;
	*egid = sc->sc_egid;

	free(crmsg);
	return 0;

sc_err:	
#endif
#endif /* LDAP_PF_LOCAL */

	return -1;
}
Example #25
0
value netsys_get_peer_credentials(value fd) {
    CAMLparam1(fd);
    CAMLlocal1(result);

#if defined(HAVE_GETPEEREID) || defined(SO_PEERCRED) || defined(HAVE_GETPEERUCRED)
    uid_t uid;
    gid_t gid;
#else
    int uid;
    int gid;
#endif

#if defined(HAVE_GETPEEREID)
    /* BSD, AIX, Cygwin */
    /* http://cr.yp.to/docs/secureipc.html */
    if (getpeereid(Int_val(fd), &uid, &gid) != 0) {
	uerror("getpeereid", Nothing);
    }

#elif defined(SO_PEERCRED)
    /* Linux */
    {
	socklen_t len;
	struct ucred credentials;

	len = sizeof(struct ucred);
	if (getsockopt(Int_val(fd),
		       SOL_SOCKET,
		       SO_PEERCRED,
		       &credentials,
		       &len) == -1) {
	    uerror("getsockopt",Nothing);
	};
	uid = credentials.uid;       /* Effective user ID */
	gid = credentials.gid;       /* Effective group ID */
    }
#elif defined(HAVE_GETPEERUCRED)
    /* Solaris */
    { 
	ucred_t    *ucred;
	ucred = NULL;			/* must be initialized to NULL */
	if (getpeerucred(Int_val(fd), &ucred) == -1) {
	    uerror("getpeerucred",Nothing);
	};
	if ((uid = ucred_geteuid(ucred)) == -1) {
	    uerror("ucred_geteuid",Nothing);
	    ucred_free(ucred);
	};
	if ((gid = ucred_getegid(ucred)) == -1) {
	    uerror("ucred_getegid",Nothing);
	    ucred_free(ucred);
	};
	ucred_free(ucred);
    }
#else
    invalid_argument("get_peer_credentials");
#endif

    /* Allocate a pair, and put the result into it: */
    result = alloc_tuple(2);
    Store_field(result, 0, Val_int(uid));
    Store_field(result, 1, Val_int(gid));

    CAMLreturn(result);
}
Example #26
0
static int32_t
qb_ipcs_uc_recv_and_auth(int32_t sock, void *msg, size_t len,
			 struct ipc_auth_ugp *ugp)
{
	int32_t res = 0;
	struct msghdr msg_recv;
	struct iovec iov_recv;

#ifdef SO_PASSCRED
	char cmsg_cred[CMSG_SPACE(sizeof(struct ucred))];
	int off = 0;
	int on = 1;
#endif
	msg_recv.msg_iov = &iov_recv;
	msg_recv.msg_iovlen = 1;
	msg_recv.msg_name = 0;
	msg_recv.msg_namelen = 0;
#ifdef SO_PASSCRED
	msg_recv.msg_control = (void *)cmsg_cred;
	msg_recv.msg_controllen = sizeof(cmsg_cred);
#endif
#ifdef QB_SOLARIS
	msg_recv.msg_accrights = 0;
	msg_recv.msg_accrightslen = 0;
#else
	msg_recv.msg_flags = 0;
#endif /* QB_SOLARIS */

	iov_recv.iov_base = msg;
	iov_recv.iov_len = len;
#ifdef SO_PASSCRED
	setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
#endif

	res = qb_ipc_us_recv_msghdr(sock, &msg_recv, msg, len);
	if (res < 0) {
		goto cleanup_and_return;
	}
	if (res != len) {
		res = -EIO;
		goto cleanup_and_return;
	}

	/*
	 * currently support getpeerucred, getpeereid, and SO_PASSCRED credential
	 * retrieval mechanisms for various Platforms
	 */
#ifdef HAVE_GETPEERUCRED
	/*
	 * Solaris and some BSD systems
	 */
	{
		ucred_t *uc = NULL;

		if (getpeerucred(sock, &uc) == 0) {
			res = 0;
			ugp->uid = ucred_geteuid(uc);
			ugp->gid = ucred_getegid(uc);
			ugp->pid = ucred_getpid(uc);
			ucred_free(uc);
		} else {
			res = -errno;
		}
	}
#elif HAVE_GETPEEREID
	/*
	 * Usually MacOSX systems
	 */
	{
		/*
		 * TODO get the peer's pid.
		 * c->pid = ?;
		 */
		if (getpeereid(sock, &ugp->uid, &ugp->gid) == 0) {
			res = 0;
		} else {
			res = -errno;
		}
	}

#elif SO_PASSCRED
	/*
	 * Usually Linux systems
	 */
	{
		struct ucred cred;
		struct cmsghdr *cmsg;

		res = -EINVAL;
		for (cmsg = CMSG_FIRSTHDR(&msg_recv); cmsg != NULL;
		     cmsg = CMSG_NXTHDR(&msg_recv, cmsg)) {
			if (cmsg->cmsg_type != SCM_CREDENTIALS)
				continue;

			memcpy(&cred, CMSG_DATA(cmsg), sizeof(struct ucred));
			res = 0;
			ugp->pid = cred.pid;
			ugp->uid = cred.uid;
			ugp->gid = cred.gid;
			break;
		}
	}
#else /* no credentials */
	ugp->pid = 0;
	ugp->uid = 0;
	ugp->gid = 0;
	res = -ENOTSUP;
#endif /* no credentials */

cleanup_and_return:

#ifdef SO_PASSCRED
	setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &off, sizeof(off));
#endif

	return res;
}
Example #27
0
/*
 * cmd_changestate()
 *
 *	Implements the door command to initate a state change operation.
 *
 *	NOTE: requires 'modify' authorization.
 */
static int
cmd_changestate(nvlist_t *args, nvlist_t **resultsp)
{
    hp_node_t	root = NULL;
    nvlist_t	*results = NULL;
    char		*path, *connection;
    ucred_t		*uc = NULL;
    uint_t		flags;
    int		rv, state, old_state, status;

    dprintf("cmd_changestate:\n");

    /* Get arguments */
    if ((nvlist_lookup_string(args, HPD_PATH, &path) != 0) ||
            (nvlist_lookup_string(args, HPD_CONNECTION, &connection) != 0) ||
            (nvlist_lookup_int32(args, HPD_STATE, &state) != 0)) {
        dprintf("cmd_changestate: invalid arguments.\n");
        return (EINVAL);
    }
    if (nvlist_lookup_uint32(args, HPD_FLAGS, (uint32_t *)&flags) != 0)
        flags = 0;

    /* Get caller's credentials */
    if (door_ucred(&uc) != 0) {
        log_err("Cannot get door credentials (%s)\n", strerror(errno));
        return (EACCES);
    }

    /* Check authorization */
    if (check_auth(uc, HP_MODIFY_AUTH) != 0) {
        dprintf("cmd_changestate: access denied.\n");
        audit_changestate(uc, HP_MODIFY_AUTH, path, connection,
                          state, -1, ADT_FAIL_VALUE_AUTH);
        ucred_free(uc);
        return (EACCES);
    }

    /* Perform the state change operation */
    status = changestate(path, connection, state, flags, &old_state, &root);
    dprintf("cmd_changestate: changestate() == %d\n", status);

    /* Audit the operation */
    audit_changestate(uc, HP_MODIFY_AUTH, path, connection, state,
                      old_state, status);

    /* Caller's credentials no longer needed */
    ucred_free(uc);

    /*
     * Pack the results into an nvlist if there is an error snapshot.
     *
     * If any error occurs while packing the results, the original
     * error code from changestate() above is still returned.
     */
    if (root != NULL) {
        char	*buf = NULL;
        size_t	len = 0;

        dprintf("cmd_changestate: results nvlist required.\n");

        /* Pack and discard the error snapshot */
        rv = hp_pack(root, &buf, &len);
        hp_fini(root);
        if (rv != 0) {
            dprintf("cmd_changestate: hp_pack() failed (%s).\n",
                    strerror(rv));
            return (status);
        }

        /* Allocate nvlist for results */
        if (nvlist_alloc(&results, NV_UNIQUE_NAME_TYPE, 0) != 0) {
            dprintf("cmd_changestate: nvlist_alloc() failed.\n");
            free(buf);
            return (status);
        }

        /* Add the results into the nvlist */
        if ((nvlist_add_int32(results, HPD_STATUS, status) != 0) ||
                (nvlist_add_byte_array(results, HPD_INFO, (uchar_t *)buf,
                                       len) != 0)) {
            dprintf("cmd_changestate: nvlist add failed.\n");
            nvlist_free(results);
            free(buf);
            return (status);
        }

        *resultsp = results;
    }

    return (status);
}
Example #28
0
/*ARGSUSED*/
static void
pkg_door_srv(void *cookie, char *argp, size_t asz, door_desc_t *dp,
    uint_t ndesc)
{
	char *p = NULL;
	pkgcmd_t *pcmd = (pkgcmd_t *)argp;
	ucred_t *uc = NULL;
	uid_t caller;
	pid_t pcaller;
	door_desc_t ddp;
	int dnum = 0;
	int one = 1;
	int len = -1;

	if (asz < sizeof (pkgcmd_t)) {
		(void) door_return(NULL, 0, NULL, 0);
		return;
	}

	if (door_ucred(&uc) != 0) {
		(void) door_return(NULL, 0, NULL, 0);
		return;
	}

	caller = ucred_geteuid(uc);
	pcaller = ucred_getpid(uc);
	ucred_free(uc);

	if (caller != myuid) {
		(void) door_return(NULL, 0, NULL, 0);
		return;
	}

	(void) mutex_lock(&mtx);
	ncalls++;

	if (pcaller != client_pid && pcaller != -1 &&
	    (client_pid == 1 || kill(client_pid, 0) != 0)) {
		client_pid = pcaller;
	}

	if (PKG_WRITE_COMMAND(pcmd->cmd))
		while (write_locked > 0)
			(void) cond_wait(&cv, &mtx);

	switch (pcmd->cmd) {
	case PKG_FINDFILE:
		p = file_find((pkgfilter_t *)argp, &len);
		break;
	case PKG_DUMP:
		if (read_only)
			goto err;
		if (logcount > 0)
			pkgdump();
		break;
	case PKG_EXIT:
		if (logcount > 0)
			pkgdump();
		exit(0);
		/*NOTREACHED*/
	case PKG_PKGSYNC:
		if (read_only || logflush() != 0)
			goto err;
		break;
	case PKG_FILTER:
		if (pkgfilter((pkgfilter_t *)argp, &ddp) == 0)
			dnum = 1;
		break;
	case PKG_ADDLINES:
		if (read_only)
			goto err;
		changes++;

		if (pkgaddlines((pkgfilter_t *)argp) != 0)
			goto err;
		/* If we've updated the database, tell the dump thread */
		lastchange = gethrtime();
		(void) cond_broadcast(&cv);
		break;
	case PKG_NOP:
		/* Do nothing but register the current client's pid. */
		break;
	default:
		goto err;
	}

	lastcall = gethrtime();
	(void) mutex_unlock(&mtx);
	(void) door_return(p, len != -1 ? len : p == NULL ? 0 : strlen(p) + 1,
	    dnum == 0 ? NULL : &ddp, dnum);
	return;

err:
	(void) mutex_unlock(&mtx);
	(void) door_return((void *)&one, 4, NULL, NULL);
}
Example #29
0
/*
 * cmd_private()
 *
 *	Implementation of the door command to set or get bus private options.
 *
 *	NOTE: requires 'modify' authorization for the 'set' command.
 */
static int
cmd_private(hp_cmd_t cmd, nvlist_t *args, nvlist_t **resultsp)
{
    nvlist_t	*results = NULL;
    ucred_t		*uc = NULL;
    char		*path, *connection, *options;
    char		*values = NULL;
    int		status;

    dprintf("cmd_private:\n");

    /* Get caller's credentials */
    if ((cmd == HP_CMD_SETPRIVATE) && (door_ucred(&uc) != 0)) {
        log_err("Cannot get door credentials (%s)\n", strerror(errno));
        return (EACCES);
    }

    /* Get arguments */
    if ((nvlist_lookup_string(args, HPD_PATH, &path) != 0) ||
            (nvlist_lookup_string(args, HPD_CONNECTION, &connection) != 0) ||
            (nvlist_lookup_string(args, HPD_OPTIONS, &options) != 0)) {
        dprintf("cmd_private: invalid arguments.\n");
        return (EINVAL);
    }

    /* Check authorization */
    if ((cmd == HP_CMD_SETPRIVATE) &&
            (check_auth(uc, HP_MODIFY_AUTH) != 0)) {
        dprintf("cmd_private: access denied.\n");
        audit_setprivate(uc, HP_MODIFY_AUTH, path, connection, options,
                         ADT_FAIL_VALUE_AUTH);
        ucred_free(uc);
        return (EACCES);
    }

    /* Perform the operation */
    status = private_options(path, connection, cmd, options, &values);
    dprintf("cmd_private: private_options() == %d\n", status);

    /* Audit the operation */
    if (cmd == HP_CMD_SETPRIVATE) {
        audit_setprivate(uc, HP_MODIFY_AUTH, path, connection, options,
                         status);
        ucred_free(uc);
    }

    /* Construct an nvlist if values were returned */
    if (values != NULL) {

        /* Allocate nvlist for results */
        if (nvlist_alloc(&results, NV_UNIQUE_NAME_TYPE, 0) != 0) {
            dprintf("cmd_private: nvlist_alloc() failed.\n");
            free(values);
            return (ENOMEM);
        }

        /* Add values and status to the results */
        if ((nvlist_add_int32(results, HPD_STATUS, status) != 0) ||
                (nvlist_add_string(results, HPD_OPTIONS, values) != 0)) {
            dprintf("cmd_private: nvlist add failed.\n");
            nvlist_free(results);
            free(values);
            return (ENOMEM);
        }

        /* The values string is no longer needed */
        free(values);

        *resultsp = results;
    }

    return (status);
}
Example #30
0
static pmix_status_t validate_cred(pmix_peer_t *peer, char *cred)
{
#if defined(SO_PEERCRED)
#ifdef HAVE_STRUCT_SOCKPEERCRED_UID
#define HAVE_STRUCT_UCRED_UID
    struct sockpeercred ucred;
#else
    struct ucred ucred;
#endif
    socklen_t crlen = sizeof (ucred);
#endif
#ifdef HAVE_GETPEERUCRED
    ucred_t *ucred = NULL;
#endif
    uid_t euid;
    gid_t gid;

    pmix_output_verbose(2, pmix_globals.debug_output,
                        "sec: native validate_cred %s", cred ? cred : "NULL");

#if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
    /* Ignore received 'cred' and validate ucred for socket instead. */
    pmix_output_verbose(2, pmix_globals.debug_output,
                        "sec:native checking getsockopt for peer credentials");
    if (getsockopt (peer->sd, SOL_SOCKET, SO_PEERCRED, &ucred, &crlen) < 0) {
        pmix_output_verbose(2, pmix_globals.debug_output,
                            "sec: getsockopt SO_PEERCRED failed: %s",
                            strerror (pmix_socket_errno));
        return PMIX_ERR_INVALID_CRED;
    }
#if defined(HAVE_STRUCT_UCRED_UID)
    euid = ucred.uid;
    gid = ucred.gid;
#else
    euid = ucred.cr_uid;
    gid = ucred.cr_gid;
#endif

#elif defined(HAVE_GETPEEREID)
    pmix_output_verbose(2, pmix_globals.debug_output,
                        "sec:native checking getpeereid for peer credentials");
    if (0 != getpeereid(peer->sd, &euid, &gid)) {
        pmix_output_verbose(2, pmix_globals.debug_output,
                            "sec: getsockopt getpeereid failed: %s",
                            strerror (pmix_socket_errno));
        return PMIX_ERR_INVALID_CRED;
    }
#elif defined(HAVE_GETPEERUCRED)
    pmix_output_verbose(2, pmix_globals.debug_output,
                        "sec:native checking getpeerucred for peer credentials");
    if (0 != getpeerucred(peer->sd, &ucred)) {
        pmix_output_verbose(2, pmix_globals.debug_output,
                            "sec: getsockopt getpeerucred failed: %s",
                            strerror (pmix_socket_errno));
        pmix_output_verbose(2, pmix_globals.debug_output,
                            "sec: getsockopt getpeerucred failed: %s",
                            strerror (errno));
        return PMIX_ERR_INVALID_CRED;
    }
    euid = ucred_geteuid(ucred);
    gid = ucred_getrgid(ucred);
    ucred_free(ucred);
#else
    pmix_output_verbose(2, pmix_globals.debug_output,
                        "sec: native cannot validate_cred on this system");
    return PMIX_ERR_NOT_SUPPORTED;
#endif

    /* check uid */
    if (euid != peer->info->uid) {
        pmix_output_verbose(2, pmix_globals.debug_output,
                            "sec: socket cred contains invalid uid %u", euid);
        return PMIX_ERR_INVALID_CRED;
    }

    /* check gid */
    if (gid != peer->info->gid) {
        pmix_output_verbose(2, pmix_globals.debug_output,
                            "sec: socket cred contains invalid gid %u", gid);
        return PMIX_ERR_INVALID_CRED;
    }

    pmix_output_verbose(2, pmix_globals.debug_output,
                        "sec: native credential %u:%u valid",
                        euid, gid);
    return PMIX_SUCCESS;
}