[dovecot-cvs] dovecot/src/auth db-passwd-file.c, 1.12,
1.13 db-passwd-file.h, 1.5, 1.6 passdb-passwd-file.c, 1.18,
1.19 userdb-passwd-file.c, 1.14, 1.15
cras at dovecot.org
cras at dovecot.org
Fri Jul 22 15:42:59 EEST 2005
- Previous message: [dovecot-cvs] dovecot/src/lib-mail message-header-search.c, 1.13,
1.14
- Next message: [dovecot-cvs] dovecot/src/imap cmd-delete.c, 1.8,
1.9 cmd-subscribe.c, 1.11, 1.12 common.h, 1.21, 1.22 main.c,
1.63, 1.64
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/lib/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv24394
Modified Files:
db-passwd-file.c db-passwd-file.h passdb-passwd-file.c
userdb-passwd-file.c
Log Message:
Added support for variables in passwd-file path.
Index: db-passwd-file.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/db-passwd-file.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- db-passwd-file.c 12 Jul 2005 12:58:47 -0000 1.12
+++ db-passwd-file.c 22 Jul 2005 12:42:57 -0000 1.13
@@ -11,6 +11,7 @@
#include "istream.h"
#include "hash.h"
#include "str.h"
+#include "var-expand.h"
#include <stdlib.h>
#include <unistd.h>
@@ -120,7 +121,21 @@
hash_insert(pw->users, pu->user_realm, pu);
}
-static void passwd_file_open(struct passwd_file *pw)
+static struct passwd_file *
+passwd_file_new(struct db_passwd_file *db, const char *expanded_path)
+{
+ struct passwd_file *pw;
+
+ pw = i_new(struct passwd_file, 1);
+ pw->db = db;
+ pw->path = i_strdup(expanded_path);
+ pw->fd = -1;
+
+ hash_insert(db->files, pw->path, pw);
+ return pw;
+}
+
+static int passwd_file_open(struct passwd_file *pw)
{
struct istream *input;
const char *const *args;
@@ -129,11 +144,16 @@
int fd;
fd = open(pw->path, O_RDONLY);
- if (fd == -1)
- i_fatal("passwd-file %s: Can't open file: %m", pw->path);
+ if (fd == -1) {
+ i_error("passwd-file %s: Can't open file: %m", pw->path);
+ return FALSE;
+ }
- if (fstat(fd, &st) != 0)
- i_fatal("passwd-file %s: fstat() failed: %m", pw->path);
+ if (fstat(fd, &st) != 0) {
+ i_error("passwd-file %s: fstat() failed: %m", pw->path);
+ (void)close(fd);
+ return FALSE;
+ }
pw->fd = fd;
pw->stamp = st.st_mtime;
@@ -153,11 +173,12 @@
/* at least two fields */
const char *no_args = NULL;
passwd_file_add(pw, args[0], args[1],
- pw->userdb ? args+2 : &no_args);
+ pw->db->userdb ? args+2 : &no_args);
}
t_pop();
}
i_stream_unref(input);
+ return TRUE;
}
static void passwd_file_close(struct passwd_file *pw)
@@ -178,51 +199,157 @@
}
}
-static void passwd_file_sync(struct passwd_file *pw)
+static void passwd_file_free(struct passwd_file *pw)
+{
+ hash_remove(pw->db->files, pw->path);
+
+ passwd_file_close(pw);
+ i_free(pw->path);
+ i_free(pw);
+}
+
+static int passwd_file_sync(struct passwd_file *pw)
{
struct stat st;
- if (stat(pw->path, &st) < 0)
- i_fatal("passwd-file %s: stat() failed: %m", pw->path);
+ if (stat(pw->path, &st) < 0) {
+ /* with variables don't give hard errors, or errors about
+ nonexisting files */
+ if (errno != ENOENT)
+ i_error("passwd-file %s: stat() failed: %m", pw->path);
+
+ passwd_file_free(pw);
+ return FALSE;
+ }
if (st.st_mtime != pw->stamp) {
passwd_file_close(pw);
- passwd_file_open(pw);
+ return passwd_file_open(pw);
}
+ return TRUE;
}
-struct passwd_file *db_passwd_file_parse(const char *path, int userdb)
+struct db_passwd_file *db_passwd_file_parse(const char *path, int userdb)
{
- struct passwd_file *pw;
+ struct db_passwd_file *db;
+ const char *p;
+ int percents = FALSE;
- pw = i_new(struct passwd_file, 1);
- pw->refcount = 1;
- pw->path = i_strdup(path);
- pw->userdb = userdb;
+ db = i_new(struct db_passwd_file, 1);
+ db->refcount = 1;
+ db->userdb = userdb;
+ db->files = hash_create(default_pool, default_pool, 100,
+ str_hash, (hash_cmp_callback_t *)strcmp);
- passwd_file_open(pw);
- return pw;
+ for (p = path; *p != '\0'; p++) {
+ if (*p == '%' && p[1] != '\0') {
+ p++;
+ switch (var_get_key(p)) {
+ case 'd':
+ db->domain_var = TRUE;
+ db->vars = TRUE;
+ break;
+ case '%':
+ percents = TRUE;
+ break;
+ default:
+ db->vars = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (percents && !db->vars) {
+ /* just extra escaped % chars. remove them. */
+ struct var_expand_table empty_table[1];
+ string_t *dest;
+
+ empty_table[0].key = '\0';
+ dest = t_str_new(256);
+ var_expand(dest, path, empty_table);
+ path = str_c(dest);
+ }
+
+ db->path = i_strdup(path);
+
+ if (!db->vars) {
+ /* no variables, open the file immediately */
+ db->default_file = passwd_file_new(db, path);
+ if (!passwd_file_open(db->default_file))
+ exit(FATAL_DEFAULT);
+ }
+ return db;
}
-void db_passwd_file_unref(struct passwd_file *pw)
+void db_passwd_file_unref(struct db_passwd_file *db)
{
- if (--pw->refcount == 0) {
- passwd_file_close(pw);
- i_free(pw->path);
- i_free(pw);
+ struct hash_iterate_context *iter;
+ void *key, *value;
+
+ if (--db->refcount == 0) {
+ iter = hash_iterate_init(db->files);
+ while (hash_iterate(iter, &key, &value))
+ passwd_file_free(value);
+ hash_iterate_deinit(iter);
+
+ hash_destroy(db->files);
+ i_free(db->path);
+ i_free(db);
}
}
+static const char *path_fix(const char *path)
+{
+ const char *p;
+
+ p = strchr(path, '/');
+ if (p == NULL)
+ return path;
+
+ /* most likely this is an invalid request. just cut off the '/' and
+ everything after it. */
+ return t_strdup_until(path, p);
+}
+
struct passwd_user *
-db_passwd_file_lookup(struct passwd_file *pw, struct auth_request *request)
+db_passwd_file_lookup(struct db_passwd_file *db, struct auth_request *request)
{
+ struct passwd_file *pw;
struct passwd_user *pu;
- passwd_file_sync(pw);
+ if (!db->vars)
+ pw = db->default_file;
+ else {
+ const struct var_expand_table *table;
+ string_t *dest;
- pu = hash_lookup(pw->users, request->user);
+ t_push();
+
+ table = auth_request_get_var_expand_table(request, path_fix);
+ dest = t_str_new(256);
+ var_expand(dest, db->path, table);
+
+ pw = hash_lookup(db->files, str_c(dest));
+ if (pw == NULL) {
+ /* doesn't exist yet. create lookup for it. */
+ pw = passwd_file_new(db, str_c(dest));
+ }
+
+ t_pop();
+ }
+
+ if (!passwd_file_sync(pw)) {
+ auth_request_log_info(request, "passwd-file",
+ "no passwd file");
+ return NULL;
+ }
+
+ t_push();
+ pu = hash_lookup(pw->users, !db->domain_var ? request->user :
+ t_strcut(request->user, '@'));
if (pu == NULL)
auth_request_log_info(request, "passwd-file", "unknown user");
+ t_pop();
return pu;
}
Index: db-passwd-file.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/db-passwd-file.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- db-passwd-file.h 31 May 2004 18:57:25 -0000 1.5
+++ db-passwd-file.h 22 Jul 2005 12:42:57 -0000 1.6
@@ -15,24 +15,35 @@
};
struct passwd_file {
- int refcount;
+ struct db_passwd_file *db;
pool_t pool;
char *path;
time_t stamp;
int fd;
- int userdb;
struct hash_table *users;
};
-extern struct passwd_file *userdb_pwf;
-extern struct passwd_file *passdb_pwf;
+struct db_passwd_file {
+ int refcount;
+
+ char *path;
+ struct hash_table *files;
+ struct passwd_file *default_file;
+
+ unsigned int domain_var:1;
+ unsigned int vars:1;
+ unsigned int userdb:1;
+};
+
+extern struct db_passwd_file *userdb_pwf;
+extern struct db_passwd_file *passdb_pwf;
struct passwd_user *
-db_passwd_file_lookup(struct passwd_file *pw, struct auth_request *request);
+db_passwd_file_lookup(struct db_passwd_file *db, struct auth_request *request);
-struct passwd_file *db_passwd_file_parse(const char *path, int userdb);
-void db_passwd_file_unref(struct passwd_file *pw);
+struct db_passwd_file *db_passwd_file_parse(const char *path, int userdb);
+void db_passwd_file_unref(struct db_passwd_file *db);
#endif
Index: passdb-passwd-file.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-passwd-file.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- passdb-passwd-file.c 12 Jul 2005 12:58:47 -0000 1.18
+++ passdb-passwd-file.c 22 Jul 2005 12:42:57 -0000 1.19
@@ -8,7 +8,7 @@
#include "password-scheme.h"
#include "db-passwd-file.h"
-struct passwd_file *passdb_pwf = NULL;
+struct db_passwd_file *passdb_pwf = NULL;
static void
passwd_file_verify_plain(struct auth_request *request, const char *password,
@@ -24,10 +24,6 @@
return;
}
- /* we use case-sensitive lookups. otherwise we'd have to update
- request->user to pu->user */
- i_assert(strcmp(request->user, pu->user_realm) == 0);
-
crypted_pass = pu->password;
scheme = password_get_scheme(&crypted_pass);
if (scheme == NULL) scheme = "CRYPT";
Index: userdb-passwd-file.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-passwd-file.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- userdb-passwd-file.c 12 Jul 2005 12:58:47 -0000 1.14
+++ userdb-passwd-file.c 22 Jul 2005 12:42:57 -0000 1.15
@@ -8,7 +8,7 @@
#include "userdb.h"
#include "db-passwd-file.h"
-struct passwd_file *userdb_pwf = NULL;
+struct db_passwd_file *userdb_pwf = NULL;
static void passwd_file_lookup(struct auth_request *auth_request,
userdb_callback_t *callback)
@@ -42,7 +42,8 @@
/* resync */
userdb_pwf->userdb = TRUE;
- userdb_pwf->stamp = 0;
+ if (userdb_pwf->default_file != NULL)
+ userdb_pwf->default_file->stamp = 0;
} else {
userdb_pwf = db_passwd_file_parse(args, TRUE);
}
- Previous message: [dovecot-cvs] dovecot/src/lib-mail message-header-search.c, 1.13,
1.14
- Next message: [dovecot-cvs] dovecot/src/imap cmd-delete.c, 1.8,
1.9 cmd-subscribe.c, 1.11, 1.12 common.h, 1.21, 1.22 main.c,
1.63, 1.64
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list