[Dovecot] Configuration of LMTP Reject Code
Petter Urkedal
urkedal at nbi.dk
Thu Mar 17 15:16:47 EET 2011
On 2011-02-22, Timo Sirainen wrote:
> On Tue, 2011-02-22 at 11:02 +0100, Petter Urkedal wrote:
> > userdb {
> > driver = passwd
> > args = home=/srv/mail/nbi.ku.dk/%1n/%n mail=maildir:~/Maildir
> > }
>
> The problem with passwd is that it can't separate "user doesn't exist"
> from "temporary error". http://wiki2.dovecot.org/UserDatabase/NSS can
> separate these, but it hasn't been tested much..
>
> > > > We use Postfix on the front-end, which is very configurable in this
> > > > respect. I don't see a way to override the error code from LMTP,
> > > > though, but suggestions are welcome.
> > >
> > > I don't really like adding settings that have very few users..
> >
> > I understand, it's really a workaround. A global directive to turn all
> > permanent errors into temporary ones, would do as well, since any error
> > from LMTP is a potential issue we want to know about. I'm not sure
> > whether that's any nicer from your point of view.
>
> Well, there aren't really any other permanent errors.. Quota already has
> quota_full_tempfail setting.
I think there is a better solution. It seems that getpwnam_r is POSIX
and does the right thing. The attached patch adds a feature-check for
getpwnam_r and, if present, uses it in userdb-passwd.c in place of the
problematic getpwnam. I've not some light testing on a non-production
server.
-------------- next part --------------
diff -r 26d5351649ac configure.in
--- a/configure.in Wed Mar 16 19:49:27 2011 +0200
+++ b/configure.in Thu Mar 17 13:54:55 2011 +0100
@@ -379,7 +379,8 @@
setrlimit setproctitle seteuid setreuid setegid setresgid \
strtoull strtoll strtouq strtoq \
setpriority quotactl getmntent kqueue kevent backtrace_symbols \
- walkcontext dirfd clearenv malloc_usable_size glob fallocate)
+ walkcontext dirfd clearenv malloc_usable_size glob fallocate \
+ getpwnam_r)
AC_CHECK_LIB(rt, clock_gettime, [
AC_DEFINE(HAVE_CLOCK_GETTIME,, Define if you have the clock_gettime function)
diff -r 26d5351649ac src/auth/userdb-passwd.c
--- a/src/auth/userdb-passwd.c Wed Mar 16 19:49:27 2011 +0200
+++ b/src/auth/userdb-passwd.c Thu Mar 17 13:54:55 2011 +0100
@@ -9,12 +9,18 @@
#include "userdb-static.h"
#include <pwd.h>
+#include <unistd.h>
#define USER_CACHE_KEY "%u"
struct passwd_userdb_module {
struct userdb_module module;
struct userdb_static_template *tmpl;
+
+#ifdef HAVE_GETPWNAM_R
+ char *buf;
+ size_t bufsize;
+#endif
};
struct passwd_userdb_iterate_context {
@@ -33,15 +39,35 @@
struct passwd_userdb_module *module =
(struct passwd_userdb_module *)_module;
struct passwd *pw;
+#ifdef HAVE_GETPWNAM_R
+ struct passwd pw_data;
+ int err;
+#endif
auth_request_log_debug(auth_request, "passwd", "lookup");
+#ifdef HAVE_GETPWNAM_R
+ err = getpwnam_r(auth_request->user, &pw_data,
+ module->buf, module->bufsize, &pw);
+ if (pw == NULL) {
+ if (err) {
+ auth_request_log_error(auth_request, "passwd", "%s",
+ strerror(err));
+ callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
+ return;
+ }
+ auth_request_log_info(auth_request, "passwd", "unknown user");
+ callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
+ return;
+ }
+#else
pw = getpwnam(auth_request->user);
if (pw == NULL) {
auth_request_log_info(auth_request, "passwd", "unknown user");
callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
return;
}
+#endif
auth_request_set_field(auth_request, "user", pw->pw_name, NULL);
@@ -151,6 +177,13 @@
module->module.cache_key = USER_CACHE_KEY;
module->tmpl = userdb_static_template_build(pool, "passwd", args);
+#ifdef HAVE_GETPWNAM_R
+ module->bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (module->bufsize == (size_t)-1)
+ module->bufsize = 16384;
+ module->buf = p_malloc(pool, module->bufsize);
+#endif
+
if (userdb_static_template_remove(module->tmpl, "blocking",
&value)) {
module->module.blocking = value == NULL ||
More information about the dovecot
mailing list