Blame perm.c

Packit 081926
/* 
Packit 081926
 *  perm.c - check user permission for at(1)
Packit 081926
 *  Copyright (C) 1994  Thomas Koenig
Packit 081926
 *
Packit 081926
 *  This program is free software; you can redistribute it and/or modify
Packit 081926
 *  it under the terms of the GNU General Public License as published by
Packit 081926
 *  the Free Software Foundation; either version 2 of the License, or
Packit 081926
 *  (at your option) any later version.
Packit 081926
 *
Packit 081926
 *  This program is distributed in the hope that it will be useful,
Packit 081926
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 081926
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 081926
 *  GNU General Public License for more details.
Packit 081926
 *
Packit 081926
 *  You should have received a copy of the GNU General Public License
Packit 081926
 *  along with this program; if not, write to the Free Software
Packit 081926
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Packit 081926
 */
Packit 081926
Packit 081926
#ifdef HAVE_CONFIG_H
Packit 081926
#include "config.h"
Packit 081926
#endif
Packit 081926
Packit 081926
/* System Headers */
Packit 081926
Packit 081926
#include <sys/types.h>
Packit 081926
Packit 081926
#ifdef HAVE_ERRNO_H
Packit 081926
#include <errno.h>
Packit 081926
#endif
Packit 081926
Packit 081926
#include <pwd.h>
Packit 081926
#include <stddef.h>
Packit 081926
#include <stdio.h>
Packit 081926
#include <stdlib.h>
Packit 081926
#include <string.h>
Packit 081926
#include <unistd.h>
Packit 081926
Packit 081926
/* Local headers */
Packit 081926
Packit 081926
#include "privs.h"
Packit 081926
#include "at.h"
Packit 081926
Packit 081926
/* Macros */
Packit 081926
Packit 081926
#if defined(DEBUG_PERM_C)
Packit 081926
#define ETCDIR "../test/etc"
Packit 081926
#undef PRIV_START
Packit 081926
#define PRIV_START while(0)
Packit 081926
#undef PRIV_END
Packit 081926
#define PRIV_END while(0)
Packit 081926
#endif
Packit 081926
Packit Service 653739
#ifdef WITH_PAM
Packit Service 653739
#include <security/pam_appl.h>
Packit Service 653739
static pam_handle_t *pamh = NULL;
Packit Service 653739
static const struct pam_conv conv = {
Packit Service 653739
       NULL
Packit Service 653739
};
Packit Service 653739
#endif
Packit Service 653739
Packit 081926
/* Structures and unions */
Packit 081926
Packit 081926
Packit 081926
/* File scope variables */
Packit 081926
Packit 081926
Packit 081926
/* Function declarations */
Packit 081926
Packit 081926
static int user_in_file(const char *path, const char *name);
Packit 081926
Packit 081926
/* Local functions */
Packit 081926
Packit 081926
/* 
Packit 081926
 */  
Packit 081926
static int 
Packit 081926
user_in_file(const char *path, const char *name)
Packit 081926
{
Packit 081926
  FILE *fp;
Packit 081926
  char buffer[256];
Packit 081926
  int found = 0;
Packit 081926
  int c = '\n';
Packit 081926
Packit 081926
  PRIV_START;
Packit 081926
    fp = fopen( path, "r");
Packit 081926
  PRIV_END;
Packit 081926
Packit 081926
  if ( fp == NULL )
Packit 081926
    return -1;
Packit 081926
Packit 081926
Packit 081926
  while ( !found && fgets(buffer, sizeof(buffer), fp) != NULL) {
Packit 081926
    size_t llen = strlen(buffer);
Packit 081926
Packit 081926
    c = buffer[llen-1];
Packit 081926
Packit 081926
    if (c == '\n')
Packit 081926
      buffer[llen-1] = '\0';
Packit 081926
    while (c != '\n' && c != EOF)
Packit 081926
      c = fgetc(fp);
Packit 081926
    
Packit 081926
    found = (strcmp(buffer, name)==0);
Packit 081926
  }
Packit 081926
Packit 081926
  fclose(fp);
Packit 081926
Packit 081926
  if (c == EOF) {
Packit 081926
    fprintf(stderr, "%s: incomplete last line.\n", path);
Packit 081926
  }
Packit 081926
Packit 081926
  return found;
Packit 081926
}
Packit 081926
Packit 081926
Packit 081926
/* Global functions */
Packit 081926
int
Packit 081926
check_permission()
Packit 081926
{
Packit Service 653739
  uid_t euid = geteuid(), uid=getuid(), egid=getegid(), gid=getgid();
Packit 081926
  struct passwd *pentry;
Packit 081926
  int    allow = 0, deny = 1;
Packit 081926
Packit Service 653739
  int    retcode = 0;
Packit Service 653739
  if (euid == 0)
Packit 081926
    return 1;
Packit 081926
Packit Service 653739
  if ((pentry = getpwuid(euid)) == NULL) {
Packit 081926
    perror("Cannot access user database");
Packit 081926
    exit(EXIT_FAILURE);
Packit 081926
  }
Packit 081926
Packit Service 653739
#ifdef  WITH_PAM
Packit Service 653739
/*
Packit Service 653739
 *  We must check if the atd daemon userid will be allowed to gain the job owner user's
Packit Service 653739
 *  credentials with PAM . If not, the user has been denied at(1) usage, eg. with pam_access.
Packit Service 653739
 */
Packit Service 653739
  if (setreuid(daemon_uid, daemon_uid) != 0) {
Packit Service 653739
      fprintf(stderr, "cannot set egid: %s", strerror(errno));
Packit Service 653739
      exit(1);
Packit Service 653739
  }
Packit Service 653739
  if (setregid(daemon_gid, daemon_gid) != 0) {
Packit Service 653739
      fprintf(stderr, "cannot set euid: %s", strerror(errno));
Packit Service 653739
      exit(1);
Packit Service 653739
  }
Packit Service 653739
Packit Service 653739
    AT_START_PAM;
Packit Service 653739
    AT_CLOSE_PAM;
Packit Service 653739
    if (setregid(gid,egid) != 0) {
Packit Service 653739
        fprintf(stderr, "cannot set egid: %s", strerror(errno));
Packit Service 653739
        exit(1);
Packit Service 653739
    }
Packit Service 653739
    if (setreuid(uid,euid) != 0) {
Packit Service 653739
        fprintf(stderr, "cannot set euid: %s", strerror(errno));
Packit Service 653739
        exit(1);
Packit Service 653739
    }
Packit Service 653739
#endif
Packit Service 653739
Packit 081926
  allow = user_in_file(ETCDIR "/at.allow", pentry->pw_name);
Packit 081926
  if (allow==0 || allow==1)
Packit 081926
    return allow;
Packit 081926
Packit 081926
  /* There was an error while looking for pw_name in at.allow.
Packit 081926
   * Check at.deny only when at.allow doesn't exist.
Packit 081926
   */
Packit 081926
 
Packit 081926
  deny = user_in_file(ETCDIR "/at.deny", pentry->pw_name);
Packit 081926
  return deny == 0;
Packit 081926
}
Packit 081926
Packit 081926
Packit 081926
#if defined(DEBUG_PERM_C)
Packit 081926
Packit 081926
int
Packit 081926
main(int argc, char *argv[])
Packit 081926
{
Packit 081926
  printf("check_permission() ==> %d\n", check_permission());
Packit 081926
  return 0;
Packit 081926
}
Packit 081926
Packit 081926
#endif