root/src/security.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. cron_conv
  2. cron_restore_default_security_context
  3. cron_set_job_security_context
  4. cron_start_pam
  5. cron_open_pam_session
  6. cron_close_pam
  7. cron_change_groups
  8. cron_change_user_permanently
  9. cron_authorize_context
  10. cron_authorize_range
  11. cron_get_job_range
  12. cron_change_selinux_range
  13. get_security_context
  14. free_security_context
  15. crontab_security_access
  16. build_env

   1 /* security.c 
   2  *
   3  * Implement Red Hat crond security context transitions
   4  *
   5  * Jason Vas Dias <jvdias@redhat.com> January 2006
   6  *
   7  * Copyright(C) Red Hat Inc., 2006
   8  *
   9  * Permission to use, copy, modify, and distribute this software for any
  10  * purpose with or without fee is hereby granted, provided that the above
  11  * copyright notice and this permission notice appear in all copies.
  12  *
  13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
  14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  15  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
  16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  20  */
  21 
  22 #include "config.h"
  23 
  24 #include <errno.h>
  25 #include <grp.h>
  26 #include <pwd.h>
  27 #include <sys/types.h>
  28 #include <unistd.h>
  29 #include <stdlib.h>
  30 #include <string.h>
  31 
  32 #include "cronie_common.h"
  33 #include "funcs.h"
  34 #include "globals.h"
  35 #include "macros.h"
  36 
  37 #ifdef WITH_PAM
  38 # include <security/pam_appl.h>
  39 #endif
  40 
  41 #ifdef WITH_SELINUX
  42 # include <selinux/selinux.h>
  43 # include <selinux/context.h>
  44 # include <selinux/get_context_list.h>
  45 #endif
  46 
  47 #ifdef WITH_AUDIT
  48 # include <libaudit.h>
  49 #endif
  50 
  51 #ifdef WITH_PAM
  52 static pam_handle_t *pamh = NULL;
  53 static int pam_session_opened = 0;      //global for open session
  54 
  55 static int
  56 cron_conv(int num_msg, const struct pam_message **msgm,
     /* [previous][next][first][last][top][bottom][index][help]  */
  57         struct pam_response **response ATTRIBUTE_UNUSED,
  58         void *appdata_ptr ATTRIBUTE_UNUSED)
  59 {
  60         int i;
  61 
  62         for (i = 0; i < num_msg; i++) {
  63                 switch (msgm[i]->msg_style) {
  64                 case PAM_ERROR_MSG:
  65                 case PAM_TEXT_INFO:
  66                         if (msgm[i]->msg != NULL) {
  67                                 log_it("CRON", getpid(), "pam_message", msgm[i]->msg, 0);
  68                         }
  69                         break;
  70                 default:
  71                         break;
  72                 }
  73         }
  74         return (0);
  75 }
  76 
  77 static const struct pam_conv conv = {
  78         cron_conv, NULL
  79 };
  80 
  81 static int cron_open_pam_session(struct passwd *pw);
  82 
  83 # define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \
  84         log_it(pw->pw_name, getpid(), "PAM ERROR", pam_strerror(pamh, retcode), 0); \
  85         if (pamh != NULL) { \
  86                 if (pam_session_opened != 0) \
  87                         pam_close_session(pamh, PAM_SILENT); \
  88                 pam_end(pamh, retcode); \
  89                 pamh = NULL; \
  90         } \
  91 return(retcode); }
  92 #endif
  93 
  94 static char **build_env(char **cronenv);
  95 
  96 #ifdef WITH_SELINUX
  97 static int cron_change_selinux_range(user * u, security_context_t ucontext);
  98 static int cron_get_job_range(user * u, security_context_t * ucontextp,
  99         char **jobenv);
 100 #endif
 101 
 102 void cron_restore_default_security_context(void) {
     /* [previous][next][first][last][top][bottom][index][help]  */
 103 #ifdef WITH_SELINUX
 104         if (is_selinux_enabled() <= 0)
 105                 return;
 106         if (setexeccon(NULL) < 0)
 107                 log_it("CRON", getpid(), "ERROR",
 108                         "failed to restore SELinux context", 0);
 109 #endif
 110 }
 111 
 112 int cron_set_job_security_context(entry *e, user *u ATTRIBUTE_UNUSED,
     /* [previous][next][first][last][top][bottom][index][help]  */
 113         char ***jobenv) {
 114         time_t minutely_time = 0;
 115 #ifdef WITH_PAM
 116         int ret;
 117 #endif
 118 
 119         if ((e->flags & MIN_STAR) == MIN_STAR) {
 120                 /* "minute-ly" job: Every minute for given hour/dow/month/dom. 
 121                  * Ensure that these jobs never run in the same minute:
 122                  */
 123                 minutely_time = time(0);
 124                 Debug(DSCH, ("Minute-ly job. Recording time %lu\n", minutely_time));
 125         }
 126 
 127 #ifdef WITH_PAM
 128         /* PAM is called only for non-root users or non-system crontab */
 129         if ((!u->system || e->pwd->pw_uid != 0) && (ret = cron_start_pam(e->pwd)) != 0) {
 130                 log_it(e->pwd->pw_name, getpid(), "FAILED to authorize user with PAM",
 131                         pam_strerror(pamh, ret), 0);
 132                 return -1;
 133         }
 134 #endif
 135 
 136 #ifdef WITH_SELINUX
 137         /* we must get the crontab context BEFORE changing user, else
 138          * we'll not be permitted to read the cron spool directory :-)
 139          */
 140         security_context_t ucontext = 0;
 141 
 142         if (cron_get_job_range(u, &ucontext, e->envp) < OK) {
 143                 log_it(e->pwd->pw_name, getpid(), "ERROR",
 144                         "failed to get SELinux context", 0);
 145                 return -1;
 146         }
 147 
 148         if (cron_change_selinux_range(u, ucontext) != 0) {
 149                 log_it(e->pwd->pw_name, getpid(), "ERROR",
 150                         "failed to change SELinux context", 0);
 151                 if (ucontext)
 152                         freecon(ucontext);
 153                 return -1;
 154         }
 155         if (ucontext)
 156                 freecon(ucontext);
 157 #endif
 158 #ifdef WITH_PAM
 159         if (pamh != NULL && (ret = cron_open_pam_session(e->pwd)) != 0) {
 160                 log_it(e->pwd->pw_name, getpid(),
 161                         "FAILED to open PAM security session", pam_strerror(pamh, ret), 0);
 162                 return -1;
 163         }
 164 #endif
 165 
 166         if (cron_change_groups(e->pwd) != 0) {
 167                 return -1;
 168         }
 169 
 170         *jobenv = build_env(e->envp);
 171 
 172         time_t job_run_time = time(0L);
 173 
 174         if ((minutely_time > 0) && ((job_run_time / 60) != (minutely_time / 60))) {
 175                 /* if a per-minute job is delayed into the next minute 
 176                  * (eg. by network authentication method timeouts), skip it.
 177                  */
 178                 struct tm tmS, tmN;
 179                 char buf[256];
 180 
 181                 localtime_r(&job_run_time, &tmN);
 182                 localtime_r(&minutely_time, &tmS);
 183 
 184                 snprintf(buf, sizeof (buf),
 185                         "Job execution of per-minute job scheduled for "
 186                         "%.2u:%.2u delayed into subsequent minute %.2u:%.2u. Skipping job run.",
 187                         tmS.tm_hour, tmS.tm_min, tmN.tm_hour, tmN.tm_min);
 188                 log_it(e->pwd->pw_name, getpid(), "INFO", buf, 0);
 189                 return -1;
 190         }
 191         return 0;
 192 }
 193 
 194 #if defined(WITH_PAM)
 195 int cron_start_pam(struct passwd *pw) {
     /* [previous][next][first][last][top][bottom][index][help]  */
 196         int retcode = 0;
 197 
 198         retcode = pam_start("crond", pw->pw_name, &conv, &pamh);
 199         PAM_FAIL_CHECK;
 200         retcode = pam_set_item(pamh, PAM_TTY, "cron");
 201         PAM_FAIL_CHECK;
 202         retcode = pam_acct_mgmt(pamh, PAM_SILENT);
 203         PAM_FAIL_CHECK;
 204         retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT);
 205         PAM_FAIL_CHECK;
 206 
 207         return retcode;
 208 }
 209 #endif
 210 
 211 #if defined(WITH_PAM)
 212 static int cron_open_pam_session(struct passwd *pw) {
     /* [previous][next][first][last][top][bottom][index][help]  */
 213         int retcode;
 214 
 215         retcode = pam_open_session(pamh, PAM_SILENT);
 216         PAM_FAIL_CHECK;
 217         if (retcode == PAM_SUCCESS)
 218                 pam_session_opened = 1;
 219 
 220         return retcode;
 221 }
 222 #endif
 223 
 224 void cron_close_pam(void) {
     /* [previous][next][first][last][top][bottom][index][help]  */
 225 #if defined(WITH_PAM)
 226         if (pam_session_opened != 0) {
 227                 pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);
 228                 pam_close_session(pamh, PAM_SILENT);
 229         }
 230         if (pamh != NULL) {
 231                 pam_end(pamh, PAM_SUCCESS);
 232                 pamh = NULL;
 233         }
 234 #endif
 235 }
 236 
 237 int cron_change_groups(struct passwd *pw) {
     /* [previous][next][first][last][top][bottom][index][help]  */
 238         pid_t pid = getpid();
 239 
 240         if (setgid(pw->pw_gid) != 0) {
 241                 log_it("CRON", pid, "ERROR", "setgid failed", errno);
 242                 return -1;
 243         }
 244 
 245         if (initgroups(pw->pw_name, pw->pw_gid) != 0) {
 246                 log_it("CRON", pid, "ERROR", "initgroups failed", errno);
 247                 return -1;
 248         }
 249 
 250 #if defined(WITH_PAM)
 251         /* credentials may take form of supplementary groups so reinitialize
 252          * them here */
 253         if (pamh != NULL) {
 254                 pam_setcred(pamh, PAM_REINITIALIZE_CRED | PAM_SILENT);
 255         }
 256 #endif
 257 
 258         return 0;
 259 }
 260 
 261 int cron_change_user_permanently(struct passwd *pw, char *homedir) {
     /* [previous][next][first][last][top][bottom][index][help]  */
 262         if (setreuid(pw->pw_uid, pw->pw_uid) != 0) {
 263                 log_it("CRON", getpid(), "ERROR", "setreuid failed", errno);
 264                 return -1;
 265         }
 266 
 267         if (chdir(homedir) == -1) {
 268                 log_it("CRON", getpid(), "ERROR chdir failed", homedir, errno);
 269                 return -1;
 270         }
 271 
 272         log_close();
 273 
 274         return 0;
 275 }
 276 
 277 
 278 #ifdef WITH_SELINUX
 279 static int cron_authorize_context(security_context_t scontext,
     /* [previous][next][first][last][top][bottom][index][help]  */
 280         security_context_t file_context) {
 281         struct av_decision avd;
 282         int retval;
 283         security_class_t tclass;
 284         access_vector_t bit;
 285 
 286         tclass = string_to_security_class("file");
 287         if (!tclass) {
 288                 log_it("CRON", getpid(), "ERROR", "Failed to translate security class file", errno);
 289                 return 0;
 290         }
 291         bit = string_to_av_perm(tclass, "entrypoint");
 292         if (!bit) {
 293                 log_it("CRON", getpid(), "ERROR", "Failed to translate av perm entrypoint", errno);
 294                 return 0;
 295         }
 296         /*
 297          * Since crontab files are not directly executed,
 298          * crond must ensure that the crontab file has
 299          * a context that is appropriate for the context of
 300          * the user cron job.  It performs an entrypoint
 301          * permission check for this purpose.
 302          */
 303         retval = security_compute_av(scontext, file_context,
 304                 tclass, bit, &avd);
 305         if (retval || ((bit & avd.allowed) != bit))
 306                 return 0;
 307         return 1;
 308 }
 309 #endif
 310 
 311 #ifdef WITH_SELINUX
 312 static int cron_authorize_range(security_context_t scontext,
     /* [previous][next][first][last][top][bottom][index][help]  */
 313         security_context_t ucontext) {
 314         struct av_decision avd;
 315         int retval;
 316         security_class_t tclass;
 317         access_vector_t bit;
 318 
 319         tclass = string_to_security_class("context");
 320         if (!tclass) {
 321                 log_it("CRON", getpid(), "ERROR", "Failed to translate security class context", errno);
 322                 return 0;
 323         }
 324         bit = string_to_av_perm(tclass, "contains");
 325         if (!bit) {
 326                 log_it("CRON", getpid(), "ERROR", "Failed to translate av perm contains", errno);
 327                 return 0;
 328         }
 329 
 330         /*
 331          * Since crontab files are not directly executed,
 332          * so crond must ensure that any user specified range
 333          * falls within the seusers-specified range for that Linux user.
 334          */
 335         retval = security_compute_av(scontext, ucontext,
 336                 tclass, bit, &avd);
 337 
 338         if (retval || ((bit & avd.allowed) != bit))
 339                 return 0;
 340         return 1;
 341 }
 342 #endif
 343 
 344 #if WITH_SELINUX
 345 /* always uses u->scontext as the default process context, then changes the
 346          level, and retuns it in ucontextp (or NULL otherwise) */
 347 static int
 348 cron_get_job_range(user * u, security_context_t * ucontextp, char **jobenv) {
     /* [previous][next][first][last][top][bottom][index][help]  */
 349         char *range;
 350 
 351         if (is_selinux_enabled() <= 0)
 352                 return 0;
 353         if (ucontextp == 0L)
 354                 return -1;
 355 
 356         *ucontextp = 0L;
 357 
 358         if ((range = env_get("MLS_LEVEL", jobenv)) != 0L) {
 359                 context_t ccon;
 360                 if (!(ccon = context_new(u->scontext))) {
 361                         log_it(u->name, getpid(), "context_new FAILED for MLS_LEVEL",
 362                                 range, 0);
 363                         context_free(ccon);
 364                         return -1;
 365                 }
 366 
 367                 if (context_range_set(ccon, range)) {
 368                         log_it(u->name, getpid(),
 369                                 "context_range_set FAILED for MLS_LEVEL", range, 0);
 370                         context_free(ccon);
 371                         return -1;
 372                 }
 373 
 374                 if (!(*ucontextp = context_str(ccon))) {
 375                         log_it(u->name, getpid(), "context_str FAILED for MLS_LEVEL",
 376                                 range, 0);
 377                         context_free(ccon);
 378                         return -1;
 379                 }
 380 
 381                 if (!(*ucontextp = strdup(*ucontextp))) {
 382                         log_it(u->name, getpid(), "strdup FAILED for MLS_LEVEL", range, 0);
 383                         return -1;
 384                 }
 385                 context_free(ccon);
 386         }
 387         else if (!u->scontext) {
 388                 /* cron_change_selinux_range() deals with this */
 389                 return 0;
 390         }
 391         else if (!(*ucontextp = strdup(u->scontext))) {
 392                 log_it(u->name, getpid(), "strdup FAILED for MLS_LEVEL", range, 0);
 393                 return -1;
 394         }
 395 
 396         return 0;
 397 }
 398 #endif
 399 
 400 #ifdef WITH_SELINUX
 401 static int cron_change_selinux_range(user * u, security_context_t ucontext) {
     /* [previous][next][first][last][top][bottom][index][help]  */
 402         char *msg = NULL;
 403 
 404         if (is_selinux_enabled() <= 0)
 405                 return 0;
 406 
 407         if (u->scontext == 0L) {
 408                 if (security_getenforce() > 0) {
 409                         log_it(u->name, getpid(), "NULL security context for user", "", 0);
 410                         return -1;
 411                 }
 412                 else {
 413                         log_it(u->name, getpid(),
 414                                 "NULL security context for user, "
 415                                 "but SELinux in permissive mode, continuing", "", 0);
 416                         return 0;
 417                 }
 418         }
 419 
 420         if (!ucontext || strcmp(u->scontext, ucontext)) {
 421                 if (!cron_authorize_range(u->scontext, ucontext)) {
 422                         if (security_getenforce() > 0) {
 423 # ifdef WITH_AUDIT
 424                                 if (asprintf(&msg,
 425                                                 "cron: Unauthorized MLS range acct=%s new_scontext=%s old_scontext=%s",
 426                                                 u->name, (char *) ucontext, u->scontext) >= 0) {
 427                                         int audit_fd = audit_open();
 428                                         audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE,
 429                                                 msg, NULL, NULL, NULL, 0);
 430                                         close(audit_fd);
 431                                         free(msg);
 432                                 }
 433 # endif
 434                                 if (asprintf
 435                                         (&msg, "Unauthorized range in %s for user range in %s",
 436                                                 (char *) ucontext, u->scontext) >= 0) {
 437                                         log_it(u->name, getpid(), "ERROR", msg, 0);
 438                                         free(msg);
 439                                 }
 440                                 return -1;
 441                         }
 442                         else {
 443                                 if (asprintf
 444                                         (&msg,
 445                                                 "Unauthorized range in %s for user range in %s,"
 446                                                 " but SELinux in permissive mod, continuing",
 447                                                 (char *) ucontext, u->scontext) >= 0) {
 448                                         log_it(u->name, getpid(), "WARNING", msg, 0);
 449                                         free(msg);
 450                                 }
 451                         }
 452                 }
 453         }
 454 
 455         if (setexeccon(ucontext) < 0) {
 456                 if (security_getenforce() > 0) {
 457                         if (asprintf
 458                                 (&msg, "Could not set exec or keycreate context to %s for user",
 459                                         (char *) ucontext) >= 0) {
 460                                 log_it(u->name, getpid(), "ERROR", msg, 0);
 461                                 free(msg);
 462                         }
 463                         return -1;
 464                 }
 465                 else {
 466                         if (asprintf
 467                                 (&msg,
 468                                         "Could not set exec context to %s for user,"
 469                                         " but SELinux in permissive mode, continuing",
 470                                         (char *) ucontext) >= 0) {
 471                                 log_it(u->name, getpid(), "WARNING", msg, 0);
 472                                 free(msg);
 473                         }
 474                         return 0;
 475                 }
 476         }
 477         return 0;
 478 }
 479 #endif
 480 
 481 #ifdef WITH_SELINUX
 482 int
 483 get_security_context(const char *name, int crontab_fd,
     /* [previous][next][first][last][top][bottom][index][help]  */
 484         security_context_t * rcontext, const char *tabname) {
 485         security_context_t scontext = NULL;
 486         security_context_t file_context = NULL;
 487         security_context_t rawcontext=NULL;
 488         context_t current_context = NULL;
 489         int retval;
 490         char *current_context_str = NULL;
 491         char *seuser = NULL;
 492         char *level = NULL;
 493 
 494         *rcontext = NULL;
 495 
 496         if (is_selinux_enabled() <= 0)
 497                 return 0;
 498 
 499         if (name != NULL) {
 500                 if (getseuserbyname(name, &seuser, &level) < 0) {
 501                         log_it(name, getpid(), "getseuserbyname FAILED", name, 0);
 502                         return security_getenforce() > 0 ? -1 : 0;
 503                 }
 504 
 505                 retval = get_default_context_with_level(seuser, level, NULL, &scontext);
 506         }
 507         else {
 508                 const char *current_user, *current_role;
 509                 if (getcon(&current_context_str) < 0) {
 510                         log_it(name, getpid(), "getcon FAILED", "", 0);
 511                         return (security_getenforce() > 0);
 512                 }
 513 
 514                 current_context = context_new(current_context_str);
 515                 if (current_context == NULL) {
 516                         log_it(name, getpid(), "context_new FAILED", current_context_str, 0);
 517                         freecon(current_context_str);
 518                         return (security_getenforce() > 0);
 519                 }
 520 
 521                 current_user = context_user_get(current_context);
 522                 current_role = context_role_get(current_context);
 523                 retval = get_default_context_with_rolelevel(current_user, current_role, level, NULL, &scontext);
 524 
 525                 freecon(current_context_str);
 526                 context_free(current_context);
 527         }
 528 
 529         if (selinux_trans_to_raw_context(scontext, &rawcontext) == 0) {
 530                 freecon(scontext);
 531                 scontext = rawcontext;
 532         }
 533         free(seuser);
 534         free(level);
 535         if (retval) {
 536                 if (security_getenforce() > 0) {
 537                         log_it(name, getpid(), "No SELinux security context", tabname, 0);
 538                         return -1;
 539                 }
 540                 else {
 541                         log_it(name, getpid(),
 542                                 "No security context but SELinux in permissive mode, continuing",
 543                                 tabname, 0);
 544                         return 0;
 545                 }
 546         }
 547 
 548         if (fgetfilecon(crontab_fd, &file_context) < OK) {
 549                 if (security_getenforce() > 0) {
 550                         log_it(name, getpid(), "getfilecon FAILED", tabname, 0);
 551                         freecon(scontext);
 552                         return -1;
 553                 }
 554                 else {
 555                         log_it(name, getpid(),
 556                                 "getfilecon FAILED but SELinux in permissive mode, continuing",
 557                                 tabname, 0);
 558                         *rcontext = scontext;
 559                         return 0;
 560                 }
 561         }
 562 
 563         if (!cron_authorize_context(scontext, file_context)) {
 564                 char *msg=NULL;
 565                 if (asprintf(&msg,
 566                      "Unauthorized SELinux context=%s file_context=%s", (char *) scontext, file_context) >= 0) {
 567                         log_it(name, getpid(), msg, tabname, 0);
 568                         free(msg);
 569                 } else {
 570                         log_it(name, getpid(), "Unauthorized SELinux context", tabname, 0);
 571                 }
 572                 freecon(scontext);
 573                 freecon(file_context);
 574                 if (security_getenforce() > 0) {
 575                         return -1;
 576                 }
 577                 else {
 578                         log_it(name, getpid(),
 579                                 "SELinux in permissive mode, continuing",
 580                                 tabname, 0);
 581                         return 0;
 582                 }
 583         }
 584         freecon(file_context);
 585 
 586         *rcontext = scontext;
 587         return 0;
 588 }
 589 #endif
 590 
 591 #ifdef WITH_SELINUX
 592 void free_security_context(security_context_t * scontext) {
     /* [previous][next][first][last][top][bottom][index][help]  */
 593         if (*scontext != NULL) {
 594                 freecon(*scontext);
 595                 *scontext = 0L;
 596         }
 597 }
 598 #endif
 599 
 600 #ifdef WITH_SELINUX
 601 int crontab_security_access(void) {
     /* [previous][next][first][last][top][bottom][index][help]  */
 602         int selinux_check_passwd_access = -1;
 603         if (is_selinux_enabled() > 0) {
 604                 security_context_t user_context;
 605                 if (getprevcon_raw(&user_context) == 0) {
 606                         security_class_t passwd_class;
 607                         access_vector_t crontab_bit;
 608                         struct av_decision avd;
 609                         int retval = 0;
 610 
 611                         passwd_class = string_to_security_class("passwd");
 612                         if (passwd_class == 0) {
 613                                 fprintf(stderr, "Security class \"passwd\" is not defined in the SELinux policy.\n");
 614                                 retval = -1;
 615                         }
 616 
 617                         if (retval == 0) {
 618                                 crontab_bit = string_to_av_perm(passwd_class, "crontab");
 619                                 if (crontab_bit == 0) {
 620                                         fprintf(stderr, "Security av permission \"crontab\" is not defined in the SELinux policy.\n");
 621                                         retval = -1;
 622                                 }
 623                         }
 624 
 625                         if (retval == 0)
 626                                 retval = security_compute_av_raw(user_context,
 627                                         user_context, passwd_class,
 628                                         crontab_bit, &avd);
 629 
 630                         if ((retval == 0) && ((crontab_bit & avd.allowed) == crontab_bit)) {
 631                                 selinux_check_passwd_access = 0;
 632                         }
 633                         freecon(user_context);
 634                 }
 635 
 636                 if (selinux_check_passwd_access != 0 && security_getenforce() == 0)
 637                         selinux_check_passwd_access = 0;
 638 
 639                 return selinux_check_passwd_access;
 640         }
 641         return 0;
 642 }
 643 #endif
 644 
 645 /* Build up the job environment from the PAM environment plus the
 646 * crontab environment 
 647 */
 648 static char **build_env(char **cronenv) {
     /* [previous][next][first][last][top][bottom][index][help]  */
 649         char **jobenv;
 650 #ifdef WITH_PAM
 651         char *cronvar;
 652         int count = 0;
 653 
 654         if (pamh == NULL || (jobenv=pam_getenvlist(pamh)) == NULL) {
 655 #endif
 656                 jobenv = env_copy(cronenv);
 657                 if (jobenv == NULL)
 658                         log_it("CRON", getpid(),
 659                                 "ERROR", "Initialization of cron environment variables failed", 0);
 660                 return jobenv;
 661 #ifdef WITH_PAM
 662         }
 663 
 664         /* Now add the cron environment variables. Since env_set()
 665          * overwrites existing variables, this will let cron's
 666          * environment settings override pam's */
 667 
 668         while ((cronvar = cronenv[count++])) {
 669                 if (!(jobenv = env_set(jobenv, cronvar))) {
 670                         log_it("CRON", getpid(),
 671                                 "Setting Cron environment variable failed", cronvar, 0);
 672                         return NULL;
 673                 }
 674         }
 675         return jobenv;
 676 #endif
 677 }

/* [previous][next][first][last][top][bottom][index][help]  */