summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2008-08-21 01:20:22 +0200
committerVolker Lendecke <vl@samba.org>2008-08-23 13:19:35 +0200
commit6e89443ebacaa082c50935e4359f70686e1cc184 (patch)
tree3d63795694c3c72b4ea7275f95b0255e4ed48cbd
parent4a5ccfb91f8d427fe9fa83cab992587fe6ce70c7 (diff)
downloadsamba-6e89443ebacaa082c50935e4359f70686e1cc184.tar.gz
samba-6e89443ebacaa082c50935e4359f70686e1cc184.tar.bz2
samba-6e89443ebacaa082c50935e4359f70686e1cc184.zip
winbindd: add event based machine password change.
Guenther (This used to be commit 15b72d44cbde0b8a375d8ed3d045c40ae97ec05a)
-rw-r--r--source3/winbindd/winbindd.h1
-rw-r--r--source3/winbindd/winbindd_dual.c119
2 files changed, 120 insertions, 0 deletions
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index 1b8cd9163f..04b0b39f81 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -153,6 +153,7 @@ struct winbindd_child {
struct fd_event event;
struct timed_event *lockout_policy_event;
+ struct timed_event *machine_password_change_event;
struct winbindd_async_request *requests;
const struct winbindd_child_dispatch_table *table;
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 1e8325f983..aa6da545d3 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -840,6 +840,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,
@@ -1138,6 +1242,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;