diff options
author | Günther Deschner <gd@samba.org> | 2008-08-21 01:20:22 +0200 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2008-11-26 10:13:32 +0100 |
commit | 672a412977914f03948e141daac9380f3126f6de (patch) | |
tree | a1c4ef01a9b42c9987b5a3266d45f4470d336801 /source/winbindd/winbindd_dual.c | |
parent | e66f1d88a6f55dea69a4c35c13cc32397cd86540 (diff) | |
download | samba-672a412977914f03948e141daac9380f3126f6de.tar.gz samba-672a412977914f03948e141daac9380f3126f6de.tar.xz samba-672a412977914f03948e141daac9380f3126f6de.zip |
winbindd: add event based machine password change.
Guenther
(This used to be commit 15b72d44cbde0b8a375d8ed3d045c40ae97ec05a)
(cherry picked from commit 4721049e840846c2ac4ba829c5eb669576b0fa0f)
Diffstat (limited to 'source/winbindd/winbindd_dual.c')
-rw-r--r-- | source/winbindd/winbindd_dual.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/source/winbindd/winbindd_dual.c b/source/winbindd/winbindd_dual.c index 64faf4dba50..a98d8024dd6 100644 --- a/source/winbindd/winbindd_dual.c +++ b/source/winbindd/winbindd_dual.c @@ -871,6 +871,110 @@ static void account_lockout_policy_handler(struct event_context *ctx, child); } +static time_t get_machine_password_timeout(void) +{ + /* until we have gpo support use lp setting */ + return lp_machine_password_timeout(); +} + +static bool calculate_next_machine_pwd_change(const char *domain, + struct timeval *t) +{ + time_t pass_last_set_time; + time_t timeout; + time_t next_change; + + if (!secrets_fetch_machine_password(domain, + &pass_last_set_time, + NULL)) { + DEBUG(0,("cannot fetch own machine password ????")); + return false; + } + + timeout = get_machine_password_timeout(); + if (timeout == 0) { + DEBUG(10,("machine password never expires\n")); + return false; + } + + if (time(NULL) < (pass_last_set_time + timeout)) { + next_change = pass_last_set_time + timeout; + DEBUG(10,("machine password still valid until: %s\n", + http_timestring(next_change))); + *t = timeval_set(next_change, 0); + return true; + } + + DEBUG(10,("machine password expired, needs immediate change\n")); + + *t = timeval_zero(); + + return true; +} + +static void machine_password_change_handler(struct event_context *ctx, + struct timed_event *te, + const struct timeval *now, + void *private_data) +{ + struct winbindd_child *child = + (struct winbindd_child *)private_data; + struct rpc_pipe_client *netlogon_pipe = NULL; + TALLOC_CTX *mem_ctx = NULL; + NTSTATUS result; + struct timeval next_change; + + DEBUG(10,("machine_password_change_handler called\n")); + + TALLOC_FREE(child->machine_password_change_event); + + if (!calculate_next_machine_pwd_change(child->domain->name, + &next_change)) { + return; + } + + if (!winbindd_can_contact_domain(child->domain)) { + DEBUG(10,("machine_password_change_handler: Removing myself since I " + "do not have an incoming trust to domain %s\n", + child->domain->name)); + return; + } + + mem_ctx = talloc_init("machine_password_change_handler "); + if (!mem_ctx) { + return; + } + + result = cm_connect_netlogon(child->domain, &netlogon_pipe); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10,("machine_password_change_handler: " + "failed to connect netlogon pipe: %s\n", + nt_errstr(result))); + TALLOC_FREE(mem_ctx); + return; + } + + result = trust_pw_find_change_and_store_it(netlogon_pipe, + mem_ctx, + child->domain->name); + TALLOC_FREE(mem_ctx); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10,("machine_password_change_handler: " + "failed to change machine password: %s\n", + nt_errstr(result))); + } else { + DEBUG(10,("machine_password_change_handler: " + "successfully changed machine password\n")); + } + + child->machine_password_change_event = event_add_timed(winbind_event_context(), NULL, + next_change, + "machine_password_change_handler", + machine_password_change_handler, + child); +} + /* Deal with a request to go offline. */ static void child_msg_offline(struct messaging_context *msg, @@ -1173,6 +1277,21 @@ static bool fork_domain_child(struct winbindd_child *child) child); } + if (child->domain && !(child->domain->internal) && + lp_server_role() == ROLE_DOMAIN_MEMBER) { + + struct timeval next_change; + + if (calculate_next_machine_pwd_change(child->domain->name, + &next_change)) { + child->machine_password_change_event = event_add_timed( + winbind_event_context(), NULL, next_change, + "machine_password_change_handler", + machine_password_change_handler, + child); + } + } + while (1) { int ret; |