/* PIPServer - A deamon for finger protocol v2
*
* Copyright (C) 1999-2001 Michael Baumer <baumi@vis.ethz.ch>
*
* 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.
*/
/* Reads the global fingerconf and fills in the config datastructure */
#include <stdio.h>
#include <string.h>
#include "finger.h"
#include "configfile.h"
#include "log.h"
#include "compat.h"
#include "acl.h"
aclT * parse_acl(Node *cfnode);
/* Init()
//
// Reads the system config file
//
// If errors occur we use the defaults
// (that's why we do not check the strdups:
// NULL is a valid configuration)
*/
void Init(char *progname, int have_tty)
{
Node *cfnode, *parent_node;
char *tmp;
int i, j;
aclT *acl, *allow, *deny, _allow, _deny;
allow = &_allow;
deny = &_deny;
allow->next = NULL;
deny->next = NULL;
/* open syslog */
if (have_tty)
log_open(progname, LOGTYPE_STDERR);
else
log_open(progname, LOGTYPE_SYSLOG);
/* initialize configuration with default values */
memset(&config, 0, sizeof(config));
config.first_uid = 100; /* This is obviously site-dependant */
if (config.gnufinger) {
config.gnufingerdir = "/usr/local/etc/fingerdir";
config.dbpath = "/usr/local/etc/fingerdir";
}
else
config.dbpath = "/usr/share/finger";
config.interval = 30; /* in seconds */
config.numclients = 0;
/* Initialize default ACL */
config.acl = (aclT *)malloc(sizeof(struct aclT));
config.acl->type = ACLTYPE_ALL;
config.acl->from = NULL;
config.acl->next = NULL;
config.acl->options = (ACL_USERLIST | ACL_MAIL);
/* read global configfile */
if ((parent_node = readFingerconf(NULL))) {
cfnode = parent_node->child;
i = 0;
j = 0;
while(cfnode) {
if (!strcmp(cfnode->id, "siteinfo"))
config.siteinfo = strdup(cfnode->value);
else if (!strcmp(cfnode->id, "userfilepath")) {
if (strcmp(cfnode->value, "/home"))
if (i<3)
config.userfilepath[i++] = strdup(cfnode->value);
else
log(LOG_ERR, "fingerconf: Only 3 userfilepaths allowed");
}
else if (!strcmp(cfnode->id, "help"))
config.help = strdup(cfnode->value);
else if (!strcmp(cfnode->id, "specialfile")) {
if (j<10) {
config.validfile[j] = strdup(cfnode->value);
if (cfnode->child)
config.filedesc[j] = strdup(cfnode->child->value);
j++;
}
else
log(LOG_ERR, "fingerconf: Only 10 special files allowed");
}
else if (!strcmp(cfnode->id, "gnufinger")) {
if (cfnode->child && !strcmp(cfnode->child->id, "fingerdir")) {
tmp = strdup(cfnode->child->value);
if (tmp)
config.gnufingerdir = tmp;
}
}
else if (!strcmp(cfnode->id, "dbpath")) {
tmp = strdup(cfnode->value);
if (tmp)
config.dbpath =tmp;
}
else if (!strcmp(cfnode->id, "poll"))
config.interval = atoi(cfnode->value);
/*
* Compatibility for pfinger config-files =< 0.7.7
* set the options on the default ACL
*/
else if (!strcmp(cfnode->id, "option")) {
if (!strcmp(cfnode->value, "showidle"))
config.acl->options |= ACL_IDLETIME;
else if (!strcmp(cfnode->value, "showfrom"))
config.acl->options |= ACL_FROMHOST;
else if (!strcmp(cfnode->value, "hidemail"))
config.acl->options &= ~ACL_MAIL;
else if (!strcmp(cfnode->value, "hideall"))
config.acl->options &= ~ACL_USERLIST;
}
/* ACL - Access Control List
*/
else if (!strcmp(cfnode->id, "acl")) {
if (cfnode->child) {
cfnode=cfnode->child;
while(1) {
if (!strcmp(cfnode->id, "order"))
/* todo */
;
else if (!strcmp(cfnode->id, "allow")) {
if (allow->next = parse_acl(cfnode->child))
allow = allow->next;
}
else if (!strcmp(cfnode->id, "deny")) {
if (deny->next = parse_acl(cfnode->child))
deny = deny->next;
}
/* Iterate */
if (cfnode->next)
cfnode = cfnode->next;
else {
cfnode = cfnode->parent;
break;
}
}
}
}
else if (!strcmp(cfnode->id, "clientlist")) {
/*
// A list of clients to be called by the master fingerd
*/
if (cfnode->child) {
cfnode = cfnode->child;
/*
// The client list is an array of pointers,
// allocated in blocks of 16
*/
config.clients = (char **)malloc(16*sizeof(void *));
while (1) {
if (!strcmp(cfnode->id, "client")) {
tmp = strdup(cfnode->value);
if (tmp) {
config.clients[config.numclients++] = tmp;
if (!(config.numclients % 16)) {
tmp = (char *)realloc(config.clients, (16+config.numclients)*sizeof(void *));
if (tmp)
config.clients = (char **)tmp;
else
break;
}
}
else
log(LOG_ERR, "Could not allocate memory for client hostname");
}
if (!cfnode->next) {
cfnode = cfnode->parent;
break;
}
cfnode = cfnode->next;
}
}
}
else if ((!strcmp(cfnode->id, "sitehost")) ||
(!strcmp(cfnode->id, "sitemaster")))
config.sitehost = strdup(cfnode->value);
cfnode = cfnode->next;
}
FreeParseTree(parent_node);
}
config.allow = _allow.next;
config.deny = _deny.next;
}
aclT * parse_acl(Node *cfnode)
{
aclT *acl;
acl = (aclT *)calloc(1, sizeof(aclT));
if (!acl)
return(0);
while(cfnode) {
if (!strcmp(cfnode->id, "from"))
acl->from = strdup(cfnode->value);
else if (!strcmp(cfnode->id, "option")) {
if (!strcmp(cfnode->value, "idletime"))
acl->options |= ACL_IDLETIME;
else if (!strcmp(cfnode->value, "fromhost"))
acl->options |= ACL_FROMHOST;
else if (!strcmp(cfnode->value, "mailstatus"))
acl->options |= ACL_MAIL;
else if (!strcmp(cfnode->value, "userlist"))
acl->options |= ACL_USERLIST;
}
cfnode = cfnode->next;
}
/* ACL Type */
if (acl->from) {
if (!strcmp(acl->from, "all"))
acl->type = ACLTYPE_ALL;
else if (!strcmp(acl->from, "localhost"))
acl->type = ACLTYPE_LOCALHOST;
else
acl->type = ACLTYPE_DOMAIN;
}
/* Fow now we discard acl's without <from> */
if (!acl->type) {
free(acl);
return(0);
}
return acl;
}
syntax highlighted by Code2HTML, v. 0.9.1