Initial revision
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@3 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
161
appl/popper/pop_dropcopy.c
Normal file
161
appl/popper/pop_dropcopy.c
Normal 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
188
appl/popper/pop_init.c
Normal 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
29
appl/popper/pop_user.c
Normal 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));
|
||||
}
|
Reference in New Issue
Block a user