16cd6a6acSopenharmony_ci#include <unistd.h>
26cd6a6acSopenharmony_ci#include <fcntl.h>
36cd6a6acSopenharmony_ci#include <string.h>
46cd6a6acSopenharmony_ci#include "selinux_internal.h"
56cd6a6acSopenharmony_ci#include "context_internal.h"
66cd6a6acSopenharmony_ci
76cd6a6acSopenharmony_ciint setexecfilecon(const char *filename, const char *fallback_type)
86cd6a6acSopenharmony_ci{
96cd6a6acSopenharmony_ci	char * mycon = NULL, *fcon = NULL, *newcon = NULL;
106cd6a6acSopenharmony_ci	context_t con = NULL;
116cd6a6acSopenharmony_ci	int rc = 0;
126cd6a6acSopenharmony_ci
136cd6a6acSopenharmony_ci	if (is_selinux_enabled() < 1)
146cd6a6acSopenharmony_ci		return 0;
156cd6a6acSopenharmony_ci
166cd6a6acSopenharmony_ci	rc = getcon(&mycon);
176cd6a6acSopenharmony_ci	if (rc < 0)
186cd6a6acSopenharmony_ci		goto out;
196cd6a6acSopenharmony_ci
206cd6a6acSopenharmony_ci	rc = getfilecon(filename, &fcon);
216cd6a6acSopenharmony_ci	if (rc < 0)
226cd6a6acSopenharmony_ci		goto out;
236cd6a6acSopenharmony_ci
246cd6a6acSopenharmony_ci	rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &newcon);
256cd6a6acSopenharmony_ci	if (rc < 0)
266cd6a6acSopenharmony_ci		goto out;
276cd6a6acSopenharmony_ci
286cd6a6acSopenharmony_ci	if (!strcmp(mycon, newcon)) {
296cd6a6acSopenharmony_ci		/* No default transition, use fallback_type for now. */
306cd6a6acSopenharmony_ci		rc = -1;
316cd6a6acSopenharmony_ci		con = context_new(mycon);
326cd6a6acSopenharmony_ci		if (!con)
336cd6a6acSopenharmony_ci			goto out;
346cd6a6acSopenharmony_ci		if (context_type_set(con, fallback_type))
356cd6a6acSopenharmony_ci			goto out;
366cd6a6acSopenharmony_ci		freecon(newcon);
376cd6a6acSopenharmony_ci		newcon = strdup(context_str(con));
386cd6a6acSopenharmony_ci		if (!newcon)
396cd6a6acSopenharmony_ci			goto out;
406cd6a6acSopenharmony_ci	}
416cd6a6acSopenharmony_ci
426cd6a6acSopenharmony_ci	rc = setexeccon(newcon);
436cd6a6acSopenharmony_ci	if (rc < 0)
446cd6a6acSopenharmony_ci		goto out;
456cd6a6acSopenharmony_ci      out:
466cd6a6acSopenharmony_ci
476cd6a6acSopenharmony_ci	if (rc < 0 && security_getenforce() == 0)
486cd6a6acSopenharmony_ci		rc = 0;
496cd6a6acSopenharmony_ci
506cd6a6acSopenharmony_ci	context_free(con);
516cd6a6acSopenharmony_ci	freecon(newcon);
526cd6a6acSopenharmony_ci	freecon(fcon);
536cd6a6acSopenharmony_ci	freecon(mycon);
546cd6a6acSopenharmony_ci	return rc < 0 ? rc : 0;
556cd6a6acSopenharmony_ci}
566cd6a6acSopenharmony_ci
576cd6a6acSopenharmony_ci#ifndef DISABLE_RPM
586cd6a6acSopenharmony_ciint rpm_execcon(unsigned int verified __attribute__ ((unused)),
596cd6a6acSopenharmony_ci		const char *filename, char *const argv[], char *const envp[])
606cd6a6acSopenharmony_ci{
616cd6a6acSopenharmony_ci	int rc;
626cd6a6acSopenharmony_ci
636cd6a6acSopenharmony_ci	rc = setexecfilecon(filename, "rpm_script_t");
646cd6a6acSopenharmony_ci	if (rc < 0)
656cd6a6acSopenharmony_ci		return rc;
666cd6a6acSopenharmony_ci
676cd6a6acSopenharmony_ci	return execve(filename, argv, envp);
686cd6a6acSopenharmony_ci}
696cd6a6acSopenharmony_ci#endif
70