#include <popper.h>
RCSID("$Id$");
int
changeuser(POP *p, struct passwd *pwd)
{
if(setgid(pwd->pw_gid) < 0) {
pop_log (p, POP_PRIORITY,
"Unable to change to gid %u: %s",
(unsigned)pwd->pw_gid,
strerror(errno));
return pop_msg (p, POP_FAILURE,
"Unable to change gid");
}
if(setuid(pwd->pw_uid) < 0) {
pop_log (p, POP_PRIORITY,
"Unable to change to uid %u: %s",
(unsigned)pwd->pw_uid,
strerror(errno));
return pop_msg (p, POP_FAILURE,
"Unable to change uid");
}
#ifdef DEBUG
if(p->debug)
pop_log(p, POP_DEBUG,"uid = %u, gid = %u",
(unsigned)getuid(),
(unsigned)getgid());
#endif
return POP_SUCCESS;
}
int
pop_dropcopy(POP *p, struct passwd *pwp)
{
int mfd;
int dfd;
FILE *tf;
char template[POP_TMPSIZE];
char buffer[BUFSIZ];
long offset;
int nchar;
int tf_fd;
int ret;
snprintf(p->temp_drop, sizeof(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
strlcpy(template, POP_TMPDROP, sizeof(template));
if ((tf_fd = mkstemp(template)) < 0 ||
(tf = fdopen(tf_fd, "w+")) == NULL) {
pop_log(p,POP_PRIORITY,
"Unable to create temporary temporary maildrop '%s': %s",template,
strerror(errno));
return pop_msg(p,POP_FAILURE,
"System error, can't create temporary file.");
}
chown(template, pwp->pw_uid, pwp->pw_gid);
chmod(template, 0600);
link(template,p->temp_drop);
fclose(tf);
unlink(template);
ret = changeuser(p, pwp);
if (ret != POP_SUCCESS)
return ret;
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,
strerror(errno));
return pop_msg(p,POP_FAILURE,
"System error, can't open temporary file, do you own it?");
}
if ( flock (dfd, (LOCK_EX | LOCK_NB)) == -1 )
switch(errno) {
case EWOULDBLOCK:
return pop_msg(p,POP_FAILURE,
"%sMaildrop lock busy! Is another session active?",
(p->flags & POP_FLAG_CAPA) ? "[IN-USE] " : "");
default:
return pop_msg(p,POP_FAILURE,"flock: '%s': %s", p->temp_drop,
strerror(errno));
}
offset = lseek(dfd,0, SEEK_END);
if ((mfd = open(p->drop_name,O_RDWR)) > 0) {
if (flock (mfd, LOCK_EX) == -1) {
close(mfd) ;
return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop,
strerror(errno));
}
while ( (nchar=read(mfd,buffer,BUFSIZ)) > 0 )
if ( nchar != write(dfd,buffer,nchar) ) {
nchar = -1 ;
break ;
}
if ( nchar != 0 ) {
ftruncate(dfd,(int)offset) ;
} else {
ftruncate(mfd,0) ;
}
close (mfd);
}
if ( (p->drop = fdopen(dfd,"a+")) == NULL ) {
close(dfd) ;
return pop_msg(p,POP_FAILURE,"Cannot assign stream for %s",
p->temp_drop);
}
rewind (p->drop);
return(POP_SUCCESS);
}