summaryrefslogtreecommitdiff
path: root/source/nsswitch/winbindd_cred_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/nsswitch/winbindd_cred_cache.c')
-rw-r--r--source/nsswitch/winbindd_cred_cache.c69
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;
}