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.