Example #1
0
int loadrulefile()
{
    FILE *fp;
    char line[1024];
    char *tmp;
    int failed = 0;

    flush_rules();

    fp = fopen(DEFAULT_RULESFILE, "r");
    if (!fp) {
        fprintf(stderr,"Rules file not found !\n");
        return 0;
    }

    if (verbose) printf("Loading filter rules\n");
    while (!feof(fp)) {
        if (!fgets(line, 1023, fp)) break;
        if ((tmp = strchr(line, '\r')) != NULL)
            *tmp = '\0';
        if ((tmp = strchr(line, '\n')) != NULL)
            *tmp = '\0';
        if (line[0] == '#' || line[0] == '\0')
            continue;
        if ((add_rule(line)) == NULL) {
            fprintf(stderr,"Cannot add rule `%s'\n",line);
            failed = 1;
            break;
        }
        else {
            if (vv)
                printf("%s\n",line);
        }
    }

    fclose(fp);

    if (failed) {
        fprintf(stderr, "Rules loading cancelled, flushing\n");
        flush_rules();
        return 0;
    }

    if (verbose) printf("Rules loaded\n");
    return 1;
}
Example #2
0
static secadm_error_t
handle_add_rule(struct thread *td, secadm_command_t *cmd, secadm_reply_t *reply)
{
	secadm_rule_t *rule, *next, *tail;
	struct secadm_prison_entry *entry;
	size_t maxid=0;
	secadm_error_t res=secadm_success;
	int err;

	entry = get_prison_list_entry(td->td_ucred->cr_prison->pr_name, 1);

	rule = malloc(sizeof(secadm_rule_t), M_SECADM, M_WAITOK);
	if ((err = copyin(cmd->sc_metadata, rule, sizeof(secadm_rule_t))) != 0) {
		free(rule, M_SECADM);
		reply->sr_code = secadm_fail;
		reply->sr_errno = err;
		return (secadm_fail);
	}

	if (read_rule_from_userland(td, rule)) {
		reply->sr_errno = EINVAL;
		rule->sr_next = NULL;
		goto error;
	}

	rule->sr_id = maxid++;

	tail = rule;
	while (tail->sr_next != NULL) {
		next = malloc(sizeof(secadm_rule_t), M_SECADM, M_WAITOK);
		if ((err = copyin(tail->sr_next, next, sizeof(secadm_rule_t))) != 0) {
			reply->sr_errno = err;
			free(next, M_SECADM);
			tail->sr_next = NULL;
			goto error;
		}

		if (read_rule_from_userland(td, next)) {
			res=secadm_fail;
			reply->sr_errno = EINVAL;
			free_rule(next, 1);
			tail->sr_next = NULL;
			goto error;
		}

		next->sr_id = maxid++;

		tail->sr_next = next;
		tail = next;
	}

	if (validate_ruleset(td, rule)) {
		res = secadm_fail;
		reply->sr_errno = EINVAL;
		goto error;
	}

	flush_rules(td);

	SPL_WLOCK(entry);
	entry->spl_rules = rule;
	entry->spl_max_id = maxid;
	SPL_WUNLOCK(entry);

	reply->sr_code = secadm_success;
	reply->sr_errno = 0;

	return (0);

error:
	while (rule != NULL) {
		next = rule->sr_next;
		free_rule(rule, 1);
		rule = next;
	}

	reply->sr_code = secadm_fail;

	return (res);
}
Example #3
0
static int
sysctl_control(SYSCTL_HANDLER_ARGS)
{
	secadm_command_t cmd;
	secadm_reply_t reply;
	int err;

	if (!(req->newptr) || (req->newlen != sizeof(secadm_command_t)))
		return (EINVAL);

	if (!(req->oldptr) || (req->oldlen) != sizeof(secadm_reply_t))
		return (EINVAL);

	err = SYSCTL_IN(req, &cmd, sizeof(secadm_command_t));
	if (err)
		return (err);

	/* Access control comes first */
	switch (cmd.sc_type) {
	case secadm_flush_rules:
	case secadm_set_rules:
		/* XXX Should we cache the ucred for local use in the
		 * sysctl lifecycle? */
		// XXXOP LOCKING
		if (req->td->td_ucred->cr_uid != 0) {
			printf("[SECADM] Disallowed command: 0x%x by uid: %d\n",
			    cmd.sc_type, req->td->td_ucred->cr_uid);
			return (EPERM);
		}

		// XXXOP LOCKING
		if (securelevel_gt(req->td->td_ucred, 0)) {
			printf("[SECADM] Disallowed command: 0x%x by uid: %d\n",
			    cmd.sc_type, req->td->td_ucred->cr_uid);
			return (EPERM);
		}
		break;
	default:
		break;
	}

	/* XXX We should relax this check once we get stable releases. */
	if (cmd.sc_version < SECADM_VERSION)
		return (EINVAL);

	memset(&reply, 0x00, sizeof(reply));
	if ((err = copyin(req->oldptr, &reply, sizeof(reply))))
		return (err);

	reply.sr_version = SECADM_VERSION;
	reply.sr_id = cmd.sc_id;

	switch (cmd.sc_type) {
	case  secadm_get_version:
		if (cmd.sc_bufsize < sizeof(unsigned long))
			return (EINVAL);

		handle_version_command(&cmd, &reply);
		break;
	case secadm_set_rules:
		if (cmd.sc_size != sizeof(secadm_rule_t))
			return (EINVAL);

		handle_add_rule(req->td, &cmd, &reply);
		break;
	case secadm_flush_rules:
		flush_rules(req->td);
		break;
	case secadm_get_rule_size:
		handle_get_rule_size(req->td, &cmd, &reply);
		break;
	case secadm_get_num_rules:
		get_num_rules(req->td, &cmd, &reply);
		break;
	case secadm_get_rule:
		handle_get_rule(req->td, &cmd, &reply);
		break;
	case secadm_get_rules:
	case secadm_get_admins:
	case secadm_set_admins:
	case secadm_get_views:
	case secadm_set_views:
		return (ENOTSUP);
	default:
		// XXXOP LOCKING
		printf("[SECADM] Unknown command: 0x%x by uid: %d\n",
		    cmd.sc_type, req->td->td_ucred->cr_uid);
		return (EINVAL);
	}

	err = SYSCTL_OUT(req, &reply, sizeof(secadm_reply_t));
	return (err);
}