/*
* FCRON - periodic command scheduler
*
* Copyright 2000-2007 Thibault Godouet <fcron@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The GNU General Public License can also be found in the file
* `LICENSE' that comes with the fcron source distribution.
*/
/* $Id: subs.c,v 1.28 2007/06/03 17:52:53 thib Exp thib $ */
#include "global.h"
#include "subs.h"
void init_conf(void);
extern char debug_opt;
extern uid_t rootuid;
extern gid_t rootgid;
/* fcron.conf parameters */
char *fcronconf = NULL;
char *fcrontabs = NULL;
char *pidfile = NULL;
char *fifofile = NULL;
char *fcronallow = NULL;
char *fcrondeny = NULL;
char *shell = NULL;
char *sendmail = NULL;
char *editor = NULL;
uid_t
get_user_uid_safe(char *username)
/* get the uid of user username, and die on error */
{
struct passwd *pass;
errno = 0;
pass = getpwnam(username);
if ( pass == NULL ) {
die_e("Unable to get the uid of user %s (is user in passwd file?)",
username);
}
return pass->pw_uid;
}
gid_t
get_group_gid_safe(char *groupname)
/* get the gid of group groupname, and die on error */
{
struct group *grp;
errno = 0;
grp = getgrnam(groupname);
if ( errno != 0 || grp == NULL ) {
die_e("Unable to get the gid of group %s", groupname);
}
return grp->gr_gid;
}
int
remove_blanks(char *str)
/* remove blanks at the the end of str */
/* return the length of the new string */
{
char *c = str;
/* scan forward to the null */
while (*c)
c++;
/* scan backward to the first character that is not a space */
do {c--;}
while (c >= str && isspace( (int) *c));
/* if last char is a '\n', we remove it */
if ( *c == '\n' )
*c = '\0';
else
/* one character beyond where we stopped above is where the null
* goes. */
*++c = '\0';
/* return the new length */
return ( c - str );
}
char *
strdup2(const char *str)
{
char *ptr;
if ( str == NULL )
return NULL;
ptr = malloc(strlen(str) + 1);
if ( ! ptr)
die_e("Could not calloc");
strcpy(ptr, str);
return(ptr);
}
int
get_word(char **str)
/* make str point the next word and return word length */
{
char *ptr;
Skip_blanks(*str);
ptr = *str;
while ( (isalnum( (int) *ptr) || *ptr == '_' || *ptr == '-')
&& *ptr != '=' && ! isspace( (int) *ptr) )
ptr++;
return (ptr - *str);
}
void
init_conf(void)
/* initialises config with compiled in constants */
{
/* set fcronconf if cmd line option -c has not been used */
if (fcronconf == NULL)
fcronconf = strdup2(ETC "/" FCRON_CONF);
fcrontabs = strdup2(FCRONTABS);
pidfile = strdup2(PIDFILE);
fifofile = strdup2(FIFOFILE);
fcronallow = strdup2(ETC "/" FCRON_ALLOW);
fcrondeny = strdup2(ETC "/" FCRON_DENY);
/* // */
/* shell = strdup2(FCRON_SHELL); */
shell = strdup2("");
#ifdef SENDMAIL
sendmail = strdup2(SENDMAIL);
#endif
editor = strdup2(FCRON_EDITOR);
}
void
free_conf(void)
/* free() the memory allocated in init_conf() */
{
free(fcronconf);
free(fcrontabs);
free(pidfile);
free(fifofile);
free(fcronallow);
free(fcrondeny);
free(shell);
free(sendmail);
free(editor);
}
void
read_conf(void)
/* reads in a config file and updates the necessary global variables */
{
FILE *f = NULL;
struct stat st;
char buf[LINE_LEN];
char *ptr1 = NULL, *ptr2 = NULL;
short namesize = 0;
char err_on_enoent = 0;
struct group *gr = NULL;
gid_t fcrongid = -1;
if (fcronconf != NULL)
/* fcronconf has been set by -c option : file must exist */
err_on_enoent = 1;
init_conf();
if ( (f = fopen(fcronconf, "r")) == NULL ) {
if ( errno == ENOENT ) {
if ( err_on_enoent )
die_e("Could not read %s", fcronconf);
else
/* file does not exist, it is not an error */
return;
}
else {
error_e("Could not read %s : config file ignored", fcronconf);
return;
}
}
/* get fcrongid */
gr = getgrnam(GROUPNAME);
if ( gr == NULL ) {
die_e("Unable to find %s in /etc/group", GROUPNAME);
}
fcrongid = gr->gr_gid;
/* check if the file is secure : owner:root, group:fcron,
* writable only by owner */
if ( fstat(fileno(f), &st) != 0
|| st.st_uid != rootuid || st.st_gid != fcrongid
|| st.st_mode & S_IWGRP || st.st_mode & S_IWOTH ) {
error("Conf file (%s) must be owned by root:" GROUPNAME
" and (no more than) 644 : ignored", fcronconf, GROUPNAME);
fclose(f);
return;
}
while ( (ptr1 = fgets(buf, sizeof(buf), f)) != NULL ) {
Skip_blanks(ptr1); /* at the beginning of the line */
/* ignore comments and blank lines */
if ( *ptr1 == '#' || *ptr1 == '\n' || *ptr1 == '\0')
continue;
remove_blanks(ptr1); /* at the end of the line */
/* get the name of the var */
if ( ( namesize = get_word(&ptr1) ) == 0 )
/* name is zero-length */
error("Zero-length var name at line %s : line ignored", buf);
ptr2 = ptr1 + namesize;
/* skip the blanks and the "=" and go to the value */
while ( isspace( (int) *ptr2 ) ) ptr2++;
if ( *ptr2 == '=' ) ptr2++;
while ( isspace( (int) *ptr2 ) ) ptr2++;
/* find which var the line refers to and update it */
if ( strncmp(ptr1, "fcrontabs", namesize) == 0 )
fcrontabs = strdup2(ptr2);
else if ( strncmp(ptr1, "pidfile", namesize) == 0 )
pidfile = strdup2(ptr2);
else if ( strncmp(ptr1, "fifofile", namesize) == 0 )
fifofile = strdup2(ptr2);
else if ( strncmp(ptr1, "fcronallow", namesize) == 0 )
fcronallow = strdup2(ptr2);
else if ( strncmp(ptr1, "fcrondeny", namesize) == 0 )
fcrondeny = strdup2(ptr2);
else if ( strncmp(ptr1, "shell", namesize) == 0 )
shell = strdup2(ptr2);
else if ( strncmp(ptr1, "sendmail", namesize) == 0 )
sendmail = strdup2(ptr2);
else if ( strncmp(ptr1, "editor", namesize) == 0 )
editor = strdup2(ptr2);
else
error("Unknown var name at line %s : line ignored", buf);
}
if (debug_opt) {
debug(" fcronconf=%s", fcronconf);
/* debug(" fcronallow=%s", fcronallow); */
/* debug(" fcrondeny=%s", fcrondeny); */
/* debug(" fcrontabs=%s", fcrontabs); */
/* debug(" pidfile=%s", pidfile); */
/* debug(" fifofile=%s", fifofile); */
/* debug(" editor=%s", editor); */
/* debug(" shell=%s", shell); */
/* debug(" sendmail=%s", sendmail); */
}
fclose(f);
}
syntax highlighted by Code2HTML, v. 0.9.1