db-passwd-file.c revision 5f21795890064f8e1ebebdff752b67f15ea59e37
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#if defined (USERDB_PASSWD_FILE) || defined(PASSDB_PASSWD_FILE)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenstatic void passwd_file_add(struct passwd_file *pw, const char *username,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen /* args = uid, gid, user info, home dir, shell, extra_fields */
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (hash_table_lookup(pw->users, username) != NULL) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen i_error("passwd-file %s: User %s exists more than once",
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (len > 4 && pass[0] != '{' && pass[0] != '$' &&
39e6fcc3e8b1ccb13087c232cb6bdea04d1a20a4Timo Sirainen /* password[type] - we're being libpam-pwdfile compatible
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen here. it uses 13 = DES and 34 = MD5. For backwards
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen comaptibility with ourself, we have also 56 = Digest-MD5. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen int num = (pass[len-3] - '0') * 10 + (pass[len-2] - '0');
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen pu->password = p_strconcat(pw->pool, "{PLAIN-MD5}",
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen pu->password = p_strconcat(pw->pool, "{DIGEST-MD5}",
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen "has invalid password",
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen pu->password = p_strconcat(pw->pool, "{CRYPT}",
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen i_error("passwd-file %s: User %s has invalid UID '%s'",
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen i_error("passwd-file %s: User %s has invalid GID '%s'",
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen /* user info */
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainen /* old format, this field is empty and next field may
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainen contain MAIL */
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainen if (*args != NULL && **args != '\0' && pw->db->userdb) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen /* new format, contains a space separated list of
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen extra fields */
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen p_strsplit_spaces(pw->pool, extra_fields, " ");
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstatic struct passwd_file *
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenpasswd_file_new(struct db_passwd_file *db, const char *expanded_path)
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainenstatic bool passwd_file_open(struct passwd_file *pw)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen i_error("passwd-file %s: Can't open file: %m", pw->path);
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen i_error("passwd-file %s: fstat() failed: %m", pw->path);
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen pw->pool = pool_alloconly_create(MEMPOOL_GROWING"passwd_file", 10240);
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen pw->users = hash_table_create(default_pool, pw->pool, 100,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen input = i_stream_create_fd(pw->fd, 4096, FALSE);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen i_stream_set_return_partial_line(input, TRUE);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen while ((line = i_stream_read_next_line(input)) != NULL) {
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen if (*line == '\0' || *line == ':' || *line == '#')
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen continue; /* no username or comment */
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen const char *const *args = t_strsplit(line, ":");
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen /* at least username+password */
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen passwd_file_add(pw, args[0], args[1], args+2);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen /* only username */
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainenstatic void passwd_file_close(struct passwd_file *pw)
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen i_error("passwd-file %s: close() failed: %m", pw->path);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenstatic void passwd_file_free(struct passwd_file *pw)
18634dae6e304bac982bb1e0ff1b6b88fc448dbcTimo Sirainenstatic bool passwd_file_sync(struct passwd_file *pw)
18634dae6e304bac982bb1e0ff1b6b88fc448dbcTimo Sirainen /* with variables don't give hard errors, or errors about
294f1a51763015cda0e2d874c5027d6fe7a2cd54Timo Sirainen nonexisting files */
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen i_error("passwd-file %s: stat() failed: %m", pw->path);
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen if (st.st_mtime != pw->stamp || st.st_size != pw->size) {
return TRUE;
struct db_passwd_file *f;
return NULL;
struct db_passwd_file *
return db;
return db;
struct db_passwd_file **p;
if (*p == db) {
if (p == NULL)
return path;
struct passwd_user *
const char *username_format)
const char *path;
return NULL;
return pu;