This is private.c in view mode; [Download] [Up]
#ifndef NO_PRIVATE
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <syslog.h>
#include <stdlib.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include "pathnames.h"
#include "extensions.h"
#define MAXGROUPLEN 100
char *passbuf = NULL;
char groupname[MAXGROUPLEN];
int group_given = 0;
struct acgrp {
char gname[MAXGROUPLEN]; /* access group name */
char gpass[MAXGROUPLEN]; /* access group password */
char gr_name[MAXGROUPLEN]; /* group to setgid() to */
};
extern int lgi_failure_threshold, autospout_free;
extern char remotehost[], remoteaddr[], *autospout;
int group_attempts;
/*************************************************************************/
/* FUNCTION : priv_setup */
/* PURPOSE : Set things up to use the private access password file. */
/* ARGUMENTS : path, the path to the private access password file */
/*************************************************************************/
void
priv_setup(path)
char *path;
{
FILE *prvfile;
struct stat finfo;
passbuf = (char *) NULL;
if (stat(path, &finfo) != 0) {
syslog(LOG_ERR, "cannot stat private access file %s: %s", path,
strerror(errno));
return;
}
if ((prvfile = fopen(path, "r")) == NULL) {
if (errno != ENOENT)
syslog(LOG_ERR, "cannot open private access file %s: %s",
path, strerror(errno));
return;
}
if (finfo.st_size == 0) {
passbuf = (char *) calloc(1, 1);
} else {
if (!(passbuf = malloc((unsigned) finfo.st_size + 1))) {
(void) syslog(LOG_ERR, "could not malloc passbuf (%d bytes)",
finfo.st_size + 1);
return;
}
if (!fread(passbuf, (size_t) finfo.st_size, 1, prvfile)) {
(void) syslog(LOG_ERR, "error reading private access file %s: %s",
path, strerror(errno));
}
*(passbuf+finfo.st_size) = '\0';
}
if (setgroupent(1) == 0) {
(void) syslog(LOG_ERR, "error opening group file");
(void) free(passbuf);
passbuf = (char *) NULL;
}
}
/*************************************************************************/
/* FUNCTION : priv_getent */
/* PURPOSE : Retrieve an entry from the in-memory copy of the group */
/* access file. */
/* ARGUMENTS : pointer to group name */
/*************************************************************************/
struct acgrp *
priv_getent(group)
char *group;
{
char *ptr = passbuf,
*cr,
*data;
static struct acgrp grp;
char linebuf[1024];
while (*ptr) {
if ((cr = index(ptr, '\n')) == NULL) return(NULL);
*cr = '\0';
strncpy(linebuf, ptr, 1024);
*cr = '\n';
if ((cr - ptr) < 1024) {
if ((data = strtok(linebuf, ":")) != NULL)
(void) strncpy(grp.gname, data, MAXGROUPLEN);
else continue; /* bad entry -- skip it */
if (strncmp(group, grp.gname, MAXGROUPLEN) != NULL) continue;
if ((data = strtok(NULL, ":")) != NULL)
(void) strncpy(grp.gpass, data, MAXGROUPLEN);
else continue; /* bad entry -- skip it */
if ((data = strtok(NULL, ":")) != NULL)
(void) strncpy(grp.gr_name, data, MAXGROUPLEN);
else continue; /* bad entry -- skip it */
return(&grp);
}
ptr = ++cr;
}
return(NULL);
}
/*************************************************************************/
/* FUNCTION : priv_group */
/* PURPOSE : */
/* ARGUMENTS : */
/*************************************************************************/
void
priv_group(group)
char *group;
{
if (strlen(group) < MAXGROUPLEN) {
strncpy(groupname, group, MAXGROUPLEN);
group_given = 1;
reply(200, "Request for access to group %s accepted.", group);
} else {
group_given = 0;
reply(500, "Illegal group name");
}
}
/*************************************************************************/
/* FUNCTION : priv_gpass */
/* PURPOSE : validate the group access request, and if OK place user */
/* in the proper group. */
/* ARGUMENTS : group access password */
/*************************************************************************/
void
priv_gpass(gpass)
char *gpass;
{
char *xgpass, *salt, *crypt();
struct acgrp *grp;
struct group *gr;
uid_t uid;
gid_t gid;
if (group_given == 0) {
reply(503, "Give group name with SITE GROUP first.");
return;
}
if (passbuf != NULL) {
grp = priv_getent(groupname);
if (grp == NULL)
salt = "xx";
else
salt = grp->gpass;
xgpass = crypt(gpass, salt);
} else
grp = NULL;
/* The strcmp does not catch null passwords! */
if (grp == NULL || *grp->gpass == '\0' || strcmp(xgpass, grp->gpass)) {
reply(530, "Group access request incorrect.");
grp = NULL;
if (++group_attempts >= lgi_failure_threshold) {
syslog(LOG_NOTICE,
"repeated group access failures from %s [%s], group %s",
remotehost, remoteaddr, groupname);
exit(0);
}
sleep(group_attempts); /* slow down password crackers */
return;
}
/* THIS CODE NEEDS CHECKING BY INFORMED, SECURITY-CONSCIOUS PEOPLE */
if ((gr = getgrnam(grp->gr_name)) != NULL) {
gid = gr->gr_gid;
} else {
lreply(500, "Configuration error -- group access not granted");
syslog(LOG_ERR, "group %s does not exist in group file", grp->gr_name);
return;
}
uid = geteuid();
seteuid(0);
setegid(gid);
seteuid(uid);
/* END CODE */
reply(200, "Group access enabled.");
group_attempts = 0;
}
#endif /* !NO_PRIVATE */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.