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