/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "auth-common.h"
#if defined (USERDB_PASSWD_FILE) || defined(PASSDB_PASSWD_FILE)
#include "userdb.h"
#include "db-passwd-file.h"
#include "array.h"
#include "buffer.h"
#include "istream.h"
#include "hash.h"
#include "str.h"
#include "eacces-error.h"
#include "ioloop.h"
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
static void ATTR_NULL(3)
{
/* args = uid, gid, user info, home dir, shell, extra_fields */
char *user;
i_error("passwd-file %s: User %s exists more than once",
return;
}
/* password[type] - we're being libpam-pwdfile compatible
here. it uses 13 = DES and 34 = MD5. For backwards
compatibility with ourself, we have also 56 = Digest-MD5. */
if (num == 34) {
} else if (num == 56) {
i_error("passwd-file %s: User %s "
"has invalid password",
return;
}
} else {
}
} else {
}
;
args++;
} else {
i_error("passwd-file %s: User %s has invalid UID '%s'",
return;
}
args++;
}
i_error("passwd-file %s: User %s is missing "
}
/* don't allow userdb lookups */
args++;
else {
i_error("passwd-file %s: User %s has invalid GID '%s'",
return;
}
args++;
}
/* user info */
args++;
/* home */
args++;
}
/* shell */
args++;
/* old format, this field is empty and next field may
contain MAIL */
args++;
t_strconcat("userdb_mail=",
}
/* new format, contains a space separated list of
extra fields */
}
if (extra_fields != NULL) {
pu->extra_fields =
}
}
static struct passwd_file *
{
return pw;
}
const char **error_r)
{
const char *line;
unsigned int time_secs;
int fd;
if (fd == -1) {
else {
}
return -1;
}
i_close_fd(&fd);
return -1;
}
continue; /* no username or comment */
T_BEGIN {
/* at least username+password */
} else {
/* only username */
}
} T_END;
}
i_warning("passwd-file %s: Reading %u users took %u secs",
i_debug("passwd-file %s: Read %u users in %u secs",
}
return 0;
}
{
}
{
}
struct passwd_file *pw)
{
const char *error;
/* with variables don't give hard errors, or errors about
nonexistent files */
} else {
}
return -1;
}
"%s", error);
return -1;
}
}
return 0;
}
{
struct db_passwd_file *f;
return f;
}
return NULL;
}
{
/* warn about missing userdb fields only when there aren't any other
userdbs. */
}
struct db_passwd_file *
{
const char *p;
if (userdb)
return db;
}
if (userdb)
for (p = path; *p != '\0'; p++) {
if (*p == '%' && p[1] != '\0') {
if (var_get_key(++p) == '%')
else
}
}
/* just extra escaped % chars. remove them. */
const char *error;
i_unreached();
}
} else {
}
passwd_files = db;
return db;
}
{
const char *error;
/* no variables, open the file immediately */
}
}
{
struct db_passwd_file **p;
char *path;
return;
if (*p == db) {
break;
}
}
else {
}
}
static const char *
{
const char *p;
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 auth_request *request,
const char *username_format,
struct passwd_user **user_r)
{
const char *error;
else {
&error) <= 0) {
"Failed to expand passwd-file path %s: %s",
return -1;
}
/* doesn't exist yet. create lookup for it. */
}
}
/* pw may be freed now */
return -1;
}
auth_request_str_escape, &error) <= 0) {
"Failed to expand username_format=%s: %s",
return -1;
}
"lookup: user=%s file=%s",
return 0;
}
return 1;
}
#endif