#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
const int vpopuid = 98;
const int vpopgid = 98;
int errno = 0;
const char *VDOMINFO = "/home/vpopmail/bin/vdominfo";
const char *VUSERINFO = "/home/vpopmail/bin/vuserinfo";
const char *VALIAS = "/home/vpopmail/bin/valias";
const char *DOMAINS = "/home/vpopmail/domains";
char *email = NULL;
char *user = NULL;
char *domain = NULL;
char *homedir = NULL;
int relayable = 0;
struct stat s_stat;
int main(int argc, char **argv){
char *stmp;
char *stmp2;
char *command;
FILE *fp;
int result;
if(getenv("RELAYCLIENT"))
relayable = 1;
// Pull in email address for checking
if(argc > 1){
email = (char *) malloc( strlen( argv[1] ) + 1 );
strcpy(email, argv[1]);
}else{
if( getenv("SMTPRCPTTO") != NULL ){
email = (char *) malloc( strlen( getenv("SMTPRCPTTO") ) + 1 );
strcpy(email, getenv("SMTPRCPTTO"));
}
}
if(email == NULL){
fprintf(stderr, "qmail-spp: vpopmail_check_recipient; No email address specified from %s\n", getenv("TCPREMOTEIP"));
printf("E550 Sorry, no mailbox here by that name (#5.5.0)\n");
exit(1);
}
// Quick validation test: only accept A-Za-z0-9-_@.[]
stmp = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_@.[]";
result = strspn(email, stmp);
if(result != strlen(email)){
fprintf(stderr, "qmail-spp: vpopmail_check_recipient: Illegal characters in email address from %s\n", getenv("TCPREMOTEIP"));
printf("E550 Sorry, no mailbox here by that name (#5.5.0)\n");
exit(1);
}
// extract user portion of email address
stmp = strtok(email, "@");
if(stmp == NULL){
fprintf(stderr, "qmail-spp: vpopmail_check_recipient: No @ sign in email address from %s\n", getenv("TCPREMOTEIP"));
printf("E550 Sorry, no mailbox here by that name (#5.5.0)\n");
exit(1);
}
user = (char *) malloc( strlen( stmp ) + 1 );
strcpy(user, stmp);
// Extract domain portion of email address
stmp = strtok(NULL, "@");
if(stmp == NULL){
fprintf(stderr, "qmail-spp: vpopmail_check_recipient: No domain in email address from %s\n", getenv("TCPREMOTEIP"));
printf("E550 Sorry, no mailbox here by that name (#5.5.0)\n");
exit(1);
}
domain = (char *) malloc( strlen( stmp ) + 1 );
strcpy(domain, stmp);
// Any more @ signs? If so, trash it.
if(strtok(NULL, "@") != NULL){
fprintf(stderr, "qmail-spp: vpopmail_check_recipient: Too many @ signs in email address from %s\n", getenv("TCPREMOTEIP"));
printf("E550 Sorry, no mailbox here by that name (#5.5.0)\n");
exit(1);
}
// Discard email and reform it. strtok isn't nice.
free(email);
email = (char *) malloc( strlen( user ) + strlen( domain ) + 2);
sprintf(email, "%s@%s", user, domain);
// Check if the domain exists
command = (char *) malloc(strlen(domain) + strlen(VDOMINFO) + 19);
sprintf(command, "%s %s |grep -e '^dir:'", VDOMINFO, domain);
fp = popen(command, "r");
stmp2 = (char *) malloc(512);
stmp = (char *) malloc(1);
while(!feof(fp)){
result = fread(stmp2, 1, 512, fp);
stmp = realloc(stmp, sizeof(stmp) + result);
strcat(stmp, stmp2);
}
free(stmp2);
result = pclose(fp);
free(command);
if(result != 0){
if(!relayable){
fprintf(stderr, "qmail-spp: vpopmail_check_recipient: Relaying denied to: %s from %s\n", email, getenv("TCPREMOTEIP"));
printf("E551 Relaying denied (#5.5.1)\n");
exit(1);
}else{
fprintf(stderr, "qmail-spp: vpopmail_check_recipient: Authorizing relay to: %s from %s\n", email, getenv("TCPREMOTEIP"));
exit(0);
}
}
// parse the output to grab the homedir, for later
stmp2 = strrchr(stmp, ' '); // find last space. Start of homedir
homedir = (char *) malloc(strlen(stmp2));
strncpy(homedir, stmp2 + 1, (strlen(stmp2) - 1)); // Read between the whitespace
homedir[strlen(stmp2) - 2] = '\0'; // Null-terminate
free(stmp);
// Check .qmail-default to see if a catchall is defined.
command = (char *) malloc( strlen(homedir) + 55);
sprintf(command, "cat %s/.qmail-default |grep 'bounce-no-mailbox' >/dev/null", homedir);
result = system(command);
if(0 != result){
// Catchall defined. Any mail delivery will succeed
exit(0);
}
// Check if the user has a mailbox in the domain
command = (char *) malloc(strlen(email) + strlen(VUSERINFO) + 14);
sprintf(command, "%s %s > /dev/null", VUSERINFO, email);
result = system(command);
free(command);
if(0 == result){
// Has mailbox
exit(0);
}
// We want a .qmail file in homedir
command = (char *) malloc( strlen(homedir) + 7 + strlen(user) + 1);
sprintf(command, "%s/.qmail-%s", homedir, user);
// fprintf(stderr, "qmail-spp: vpopmail_check_recipient: Checking for file %s\n", command);
result = stat(command, &s_stat);
// fprintf(stderr, "qmail-spp: vpopmail_check_recipient: stat() returned %d %d\n", result, errno);
free(command);
if(0 == result){
// Has .qmail file
exit(0);
}
// Delivery will probably fail. Dump out.
printf("E550 Sorry, no mailbox here by that name (#5.5.0)\n");
exit(1);
}