ad_machine_pw_renewal.c revision 45e11be651dbd3855a35de4abd2922e5b9d4b963
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen Sumit Bose <sbose@redhat.com>
1f366614aaafcc9496ff85b25988f19c3254ab7cTimo Sirainen Copyright (C) 2016 Red Hat
97943a36e08923d625898f5ca8ffd38325a3986dTimo Sirainen This program is free software; you can redistribute it and/or modify
3bc62efe513ebc7450cffe9a4e8f0b07424bf190Timo Sirainen it under the terms of the GNU General Public License as published by
f739c92a9237db03327dc82e3792e39c160a1e4dTimo Sirainen the Free Software Foundation; either version 3 of the License, or
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen (at your option) any later version.
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen This program is distributed in the hope that it will be useful,
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
8bf42ce5ef783b96a2ded67524173e95e9b45adaTimo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen GNU General Public License for more details.
f739c92a9237db03327dc82e3792e39c160a1e4dTimo Sirainen You should have received a copy of the GNU General Public License
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
9c7f6dbf65ca01026e5f9c8c8b67c7e629c0b5e7Timo Sirainenstatic errno_t get_adcli_extra_args(const char *ad_domain,
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen const char **args;
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen if (ad_domain == NULL || ad_hostname == NULL) {
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Missing AD domain or hostname.\n");
f323e3f0de9841f399aba5919e3f25652a88fa65Timo Sirainen renewal_data->prog_path = talloc_strdup(renewal_data, RENEWAL_PROG_PATH);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
39ea5717264668e2c7f9f7986eb821d21785f47fTimo Sirainen args = talloc_array(renewal_data, const char *, 8);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
bdb0f594a5673a0c5a16b92dc49eb2a8a66bdaceTimo Sirainen /* extra_args are added in revers order */
bdb0f594a5673a0c5a16b92dc49eb2a8a66bdaceTimo Sirainen /* first add NULL as a placeholder for the server name which is determined
bdb0f594a5673a0c5a16b92dc49eb2a8a66bdaceTimo Sirainen * at runtime */
bdb0f594a5673a0c5a16b92dc49eb2a8a66bdaceTimo Sirainen args[c++] = talloc_asprintf(args, "--computer-password-lifetime=%zu",
f739c92a9237db03327dc82e3792e39c160a1e4dTimo Sirainen args[c++] = talloc_asprintf(args, "--host-fqdn=%s", ad_hostname);
bdb0f594a5673a0c5a16b92dc49eb2a8a66bdaceTimo Sirainen args[c++] = talloc_asprintf(args, "--host-keytab=%s", ad_keytab);
bdb0f594a5673a0c5a16b92dc49eb2a8a66bdaceTimo Sirainen args[c++] = talloc_asprintf(args, "--domain=%s", ad_domain);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen "talloc failed while copying arguments.\n");
10399559650f552a23949772be79eb6a80198c5aTimo Sirainen } while (c != 1); /* is is expected that the first element is NULL */
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainenstatic void ad_machine_account_password_renewal_done(struct tevent_req *subreq);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainenad_machine_account_password_renewal_timeout(struct tevent_context *ev,
37fed1bc1545f7eb1755b61d6a5ac4d083a693b3Timo Sirainenstatic struct tevent_req *
37fed1bc1545f7eb1755b61d6a5ac4d083a693b3Timo Sirainenad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx,
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen req = tevent_req_create(mem_ctx, &state, struct renewal_state);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen renewal_data = talloc_get_type(pvt, struct renewal_data);
b5052fbfdbc2678cc8f12899afe55c998f43b740Timo Sirainen state->io = talloc(state, struct child_io_fds);
f739c92a9237db03327dc82e3792e39c160a1e4dTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
f739c92a9237db03327dc82e3792e39c160a1e4dTimo Sirainen talloc_set_destructor((void *) state->io, child_io_destructor);
f739c92a9237db03327dc82e3792e39c160a1e4dTimo Sirainen server_name = be_fo_get_active_server_name(be_ctx, AD_SERVICE_NAME);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen renewal_data->extra_args[0] = talloc_asprintf(renewal_data->extra_args,
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen "--domain-controller=%s",
b5052fbfdbc2678cc8f12899afe55c998f43b740Timo Sirainen /* if talloc_asprintf() fails we let adcli try to find a server */
f739c92a9237db03327dc82e3792e39c160a1e4dTimo Sirainen "pipe failed [%d][%s].\n", ret, strerror(ret));
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen "pipe failed [%d][%s].\n", ret, strerror(ret));
3350b29fce44f8bc8fa015dad57024a8de301d38Timo Sirainen exec_child_ex(state, pipefd_to_child, pipefd_from_child,
3350b29fce44f8bc8fa015dad57024a8de301d38Timo Sirainen /* We should never get here */
3350b29fce44f8bc8fa015dad57024a8de301d38Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec renewal child\n");
bdb0f594a5673a0c5a16b92dc49eb2a8a66bdaceTimo Sirainen state->io->read_from_child_fd = pipefd_from_child[0];
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen sss_fd_nonblocking(state->io->read_from_child_fd);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen state->io->write_to_child_fd = pipefd_to_child[1];
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen sss_fd_nonblocking(state->io->write_to_child_fd);
b5052fbfdbc2678cc8f12899afe55c998f43b740Timo Sirainen /* Set up SIGCHLD handler */
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen ret = child_handler_setup(ev, child_pid, NULL, NULL, &state->child_ctx);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "Could not set up child handlers [%d]: %s\n",
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen /* Set up timeout handler */
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen tv = tevent_timeval_current_ofs(be_ptask_get_timeout(be_ptask), 0);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen state->timeout_handler = tevent_add_timer(ev, req, tv,
9c7f6dbf65ca01026e5f9c8c8b67c7e629c0b5e7Timo Sirainen subreq = read_pipe_send(state, ev, state->io->read_from_child_fd);
9c7f6dbf65ca01026e5f9c8c8b67c7e629c0b5e7Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "read_pipe_send failed.\n");
9c7f6dbf65ca01026e5f9c8c8b67c7e629c0b5e7Timo Sirainen ad_machine_account_password_renewal_done, req);
9c7f6dbf65ca01026e5f9c8c8b67c7e629c0b5e7Timo Sirainen /* Now either wait for the timeout to fire or the child
9c7f6dbf65ca01026e5f9c8c8b67c7e629c0b5e7Timo Sirainen } else { /* error */
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n",
9c7f6dbf65ca01026e5f9c8c8b67c7e629c0b5e7Timo Sirainenstatic void ad_machine_account_password_renewal_done(struct tevent_req *subreq)
8d25b6ad05b99e75613cb045a121efd51e6afbb6Timo Sirainen struct tevent_req *req = tevent_req_callback_data(subreq,
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen struct renewal_state *state = tevent_req_data(req, struct renewal_state);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen ret = read_pipe_recv(subreq, state, &buf, &buf_len);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen DEBUG(SSSDBG_TRACE_LIBS, "--- adcli output start---\n"
76b4207273534f71365bc7f900c23a5160692802Timo Sirainen "---adcli output end---\n",
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainenad_machine_account_password_renewal_timeout(struct tevent_context *ev,
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
8d25b6ad05b99e75613cb045a121efd51e6afbb6Timo Sirainen struct renewal_state *state = tevent_req_data(req, struct renewal_state);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Timeout reached for AD renewal child.\n");
055389c58fa3915e12fb4e72ec86782ce77c5c72Timo Sirainenad_machine_account_password_renewal_recv(struct tevent_req *req)
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainenerrno_t ad_machine_account_password_renewal_init(struct be_ctx *be_ctx,
8bf42ce5ef783b96a2ded67524173e95e9b45adaTimo Sirainen "The helper program ["RENEWAL_PROG_PATH"] for renewal "
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen "doesn't exist [%d]: %s\n", ret, strerror(ret));
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen DEBUG(SSSDBG_CONF_SETTINGS, "Automatic machine account renewal disabled.\n");
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen "Illegal value [%d] for password lifetime.\n", lifetime);
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen renewal_data = talloc(be_ctx, struct renewal_data);
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen ret = split_on_separator(renewal_data, dummy, ':', true, false,
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "split_on_separator failed.\n");
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Wrong number of renewal options.\n");
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen period = strtouint32(opt_list[0], &endptr, 10);
8bf42ce5ef783b96a2ded67524173e95e9b45adaTimo Sirainen if (errno != 0 || *endptr != '\0' || opt_list[0] == endptr) {
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse first renewal option.\n");
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen initial_delay = strtouint32(opt_list[1], &endptr, 10);
e5ff2112aea089f3de2badf9b1635677791d1384Timo Sirainen if (errno != 0 || *endptr != '\0' || opt_list[0] == endptr) {
e5ff2112aea089f3de2badf9b1635677791d1384Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse second renewal option.\n");
b141c303bf09b6ae43e1eb4aac1e1a6b796b9d35Timo Sirainen ret = get_adcli_extra_args(dp_opt_get_cstring(ad_opts->basic, AD_DOMAIN),
b141c303bf09b6ae43e1eb4aac1e1a6b796b9d35Timo Sirainen dp_opt_get_cstring(ad_opts->basic, AD_HOSTNAME),
b141c303bf09b6ae43e1eb4aac1e1a6b796b9d35Timo Sirainen dp_opt_get_cstring(ad_opts->id_ctx->sdap_id_ctx->opts->basic,
b141c303bf09b6ae43e1eb4aac1e1a6b796b9d35Timo Sirainen lifetime, period, initial_delay, renewal_data);
e5ff2112aea089f3de2badf9b1635677791d1384Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "get_adcli_extra_args failed.\n");
b141c303bf09b6ae43e1eb4aac1e1a6b796b9d35Timo Sirainen ret = be_ptask_create(be_ctx, be_ctx, period, initial_delay, 0, 0, 60,
e5ff2112aea089f3de2badf9b1635677791d1384Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "be_ptask_create failed.\n");