Ejemplo n.º 1
0
static int eval_data(const char *type, const char *local_address,
	unsigned int local_port)
{
	SEXP_t *r0;

	r0 = SEXP_string_newf("%s", type);
	if (probe_entobj_cmp(req.protocol_ent, r0) != OVAL_RESULT_TRUE) {
		SEXP_free(r0);
		return 0;
	}
	SEXP_free(r0);

	r0 = SEXP_string_newf("%s", local_address);
	if (probe_entobj_cmp(req.local_address_ent, r0) != OVAL_RESULT_TRUE) {
		SEXP_free(r0);
		return 0;
	}
	SEXP_free(r0);

	r0 = SEXP_number_newu_32(local_port);
	if (probe_entobj_cmp(req.local_port_ent, r0) != OVAL_RESULT_TRUE) {
		SEXP_free(r0);
		return 0;
	}
	SEXP_free(r0);

	return 1;
}
Ejemplo n.º 2
0
static SEXP_t *oval_behaviors_to_sexp(struct oval_behavior_iterator *bit)
{
	char *attr_name, *attr_val;
	SEXP_t *elm_name;
	SEXP_t *r0;

	struct oval_behavior *behavior;

	elm_name = SEXP_list_new(r0 = SEXP_string_newf("behaviors"), NULL);
	SEXP_free(r0);

	while (oval_behavior_iterator_has_more(bit)) {
		behavior = oval_behavior_iterator_next(bit);
		attr_name = oval_behavior_get_key(behavior);
		attr_val = oval_behavior_get_value(behavior);

		SEXP_list_add(elm_name, r0 = SEXP_string_newf(":%s", attr_name));
		SEXP_free(r0);

		if (attr_val != NULL) {
			SEXP_list_add(elm_name, r0 = SEXP_string_new(attr_val, strlen(attr_val)));
			SEXP_free(r0);
		}
	}

	r0 = SEXP_list_new(elm_name, NULL);
	SEXP_free(elm_name);

	return (r0);
}
Ejemplo n.º 3
0
static SEXP_t *oval_entity_to_sexp(struct oval_entity *ent)
{
	SEXP_t *elm, *elm_name;
	SEXP_t *r0, *r1, *r2;
	oval_datatype_t datatype;
	oval_entity_varref_type_t vr_type;

	elm_name = SEXP_list_new(r0 = SEXP_string_newf("%s", oval_entity_get_name(ent)),
				 /* operation */
				 r1 = SEXP_string_new(":operation", 10),
				 r2 = SEXP_number_newu_32(oval_entity_get_operation(ent)), NULL);
	SEXP_vfree(r0, r1, r2, NULL);

        if (oval_entity_get_mask(ent)) {
            SEXP_list_add(elm_name, r0 = SEXP_string_new("mask", 4));
            SEXP_free(r0);
        }

	elm = SEXP_list_new(NULL);
	datatype = oval_entity_get_datatype(ent);
	probe_ent_setdatatype(elm, datatype);

	vr_type = oval_entity_get_varref_type(ent);
	if (vr_type == OVAL_ENTITY_VARREF_ATTRIBUTE
	    || vr_type == OVAL_ENTITY_VARREF_ELEMENT) {
		/* var_ref */
		struct oval_variable *var;

		var = oval_entity_get_variable(ent);
		SEXP_list_add(elm_name, r0 = SEXP_string_new(":var_ref", 8));
		SEXP_list_add(elm_name, r1 = SEXP_string_newf("%s", oval_variable_get_id(var)));
		SEXP_list_add(elm, elm_name);
		SEXP_vfree(r0, r1, elm_name, NULL);
	} else {
		/* value */
		struct oval_value *val;

		SEXP_list_add(elm, elm_name);
		SEXP_free(elm_name);
		val = oval_entity_get_value(ent);

		if (datatype != OVAL_DATATYPE_RECORD
		    && val != NULL) {
			SEXP_t *val_sexp;

			val_sexp = oval_value_to_sexp(val, datatype);
			if (val_sexp != NULL) {
				SEXP_list_add(elm, val_sexp);
				SEXP_free(val_sexp);
			}
		}
	}

	return (elm);
}
Ejemplo n.º 4
0
static SEXP_t *create_item(const char *path, const char *filename, char *pattern,
			   int instance, char **substrs, int substr_cnt, oval_schema_version_t over)
{
	int i;
	SEXP_t *item;
        SEXP_t *r0;
	SEXP_t *se_instance, *se_filepath;
	char *text;

        if (strlen(path) + strlen(filename) + 1 > PATH_MAX) {
                dE("path+filename too long");
                return (NULL);
        }

	if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.4)) < 0) {
		pattern = text = NULL;
		se_instance = NULL;
	} else {
		text = substrs[0];
		se_instance = SEXP_number_newu_64((int64_t) instance);
	}
	if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.6)) < 0) {
		se_filepath = NULL;
	} else {
		const size_t path_len = strlen(path);
		/* Avoid 2 slashes */
		if (path_len >= 1 && path[path_len - 1] == FILE_SEPARATOR) {
			se_filepath = SEXP_string_newf("%s%s", path, filename);
		} else {
			se_filepath = SEXP_string_newf("%s%c%s", path, FILE_SEPARATOR, filename);
		}
	}

        item = probe_item_create(OVAL_INDEPENDENT_TEXT_FILE_CONTENT, NULL,
                                 "filepath", OVAL_DATATYPE_SEXP, se_filepath,
                                 "path",     OVAL_DATATYPE_STRING, path,
                                 "filename", OVAL_DATATYPE_STRING, filename,
                                 "pattern",  OVAL_DATATYPE_STRING, pattern,
                                 "instance", OVAL_DATATYPE_SEXP, se_instance,
                                 "line",     OVAL_DATATYPE_STRING, pattern,
                                 "text",     OVAL_DATATYPE_STRING, substrs[0],
                                 NULL);

	for (i = 1; i < substr_cnt; ++i) {
                probe_item_ent_add (item, "subexpression", NULL, r0 = SEXP_string_new (substrs[i], strlen (substrs[i])));
                SEXP_free (r0);
	}

	return item;
}
Ejemplo n.º 5
0
static int read_packet(llist *l, probe_ctx *ctx, oval_schema_version_t over)
{
	int line = 0;
	FILE *f;
	char buf[256];

	void *s;
	int refcnt, sk_type, ifindex, running;
	unsigned long inode;
	unsigned rmem, uid, proto_num;
	struct interface_t interface;


	f = fopen("/proc/net/packet", "rt");
	if (f == NULL) {
		if (errno != ENOENT)
			return 1;
		else
			return 0;
	}
	__fsetlocking(f, FSETLOCKING_BYCALLER);
	while (fgets(buf, sizeof(buf), f)) {
		if (line == 0) {
			line++;
			continue;
		}
		/* follow structure from net/packet/af_packet.c */
		sscanf(buf,
			"%p %d %d %04x %d %d %u %u %lu\n",
			&s, &refcnt, &sk_type, &proto_num, &ifindex, &running, &rmem, &uid, &inode
		);
		if (list_find_inode(l, inode) && get_interface(ifindex, &interface)) {
			struct result_info r;
			SEXP_t *r0;
			dI("Have interface_name: %s, hw_address: %s\n",
					interface.interface_name, interface.hw_address);

			r0 = SEXP_string_newf("%s", interface.interface_name);
			if (probe_entobj_cmp(interface_name_ent, r0) != OVAL_RESULT_TRUE) {
				SEXP_free(r0);
				continue;
			}
			SEXP_free(r0);

			r.interface_name = interface.interface_name;
			r.protocol = oscap_enum_to_string(ProtocolType, proto_num);
			r.hw_address = interface.hw_address;
			report_finding(&r, l, ctx, over);
		}
	}
	fclose(f);
	return 0;
}
Ejemplo n.º 6
0
static SEXP_t *oval_filter_to_sexp(struct oval_filter *filter)
{
	SEXP_t *elm, *attr, *r0, *r1;
	oval_filter_action_t act;
	struct oval_state *ste;
	char *ste_id;

	act = oval_filter_get_filter_action(filter);
	ste = oval_filter_get_state(filter);
	ste_id = oval_state_get_id(ste);
	attr = probe_attr_creat("action", r0 = SEXP_number_newu(act), NULL);
	elm = probe_ent_creat1("filter",
			       attr,
			       r1 = SEXP_string_newf("%s", ste_id));
	SEXP_vfree(attr, r0, r1, NULL);

	return (elm);
}
Ejemplo n.º 7
0
SEXP_t *oval_value_to_sexp(struct oval_value *val, oval_datatype_t dtype)
{
	SEXP_t *val_sexp = NULL;
        char   *val_rptr = NULL;

	switch (dtype) {
	case OVAL_DATATYPE_EVR_STRING:
	case OVAL_DATATYPE_DEBIAN_EVR_STRING:
	case OVAL_DATATYPE_IPV4ADDR:
	case OVAL_DATATYPE_IPV6ADDR:
	case OVAL_DATATYPE_STRING:
	case OVAL_DATATYPE_VERSION:
                val_rptr = oval_value_get_text (val);
                if (val_rptr != NULL) {
                        val_sexp = SEXP_string_newf("%s", val_rptr);
                }

		break;
	case OVAL_DATATYPE_FLOAT:
		val_sexp = SEXP_number_newf(oval_value_get_float(val));
		break;
	case OVAL_DATATYPE_INTEGER:
		val_sexp = SEXP_number_newi_64(oval_value_get_integer(val));
		break;
	case OVAL_DATATYPE_BOOLEAN:
		val_sexp = SEXP_number_newb(oval_value_get_boolean(val));
		break;
	case OVAL_DATATYPE_BINARY:
	case OVAL_DATATYPE_FILESET_REVISION:
	case OVAL_DATATYPE_IOS_VERSION:
		// todo:
		oscap_seterr(OSCAP_EFAMILY_OVAL, "Unsupported datatype: %s.", dtype);
		val_sexp = NULL;
		break;
	default:
		oscap_seterr(OSCAP_EFAMILY_OVAL, "Unknown datatype: %s.", dtype);
		val_sexp = NULL;
		break;
	}

	return val_sexp;
}
Ejemplo n.º 8
0
static int read_password(SEXP_t *un_ent, probe_ctx *ctx, oval_schema_version_t over)
{
        struct passwd *pw;

        while ((pw = getpwent())) {
                SEXP_t *un;

                dI("Have user: %s", pw->pw_name);
                un = SEXP_string_newf("%s", pw->pw_name);
                if (probe_entobj_cmp(un_ent, un) == OVAL_RESULT_TRUE) {
                        struct result_info r;

                        r.username = pw->pw_name;
                        r.password = pw->pw_passwd;
                        r.user_id = pw->pw_uid;
                        r.group_id = pw->pw_gid;
                        r.gcos = pw->pw_gecos;
                        r.home_dir = pw->pw_dir;
                        r.login_shell = pw->pw_shell;
                        r.last_login = -1;

                        if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.10)) >= 0) {
	                        FILE *ll_fp = fopen(_PATH_LASTLOG, "r");

	                        if (ll_fp != NULL) {
		                        struct lastlog ll;

		                        if (fseeko(ll_fp, (off_t)pw->pw_uid * sizeof(ll), SEEK_SET) == 0)
			                        if (fread((char *)&ll, sizeof(ll), 1, ll_fp) == 1)
				                        r.last_login = (int64_t)ll.ll_time;
		                        fclose(ll_fp);
	                        }
                        }

                        report_finding(&r, ctx, over);
                }
                SEXP_free(un);
        }
        endpwent();
        return 0;
}
Ejemplo n.º 9
0
static void report_finding(struct result_info *res, llist *l, probe_ctx *ctx, oval_schema_version_t over)
{
        SEXP_t *item, *user_id;
	lnode *n = list_get_cur(l);

	if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.10)) < 0)
		user_id = SEXP_string_newf("%d", n->uid);
	else
		user_id = SEXP_number_newi_64((int64_t)n->uid);

	item = probe_item_create(OVAL_LINUX_IFLISTENERS, NULL,
                                 "interface_name",       OVAL_DATATYPE_STRING,  res->interface_name,
                                 "protocol",             OVAL_DATATYPE_STRING,  res->protocol,
                                 "hw_address",           OVAL_DATATYPE_STRING,  res->hw_address,
                                 "program_name",         OVAL_DATATYPE_STRING,  n->cmd,
                                 "pid",                  OVAL_DATATYPE_INTEGER, (int64_t)n->pid,
				 "user_id",              OVAL_DATATYPE_SEXP, user_id,
                                 NULL);

        probe_item_collect(ctx, item);
	SEXP_free(user_id);

}
Ejemplo n.º 10
0
int main (void)
{
        SEXP_t *s_exp;
        char   *s1, *s2;

        s1 = "Hello, world!";
        s2 = "abcdefghijklmnopqrstuvwxyz";

        setbuf (stdout, NULL);
        
        s_exp = SEXP_string_new (s1, strlen (s1));
        SEXP_fprintfa (stdout, s_exp);
        putc ('\n', stdout);

        SEXP_free (s_exp);
        
        s_exp = SEXP_string_newf ("s2=%s", s2);
        SEXP_fprintfa (stdout, s_exp);
        putc ('\n', stdout);
        
        SEXP_free (s_exp);
        
        return (0);
}
Ejemplo n.º 11
0
static int rpmverify_collect(probe_ctx *ctx,
                             const char *name, oval_operation_t name_op,
                             const char *file, oval_operation_t file_op,
			     SEXP_t *name_ent, SEXP_t *filepath_ent,
                             uint64_t flags,
                             void (*callback)(probe_ctx *, struct rpmverify_res *))
{
	rpmdbMatchIterator match;
        rpmVerifyAttrs omit = (rpmVerifyAttrs)(flags & RPMVERIFY_RPMATTRMASK);
	Header pkgh;
        pcre *re = NULL;
	int  ret = -1;

        /* pre-compile regex if needed */
        if (file_op == OVAL_OPERATION_PATTERN_MATCH) {
                const char *errmsg;
                int erroff;

                re = pcre_compile(file, PCRE_UTF8, &errmsg,  &erroff, NULL);

                if (re == NULL) {
                        /* TODO */
                        return (-1);
                }
        }

        RPMVERIFY_LOCK;

        switch (name_op) {
        case OVAL_OPERATION_EQUALS:
                match = rpmtsInitIterator (g_rpm.rpmts, RPMTAG_NAME, (const void *)name, 0);

                if (match == NULL) {
                        ret = 0;
                        goto ret;
                }

                ret = rpmdbGetIteratorCount (match);

                break;
	case OVAL_OPERATION_NOT_EQUAL:
                match = rpmtsInitIterator (g_rpm.rpmts, RPMDBI_PACKAGES, NULL, 0);

                if (match == NULL) {
                        ret = 0;
                        goto ret;
                }

                if (rpmdbSetIteratorRE (match, RPMTAG_NAME, RPMMIRE_GLOB, "*") != 0)
                {
                        ret = -1;
                        goto ret;
                }

                break;
        case OVAL_OPERATION_PATTERN_MATCH:
                match = rpmtsInitIterator (g_rpm.rpmts, RPMDBI_PACKAGES, NULL, 0);

                if (match == NULL) {
                        ret = 0;
                        goto ret;
                }

                if (rpmdbSetIteratorRE (match, RPMTAG_NAME, RPMMIRE_REGEX,
                                        (const char *)name) != 0)
                {
                        ret = -1;
                        goto ret;
                }

                break;
        default:
                /* not supported */
                dE("package name: operation not supported");
                ret = -1;
                goto ret;
        }

	assume_d(RPMTAG_BASENAMES != 0, -1);
	assume_d(RPMTAG_DIRNAMES  != 0, -1);

        while ((pkgh = rpmdbNextIterator (match)) != NULL) {
                rpmfi  fi;
		rpmTag tag[2] = { RPMTAG_BASENAMES, RPMTAG_DIRNAMES };
                struct rpmverify_res res;
                errmsg_t rpmerr;
		int i;
		SEXP_t *name_sexp;

                res.name = headerFormat(pkgh, "%{NAME}", &rpmerr);

		name_sexp = SEXP_string_newf("%s", res.name);
		if (probe_entobj_cmp(name_ent, name_sexp) != OVAL_RESULT_TRUE) {
			SEXP_free(name_sexp);
			continue;
		}
		SEXP_free(name_sexp);

                /*
                 * Inspect package files & directories
                 */
		for (i = 0; i < 2; ++i) {
		  fi = rpmfiNew(g_rpm.rpmts, pkgh, tag[i], 1);

		  while (rpmfiNext(fi) != -1) {
		    SEXP_t *filepath_sexp;

		    res.fflags = rpmfiFFlags(fi);
		    res.oflags = omit;

		    if (((res.fflags & RPMFILE_CONFIG) && (flags & RPMVERIFY_SKIP_CONFIG)) ||
			((res.fflags & RPMFILE_GHOST)  && (flags & RPMVERIFY_SKIP_GHOST)))
		      continue;

		    res.file   = strdup(rpmfiFN(fi));

		    filepath_sexp = SEXP_string_newf("%s", res.file);
		    if (probe_entobj_cmp(filepath_ent, filepath_sexp) != OVAL_RESULT_TRUE) {
		      SEXP_free(filepath_sexp);
		      free(res.file);
		      continue;
		    }
		    SEXP_free(filepath_sexp);

		    if (rpmVerifyFile(g_rpm.rpmts, fi, &res.vflags, omit) != 0)
		      res.vflags = RPMVERIFY_FAILURES;

		    callback(ctx, &res);
		    free(res.file);
		  }

		  rpmfiFree(fi);
		}
	}

	match = rpmdbFreeIterator (match);
        ret   = 0;
ret:
        if (re != NULL)
                pcre_free(re);

        RPMVERIFY_UNLOCK;
        return (ret);
}
Ejemplo n.º 12
0
static int read_process(SEXP_t *cmd_ent, probe_ctx *ctx)
{
	int err = 1;
	DIR *d;
	struct dirent *ent;

	d = opendir("/proc");
	if (d == NULL)
		return err;

	// Get the time tick hertz
	ticks = (unsigned long)sysconf(_SC_CLK_TCK);
	get_boot_time();

	// Scan the directories
	while (( ent = readdir(d) )) {
		int fd, len;
		char buf[256];
		char *tmp, cmd[16], state, tty_dev[128];
		int pid, ppid, pgrp, session, tty_nr, tpgid;
		unsigned flags, sched_policy;
		unsigned long minflt, cminflt, majflt, cmajflt, uutime, ustime;
		long cutime, cstime, priority, cnice, nthreads, itrealvalue;
		unsigned long long start;
		SEXP_t *cmd_sexp;

		// Skip non-process dir entries
		if(*ent->d_name<'0' || *ent->d_name>'9')
			continue;
		errno = 0;
		pid = strtol(ent->d_name, NULL, 10);
		if (errno || pid == 2) // skip err & kthreads
			continue;

		// Parse up the stat file for the proc
		snprintf(buf, 32, "/proc/%d/stat", pid);
		fd = open(buf, O_RDONLY, 0);
		if (fd < 0)
			continue;
		len = read(fd, buf, sizeof buf - 1);
		close(fd);
		if (len < 40)
			continue;
		buf[len] = 0;
		tmp = strrchr(buf, ')');
		if (tmp)
			*tmp = 0;
		else
			continue;
		memset(cmd, 0, sizeof(cmd));
		sscanf(buf, "%d (%15c", &ppid, cmd);
		sscanf(tmp+2,	"%c %d %d %d %d %d "
				"%u %lu %lu %lu %lu "
				"%lu %lu %lu %ld %ld "
				"%ld %ld %ld %llu",
			&state, &ppid, &pgrp, &session, &tty_nr, &tpgid,
			&flags, &minflt, &cminflt, &majflt, &cmajflt,
			&uutime, &ustime, &cutime, &cstime, &priority,
			&cnice, &nthreads, &itrealvalue, &start
		);

		// Skip kthreads
		if (ppid == 2)
			continue;

		err = 0; // If we get this far, no permission problems
		dI("Have command: %s\n", cmd);
		cmd_sexp = SEXP_string_newf("%s", cmd);
		if (probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) {
			struct result_info r;
			unsigned long t = uutime/ticks + ustime/ticks;
			char tbuf[32], sbuf[32];
			int tday,tyear;
			time_t s_time;
			struct tm *proc, *now;
			const char *fmt;

			// Now get scheduler policy
			sched_policy = sched_getscheduler(pid);
			switch (sched_policy) {
				case SCHED_OTHER:
					r.scheduling_class = "TS";
					break;
				case SCHED_BATCH:
					r.scheduling_class = "B";
					break;
#ifdef SCHED_IDLE
				case SCHED_IDLE:
					r.scheduling_class = "#5";
					break;
#endif
				case SCHED_FIFO:
					r.scheduling_class = "FF";
					break;
				case SCHED_RR:
					r.scheduling_class = "RR";
					break;
				default:
					r.scheduling_class = "?";
					break;
			}

			// Calculate the start time
			s_time = time(NULL);
			now = localtime(&s_time);
			tyear = now->tm_year;
			tday = now->tm_yday;
			s_time = boot + (start / ticks);
			proc = localtime(&s_time);

			// Select format based on how long we've been running
			//
			// FROM THE SPEC:
			// "This is the time of day the process started formatted in HH:MM:SS if
			// the same day the process started or formatted as MMM_DD (Ex.: Feb_5)
			// if process started the previous day or further in the past."
			//
			if (tday != proc->tm_yday || tyear != proc->tm_year)
				fmt = "%b_%d";
			else
				fmt = "%H:%M:%S";
			strftime(sbuf, sizeof(sbuf), fmt, proc);

			r.command = cmd;
			r.exec_time = convert_time(t, tbuf, sizeof(tbuf));
			r.pid = pid;
			r.ppid = ppid;
			r.priority = priority;
			r.start_time = sbuf;

                        dev_to_tty(tty_dev, sizeof(tty_dev), (dev_t) tty_nr, pid, ABBREV_DEV);
                        r.tty = tty_dev;

			get_uids(pid, &r);
			report_finding(&r, ctx);
		}
		SEXP_free(cmd_sexp);
	}
        closedir(d);

	return err;
}
Ejemplo n.º 13
0
static SEXP_t *oval_set_to_sexp(struct oval_setobject *set)
{
	SEXP_t *elm, *elm_name;
	SEXP_t *r0, *r1, *r2;

	elm_name = SEXP_list_new(r0 = SEXP_string_new("set", 3),
				 /* operation */
				 r1 = SEXP_string_new(":operation", 10),
				 r2 = SEXP_number_newu_32(oval_setobject_get_operation(set)), NULL);

	SEXP_free(r0);
	SEXP_free(r1);
	SEXP_free(r2);

	elm = SEXP_list_new(elm_name, NULL);
	SEXP_free(elm_name);

	switch (oval_setobject_get_type(set)) {
	case OVAL_SET_AGGREGATE:{
			struct oval_setobject_iterator *sit;
			struct oval_setobject *subset;

			sit = oval_setobject_get_subsets(set);

			while (oval_setobject_iterator_has_more(sit)) {
				subset = oval_setobject_iterator_next(sit);
				SEXP_list_add(elm, r0 = oval_set_to_sexp(subset));
				SEXP_free(r0);
			}

			oval_setobject_iterator_free(sit);
		}
		break;
	case OVAL_SET_COLLECTIVE:{
			struct oval_object_iterator *oit;
			struct oval_filter_iterator *fit;
			struct oval_object *obj;
			SEXP_t *subelm;

			oit = oval_setobject_get_objects(set);
			while (oval_object_iterator_has_more(oit)) {
				obj = oval_object_iterator_next(oit);

				subelm = SEXP_list_new(r0 = SEXP_string_new("obj_ref", 7),
						       r1 = SEXP_string_newf("%s", oval_object_get_id(obj)), NULL);
				SEXP_free(r0);
				SEXP_free(r1);

				SEXP_list_add(elm, subelm);

				SEXP_free(subelm);
			}
			oval_object_iterator_free(oit);

			fit = oval_setobject_get_filters(set);
			while (oval_filter_iterator_has_more(fit)) {
				struct oval_filter *fil;

				fil = oval_filter_iterator_next(fit);
				subelm = oval_filter_to_sexp(fil);
				SEXP_list_add(elm, subelm);
				SEXP_free(subelm);
			}
			oval_filter_iterator_free(fit);
		}
		break;
	default:
		abort();
	}

	return (elm);
}
Ejemplo n.º 14
0
static int oval_varref_attr_to_sexp(void *sess, struct oval_entity *entity, struct oval_syschar *syschar, SEXP_t **out_sexp)
{
	unsigned int val_cnt = 0;
	SEXP_t *val_lst, *val_sexp, *varref, *id_sexp, *val_cnt_sexp;
	oval_datatype_t dt;
	struct oval_variable *var;
	struct oval_value_iterator *vit;
	struct oval_value *val;
	oval_syschar_collection_flag_t flag;
	char msg[100];
	int ret = 0;

	var = oval_entity_get_variable(entity);
	if (oval_probe_query_variable(sess, var) != 0) {
		dE("Can't convert variable reference to SEXP.");
		return -1;
	}

	flag = oval_variable_get_collection_flag(var);
	switch (flag) {
	case SYSCHAR_FLAG_COMPLETE:
	case SYSCHAR_FLAG_INCOMPLETE:
		vit = oval_variable_get_values(var);
		if (oval_value_iterator_has_more(vit))
			break;
		oval_value_iterator_free(vit);
		/* fall through */
	case SYSCHAR_FLAG_DOES_NOT_EXIST:
		snprintf(msg, sizeof(msg), "Referenced variable has no values (%s).", oval_variable_get_id(var));
		dI("%s", msg);
		ret = 1;
		break;
	default:
		snprintf(msg, sizeof(msg), "There was a problem processing referenced variable (%s).", oval_variable_get_id(var));
		dW("%s", msg);
		ret = 1;
	}

	if (ret) {
		oval_syschar_add_new_message(syschar, msg, OVAL_MESSAGE_LEVEL_WARNING);
		oval_syschar_set_flag(syschar, SYSCHAR_FLAG_DOES_NOT_EXIST);
		return ret;
	}

	val_lst = SEXP_list_new(NULL);

	while (oval_value_iterator_has_more(vit)) {
		val = oval_value_iterator_next(vit);

		dt = oval_entity_get_datatype(entity);
		val_sexp = oval_value_to_sexp(val, dt);
		if (val_sexp == NULL) {
			oval_syschar_add_new_message(syschar, "Failed to convert variable value.", OVAL_MESSAGE_LEVEL_ERROR);
			oval_syschar_set_flag(syschar, SYSCHAR_FLAG_ERROR);
			SEXP_free(val_lst);
			oval_value_iterator_free(vit);
			return -1;
		}

		SEXP_list_add(val_lst, val_sexp);
		SEXP_free(val_sexp);
		++val_cnt;
	}
	oval_value_iterator_free(vit);

	id_sexp = SEXP_string_newf("%s", oval_variable_get_id(var));
	val_cnt_sexp = SEXP_number_newu(val_cnt);

	varref = SEXP_list_new(id_sexp, val_cnt_sexp, val_lst, NULL);

	SEXP_free(id_sexp);
	SEXP_free(val_cnt_sexp);
	SEXP_free(val_lst);

	*out_sexp = varref;
	return 0;
}
Ejemplo n.º 15
0
static int read_process(SEXP_t *cmd_ent, SEXP_t *pid_ent, probe_ctx *ctx)
{
	int err = 1, max_cap_id;
	DIR *d;
	struct dirent *ent;
	oval_version_t oval_version;

	d = opendir("/proc");
	if (d == NULL)
		return err;

	// Get the time tick hertz
	ticks = (unsigned long)sysconf(_SC_CLK_TCK);
	get_boot_time();

	oval_version = probe_obj_get_schema_version(probe_ctx_getobject(ctx));
	if (oval_version_cmp(oval_version, OVAL_VERSION(5.11)) < 0) {
		max_cap_id = OVAL_5_8_MAX_CAP_ID;
	} else {
		max_cap_id = OVAL_5_11_MAX_CAP_ID;
	}

	struct oscap_buffer *cmdline_buffer = oscap_buffer_new();
	
	char cmd_buffer[1 + 15 + 11 + 1]; // Format:" [ cmd:15 ] <defunc>"
	cmd_buffer[0] = '[';

	// Scan the directories
	while (( ent = readdir(d) )) {
		int fd, len;
		char buf[256];
		char *tmp, state, tty_dev[128];
		int pid, ppid, pgrp, session, tty_nr, tpgid;
		unsigned flags, sched_policy;
		unsigned long minflt, cminflt, majflt, cmajflt, uutime, ustime;
		long cutime, cstime, priority, cnice, nthreads, itrealvalue;
		unsigned long long start;
		SEXP_t *cmd_sexp = NULL, *pid_sexp = NULL;

		// Skip non-process58 dir entries
		if(*ent->d_name<'0' || *ent->d_name>'9')
			continue;
		errno = 0;
		pid = strtol(ent->d_name, NULL, 10);
		if (errno || pid == 2) // skip err & kthreads
			continue;

		// Parse up the stat file for the proc
		snprintf(buf, 32, "/proc/%d/stat", pid);
		fd = open(buf, O_RDONLY, 0);
		if (fd < 0)
			continue;
		len = read(fd, buf, sizeof buf - 1);
		close(fd);
		if (len < 40)
			continue;
		buf[len] = 0;
		tmp = strrchr(buf, ')');
		if (tmp)
			*tmp = 0;
		else
			continue;
		memset(cmd_buffer + 1, 0, sizeof(cmd_buffer)-1); // clear cmd after starting '['
		sscanf(buf, "%d (%15c", &ppid, cmd_buffer + 1);
		sscanf(tmp+2,	"%c %d %d %d %d %d "
				"%u %lu %lu %lu %lu "
				"%lu %lu %lu %ld %ld "
				"%ld %ld %ld %llu",
			&state, &ppid, &pgrp, &session, &tty_nr, &tpgid,
			&flags, &minflt, &cminflt, &majflt, &cmajflt,
			&uutime, &ustime, &cutime, &cstime, &priority,
			&cnice, &nthreads, &itrealvalue, &start
		);

		// Skip kthreads
		if (ppid == 2)
			continue;

		const char* cmd;
		if (state == 'Z') { // zombie
			cmd = make_defunc_str(cmd_buffer);
		} else {
			snprintf(buf, 32, "/proc/%d/cmdline", pid);
			if (get_process_cmdline(buf, cmdline_buffer)) {
				cmd = oscap_buffer_get_raw(cmdline_buffer); // use full cmdline
			} else {
				cmd = cmd_buffer + 1;
			}
		}


		err = 0; // If we get this far, no permission problems
		dI("Have command: %s\n", cmd);
		cmd_sexp = SEXP_string_newf("%s", cmd);
		pid_sexp = SEXP_number_newu_32(pid);
		if ((cmd_sexp == NULL || probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) &&
		    (pid_sexp == NULL || probe_entobj_cmp(pid_ent, pid_sexp) == OVAL_RESULT_TRUE)
		) {
			struct result_info r;
			unsigned long t = uutime/ticks + ustime/ticks;
			char tbuf[32], sbuf[32], *selinux_domain_label, **posix_capabilities;
			int tday,tyear;
			time_t s_time;
			struct tm *proc, *now;
			const char *fmt;

			// Now get scheduler policy
			sched_policy = sched_getscheduler(pid);
			switch (sched_policy) {
				case SCHED_OTHER:
					r.scheduling_class = "TS";
					break;
				case SCHED_BATCH:
					r.scheduling_class = "B";
					break;
#ifdef SCHED_IDLE
				case SCHED_IDLE:
					r.scheduling_class = "#5";
					break;
#endif
				case SCHED_FIFO:
					r.scheduling_class = "FF";
					break;
				case SCHED_RR:
					r.scheduling_class = "RR";
					break;
				default:
					r.scheduling_class = "?";
					break;
			}

			// Calculate the start time
			s_time = time(NULL);
			now = localtime(&s_time);
			tyear = now->tm_year;
			tday = now->tm_yday;
			s_time = boot + (start / ticks);
			proc = localtime(&s_time);

			// Select format based on how long we've been running
			//
			// FROM THE SPEC:
			// "This is the time of day the process started formatted in HH:MM:SS if
			// the same day the process started or formatted as MMM_DD (Ex.: Feb_5)
			// if process started the previous day or further in the past."
			//
			if (tday != proc->tm_yday || tyear != proc->tm_year)
				fmt = "%b_%d";
			else
				fmt = "%H:%M:%S";
			strftime(sbuf, sizeof(sbuf), fmt, proc);

			r.command_line = cmd;
			r.exec_time = convert_time(t, tbuf, sizeof(tbuf));
			r.pid = pid;
			r.ppid = ppid;
			r.priority = priority;
			r.start_time = sbuf;

			dev_to_tty(tty_dev, sizeof(tty_dev), (dev_t) tty_nr, pid, ABBREV_DEV);
			r.tty = tty_dev;

			r.exec_shield = (get_exec_shield_status(pid) > 0);

			selinux_domain_label = get_selinux_label(pid);
			r.selinux_domain_label = selinux_domain_label;

			posix_capabilities = get_posix_capability(pid, max_cap_id);
			r.posix_capability = posix_capabilities;

			r.session_id = session;

			get_uids(pid, &r);
			report_finding(&r, ctx);

			if (selinux_domain_label != NULL)
				free(selinux_domain_label);

			if (posix_capabilities != NULL) {
				char **posix_capabilities_p = posix_capabilities;
				while (*posix_capabilities_p)
					free(*posix_capabilities_p++);
				free(posix_capabilities);
			}
		}
		SEXP_free(cmd_sexp);
		SEXP_free(pid_sexp);
	}
        closedir(d);
	oscap_buffer_free(cmdline_buffer);
	return err;
}
Ejemplo n.º 16
0
static int read_environment(SEXP_t *pid_ent, SEXP_t *name_ent, probe_ctx *ctx)
{
	int err = 1, pid, fd;
	bool empty;
	size_t env_name_size;
	SEXP_t *env_name, *env_value, *item, *pid_sexp;
	DIR *d;
	struct dirent *d_entry;
	char *buffer, env_file[256], *null_char;
	ssize_t buffer_used;
	size_t buffer_size;

	d = opendir("/proc");
	if (d == NULL) {
		dE("Can't read /proc: errno=%d, %s.\n", errno, strerror (errno));
		return PROBE_EACCESS;
	}

	if ((buffer = oscap_realloc(NULL, BUFFER_SIZE)) == NULL) {
		dE("Can't allocate memory");
		closedir(d);
		return PROBE_EFAULT;
	}
	buffer_size = BUFFER_SIZE;

	while ((d_entry = readdir(d))) {
		if (strspn(d_entry->d_name, "0123456789") != strlen(d_entry->d_name))
			continue;

		pid = atoi(d_entry->d_name);
		pid_sexp = SEXP_number_newi_32(pid);

		if (probe_entobj_cmp(pid_ent, pid_sexp) != OVAL_RESULT_TRUE) {
			SEXP_free(pid_sexp);
			continue;
		}
		SEXP_free(pid_sexp);

		sprintf(env_file, "/proc/%d/environ", pid);

		if ((fd = open(env_file, O_RDONLY)) == -1) {
			dE("Can't open \"%s\": errno=%d, %s.\n", env_file, errno, strerror (errno));
			item = probe_item_create(
					OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE58, NULL,
					"pid", OVAL_DATATYPE_INTEGER, (int64_t)pid,
					NULL
			);

			probe_item_setstatus(item, SYSCHAR_STATUS_ERROR);
			probe_item_add_msg(item, OVAL_MESSAGE_LEVEL_ERROR,
					   "Can't open \"%s\": errno=%d, %s.", env_file, errno, strerror (errno));
			probe_item_collect(ctx, item);
			continue;
		}

		empty = true;

		if ((buffer_used = read(fd, buffer, buffer_size - 1)) > 0) {
			empty = false;
		}

		while (! empty) {
			while (! (null_char = memchr(buffer, 0, buffer_used))) {
				ssize_t s;
				if ((size_t)buffer_used >= buffer_size) {
					buffer_size += BUFFER_SIZE;
					buffer = oscap_realloc(buffer, buffer_size);
					if (buffer == NULL) {
						dE("Can't allocate memory");
						exit(ENOMEM);
					}

				}
				s = read(fd, buffer + buffer_used, buffer_size - buffer_used);
				if (s <= 0) {
					empty = true;
					buffer[buffer_used++] = 0;
				}
				else {
					buffer_used += s;
				}
			}

			do {
				char *eq_char = strchr(buffer, '=');
				if (eq_char == NULL) {
					/* strange but possible:
					 * $ strings /proc/1218/environ
 					/dev/input/event0 /dev/input/event1 /dev/input/event4 /dev/input/event3
					*/
					buffer_used -= null_char + 1 - buffer;
					memmove(buffer, null_char + 1, buffer_used);
					continue;
				}

				env_name_size =  eq_char - buffer;
				env_name = SEXP_string_new(buffer, env_name_size);
				env_value = SEXP_string_newf("%s", buffer + env_name_size + 1);
				if (probe_entobj_cmp(name_ent, env_name) == OVAL_RESULT_TRUE) {
					item = probe_item_create(
						OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE58, NULL,
						"pid", OVAL_DATATYPE_INTEGER, (int64_t)pid,
						"name",  OVAL_DATATYPE_SEXP, env_name,
						"value", OVAL_DATATYPE_SEXP, env_value,
					      NULL);
					probe_item_collect(ctx, item);
					err = 0;
				}
				SEXP_free(env_name);
				SEXP_free(env_value);

				buffer_used -= null_char + 1 - buffer;
				memmove(buffer, null_char + 1, buffer_used);
			} while ((null_char = memchr(buffer, 0, buffer_used)));
		}

		close(fd);
	}
	closedir(d);
	oscap_free(buffer);
	if (err) {
		SEXP_t *msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR,
				"Can't find process with requested PID.");
		probe_cobj_add_msg(probe_ctx_getresult(ctx), msg);
		SEXP_free(msg);
		err = 0;
	}

	return err;
}
Ejemplo n.º 17
0
int oval_state_to_sexp(void *sess, struct oval_state *state, SEXP_t **out_sexp)
{
	SEXP_t *ste, *ste_name, *ste_ent;
	SEXP_t *r0, *r1, *r2, *r3, *r4;
	char buffer[128];
	size_t buflen;
	const char *subtype_name;
	struct oval_state_content_iterator *contents;

        subtype_name = oval_subtype_to_str(oval_state_get_subtype(state));

	if (subtype_name == NULL) {
		dI("FAIL: unknown subtype: %d", oval_state_get_subtype(state));
		return (-1);
	}

	buflen = snprintf(buffer, sizeof buffer, "%s_state", subtype_name);
	_A(buflen < sizeof buffer);

	ste_name = SEXP_list_new(r0 = SEXP_string_new(buffer, buflen),
				 r1 = SEXP_string_new(":id", 3),
				 r2 = SEXP_string_newf("%s", oval_state_get_id(state)),
				 r3 = SEXP_string_new(":operator", 9),
				 r4 = SEXP_number_newu(oval_state_get_operator(state)),
				 NULL);

	ste = SEXP_list_new(ste_name, NULL);
	SEXP_vfree(r0, r1, r2, r3, r4, ste_name, NULL);

	contents = oval_state_get_contents(state);
	while (oval_state_content_iterator_has_more(contents)) {
		oval_check_t ochk;
		oval_existence_t oext;
		oval_entity_varref_type_t vr_type;
		struct oval_entity *ent;
		struct oval_state_content *content = oval_state_content_iterator_next(contents);
		struct oval_record_field_iterator *rf_itr;

		ent = oval_state_content_get_entity(content);
		ste_ent = oval_entity_to_sexp(ent);
		if (ste_ent == NULL) {
			goto fail;
		}

		rf_itr = oval_state_content_get_record_fields(content);
		while (oval_record_field_iterator_has_more(rf_itr)) {
			struct oval_record_field *rf;
			SEXP_t *rf_sexp;

			rf = oval_record_field_iterator_next(rf_itr);
			rf_sexp = oval_record_field_STATE_to_sexp(rf);

			SEXP_list_add(ste_ent, rf_sexp);
			SEXP_free(rf_sexp);
		}
		oval_record_field_iterator_free(rf_itr);

		ochk = oval_state_content_get_var_check(content);
		if (ochk != OVAL_CHECK_UNKNOWN) {
			probe_ent_attr_add(ste_ent, "var_check", r0 = SEXP_number_newu_32(ochk));
			SEXP_free(r0);
		}

		ochk = oval_state_content_get_ent_check(content);
		if (ochk != OVAL_CHECK_UNKNOWN) {
			probe_ent_attr_add(ste_ent, "entity_check", r0 = SEXP_number_newu_32(ochk));
			SEXP_free(r0);
		}

		oext = oval_state_content_get_check_existence(content);
		if (oext != OVAL_EXISTENCE_UNKNOWN) {
			probe_ent_attr_add(ste_ent, "check_existence", r0 = SEXP_number_newu_32(oext));
			SEXP_free(r0);
		}

		vr_type = oval_entity_get_varref_type(ent);
		if (vr_type == OVAL_ENTITY_VARREF_ATTRIBUTE
		    || vr_type == OVAL_ENTITY_VARREF_ELEMENT) {
			SEXP_t *val_lst;
			struct oval_variable *var;
			oval_datatype_t dt;

			var = oval_entity_get_variable(ent);
			dt = oval_entity_get_datatype(ent);

			if (oval_varref_elm_to_sexp(sess, var, dt, &val_lst, NULL) != 0)
				goto fail;

			SEXP_list_add(ste_ent, val_lst);
			SEXP_free(val_lst);
		}

		SEXP_list_add(ste, ste_ent);
		SEXP_free(ste_ent);
	}
	oval_state_content_iterator_free(contents);

	*out_sexp = ste;
	return (0);

 fail:
	oval_state_content_iterator_free(contents);
	SEXP_vfree(ste, ste_ent, NULL);
	return (-1);
}
Ejemplo n.º 18
0
static int read_process(SEXP_t *cmd_ent, probe_ctx *ctx)
{
	int err = 1;
	DIR *d;
	struct dirent *ent;

	d = opendir("/proc");
	if (d == NULL)
		return err;

	psinfo_t *psinfo;

	// Scan the directories
	while (( ent = readdir(d) )) {
		int fd, len;
		char buf[336];
		int pid;
		unsigned sched_policy;
		SEXP_t *cmd_sexp;


		// Skip non-process dir entries
		if(*ent->d_name<'0' || *ent->d_name>'9')
			continue;
		errno = 0;
		pid = strtol(ent->d_name, NULL, 10);
		if (errno || pid == 2) // skip err & kthreads
			continue;

		// Parse up the stat file for the proc
		snprintf(buf, 32, "/proc/%d/psinfo", pid);
		fd = open(buf, O_RDONLY, 0);
		if (fd < 0)
			continue;
		len = read(fd, buf, sizeof buf);
		close(fd);
		if (len < 336)
			continue;

		// The psinfo file contains a psinfo struct; this typecast gets us the struct directly
		psinfo = (psinfo_t *) buf;


		err = 0; // If we get this far, no permission problems
		dI("Have command: %s\n", psinfo->pr_fname);
		cmd_sexp = SEXP_string_newf("%s", psinfo->pr_fname);
		if (probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) {
			struct result_info r;
			char tbuf[32], sbuf[32];
			int tday,tyear;
			time_t s_time;
			struct tm *proc, *now;
			const char *fmt;
			int fixfmt_year;

			r.scheduling_class = malloc(PRCLSZ);
			strncpy(r.scheduling_class, (psinfo->pr_lwp).pr_clname, sizeof(r.scheduling_class));

			// Get the start time
			s_time = time(NULL);
			now = localtime(&s_time);
			tyear = now->tm_year;
			tday = now->tm_yday;

			// Get current time
			s_time = psinfo->pr_start.tv_sec;
			proc = localtime(&s_time);

			// Select format based on how long we've been running
			//
			// FROM THE SPEC:
			// "This is the time of day the process started formatted in HH:MM:SS if
			// the same day the process started or formatted as MMM_DD (Ex.: Feb_5)
			// if process started the previous day or further in the past."
			//
			if (tday != proc->tm_yday || tyear != proc->tm_year)
				fmt = "%b_%d";
			else
				fmt = "%H:%M:%S";
			strftime(sbuf, sizeof(sbuf), fmt, proc);

			r.command = psinfo->pr_fname;
			r.exec_time = convert_time(psinfo->pr_time.tv_sec, tbuf, sizeof(tbuf));
			r.pid = psinfo->pr_pid;
			r.ppid = psinfo->pr_ppid;
			r.priority = (psinfo->pr_lwp).pr_pri;
			r.ruid = psinfo->pr_uid;
			r.start_time = sbuf;
			r.tty = oscap_sprintf("%s", psinfo->pr_ttydev);
			r.user_id = psinfo->pr_euid;
			report_finding(&r, ctx);
		}
		SEXP_free(cmd_sexp);
	}
        closedir(d);

	return err;
}
Ejemplo n.º 19
0
static int get_runlevel_sysv (struct runlevel_req *req, struct runlevel_rep **rep, bool suse, const char *init_path, const char *rc_path)
{
	const char runlevel_list[] = {'0', '1', '2', '3', '4', '5', '6'};

	char pathbuf[PATH_MAX];
	DIR *init_dir, *rc_dir;
	struct dirent *init_dp, *rc_dp;
	struct stat init_st, rc_st;
	struct runlevel_rep *rep_lst = NULL;

	_A(req != NULL);
	_A(rep != NULL);

	init_dir = opendir(init_path);
	if (init_dir == NULL) {
		dI("Can't open directory \"%s\": errno=%d, %s.",
		   init_path, errno, strerror (errno));
		return (-1);
	}

	while ((init_dp = readdir(init_dir)) != NULL) {
		char *service_name;
		unsigned int i;
		SEXP_t *r0;

		// Ensure that we are in the expected directory before
		// touching relative paths
		if (fchdir(dirfd(init_dir)) != 0) {
			dI("Can't fchdir to \"%s\": errno=%d, %s.",
			   init_path, errno, strerror (errno));
			closedir(init_dir);
			return -1;
		}

		if (stat(init_dp->d_name, &init_st) != 0) {
			dI("Can't stat file %s/%s: errno=%d, %s.",
			   init_path, init_dp->d_name, errno, strerror(errno));
			continue;
		}

		r0 = SEXP_string_newf("%s", init_dp->d_name);
		if (probe_entobj_cmp(req->service_name_ent, r0) != OVAL_RESULT_TRUE) {
			SEXP_free(r0);
			continue;
		}
		SEXP_free(r0);
		service_name = init_dp->d_name;

		for (i = 0; i < (sizeof (runlevel_list) / sizeof (runlevel_list[0])); ++i) {
			char runlevel[2] = {'\0', '\0'};
			bool start, kill;

			r0 = SEXP_string_newf("%c", runlevel_list[i]);
			if (probe_entobj_cmp(req->runlevel_ent, r0) != OVAL_RESULT_TRUE) {
				SEXP_free(r0);
				continue;
			}
			SEXP_free(r0);
			runlevel[0] = runlevel_list[i];

			snprintf(pathbuf, sizeof (pathbuf), rc_path, runlevel_list[i]);
			rc_dir = opendir(pathbuf);
			if (rc_dir == NULL) {
				dI("Can't open directory \"%s\": errno=%d, %s.",
				   rc_path, errno, strerror (errno));
				continue;
			}
			if (chdir(pathbuf) != 0) {
				dI("Can't fchdir to \"%s\": errno=%d, %s.",
				   rc_path, errno, strerror (errno));
				closedir(rc_dir);
				continue;
			}

			// On SUSE, the presence of a symbolic link to the init.d/<service> in 
			// a runlevel directory rcx.d implies that the sevice is started on x.
			
			if (suse) {			
				start = false;
				kill = true;
			}
			else
				start = kill = false;

			while ((rc_dp = readdir(rc_dir)) != NULL) {
				if (stat(rc_dp->d_name, &rc_st) != 0) {
					dI("Can't stat file %s/%s: errno=%d, %s.",
					   rc_path, rc_dp->d_name, errno, strerror(errno));
					continue;
				}

				if (init_st.st_ino == rc_st.st_ino) {

					if (suse) {
						if (rc_dp->d_name[0] == 'S') {
						
							start = true;
							kill = false;

							break;
						}
					}						
					else {
						if (rc_dp->d_name[0] == 'S') {
							start = true;
							break;
						} else if (rc_dp->d_name[0] == 'K') {
							kill = true;
							break;
						} else {
							dI("Unexpected character in filename: %c, %s/%s.",
							   rc_dp->d_name[0], pathbuf, rc_dp->d_name);
						}
					}
				}
			}
			closedir(rc_dir);

			if (rep_lst == NULL) {
				rep_lst = *rep = oscap_alloc(sizeof (struct runlevel_rep));
			} else {
				rep_lst->next = oscap_alloc(sizeof (struct runlevel_rep));
				rep_lst = rep_lst->next;
			}

			rep_lst->service_name = strdup(service_name);
			rep_lst->runlevel = strdup(runlevel);
			rep_lst->start = start;
			rep_lst->kill = kill;
			rep_lst->next = NULL;
		}
	}
	closedir(init_dir);

	return (1);
}