From 45c2c496dcf89f568b90fcf403af9d63b2361fbd Mon Sep 17 00:00:00 2001 From: Iker Pedrosa Date: Mon, 10 Jul 2023 12:45:12 +0200 Subject: pam_userdb: enable GDBM support * configure.ac: add `gdbm` option to `enable-db` * modules/pam_userdb/pam_userdb.c: conditionally provide database access depending on the database technology Signed-off-by: Iker Pedrosa --- modules/pam_userdb/pam_userdb.c | 90 +++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 12 deletions(-) (limited to 'modules/pam_userdb') diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c index 297403b0..0b5e5965 100644 --- a/modules/pam_userdb/pam_userdb.c +++ b/modules/pam_userdb/pam_userdb.c @@ -25,6 +25,8 @@ #ifdef HAVE_NDBM_H # include +#elif defined(HAVE_GDBM_H) +# include #else # ifdef HAVE_DB_H # define DB_DBM_HSEARCH 1 /* use the dbm interface */ @@ -40,6 +42,12 @@ #include #include "pam_inline.h" +#ifndef HAVE_GDBM_H +# define COND_UNUSED UNUSED +#else +# define COND_UNUSED +#endif /* HAVE_GDBM_H */ + /* * Conversation function to obtain the user's password */ @@ -129,6 +137,60 @@ _pam_parse (pam_handle_t *pamh, int argc, const char **argv, return ctrl; } +/* + * Database abstraction functions + */ +static void * +db_open(const char *database, mode_t file_mode) +{ +#ifdef HAVE_GDBM_H + return gdbm_open(database, 4096, GDBM_READER, file_mode, NULL); +#else + return dbm_open(database, O_RDONLY, file_mode); +#endif /* HAVE_GDBM_H */ +} + +static datum +db_firstkey(void *dbm) +{ +#ifdef HAVE_GDBM_H + return gdbm_firstkey(dbm); +#else + return dbm_firstkey(dbm); +#endif /* HAVE_GDBM_H */ +} + +static datum +db_nextkey(void *dbm, datum key COND_UNUSED) +{ +#ifdef HAVE_GDBM_H + return gdbm_nextkey(dbm, key); +#else + return dbm_nextkey(dbm); +#endif /* HAVE_GDBM_H */ +} + +static datum +db_fetch(void *dbm, datum key) +{ +#ifdef HAVE_GDBM_H + return gdbm_fetch(dbm, key); +#else + return dbm_fetch(dbm, key); +#endif /* HAVE_GDBM_H */ +} + +static int +db_close(void *dbm) +{ +#ifdef HAVE_GDBM_H + return gdbm_close(dbm); +#else + dbm_close(dbm); + return 0; +#endif /* HAVE_GDBM_H */ +} + /* * Looks up a user name in a database and checks the password @@ -143,11 +205,15 @@ static int user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, const char *user, const char *pass, int ctrl) { +#ifdef HAVE_GDBM_H + GDBM_FILE *dbm; +#else DBM *dbm; +#endif datum key, data; /* Open the DB file. */ - dbm = dbm_open(database, O_RDONLY, 0644); + dbm = db_open(database, 0644); if (dbm == NULL) { pam_syslog(pamh, LOG_ERR, "user_lookup: could not open database `%s': %m", database); @@ -157,9 +223,9 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, /* dump out the database contents for debugging */ if (ctrl & PAM_DUMP_ARG) { pam_syslog(pamh, LOG_INFO, "Database dump:"); - for (key = dbm_firstkey(dbm); key.dptr != NULL; - key = dbm_nextkey(dbm)) { - data = dbm_fetch(dbm, key); + for (key = db_firstkey(dbm); key.dptr != NULL; + key = db_nextkey(dbm, key)) { + data = db_fetch(dbm, key); pam_syslog(pamh, LOG_INFO, "key[len=%d] = `%s', data[len=%d] = `%s'", key.dsize, key.dptr, data.dsize, data.dptr); @@ -180,7 +246,7 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, } if (key.dptr) { - data = dbm_fetch(dbm, key); + data = db_fetch(dbm, key); pam_overwrite_n(key.dptr, key.dsize); free(key.dptr); } @@ -196,7 +262,7 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, if (ctrl & PAM_KEY_ONLY_ARG) { - dbm_close (dbm); + db_close (dbm); return 0; /* found it, data contents don't matter */ } @@ -275,7 +341,7 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, } - dbm_close(dbm); + db_close(dbm); if (compare == 0) return 0; /* match */ else @@ -290,14 +356,14 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, /* probably we should check dbm_error() here */ if ((ctrl & PAM_KEY_ONLY_ARG) == 0) { - dbm_close(dbm); + db_close(dbm); return 1; /* not key_only, so no entry => no entry for the user */ } /* now handle the key_only case */ - for (key = dbm_firstkey(dbm); + for (key = db_firstkey(dbm); key.dptr != NULL; - key = dbm_nextkey(dbm)) { + key = db_nextkey(dbm, key)) { int compare; /* first compare the user portion (case sensitive) */ compare = strncmp(key.dptr, user, strlen(user)); @@ -322,12 +388,12 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, } } if (compare == 0) { - dbm_close(dbm); + db_close(dbm); return 0; /* match */ } } } - dbm_close(dbm); + db_close(dbm); if (saw_user) return -1; /* saw the user, but password mismatch */ else -- cgit v1.2.3