#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); }