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