0a1,6 > /* NEWER VERSION 2.0 HAS BEEN RELEASED. > * SEE HTTP://www.interazioni.it/opensource > * > * Includes patch qmail-smtpd-chkusr v.0.2 > * for qmail 1.0.3 and vpopmail 4.9.x > */ 26a33,44 > #include > #include > #include > #include > #include > > #include "open.h" > #include "/vpopmail/include/vpopmail.h" > #include "/vpopmail/include/vauth.h" > #include "/vpopmail/include/vpopmail_config.h" > > 62d79 < 119c136 < --- > 210a228,377 > void err_realrcpt() { out("550 sorry, no mailbox here by that name (#5.1.1 - chkusr)\r\n"); } > > 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 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 (&user, addr.s, count)) die_nomem(); > if (!stralloc_0 (&user)) die_nomem(); > if (!stralloc_copys (&domain, addr.s + count + 1)) die_nomem(); > if (!stralloc_0 (&domain)) die_nomem(); > } > else { > if (!stralloc_copys (&user, addr.s)) die_nomem(); > if (!stralloc_0 (&user)) die_nomem(); > if (!stralloc_copys (&domain, DEFAULT_DOMAIN)) die_nomem(); > if (!stralloc_0 (&domain)) die_nomem(); > } > > /* My control: continue only if a domain (default or not) is specified */ > > if (str_len (domain.s) == 0) > return 0; > > /* 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 (&domain, fakestr, sizeof (fakestr))) die_nomem(); > > vget_real_domain(domain.s, domain.len); > > /* General control: check the existance 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 { > > /* My control: check for alias only if a domain (default or not) is specified */ > /* Change all '.' in ':' before continuing on aliases */ > > if (!stralloc_copys (&alias_name, user.s)) die_nomem(); > if (!stralloc_0 (&alias_name)) 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 (&alias_path, VPOPMAILDIR)) die_nomem(); > if (!stralloc_cats (&alias_path, "/domains/")) die_nomem(); > if (!stralloc_cats (&alias_path, domain.s)) die_nomem(); > if (!stralloc_cats (&alias_path, "/.qmail-")) die_nomem(); > if (!stralloc_cats (&alias_path, alias_name.s)) die_nomem(); > if (!stralloc_0 (&alias_path)) die_nomem(); > > fd_file = open_read (alias_path.s); > if (fd_file != -1) { > close (fd_file); > retstat = 1; > } > else { > /* Let's check for mailing lists */ > > /* Set up the search string for mailing-list path */ > if (!stralloc_copys (&mailing_path, VPOPMAILDIR)) die_nomem(); > if (!stralloc_cats (&mailing_path, "/domains/")) die_nomem(); > if (!stralloc_cats (&mailing_path, domain.s)) die_nomem(); > if (!stralloc_cats (&mailing_path, "/")) die_nomem(); > if (!stralloc_cats (&mailing_path, user.s)) die_nomem(); > if (!stralloc_0 (&mailing_path)) 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; > } > } > } > } > } > > /* Set back the effective UID and GID (smtp) */ > > setegid (eff_gid); > seteuid (eff_uid); > > return retstat; > } > 260a428 > if (!realrcpt_check()) { err_realrcpt(); return; }