diff options
Diffstat (limited to 'source/nsswitch/winbindd_cred_cache.c')
-rw-r--r-- | source/nsswitch/winbindd_cred_cache.c | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/source/nsswitch/winbindd_cred_cache.c b/source/nsswitch/winbindd_cred_cache.c index 4c539b9b23a..5fdb79c107a 100644 --- a/source/nsswitch/winbindd_cred_cache.c +++ b/source/nsswitch/winbindd_cred_cache.c @@ -74,7 +74,25 @@ 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; } } @@ -104,7 +122,7 @@ static void krb5_ticket_refresh_handler(struct timed_event *te, if ((entry->renew_until < time(NULL)) && (entry->pass != NULL)) { - seteuid(entry->uid); + set_effective_uid(entry->uid); ret = kerberos_kinit_password_ext(entry->principal_name, entry->pass, @@ -113,8 +131,9 @@ static void krb5_ticket_refresh_handler(struct timed_event *te, &entry->renew_until, entry->ccname, False, /* no PAC required anymore */ + True, WINBINDD_PAM_AUTH_KRB5_RENEW_TIME); - seteuid(0); + gain_root_privilege(); if (ret) { DEBUG(3,("could not re-kinit: %s\n", error_message(ret))); @@ -130,13 +149,13 @@ static void krb5_ticket_refresh_handler(struct timed_event *te, goto done; } - seteuid(entry->uid); + set_effective_uid(entry->uid); ret = smb_krb5_renew_ticket(entry->ccname, entry->principal_name, entry->service, &new_start); - seteuid(0); + gain_root_privilege(); if (ret) { DEBUG(3,("could not renew tickets: %s\n", error_message(ret))); @@ -170,6 +189,7 @@ NTSTATUS add_ccache_to_list(const char *princ_name, BOOL schedule_refresh_event) { struct WINBINDD_CCACHE_ENTRY *new_entry = NULL; + struct WINBINDD_CCACHE_ENTRY *old_entry = NULL; NTSTATUS status; if ((username == NULL && sid_string == NULL && princ_name == NULL) || @@ -191,6 +211,16 @@ NTSTATUS add_ccache_to_list(const char *princ_name, return NT_STATUS_NO_MORE_ENTRIES; } + /* get rid of old entries */ + old_entry = get_ccache_by_username(username); + if (old_entry) { + status = remove_ccache_by_ccname(old_entry->ccname); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("add_ccache_to_list: failed to delete old ccache entry\n")); + return status; + } + } + new_entry = TALLOC_P(mem_ctx, struct WINBINDD_CCACHE_ENTRY); if (new_entry == NULL) { return NT_STATUS_NO_MEMORY; @@ -214,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 (pass) { + + 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; @@ -248,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; } |