Esempio n. 1
0
static int parse_components(context_t con, char **components) {
	components[COLOR_USER] = (char *)context_user_get(con);
	components[COLOR_ROLE] = (char *)context_role_get(con);
	components[COLOR_TYPE] = (char *)context_type_get(con);
	components[COLOR_RANGE] = (char *)context_range_get(con);

	return 0;
}
Esempio n. 2
0
int get_default_context_with_role(const char *user,
				  const char *role,
				  char * fromcon,
				  char ** newcon)
{
	char **conary;
	char **ptr;
	context_t con;
	const char *role2;
	int rc;

	rc = get_ordered_context_list(user, fromcon, &conary);
	if (rc <= 0)
		return -1;

	for (ptr = conary; *ptr; ptr++) {
		con = context_new(*ptr);
		if (!con)
			continue;
		role2 = context_role_get(con);
		if (role2 && !strcmp(role, role2)) {
			context_free(con);
			break;
		}
		context_free(con);
	}

	rc = -1;
	if (!(*ptr)) {
		errno = EINVAL;
		goto out;
	}
	*newcon = strdup(*ptr);
	if (!(*newcon))
		goto out;
	rc = 0;
      out:
	freeconary(conary);
	return rc;
}
Esempio n. 3
0
static int find_partialcon(security_context_t * list,
			   unsigned int nreach, char *part)
{
	const char *conrole, *contype;
	char *partrole, *parttype, *ptr;
	context_t con;
	unsigned int i;

	partrole = part;
	ptr = part;
	while (*ptr && !isspace(*ptr) && *ptr != ':')
		ptr++;
	if (*ptr != ':')
		return -1;
	*ptr++ = 0;
	parttype = ptr;
	while (*ptr && !isspace(*ptr) && *ptr != ':')
		ptr++;
	*ptr = 0;

	for (i = 0; i < nreach; i++) {
		con = context_new(list[i]);
		if (!con)
			return -1;
		conrole = context_role_get(con);
		contype = context_type_get(con);
		if (!conrole || !contype) {
			context_free(con);
			return -1;
		}
		if (!strcmp(conrole, partrole) && !strcmp(contype, parttype)) {
			context_free(con);
			return i;
		}
		context_free(con);
	}

	return -1;
}
Esempio n. 4
0
static void disp_con(security_context_t scon)
{
	context_t con = NULL;

	if (!*scon) {		/* --self-exec and --self-fs etc. */
		if (opts->disp_user)
			disp__con_val("user", NULL);
		if (opts->disp_role)
			disp__con_val("role", NULL);
		if (opts->disp_type)
			disp__con_val("type", NULL);
		if (opts->disp_sen)
			disp__con_val("sensitivity", NULL);
		if (opts->disp_clr)
			disp__con_val("clearance", NULL);
		if (opts->disp_mlsr)
			disp__con_val("mls-range", NULL);
		return;
	}

	if (!(con = context_new(scon)))
		errx(EXIT_FAILURE, "Couldn't create context from: %s", scon);

	if (opts->disp_user)
		disp__con_val("user", context_user_get(con));
	if (opts->disp_role)
		disp__con_val("role", context_role_get(con));
	if (opts->disp_type)
		disp__con_val("type", context_type_get(con));
	if (opts->disp_sen) {
		const char *val = NULL;
		char *tmp = NULL;

		val = context_range_get(con);
		if (!val)
			val = "";	/* targeted has no "level" etc.,
					   any errors should happen at context_new() time */

		tmp = strdup(val);
		if (!tmp)
			errx(EXIT_FAILURE, "Couldn't create context from: %s",
			     scon);
		if (strchr(tmp, '-'))
			*strchr(tmp, '-') = 0;

		disp__con_val("sensitivity", tmp);

		free(tmp);
	}
	if (opts->disp_clr) {
		const char *val = NULL;
		char *tmp = NULL;

		val = context_range_get(con);
		if (!val)
			val = "";	/* targeted has no "level" etc.,
					   any errors should happen at context_new() time */

		tmp = strdup(val);
		if (!tmp)
			errx(EXIT_FAILURE, "Couldn't create context from: %s",
			     scon);
		if (strchr(tmp, '-'))
			disp__con_val("clearance", strchr(tmp, '-') + 1);
		else
			disp__con_val("clearance", tmp);

		free(tmp);
	}

	if (opts->disp_mlsr)
		disp__con_val("mls-range", context_range_get(con));

	context_free(con);
}
Esempio n. 5
0
/*
 * do_set_domain
 *   It tries to replace the domain/range of the current context.
 */
static int
do_set_domain(security_context_t old_context, char *domain, server_rec *s)
{
    security_context_t  new_context;
    security_context_t  raw_context;
    context_t           context;
    char               *range;

    /*
     * Compute the new security context
     */
    context = context_new(old_context);
    if (!context) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: context_new(\"%s\") failed",
                     old_context);
        return -1;
    }

    range = strchr(domain, ':');
    if (range)
        *range++ = '\0';

    if (domain && strcmp(domain, "*") != 0)
        context_type_set(context, domain);
    if (range  && strcmp(range, "*") != 0)
        context_range_set(context, range);

    if (range)
        *--range = ':';     /* fixup */

    new_context = context_str(context);
    if (!new_context) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: context_str(\"%s:%s:%s:%s\") failed",
                     context_user_get(context),
                     context_role_get(context),
                     context_type_get(context),
                     context_range_get(context));
        context_free(context);
        return -1;
    }

    /*
     * If old_context == new_context, we don't need to do anything
     */
    if (selinux_trans_to_raw_context(new_context, &raw_context) < 0) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: selinux_trans_to_raw_context(\"%s\") failed",
                     new_context);
        context_free(context);
        return -1;
    }
    context_free(context);

    if (!strcmp(old_context, raw_context)) {
        freecon(raw_context);
        return 1;
    }

    if (setcon_raw(raw_context) < 0) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: setcon_raw(\"%s\") failed",
                     raw_context);
        freecon(raw_context);
        return -1;
    }

    freecon(raw_context);

    return 0;
}
Esempio n. 6
0
static security_context_t
config_context (pam_handle_t *pamh, security_context_t defaultcon, int use_current_range, int debug)
{
  security_context_t newcon=NULL;
  context_t new_context;
  int mls_enabled = is_selinux_mls_enabled();
  char *response=NULL;
  char *type=NULL;
  char resp_val = 0;

  pam_prompt (pamh, PAM_TEXT_INFO, NULL, _("Default Security Context %s\n"), defaultcon);

  while (1) {
    if (query_response(pamh,
		   _("Would you like to enter a different role or level?"), "n", 
		   &response, debug) == PAM_SUCCESS) {
	resp_val = response[0];
	_pam_drop(response);
    } else {
	resp_val = 'N';
    }
    if ((resp_val == 'y') || (resp_val == 'Y'))
      {
        if ((new_context = context_new(defaultcon)) == NULL)
    	    goto fail_set;

	/* Allow the user to enter role and level individually */
	if (query_response(pamh, _("role:"), context_role_get(new_context), 
		       &response, debug) == PAM_SUCCESS && response[0]) {
	  if (get_default_type(response, &type)) {
	    pam_prompt (pamh, PAM_ERROR_MSG, NULL, _("No default type for role %s\n"), response);
	    _pam_drop(response);
	    continue;
	  } else {
	    if (context_role_set(new_context, response)) 
	      goto fail_set;
	    if (context_type_set (new_context, type))
	      goto fail_set;
	  } 
	}
	_pam_drop(response);

	if (mls_enabled)
	  {
	    if (use_current_range) {
	        security_context_t mycon = NULL;
	        context_t my_context;

		if (getcon(&mycon) != 0)
		    goto fail_set;
    		my_context = context_new(mycon);
	        if (my_context == NULL) {
    		    freecon(mycon);
		    goto fail_set;
		}
		freecon(mycon);
		if (context_range_set(new_context, context_range_get(my_context))) {
		    context_free(my_context);
		    goto fail_set;
		}
		context_free(my_context);
	    } else if (query_response(pamh, _("level:"), context_range_get(new_context), 
			   &response, debug) == PAM_SUCCESS && response[0]) {
		if (context_range_set(new_context, response))
		    goto fail_set;
	    } 
	    _pam_drop(response);
	  }

	if (debug)
	  pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", context_str(new_context));

        /* Get the string value of the context and see if it is valid. */
        if (!security_check_context(context_str(new_context))) {
	  newcon = strdup(context_str(new_context));
	  if (newcon == NULL)
	    goto fail_set;
	  context_free(new_context);

          /* we have to check that this user is allowed to go into the
             range they have specified ... role is tied to an seuser, so that'll
             be checked at setexeccon time */
          if (mls_enabled && !mls_range_allowed(pamh, defaultcon, newcon, debug)) {
	    pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);

    	    send_audit_message(pamh, 0, defaultcon, newcon);

	    free(newcon);
            goto fail_range;
	  }
	  return newcon;
	}
	else {
	  send_audit_message(pamh, 0, defaultcon, context_str(new_context));
	  send_text(pamh,_("Not a valid security context"),debug);
	}
        context_free(new_context); /* next time around allocates another */
      }
    else
      return strdup(defaultcon);
  } /* end while */

  return NULL;

 fail_set:
  free(type);
  _pam_drop(response);
  context_free (new_context);
  send_audit_message(pamh, 0, defaultcon, NULL);
 fail_range:
  return NULL;  
}
Esempio n. 7
0
static bool
testSELinuxCheckCon(context_t con,
                    const char *user,
                    const char *role,
                    const char *type,
                    int sensMin,
                    int sensMax ATTRIBUTE_UNUSED,
                    int catMin,
                    int catMax)
{
    const char *range;
    char *tmp;
    int gotSens;
    int gotCatOne;
    int gotCatTwo;

    if (STRNEQ(context_user_get(con), user)) {
        fprintf(stderr, "Expect user %s got %s\n",
                user, context_user_get(con));
        return false;
    }
    if (STRNEQ(context_role_get(con), role)) {
        fprintf(stderr, "Expect role %s got %s\n",
                role, context_role_get(con));
        return false;
    }
    if (STRNEQ(context_type_get(con), type)) {
        fprintf(stderr, "Expect type %s got %s\n",
                type, context_type_get(con));
        return false;
    }

    range = context_range_get(con);
    if (range[0] != 's') {
        fprintf(stderr, "Malformed range %s, cannot find sensitivity\n",
                range);
        return false;
    }
    if (virStrToLong_i(range + 1, &tmp, 10, &gotSens) < 0 ||
        !tmp) {
        fprintf(stderr, "Malformed range %s, cannot parse sensitivity\n",
                range + 1);
        return false;
    }
    if (*tmp != ':') {
        fprintf(stderr, "Malformed range %s, too many sensitivity values\n",
                tmp);
        return false;
    }
    tmp++;
    if (*tmp != 'c') {
        fprintf(stderr, "Malformed range %s, cannot find first category\n",
                tmp);
        return false;
    }
    tmp++;
    if (virStrToLong_i(tmp, &tmp, 10, &gotCatOne) < 0) {
        fprintf(stderr, "Malformed range %s, cannot parse category one\n",
                tmp);
        return false;
    }
    if (tmp && *tmp == ',')
        tmp++;
    if (tmp && *tmp == 'c') {
        tmp++;
        if (virStrToLong_i(tmp, &tmp, 10, &gotCatTwo) < 0) {
            fprintf(stderr, "Malformed range %s, cannot parse category two\n",
                    tmp);
            return false;
        }
        if (*tmp != '\0') {
            fprintf(stderr, "Malformed range %s, junk after second category\n",
                    tmp);
            return false;
        }
        if (gotCatOne == gotCatTwo) {
            fprintf(stderr, "Saw category pair %d,%d where cats were equal\n",
                    gotCatOne, gotCatTwo);
            return false;
        }
    } else {
        gotCatTwo = gotCatOne;
    }

    if (gotSens != sensMin) {
        fprintf(stderr, "Sensitivity %d is not equal to min %d\n",
                gotSens, sensMin);
        return false;
    }
    if (gotCatOne < catMin ||
        gotCatOne > catMax) {
        fprintf(stderr, "Category one %d is out of range %d-%d\n",
                gotCatTwo, catMin, catMax);
        return false;
    }
    if (gotCatTwo < catMin ||
        gotCatTwo > catMax) {
        fprintf(stderr, "Category two %d is out of range %d-%d\n",
                gotCatTwo, catMin, catMax);
        return false;
    }

    if (gotCatOne > gotCatTwo) {
        fprintf(stderr, "Category one %d is greater than category two %d\n",
                gotCatOne, gotCatTwo);
        return false;
    }

    return true;
}
Esempio n. 8
0
static int get_context_order(FILE * fp,
			     security_context_t fromcon,
			     security_context_t * reachable,
			     unsigned int nreach,
			     unsigned int *ordering, unsigned int *nordered)
{
	char *start, *end = NULL;
	char *line = NULL;
	size_t line_len = 0;
	ssize_t len;
	int found = 0;
	const char *fromrole, *fromtype;
	char *linerole, *linetype;
	unsigned int i;
	context_t con;
	int rc;

	errno = -EINVAL;

	/* Extract the role and type of the fromcon for matching.
	   User identity and MLS range can be variable. */
	con = context_new(fromcon);
	if (!con)
		return -1;
	fromrole = context_role_get(con);
	fromtype = context_type_get(con);
	if (!fromrole || !fromtype) {
		context_free(con);
		return -1;
	}

	while ((len = getline(&line, &line_len, fp)) > 0) {
		if (line[len - 1] == '\n')
			line[len - 1] = 0;

		/* Skip leading whitespace. */
		start = line;
		while (*start && isspace(*start))
			start++;
		if (!(*start))
			continue;

		/* Find the end of the (partial) fromcon in the line. */
		end = start;
		while (*end && !isspace(*end))
			end++;
		if (!(*end))
			continue;

		/* Check for a match. */
		linerole = start;
		while (*start && !isspace(*start) && *start != ':')
			start++;
		if (*start != ':')
			continue;
		*start = 0;
		linetype = ++start;
		while (*start && !isspace(*start) && *start != ':')
			start++;
		if (!(*start))
			continue;
		*start = 0;
		if (!strcmp(fromrole, linerole) && !strcmp(fromtype, linetype)) {
			found = 1;
			break;
		}
	}

	if (!found) {
		errno = ENOENT;
		rc = -1;
		goto out;
	}

	start = ++end;
	while (*start) {
		/* Skip leading whitespace */
		while (*start && isspace(*start))
			start++;
		if (!(*start))
			break;

		/* Find the end of this partial context. */
		end = start;
		while (*end && !isspace(*end))
			end++;
		if (*end)
			*end++ = 0;

		/* Check for a match in the reachable list. */
		rc = find_partialcon(reachable, nreach, start);
		if (rc < 0) {
			/* No match, skip it. */
			start = end;
			continue;
		}

		/* If a match is found and the entry is not already ordered
		   (e.g. due to prior match in prior config file), then set
		   the ordering for it. */
		i = rc;
		if (ordering[i] == nreach)
			ordering[i] = (*nordered)++;
		start = end;
	}

	rc = 0;

      out:
	context_free(con);
	free(line);
	return rc;
}