**env_copy(char **),
**env_set(char **, char *);
-user *load_user(int, struct passwd *, const char *),
+user *load_user(int, struct passwd *, const char *, const char *, const char *),
*find_user(cron_db *, const char *);
entry *load_entry(FILE *, void (*)(), struct passwd *, char **);
/* vix 26jan87 [log is in RCS file]
*/
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/flask.h>
+#include <selinux/av_permissions.h>
+#endif
+
#include "cron.h"
+#ifdef WITH_SELINUX
+static int get_security_context(char *name,
+ int crontab_fd,
+ security_context_t *rcontext,
+ char *tabname) {
+ security_context_t scontext;
+ security_context_t file_context=NULL;
+ struct av_decision avd;
+ int retval=0;
+ *rcontext = NULL;
+ if (get_default_context(name, NULL, &scontext)) {
+ if (security_getenforce() > 0) {
+ log_it(name, getpid(), "No SELinux security context",tabname);
+ return -1;
+ } else {
+ log_it(name, getpid(), "No security context but SELinux in permissive mode, continuing",tabname);
+ }
+ }
+
+ if (fgetfilecon(crontab_fd, &file_context) < OK) {
+ if (security_getenforce() > 0) {
+ log_it(name, getpid(), "getfilecon FAILED", tabname);
+ freecon(scontext);
+ return -1;
+ } else {
+ log_it(name, getpid(), "getfilecon FAILED but SELinux in permissive mode, continuing", tabname);
+ *rcontext=scontext;
+ return 0;
+ }
+ }
+
+ /*
+ * Since crontab files are not directly executed,
+ * crond must ensure that the crontab file has
+ * a context that is appropriate for the context of
+ * the user cron job. It performs an entrypoint
+ * permission check for this purpose.
+ */
+ retval = security_compute_av(scontext,
+ file_context,
+ SECCLASS_FILE,
+ FILE__ENTRYPOINT,
+ &avd);
+ freecon(file_context);
+ if (retval || ((FILE__ENTRYPOINT & avd.allowed) != FILE__ENTRYPOINT)) {
+ if (security_getenforce() > 0) {
+ log_it(name, getpid(), "ENTRYPOINT FAILED", tabname);
+ freecon(scontext);
+ return -1;
+ } else {
+ log_it(name, getpid(), "ENTRYPOINT FAILED but SELinux in permissive mode, continuing", tabname);
+ }
+ }
+ *rcontext=scontext;
+ return 0;
+}
+#endif
+
void
free_user(user *u) {
entry *e, *ne;
ne = e->next;
free_entry(e);
}
+#ifdef WITH_SELINUX
+ freecon(u->scontext);
+#endif
free(u);
}
user *
-load_user(int crontab_fd, struct passwd *pw, const char *name) {
+load_user(int crontab_fd, struct passwd *pw, const char *uname, const char *fname, const char *tabname) {
char envstr[MAX_ENVSTR];
FILE *file;
user *u;
*/
if ((u = (user *) malloc(sizeof(user))) == NULL)
return (NULL);
- if ((u->name = strdup(name)) == NULL) {
+ if ((u->name = strdup(fname)) == NULL) {
save_errno = errno;
free(u);
errno = save_errno;
return (NULL);
}
+#ifdef WITH_SELINUX
+ if (is_selinux_enabled() > 0) {
+ char *sname=uname;
+ if (pw==NULL) {
+ sname="system_u";
+ }
+
+ if (get_security_context(sname, crontab_fd,
+ &u->scontext, tabname) != 0) {
+ free_user(u);
+ u = NULL;
+ goto done;
+ }
+ }
+#endif
+
/* load the crontab
*/
while ((status = load_env(envstr, file)) >= OK) {