qmail-smtpd-chkusr 0.2 patch

This version of chkusr has been substituted by chkuser 2.0, that you find at this page.

 

qmail-smtpd-chkusr V. 0.2

 

> > /* > * Includes patch qmail-smtpd-chkusr v.0.2 > * for qmail 1.0.3 and vpopmail 4.9.x > */ > includes needed for patch to work > #include <pwd.h> > #include <sys/types.h> > #include <unistd.h> > #include <dirent.h> > #include <stdio.h> > Change the following includes to point at your real directories. open.h is in the qmail source directory and should remains as is. vauth.h, vpopmail.h and vpopmail_config.h should be in the vpopmail include dir. > #include "open.h" > #include "/vpopmail/include/vpopmail.h" > #include "/vpopmail/include/vauth.h" > #include "/vpopmail/include/vpopmail_config.h" > 210a219,362 routine that emits the new error > void err_realrcpt() { out("550 sorry, no mailbox here by that name (#5.1.1 - chkusr)\r\n"); } > This is the routine that contains all the code used to check user, alias, mailing list existence. > int realrcpt_check() > { > stralloc user = {0}; > stralloc domain = {0}; > stralloc alias_name = {0}; > stralloc alias_path = {0}; > stralloc mailing_path = {0}; > int count; > int retstat = 0; > static struct passwd *user_passwd = NULL; > int fd_file = -1; > DIR *dir_file = NULL; > uid_t eff_uid; > gid_t eff_gid; > char fakestr[100] = ""; > int offset; > > /* if not local rcpthost we cannot control mailbox */ > > if (!addrallowed()) { return 1; } > > /* Set up our variables */ > save starting UID and GID, for later resume of original ones. > /* Save the effective UID and GID (smtp) */ > eff_uid = geteuid (); > eff_gid = getegid (); > > /* Search the '@' character */ > count = byte_rchr(addr.s,addr.len,'@'); > > /* The following lines could interest someone ? */ > /* If '@' not found search the '%' character */ > > /* > if (count >= addr.len) { > count = byte_rchr(addr.s,addr.len,'%'); > } > */ > > if (count < addr.len) { > if (!stralloc_copyb ( addr.s, count)) die_nomem(); > if (!stralloc_0 ( die_nomem(); > if (!stralloc_copys ( addr.s + count + 1)) die_nomem(); > if (!stralloc_0 ( die_nomem(); > } > else { > if (!stralloc_copys ( addr.s)) die_nomem(); > if (!stralloc_0 ( die_nomem(); > if (!stralloc_copys ( DEFAULT_DOMAIN)) die_nomem(); > if (!stralloc_0 ( die_nomem(); > } > > /* My control: continue only if a domain (default or not) is specified */ > > if (str_len (domain.s) == 0) > return 0; > Until now code is running with QMAIL-SMTP UID and GID. Now we switch to vpopmail UID and GID, and do no exit from the routine until we finish our job and resume our starting UID and GID (or unless there is a fatal error) > /* Now set the real UID and GID (vpopmail) */ > > setegid (getgid()); > seteuid (getuid()); > > case_lowers (user.s); > case_lowers (domain.s); > > /* Check if domain is a real domain */ > > if (!stralloc_catb ( fakestr, sizeof (fakestr))) die_nomem(); > > vget_real_domain(domain.s, domain.len); > Checking user existence using vpopmail library
This version includes additional control on BOUNCE_MAIL flag > /* General control: check the existence of a real user */ > > user_passwd = vauth_getpw (user.s, domain.s); > > if (user_passwd != NULL) { > > /* If user exists check if he has BOUNCE_MAIL flag set */ > > if (user_passwd->pw_gid BOUNCE_MAIL) > retstat = 0; > else > retstat = 1; > } > else { > Checking alias existence throught .qmail-alias files > /* My control: check for alias only if a domain (default or not) is specified */ > /* Change all '.' in ':' before continuing on aliases */ > > if (!stralloc_copys ( user.s)) die_nomem(); > if (!stralloc_0 ( die_nomem(); > > for (count = 0; *(alias_name.s + count) != 0; ++count) > if (*(alias_name.s + count) == '.') *(alias_name.s + count) = ':'; > > /* Check if alias file exists */ > > if (!stralloc_copys ( VPOPMAILDIR)) die_nomem(); > if (!stralloc_cats ( "/domains/")) die_nomem(); > if (!stralloc_cats ( domain.s)) die_nomem(); > if (!stralloc_cats ( "/.qmail-")) die_nomem(); > if (!stralloc_cats ( alias_name.s)) die_nomem(); > if (!stralloc_0 ( die_nomem(); > > fd_file = open_read (alias_path.s); > if (fd_file != -1) { > close (fd_file); > retstat = 1; > } > else { Checking for mailing list, controlling if the recipient name starts with a valid mailing list name > /* Let's check for mailing lists */ > > /* Set up the search string for mailing-list path */ > if (!stralloc_copys ( VPOPMAILDIR)) die_nomem(); > if (!stralloc_cats ( "/domains/")) die_nomem(); > if (!stralloc_cats ( domain.s)) die_nomem(); > if (!stralloc_cats ( "/")) die_nomem(); > if (!stralloc_cats ( user.s)) die_nomem(); > if (!stralloc_0 ( die_nomem(); > > /* Search for the outer '-' character */ > > for (offset = user.len - 1; offset > 0; --offset) > if (*(user.s + offset) == '-') { > *(alias_path.s + alias_path.len - user.len + offset) = 0; > *(mailing_path.s + mailing_path.len - user.len + offset) = 0; > fd_file = open_read (alias_path.s); > if (fd_file != -1) { > close (fd_file); > dir_file = opendir (mailing_path.s); > if (dir_file != NULL) { > closedir (dir_file); > retstat = 1; > break; > } > } > } > } > } > Resume original UID and GID > /* Set back the effective UID and GID (smtp) */ > > setegid (eff_gid); > seteuid (eff_uid); > Exits the routine returning the result > return retstat; > } > Calling the new checking user routine, within the existing addrallowed function. int addrallowed() { ......................... ......................... else if (!addrallowed()) { err_nogateway(); return; } + if (!realrcpt_check()) { err_realrcpt(); return; } if (!stralloc_cats( die_nomem(); if (!stralloc_cats( die_nomem(); if (!stralloc_0( die_nomem();

Document info

Page created on 5 march 2002, last modified on 5 march 2002.