From ae0939ee66602f8667aab2b069768ef17102d851 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 16 May 2006 14:29:39 +0000 Subject: r15634: Prevent passwords of winbindd's list of credential caches from beeing swapped to disc using mlock(). (patch was reviewed by Jeremy). Guenther (This used to be commit 206cdbb8e9a4a0900060d56510e58b85a2b8aec5) --- source3/configure.in | 2 ++ source3/nsswitch/winbindd.h | 4 +++ source3/nsswitch/winbindd_cred_cache.c | 46 ++++++++++++++++++++++++++++++++++ source3/nsswitch/winbindd_nss.h | 2 +- 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index d26e13a6bb..954aa99722 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1243,6 +1243,8 @@ AC_CHECK_FUNCS(srandom random srand rand setenv usleep strcasecmp fcvt fcvtl sym AC_CHECK_FUNCS(syslog vsyslog timegm) AC_CHECK_FUNCS(setlocale nl_langinfo) AC_CHECK_FUNCS(nanosleep) +AC_CHECK_FUNCS(mlock munlock mlockall munlockall) +AC_CHECK_HEADERS(sys/mman.h) # setbuffer, shmget, shm_open are needed for smbtorture AC_CHECK_FUNCS(setbuffer shmget shm_open) diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index e5f1c9699c..7d5330dccb 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -33,6 +33,10 @@ #include "libnscd.h" #endif +#ifdef HAVE_SYS_MMAN_H +#include +#endif + #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND diff --git a/source3/nsswitch/winbindd_cred_cache.c b/source3/nsswitch/winbindd_cred_cache.c index 8fc8058441..5fdb79c107 100644 --- a/source3/nsswitch/winbindd_cred_cache.c +++ b/source3/nsswitch/winbindd_cred_cache.c @@ -74,6 +74,23 @@ NTSTATUS remove_ccache_by_ccname(const char *ccname) if (strequal(entry->ccname, ccname)) { DLIST_REMOVE(ccache_list, entry); TALLOC_FREE(entry->event); /* unregisters events */ +#ifdef HAVE_MUNLOCK + if (entry->pass) { + size_t len = strlen(entry->pass)+1; +#ifdef DEBUG_PASSWORD + DEBUG(10,("unlocking memory: %p\n", entry->pass)); +#endif + memset(&(entry->pass), 0, len); + if ((munlock(&entry->pass, len)) == -1) { + DEBUG(0,("failed to munlock memory: %s (%d)\n", + strerror(errno), errno)); + return map_nt_error_from_unix(errno); + } +#ifdef DEBUG_PASSWORD + DEBUG(10,("munlocked memory: %p\n", entry->pass)); +#endif + } +#endif /* HAVE_MUNLOCK */ TALLOC_FREE(entry); DEBUG(10,("remove_ccache_by_ccname: removed ccache %s\n", ccname)); return NT_STATUS_OK; @@ -227,9 +244,31 @@ NTSTATUS add_ccache_to_list(const char *princ_name, new_entry->service = talloc_strdup(mem_ctx, service); NT_STATUS_HAVE_NO_MEMORY(new_entry->service); } + if (schedule_refresh_event && pass) { +#ifdef HAVE_MLOCK + size_t len = strlen(pass)+1; + + new_entry->pass = TALLOC_ZERO(mem_ctx, len); + NT_STATUS_HAVE_NO_MEMORY(new_entry->pass); + +#ifdef DEBUG_PASSWORD + DEBUG(10,("mlocking memory: %p\n", new_entry->pass)); +#endif + if ((mlock(new_entry->pass, len)) == -1) { + DEBUG(0,("failed to mlock memory: %s (%d)\n", + strerror(errno), errno)); + return map_nt_error_from_unix(errno); + } + +#ifdef DEBUG_PASSWORD + DEBUG(10,("mlocked memory: %p\n", new_entry->pass)); +#endif + memcpy(new_entry->pass, pass, len); +#else new_entry->pass = talloc_strdup(mem_ctx, pass); NT_STATUS_HAVE_NO_MEMORY(new_entry->pass); +#endif /* HAVE_MLOCK */ } new_entry->create_time = create_time; @@ -261,6 +300,13 @@ NTSTATUS add_ccache_to_list(const char *princ_name, NTSTATUS destroy_ccache_list(void) { +#ifdef HAVE_MUNLOCKALL + if ((munlockall()) == -1) { + DEBUG(0,("failed to unlock memory: %s (%d)\n", + strerror(errno), errno)); + return map_nt_error_from_unix(errno); + } +#endif /* HAVE_MUNLOCKALL */ return talloc_destroy(mem_ctx) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index fe09cd8a06..34e0d09721 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -394,7 +394,7 @@ struct WINBINDD_CCACHE_ENTRY { const char *service; const char *username; const char *sid_string; - const char *pass; + char *pass; uid_t uid; time_t create_time; time_t renew_until; -- cgit