Initial revision

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@3 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Björn Groenvall
1992-05-05 22:35:44 +00:00
parent 2ea6910976
commit 3ee6e108c0
3 changed files with 378 additions and 0 deletions

161
appl/popper/pop_dropcopy.c Normal file
View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) 1989 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
static char SccsId[] = "@(#)@(#)pop_dropcopy.c 2.6 2.6 4/3/91";
#endif not lint
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <pwd.h>
#include "popper.h"
extern int errno;
extern int sys_nerr;
extern char *sys_errlist[];
/*
* dropcopy: Make a temporary copy of the user's mail drop and
* save a stream pointer for it.
*/
pop_dropcopy(p,pwp)
POP * p;
struct passwd * pwp;
{
int mfd; /* File descriptor for
the user's maildrop */
int dfd; /* File descriptor for
the SERVER maildrop */
FILE *tf; /* The temp file */
char template[POP_TMPSIZE]; /* Temp name holder */
char buffer[BUFSIZ]; /* Read buffer */
long offset; /* Old/New boundary */
int nchar; /* Bytes written/read */
struct stat mybuf; /* For lstat() */
/* Create a temporary maildrop into which to copy the updated maildrop */
(void)sprintf(p->temp_drop,POP_DROP,p->user);
#ifdef DEBUG
if(p->debug)
pop_log(p,POP_DEBUG,"Creating temporary maildrop '%s'",
p->temp_drop);
#endif DEBUG
/* Here we work to make sure the user doesn't cause us to remove or
* write over existing files by limiting how much work we do while
* running as root.
*/
/* First create a unique file. Would prefer mkstemp, but Ultrix...*/
strcpy(template,POP_TMPDROP);
(void) mktemp(template);
if ( (tf=fopen(template,"w+")) == NULL ) { /* failure, bail out */
pop_log(p,POP_PRIORITY,
"Unable to create temporary temporary maildrop '%s': %s",template,
(errno < sys_nerr) ? sys_errlist[errno] : "") ;
return pop_msg(p,POP_FAILURE,
"System error, can't create temporary file.");
}
/* Now give this file to the user */
(void) chown(template,pwp->pw_uid, pwp->pw_gid);
(void) chmod(template,0600);
/* Now link this file to the temporary maildrop. If this fails it
* is probably because the temporary maildrop already exists. If so,
* this is ok. We can just go on our way, because by the time we try
* to write into the file we will be running as the user.
*/
(void) link(template,p->temp_drop);
(void) fclose(tf);
(void) unlink(template);
/* Now we run as the user. */
(void) setuid(pwp->pw_uid);
(void) setgid(pwp->pw_gid);
#ifdef DEBUG
if(p->debug)pop_log(p,POP_DEBUG,"uid = %d, gid = %d",getuid(),getgid());
#endif DEBUG
/* Open for append, this solves the crash recovery problem */
if ((dfd = open(p->temp_drop,O_RDWR|O_APPEND|O_CREAT,0600)) == -1){
pop_log(p,POP_PRIORITY,
"Unable to open temporary maildrop '%s': %s",p->temp_drop,
(errno < sys_nerr) ? sys_errlist[errno] : "") ;
return pop_msg(p,POP_FAILURE,
"System error, can't open temporary file, do you own it?");
}
/* Lock the temporary maildrop */
if ( flock (dfd, LOCK_EX|LOCK_NB) == -1 )
switch(errno) {
case EWOULDBLOCK:
return pop_msg(p,POP_FAILURE,
"Maildrop lock busy! Is another session active?");
/* NOTREACHED */
default:
return pop_msg(p,POP_FAILURE,"flock: '%s': %s", p->temp_drop,
(errno < sys_nerr) ? sys_errlist[errno] : "");
/* NOTREACHED */
}
/* May have grown or shrunk between open and lock! */
offset = lseek(dfd,0,L_XTND);
/* Open the user's maildrop, If this fails, no harm in assuming empty */
if ((mfd = open(p->drop_name,O_RDWR)) > 0) {
/* Lock the maildrop */
if (flock (mfd,LOCK_EX) == -1) {
(void)close(mfd) ;
return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop,
(errno < sys_nerr) ? sys_errlist[errno] : "");
}
/* Copy the actual mail drop into the temporary mail drop */
while ( (nchar=read(mfd,buffer,BUFSIZ)) > 0 )
if ( nchar != write(dfd,buffer,nchar) ) {
nchar = -1 ;
break ;
}
if ( nchar != 0 ) {
/* Error adding new mail. Truncate to original size,
and leave the maildrop as is. The user will not
see the new mail until the error goes away.
Should let them process the current backlog, in case
the error is a quota problem requiring deletions! */
(void)ftruncate(dfd,(int)offset) ;
} else {
/* Mail transferred! Zero the mail drop NOW, that we
do not have to do gymnastics to figure out what's new
and what is old later */
(void)ftruncate(mfd,0) ;
}
/* Close the actual mail drop */
(void)close (mfd);
}
/* Acquire a stream pointer for the temporary maildrop */
if ( (p->drop = fdopen(dfd,"a+")) == NULL ) {
(void)close(dfd) ;
return pop_msg(p,POP_FAILURE,"Cannot assign stream for %s",
p->temp_drop);
}
rewind (p->drop);
return(POP_SUCCESS);
}

188
appl/popper/pop_init.c Normal file
View File

@@ -0,0 +1,188 @@
/*
* Copyright (c) 1989 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
static char SccsId[] = "@(#)@(#)pop_init.c 2.1 2.1 3/18/91";
#endif not lint
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "popper.h"
extern int errno;
/*
* init: Start a Post Office Protocol session
*/
pop_init(p,argcount,argmessage)
POP * p;
int argcount;
char ** argmessage;
{
struct sockaddr_in cs; /* Communication parameters */
struct hostent * ch; /* Client host information */
int errflag = 0;
int c;
int len;
extern char * optarg;
int options = 0;
int sp = 0; /* Socket pointer */
char * trace_file_name;
/* Initialize the POP parameter block */
bzero ((char *)p,(int)sizeof(POP));
/* Save my name in a global variable */
p->myname = argmessage[0];
/* Get the name of our host */
(void)gethostname(p->myhost,MAXHOSTNAMELEN);
/* Open the log file */
#ifdef SYSLOG42
(void)openlog(p->myname,0);
#else
(void)openlog(p->myname,POP_LOGOPTS,POP_FACILITY);
#endif
/* Process command line arguments */
while ((c = getopt(argcount,argmessage,"dt:")) != EOF)
switch (c) {
/* Debugging requested */
case 'd':
p->debug++;
options |= SO_DEBUG;
break;
/* Debugging trace file specified */
case 't':
p->debug++;
if ((p->trace = fopen(optarg,"a+")) == NULL) {
pop_log(p,POP_PRIORITY,
"Unable to open trace file \"%s\", err = %d",
optarg,errno);
exit(-1);
}
trace_file_name = optarg;
break;
/* Unknown option received */
default:
errflag++;
}
/* Exit if bad options specified */
if (errflag) {
(void)fprintf(stderr,"Usage: %s [-d]\n",argmessage[0]);
exit(-1);
}
/* Get the address and socket of the client to whom I am speaking */
len = sizeof(cs);
if (getpeername(sp,(struct sockaddr *)&cs,&len) < 0){
pop_log(p,POP_PRIORITY,
"Unable to obtain socket and address of client, err = %d",errno);
exit(-1);
}
/* Save the dotted decimal form of the client's IP address
in the POP parameter block */
p->ipaddr = inet_ntoa(cs.sin_addr);
/* Save the client's port */
p->ipport = ntohs(cs.sin_port);
/* Get the canonical name of the host to whom I am speaking */
ch = gethostbyaddr((char *) &cs.sin_addr, sizeof(cs.sin_addr), AF_INET);
if (ch == NULL){
pop_log(p,POP_PRIORITY,
"Unable to get canonical name of client, err = %d",errno);
p->client = p->ipaddr;
}
/* Save the cannonical name of the client host in
the POP parameter block */
else {
#ifndef BIND43
p->client = ch->h_name;
#else
# include <arpa/nameser.h>
# include <resolv.h>
/* Distrust distant nameservers */
extern struct state _res;
struct hostent * ch_again;
char * * addrp;
/* We already have a fully-qualified name */
_res.options &= ~RES_DEFNAMES;
/* See if the name obtained for the client's IP
address returns an address */
if ((ch_again = gethostbyname(ch->h_name)) == NULL) {
pop_log(p,POP_PRIORITY,
"Client at \"%s\" resolves to an unknown host name \"%s\"",
p->ipaddr,ch->h_name);
p->client = p->ipaddr;
}
else {
/* Save the host name (the previous value was
destroyed by gethostbyname) */
p->client = ch_again->h_name;
/* Look for the client's IP address in the list returned
for its name */
for (addrp=ch_again->h_addr_list; *addrp; ++addrp)
if (bcmp(*addrp,&(cs.sin_addr),sizeof(cs.sin_addr)) == 0) break;
if (!*addrp) {
pop_log (p,POP_PRIORITY,
"Client address \"%s\" not listed for its host name \"%s\"",
p->ipaddr,ch->h_name);
p->client = p->ipaddr;
}
}
#endif BIND43
}
/* Create input file stream for TCP/IP communication */
if ((p->input = fdopen(sp,"r")) == NULL){
pop_log(p,POP_PRIORITY,
"Unable to open communication stream for input, err = %d",errno);
exit (-1);
}
/* Create output file stream for TCP/IP communication */
if ((p->output = fdopen(sp,"w")) == NULL){
pop_log(p,POP_PRIORITY,
"Unable to open communication stream for output, err = %d",errno);
exit (-1);
}
pop_log(p,POP_PRIORITY,
"(v%s) Servicing request from \"%s\" at %s\n",
VERSION,p->client,p->ipaddr);
#ifdef DEBUG
if (p->trace)
pop_log(p,POP_PRIORITY,
"Tracing session and debugging information in file \"%s\"",
trace_file_name);
else if (p->debug)
pop_log(p,POP_PRIORITY,"Debugging turned on");
#endif DEBUG
return(POP_SUCCESS);
}

29
appl/popper/pop_user.c Normal file
View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 1989 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
static char SccsId[] = "@(#)@(#)pop_user.c 2.1 2.1 3/18/91";
#endif not lint
#include <stdio.h>
#include <sys/types.h>
#include <strings.h>
#include "popper.h"
/*
* user: Prompt for the user name at the start of a POP session
*/
int pop_user (p)
POP * p;
{
/* Save the user name */
(void)strcpy(p->user, p->pop_parm[1]);
/* Tell the user that the password is required */
return (pop_msg(p,POP_SUCCESS,"Password required for %s.",p->user));
}