ad_machine_pw_renewal.c revision de8815aba87d08b6b7ac5d502dcb1755787e0857
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes/*
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes SSSD
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes Authors:
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes Sumit Bose <sbose@redhat.com>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes Copyright (C) 2016 Red Hat
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes This program is free software; you can redistribute it and/or modify
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes it under the terms of the GNU General Public License as published by
0662ed52e814f8f08ef0e09956413a792584eddffuankg the Free Software Foundation; either version 3 of the License, or
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes (at your option) any later version.
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes This program is distributed in the hope that it will be useful,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes but WITHOUT ANY WARRANTY; without even the implied warranty of
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes GNU General Public License for more details.
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
70953fb44a7140fe206c3a5f011e24209c8c5c6abnicholes You should have received a copy of the GNU General Public License
70953fb44a7140fe206c3a5f011e24209c8c5c6abnicholes along with this program. If not, see <http://www.gnu.org/licenses/>.
16b55a35cff91315d261d1baa776138af465c4e4fuankg*/
16b55a35cff91315d261d1baa776138af465c4e4fuankg
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include "util/util.h"
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include "util/strtonum.h"
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include "providers/dp_ptask.h"
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include "providers/ad/ad_common.h"
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#ifndef RENEWAL_PROG_PATH
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#define RENEWAL_PROG_PATH "/usr/sbin/adcli"
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#endif
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstruct renewal_data {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct be_ctx *be_ctx;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes char *prog_path;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char **extra_args;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes};
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic errno_t get_adcli_extra_args(const char *ad_domain,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char *ad_hostname,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char *ad_keytab,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes size_t pw_lifetime_in_days,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes size_t period,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes size_t initial_delay,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct renewal_data *renewal_data)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes{
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char **args;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes size_t c = 0;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (ad_domain == NULL || ad_hostname == NULL) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes DEBUG(SSSDBG_CRIT_FAILURE, "Missing AD domain or hostname.\n");
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return EINVAL;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes renewal_data->prog_path = talloc_strdup(renewal_data, RENEWAL_PROG_PATH);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (renewal_data->prog_path == NULL) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg return ENOMEM;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes args = talloc_array(renewal_data, const char *, 8);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (args == NULL) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return ENOMEM;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* extra_args are added in revers order */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* first add NULL as a placeholder for the server name which is determined
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * at runtime */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes args[c++] = NULL;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes args[c++] = talloc_asprintf(args, "--computer-password-lifetime=%zu",
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg pw_lifetime_in_days);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes args[c++] = talloc_asprintf(args, "--host-fqdn=%s", ad_hostname);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (ad_keytab != NULL) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes args[c++] = talloc_asprintf(args, "--host-keytab=%s", ad_keytab);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes args[c++] = talloc_asprintf(args, "--domain=%s", ad_domain);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (DEBUG_IS_SET(SSSDBG_TRACE_LIBS)) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes args[c++] = talloc_strdup(args, "--verbose");
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes args[c++] = talloc_strdup(args, "update");
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes args[c] = NULL;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes do {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (args[--c] == NULL) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes DEBUG(SSSDBG_OP_FAILURE,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "talloc failed while copying arguments.\n");
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes talloc_free(args);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return ENOMEM;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes } while (c != 1); /* is is expected that the first element is NULL */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes renewal_data->extra_args = args;
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return EOK;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes}
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstruct renewal_state {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes int child_status;
0a39e7683f6611d66c55712f50bb240428d832a1bnicholes struct sss_child_ctx_old *child_ctx;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct tevent_timer *timeout_handler;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct tevent_context *ev;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes int write_to_child_fd;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes int read_from_child_fd;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes};
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic void ad_machine_account_password_renewal_done(struct tevent_req *subreq);
ac7985784d08a3655291f24f711812b4d8b1cbcffuankgstatic void
0662ed52e814f8f08ef0e09956413a792584eddffuankgad_machine_account_password_renewal_timeout(struct tevent_context *ev,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct tevent_timer *te,
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg struct timeval tv, void *pvt);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic struct tevent_req *
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct tevent_context *ev,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct be_ctx *be_ctx,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct be_ptask *be_ptask,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes void *pvt)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes{
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct renewal_data *renewal_data;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct renewal_state *state;
0662ed52e814f8f08ef0e09956413a792584eddffuankg struct tevent_req *req;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct tevent_req *subreq;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes pid_t child_pid;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct timeval tv;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes int pipefd_to_child[2];
0662ed52e814f8f08ef0e09956413a792584eddffuankg int pipefd_from_child[2];
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes int ret;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char **extra_args;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char *server_name;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes req = tevent_req_create(mem_ctx, &state, struct renewal_state);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (req == NULL) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return NULL;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
0662ed52e814f8f08ef0e09956413a792584eddffuankg
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes renewal_data = talloc_get_type(pvt, struct renewal_data);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg state->ev = ev;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes state->child_status = EFAULT;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes state->read_from_child_fd = -1;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes state->write_to_child_fd = -1;
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes server_name = be_fo_get_active_server_name(be_ctx, AD_SERVICE_NAME);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes talloc_zfree(renewal_data->extra_args[0]);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (server_name != NULL) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes renewal_data->extra_args[0] = talloc_asprintf(renewal_data->extra_args,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "--domain-controller=%s",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes server_name);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* if talloc_asprintf() fails we let adcli try to find a server */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes extra_args = renewal_data->extra_args;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (extra_args[0] == NULL) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes extra_args = &renewal_data->extra_args[1];
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ret = pipe(pipefd_from_child);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (ret == -1) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ret = errno;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes DEBUG(SSSDBG_CRIT_FAILURE,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "pipe failed [%d][%s].\n", ret, strerror(ret));
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes goto done;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ret = pipe(pipefd_to_child);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (ret == -1) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ret = errno;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes DEBUG(SSSDBG_CRIT_FAILURE,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "pipe failed [%d][%s].\n", ret, strerror(ret));
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes goto done;
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes child_pid = fork();
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (child_pid == 0) { /* child */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes exec_child_ex(state, pipefd_to_child, pipefd_from_child,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes renewal_data->prog_path, -1,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes extra_args, true,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes STDIN_FILENO, STDERR_FILENO);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* We should never get here */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec renewal child\n");
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes } else if (child_pid > 0) { /* parent */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes state->read_from_child_fd = pipefd_from_child[0];
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes close(pipefd_from_child[1]);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes sss_fd_nonblocking(state->read_from_child_fd);
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes state->write_to_child_fd = pipefd_to_child[1];
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes close(pipefd_to_child[0]);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes sss_fd_nonblocking(state->write_to_child_fd);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* Set up SIGCHLD handler */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ret = child_handler_setup(ev, child_pid, NULL, NULL, &state->child_ctx);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (ret != EOK) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes DEBUG(SSSDBG_OP_FAILURE, "Could not set up child handlers [%d]: %s\n",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ret, sss_strerror(ret));
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ret = ERR_RENEWAL_CHILD;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes goto done;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* Set up timeout handler */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes tv = tevent_timeval_current_ofs(be_ptask_get_timeout(be_ptask), 0);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes state->timeout_handler = tevent_add_timer(ev, req, tv,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ad_machine_account_password_renewal_timeout,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes req);
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg if(state->timeout_handler == NULL) {
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg ret = ERR_RENEWAL_CHILD;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes goto done;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes subreq = read_pipe_send(state, ev, state->read_from_child_fd);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (subreq == NULL) {
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg DEBUG(SSSDBG_OP_FAILURE, "read_pipe_send failed.\n");
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg ret = ERR_RENEWAL_CHILD;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes goto done;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes tevent_req_set_callback(subreq,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ad_machine_account_password_renewal_done, req);
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* Now either wait for the timeout to fire or the child
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * to finish
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes } else { /* error */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ret = errno;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ret, sss_strerror(ret));
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes goto done;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg ret = EOK;
0662ed52e814f8f08ef0e09956413a792584eddffuankg
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesdone:
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (ret != EOK) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes tevent_req_error(req, ret);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes tevent_req_post(req, ev);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return req;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes}
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic void ad_machine_account_password_renewal_done(struct tevent_req *subreq)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes{
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes uint8_t *buf;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ssize_t buf_len;
0662ed52e814f8f08ef0e09956413a792584eddffuankg struct tevent_req *req = tevent_req_callback_data(subreq,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct tevent_req);
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg struct renewal_state *state = tevent_req_data(req, struct renewal_state);
int ret;
talloc_zfree(state->timeout_handler);
ret = read_pipe_recv(subreq, state, &buf, &buf_len);
talloc_zfree(subreq);
if (ret != EOK) {
tevent_req_error(req, ret);
return;
}
DEBUG(SSSDBG_TRACE_LIBS, "--- adcli output start---\n"
"%.*s"
"---adcli output end---\n",
(int) buf_len, buf);
close(state->read_from_child_fd);
state->read_from_child_fd = -1;
tevent_req_done(req);
return;
}
static void
ad_machine_account_password_renewal_timeout(struct tevent_context *ev,
struct tevent_timer *te,
struct timeval tv, void *pvt)
{
struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
struct renewal_state *state = tevent_req_data(req, struct renewal_state);
DEBUG(SSSDBG_CRIT_FAILURE, "Timeout reached for AD renewal child.\n");
child_handler_destroy(state->child_ctx);
state->child_ctx = NULL;
state->child_status = ETIMEDOUT;
tevent_req_error(req, ERR_RENEWAL_CHILD);
}
static errno_t
ad_machine_account_password_renewal_recv(struct tevent_req *req)
{
TEVENT_REQ_RETURN_ON_ERROR(req);
return EOK;
}
errno_t ad_machine_account_password_renewal_init(struct be_ctx *be_ctx,
struct ad_options *ad_opts)
{
int ret;
struct renewal_data *renewal_data;
int lifetime;
size_t period;
size_t initial_delay;
const char *dummy;
char **opt_list;
int opt_list_size;
char *endptr;
lifetime = dp_opt_get_int(ad_opts->basic,
AD_MAXIMUM_MACHINE_ACCOUNT_PASSWORD_AGE);
if (lifetime == 0) {
DEBUG(SSSDBG_CONF_SETTINGS, "Automatic machine account renewal disabled.\n");
return EOK;
}
if (lifetime < 0) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Illegal value [%d] for password lifetime.\n", lifetime);
return EINVAL;
}
renewal_data = talloc(be_ctx, struct renewal_data);
if (renewal_data == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "talloc failed.\n");
return ENOMEM;
}
dummy = dp_opt_get_cstring(ad_opts->basic,
AD_MACHINE_ACCOUNT_PASSWORD_RENEWAL_OPTS);
ret = split_on_separator(renewal_data, dummy, ':', true, false,
&opt_list, &opt_list_size);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "split_on_separator failed.\n");
goto done;
}
if (opt_list_size != 2) {
DEBUG(SSSDBG_CRIT_FAILURE, "Wrong number of renewal options.\n");
ret = EINVAL;
goto done;
}
errno = 0;
period = strtouint32(opt_list[0], &endptr, 10);
if (errno != 0 || *endptr != '\0' || opt_list[0] == endptr) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse first renewal option.\n");
ret = EINVAL;
goto done;
}
errno = 0;
initial_delay = strtouint32(opt_list[1], &endptr, 10);
if (errno != 0 || *endptr != '\0' || opt_list[0] == endptr) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse second renewal option.\n");
ret = EINVAL;
goto done;
}
ret = get_adcli_extra_args(dp_opt_get_cstring(ad_opts->basic, AD_DOMAIN),
dp_opt_get_cstring(ad_opts->basic, AD_HOSTNAME),
dp_opt_get_cstring(ad_opts->id_ctx->sdap_id_ctx->opts->basic,
SDAP_KRB5_KEYTAB),
lifetime, period, initial_delay, renewal_data);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "get_adcli_extra_args failed.\n");
goto done;
}
ret = be_ptask_create(be_ctx, be_ctx, period, initial_delay, 0, 0, 60,
BE_PTASK_OFFLINE_DISABLE, 0,
ad_machine_account_password_renewal_send,
ad_machine_account_password_renewal_recv,
renewal_data,
"AD machine account password renewal", NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "be_ptask_create failed.\n");
goto done;
}
ret = EOK;
done:
if (ret != EOK) {
talloc_free(renewal_data);
}
return ret;
}