|
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
|