Example #1
0
int within_range(security_context_t sl, security_context_t range)
{
	int rtn = 1;
	security_id_t slsid;
	security_id_t rangesid;
	struct av_decision avd;
	security_class_t tclass;
	access_vector_t av;

	if (!selinux_ready) {  /* mls may not be enabled */
		DBG_log("selinux check failed");
		return 0;
	}

	/*
	 * * Get the sids for the sl and range contexts
	 * */
	rtn = avc_context_to_sid(sl, &slsid);
	if (rtn != 0) {
		DBG_log(
			"within_range: Unable to retrieve sid for sl context (%s)",
			sl);
		return 0;
	}
	rtn = avc_context_to_sid(range, &rangesid);
	if (rtn != 0) {
		DBG_log(
			"within_range: Unable to retrieve sid for range context (%s)",
			range);
		sidput(slsid);
		return 0;
	}

	/*
	** Straight up test between sl and range
	**/
	tclass = SECCLASS_ASSOCIATION;
	av = ASSOCIATION__POLMATCH;
	rtn = avc_has_perm(slsid, rangesid, tclass, av, NULL, &avd);
	if (rtn != 0) {
		DBG_log(
			"within_range: The sl (%s) is not within range of (%s)", sl,
			range);
		sidput(slsid);
		sidput(rangesid);
		return 0;
	}
	DBG_log("within_range: The sl (%s) is within range of (%s)", sl,
		range);
	return 1;
}
Example #2
0
/* Check the permission from the caller (via getpeercon) to nscd.
   Returns 0 if access is allowed, 1 if denied, and -1 on error.  */
int
nscd_request_avc_has_perm (int fd, request_type req)
{
  /* Initialize to NULL so we know what to free in case of failure.  */
  security_context_t scon = NULL;
  security_context_t tcon = NULL;
  security_id_t ssid = NULL;
  security_id_t tsid = NULL;
  int rc = -1;

  if (getpeercon (fd, &scon) < 0)
    {
      dbg_log (_("Error getting context of socket peer"));
      goto out;
    }
  if (getcon (&tcon) < 0)
    {
      dbg_log (_("Error getting context of nscd"));
      goto out;
    }
  if (avc_context_to_sid (scon, &ssid) < 0
      || avc_context_to_sid (tcon, &tsid) < 0)
    {
      dbg_log (_("Error getting sid from context"));
      goto out;
    }

#ifndef NSCD__GETSERV
  if (perms[req] == 0)
    {
      dbg_log (_("compile-time support for database policy missing"));
      goto out;
    }
#endif

  rc = avc_has_perm (ssid, tsid, SECCLASS_NSCD, perms[req], &aeref, NULL) < 0;

out:
  if (scon)
    freecon (scon);
  if (tcon)
    freecon (tcon);
  if (ssid)
    sidput (ssid);
  if (tsid)
    sidput (tsid);

  return rc;
}
Example #3
0
int within_range(security_context_t sl, security_context_t range)
{
	int rtn = 1;
	security_id_t slsid;
	security_id_t rangesid;
	struct av_decision avd;
	security_class_t tclass;
	access_vector_t av;

	if (!selinux_ready) {
		/* mls may not be enabled */
		dbg("selinux check failed");
		return 0;
	}

	/*
	 * * Get the sids for the sl and range contexts
	 */
	rtn = avc_context_to_sid(sl, &slsid);
	if (rtn != 0) {
		dbg("within_range: Unable to retrieve sid for sl context (%s)", sl);
		return 0;
	}
	rtn = avc_context_to_sid(range, &rangesid);
	if (rtn != 0) {
		dbg("within_range: Unable to retrieve sid for range context (%s)", range);
		sidput(slsid);
		return 0;
	}

	/*
	** Straight up test between sl and range
	**/
	tclass = string_to_security_class("association");
	av = string_to_av_perm(tclass, "polmatch");
	rtn = avc_has_perm(slsid, rangesid, tclass, av, NULL, &avd);
	if (rtn != 0) {
		dbg("within_range: The sl (%s) is not within range of (%s)", sl, range);
		sidput(slsid);
		sidput(rangesid);
		return 0;
	}
	dbg("within_range: The sl (%s) is within range of (%s)", sl, range);
	return 1;
}
Example #4
0
static void
mselinux_on_connect(const void *cookie,
					ENGINE_EVENT_TYPE type,
					const void *event_data,
					const void *cb_data)
{
	selinux_engine_t   *se = (selinux_engine_t *)cb_data;
	security_context_t	context;
	security_id_t		ssid;
	int					sockfd;

	sockfd = se->server.core->get_socket_fd(cookie);

	if (getpeercon_raw(sockfd, &context) < 0)
		context = "user_u:user_r:user_t:s0";

	if (avc_context_to_sid(context, &ssid) < 0)
		ssid = NULL;

	se->server.core->store_engine_specific(cookie, ssid);
}
Example #5
0
/* Check the permission from the caller (via getpeercon) to nscd.
   Returns 0 if access is allowed, 1 if denied, and -1 on error.

   The SELinux policy, enablement, and permission bits are all dynamic and the
   caching done by glibc is not entirely correct.  This nscd support should be
   rewritten to use selinux_check_permission.  A rewrite is risky though and
   requires some refactoring.  Currently we use symbolic mappings instead of
   compile time constants (which SELinux upstream says are going away), and we
   use security_deny_unknown to determine what to do if selinux-policy* doesn't
   have a definition for the the permission or object class we are looking
   up.  */
int
nscd_request_avc_has_perm (int fd, request_type req)
{
  /* Initialize to NULL so we know what to free in case of failure.  */
  security_context_t scon = NULL;
  security_context_t tcon = NULL;
  security_id_t ssid = NULL;
  security_id_t tsid = NULL;
  int rc = -1;
  security_class_t sc_nscd;
  access_vector_t perm;
  int avc_deny_unknown;

  /* Check if SELinux denys or allows unknown object classes
     and permissions.  It is 0 if they are allowed, 1 if they
     are not allowed and -1 on error.  */
  if ((avc_deny_unknown = security_deny_unknown ()) == -1)
    dbg_log (_("Error querying policy for undefined object classes "
	       "or permissions."));

  /* Get the security class for nscd.  If this fails we will likely be
     unable to do anything unless avc_deny_unknown is 0.  */
  sc_nscd = string_to_security_class ("nscd");
  if (sc_nscd == 0 && avc_deny_unknown == 1)
    dbg_log (_("Error getting security class for nscd."));

  /* Convert permission to AVC bits.  */
  perm = string_to_av_perm (sc_nscd, perms[req]);
  if (perm == 0 && avc_deny_unknown == 1)
      dbg_log (_("Error translating permission name "
		 "\"%s\" to access vector bit."), perms[req]);

  /* If the nscd security class was not found or perms were not
     found and AVC does not deny unknown values then allow it.  */
  if ((sc_nscd == 0 || perm == 0) && avc_deny_unknown == 0)
    return 0;

  if (getpeercon (fd, &scon) < 0)
    {
      dbg_log (_("Error getting context of socket peer"));
      goto out;
    }
  if (getcon (&tcon) < 0)
    {
      dbg_log (_("Error getting context of nscd"));
      goto out;
    }
  if (avc_context_to_sid (scon, &ssid) < 0
      || avc_context_to_sid (tcon, &tsid) < 0)
    {
      dbg_log (_("Error getting sid from context"));
      goto out;
    }

  /* The SELinux API for avc_has_perm conflates access denied and error into
     the return code -1, while nscd_request_avs_has_perm has distinct error
     (-1) and denied (1) return codes. We map the avc_has_perm access denied or
     error into an access denied at the nscd interface level (we do accurately
     report error for the getpeercon, getcon, and avc_context_to_sid interfaces
     used above).  */
  rc = avc_has_perm (ssid, tsid, sc_nscd, perm, &aeref, NULL) < 0;

out:
  if (scon)
    freecon (scon);
  if (tcon)
    freecon (tcon);
  if (ssid)
    sidput (ssid);
  if (tsid)
    sidput (tsid);

  return rc;
}