diff -urN --exclude='*~' dovecot-1.0.0.orig/src/auth/userdb-static.c dovecot-1.0.0-semistatic/src/auth/userdb-static.c
--- dovecot-1.0.0.orig/src/auth/userdb-static.c	2007-03-21 20:01:56.000000000 +0000
+++ dovecot-1.0.0-semistatic/src/auth/userdb-static.c	2007-05-15 02:46:32.000000000 +0100
@@ -10,6 +10,8 @@
 #include "userdb.h"
 
 #include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
 
 struct static_context {
 	userdb_callback_t *callback, *old_callback;
@@ -33,8 +35,10 @@
         const struct var_expand_table *table;
 	struct auth_stream_reply *reply;
 	string_t *str;
-	const char *const *args, *value;
+	const char *const *args, *key, *value;
 	unsigned int i, count;
+	bool ok = TRUE;
+	struct stat fileinfo;
 
 	t_push();
 	str = t_str_new(256);
@@ -46,17 +50,39 @@
 	args = array_get(&module->template, &count);
 	i_assert((count % 2) == 0);
 	for (i = 0; i < count; i += 2) {
+		key = args[i];
 		if (args[i+1] == NULL)
 			value = NULL;
 		else {
 			str_truncate(str, 0);
 			var_expand(str, args[i+1], table);
 			value = str_c(str);
+			if (strcasecmp(key, "uid_file") == 0) {
+			    if (stat(value, &fileinfo) != 0) {
+				ok = FALSE;
+				auth_request_log_info(auth_request, "static-userdb",
+						      "Can't stat uid_file %s: %s",
+						      value, strerror(errno));
+			    } else {
+				key = "uid";
+				value = dec2str(fileinfo.st_uid);
+			    }
+			} else if (strcasecmp(key, "gid_file") == 0) {
+			    if (stat(value, &fileinfo) != 0) {
+				ok = FALSE;
+				auth_request_log_info(auth_request, "static-userdb",
+						      "Can't stat gid_file %s: %s",
+						      value, strerror(errno));
+			    } else {
+				key = "gid";
+				value = dec2str(fileinfo.st_gid);
+			    }
+			}
 		}
-		auth_stream_reply_add(reply, args[i], value);
+		auth_stream_reply_add(reply, key, value);
 	}
 
-	callback(USERDB_RESULT_OK, reply, auth_request);
+	callback((ok ? USERDB_RESULT_OK : USERDB_RESULT_INTERNAL_FAILURE), reply, auth_request);
 	t_pop();
 }
 
@@ -131,11 +157,14 @@
 	const char *const *tmp, *key, *value;
 	uid_t uid;
 	gid_t gid;
+	bool uid_file;
+	bool gid_file;
 
 	module = p_new(auth_userdb->auth->pool, struct static_userdb_module, 1);
 
 	uid = (uid_t)-1;
 	gid = (gid_t)-1;
+	uid_file = gid_file = FALSE;
 
 	tmp = t_strsplit_spaces(args, " ");
 	ARRAY_CREATE(&module->template, auth_userdb->auth->pool,
@@ -165,6 +194,10 @@
 					value);
 			}
 			value = dec2str(gid);
+		} else if (strcasecmp(key, "uid_file") == 0) {
+			uid_file = TRUE;
+		} else if (strcasecmp(key, "gid_file") == 0) {
+			gid_file = TRUE;
 		} else if (strcmp(key, "allow_all_users") == 0) {
 			module->allow_all_users = value == NULL ||
 				strcasecmp(value, "yes") == 0;
@@ -180,9 +213,9 @@
 	}
 	t_pop();
 
-	if (uid == (uid_t)-1)
+	if ((uid == (uid_t)-1) && !uid_file)
 		i_fatal("static userdb: uid missing");
-	if (gid == (gid_t)-1)
+	if ((gid == (gid_t)-1) && !gid_file)
 		i_fatal("static userdb: gid missing");
 	return &module->module;
 }
