16cd6a6acSopenharmony_ci#include <unistd.h>
26cd6a6acSopenharmony_ci#include <fcntl.h>
36cd6a6acSopenharmony_ci#include <string.h>
46cd6a6acSopenharmony_ci#include <stdlib.h>
56cd6a6acSopenharmony_ci#include <errno.h>
66cd6a6acSopenharmony_ci#include <sys/xattr.h>
76cd6a6acSopenharmony_ci#include "selinux_internal.h"
86cd6a6acSopenharmony_ci#include "policy.h"
96cd6a6acSopenharmony_ci
106cd6a6acSopenharmony_ciint setfilecon_raw(const char *path, const char * context)
116cd6a6acSopenharmony_ci{
126cd6a6acSopenharmony_ci	int rc = setxattr(path, XATTR_NAME_SELINUX, context, strlen(context) + 1,
136cd6a6acSopenharmony_ci			0);
146cd6a6acSopenharmony_ci	if (rc < 0 && errno == ENOTSUP) {
156cd6a6acSopenharmony_ci		char * ccontext = NULL;
166cd6a6acSopenharmony_ci		int err = errno;
176cd6a6acSopenharmony_ci		if ((getfilecon_raw(path, &ccontext) >= 0) &&
186cd6a6acSopenharmony_ci		    (strcmp(context,ccontext) == 0)) {
196cd6a6acSopenharmony_ci			rc = 0;
206cd6a6acSopenharmony_ci		} else {
216cd6a6acSopenharmony_ci			errno = err;
226cd6a6acSopenharmony_ci		}
236cd6a6acSopenharmony_ci		freecon(ccontext);
246cd6a6acSopenharmony_ci	}
256cd6a6acSopenharmony_ci	return rc;
266cd6a6acSopenharmony_ci}
276cd6a6acSopenharmony_ci
286cd6a6acSopenharmony_ci
296cd6a6acSopenharmony_ciint setfilecon(const char *path, const char *context)
306cd6a6acSopenharmony_ci{
316cd6a6acSopenharmony_ci	int ret;
326cd6a6acSopenharmony_ci	char * rcontext;
336cd6a6acSopenharmony_ci
346cd6a6acSopenharmony_ci	if (selinux_trans_to_raw_context(context, &rcontext))
356cd6a6acSopenharmony_ci		return -1;
366cd6a6acSopenharmony_ci
376cd6a6acSopenharmony_ci	ret = setfilecon_raw(path, rcontext);
386cd6a6acSopenharmony_ci
396cd6a6acSopenharmony_ci	freecon(rcontext);
406cd6a6acSopenharmony_ci
416cd6a6acSopenharmony_ci	return ret;
426cd6a6acSopenharmony_ci}
43