sdap_sudo.c revision 7ed683eba94b5bcdc4fe3f9037d80d0fedcddfd0
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen/*
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen Authors:
2fbc2a7c65d30e46803195ebb4547176b85c22c7Timo Sirainen Pavel Březina <pbrezina@redhat.com>
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen Copyright (C) 2011 Red Hat
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
7d6389e4053c2dac1fb37180b5756b00785983dcTimo Sirainen This program is free software; you can redistribute it and/or modify
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen it under the terms of the GNU General Public License as published by
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen the Free Software Foundation; either version 3 of the License, or
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen (at your option) any later version.
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen This program is distributed in the hope that it will be useful,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen GNU General Public License for more details.
0cb57ee35d4cab9c03434d7abf312c081ed554d4Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen You should have received a copy of the GNU General Public License
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen*/
3e1ded79bbc9166aa221bcf62d8eb2bee179c557Timo Sirainen
3e1ded79bbc9166aa221bcf62d8eb2bee179c557Timo Sirainen#include <errno.h>
3e1ded79bbc9166aa221bcf62d8eb2bee179c557Timo Sirainen#include <string.h>
48559742084e98049335c21c53dfd1ff95f11cd8Timo Sirainen#include <tevent.h>
48559742084e98049335c21c53dfd1ff95f11cd8Timo Sirainen
48559742084e98049335c21c53dfd1ff95f11cd8Timo Sirainen#include "providers/dp_backend.h"
48559742084e98049335c21c53dfd1ff95f11cd8Timo Sirainen#include "providers/ldap/ldap_common.h"
48559742084e98049335c21c53dfd1ff95f11cd8Timo Sirainen#include "providers/ldap/sdap.h"
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen#include "providers/ldap/sdap_async.h"
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen#include "providers/ldap/sdap_sudo.h"
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen#include "providers/ldap/sdap_sudo_cache.h"
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen#include "db/sysdb_sudo.h"
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen#define SUDO_MAX_FIRST_REFRESH_DELAY 16
7d6389e4053c2dac1fb37180b5756b00785983dcTimo Sirainen
7d6389e4053c2dac1fb37180b5756b00785983dcTimo Sirainenstruct sdap_sudo_full_refresh_state {
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen struct sdap_sudo_ctx *sudo_ctx;
f1ddb98e6b639394ae205b305be1ddcfab102578Timo Sirainen struct sdap_id_ctx *id_ctx;
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen struct sysdb_ctx *sysdb;
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen int dp_error;
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen int error;
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen};
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainenstatic struct tevent_req *sdap_sudo_full_refresh_send(TALLOC_CTX *mem_ctx,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct sdap_sudo_ctx *sudo_ctx);
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic void sdap_sudo_full_refresh_done(struct tevent_req *subreq);
b567e0172c73dcf7642462e86962060358dd5f28Timo Sirainen
10c5fd417af4ee30b68c967f5e7d5a49f4f149b5Timo Sirainenstatic int sdap_sudo_full_refresh_recv(struct tevent_req *req,
10c5fd417af4ee30b68c967f5e7d5a49f4f149b5Timo Sirainen int *dp_error,
10c5fd417af4ee30b68c967f5e7d5a49f4f149b5Timo Sirainen int *error);
1f18053d463f0294387b5e4dd11f9010bda9a24eTimo Sirainen
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainenstruct sdap_sudo_rules_refresh_state {
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen struct sdap_id_ctx *id_ctx;
e25885d4c7c4b392c66bbf26a9b892362d90f001Timo Sirainen size_t num_rules;
e25885d4c7c4b392c66bbf26a9b892362d90f001Timo Sirainen int dp_error;
e25885d4c7c4b392c66bbf26a9b892362d90f001Timo Sirainen int error;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen};
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic struct tevent_req *sdap_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx,
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen struct sdap_sudo_ctx *sudo_ctx,
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen struct be_ctx *be_ctx,
7d6389e4053c2dac1fb37180b5756b00785983dcTimo Sirainen struct sdap_options *opts,
7d6389e4053c2dac1fb37180b5756b00785983dcTimo Sirainen struct sdap_id_conn_cache *conn_cache,
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen char **rules);
f1ddb98e6b639394ae205b305be1ddcfab102578Timo Sirainen
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainenstatic void sdap_sudo_rules_refresh_done(struct tevent_req *subreq);
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainenstatic int sdap_sudo_rules_refresh_recv(struct tevent_req *req,
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen int *dp_error,
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen int *error);
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstruct sdap_sudo_smart_refresh_state {
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen struct tevent_req *subreq;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct sdap_id_ctx *id_ctx;
b567e0172c73dcf7642462e86962060358dd5f28Timo Sirainen struct sysdb_ctx *sysdb;
5a8b0ce25f7838652b4a0cb9dab0ad19ec0fab25Timo Sirainen};
5a8b0ce25f7838652b4a0cb9dab0ad19ec0fab25Timo Sirainen
5a8b0ce25f7838652b4a0cb9dab0ad19ec0fab25Timo Sirainenstatic struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
5a8b0ce25f7838652b4a0cb9dab0ad19ec0fab25Timo Sirainen struct sdap_sudo_ctx *sudo_ctx);
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainenstatic void sdap_sudo_smart_refresh_done(struct tevent_req *subreq);
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic int sdap_sudo_smart_refresh_recv(struct tevent_req *req,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen int *dp_error,
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen int *error);
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenstatic void sdap_sudo_periodical_first_refresh_done(struct tevent_req *req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic void sdap_sudo_periodical_full_refresh_done(struct tevent_req *req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic void sdap_sudo_periodical_smart_refresh_done(struct tevent_req *req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic int sdap_sudo_schedule_refresh(TALLOC_CTX *mem_ctx,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct sdap_sudo_ctx *sudo_ctx,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen enum sdap_sudo_refresh_type refresh,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen tevent_req_fn callback,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen time_t delay,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen time_t timeout,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct tevent_req **_req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic int sdap_sudo_schedule_full_refresh(struct sdap_sudo_ctx *sudo_ctx,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen time_t delay);
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainenstatic int sdap_sudo_schedule_smart_refresh(struct sdap_sudo_ctx *sudo_ctx,
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen time_t delay);
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainenstatic void
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainensdap_sudo_shutdown(struct be_req *req)
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen{
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen sdap_handler_done(req, DP_ERR_OK, EOK, NULL);
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen}
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainenstruct bet_ops sdap_sudo_ops = {
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen .handler = sdap_sudo_handler,
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen .finalize = sdap_sudo_shutdown
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen};
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic void sdap_sudo_get_hostinfo_done(struct tevent_req *req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic int sdap_sudo_setup_periodical_refresh(struct sdap_sudo_ctx *sudo_ctx);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenint sdap_sudo_init(struct be_ctx *be_ctx,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct sdap_id_ctx *id_ctx,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct bet_ops **ops,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen void **pvt_data)
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen{
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct sdap_sudo_ctx *sudo_ctx = NULL;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct tevent_req *req = NULL;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen int ret;
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen DEBUG(SSSDBG_TRACE_INTERNAL, ("Initializing sudo LDAP back end\n"));
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sudo_ctx = talloc_zero(be_ctx, struct sdap_sudo_ctx);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen if (sudo_ctx == NULL) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("talloc() failed\n"));
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen return ENOMEM;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen }
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sudo_ctx->id_ctx = id_ctx;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen *ops = &sdap_sudo_ops;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen *pvt_data = sudo_ctx;
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen /* we didn't do any full refresh now,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen * so we don't have current usn values available */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sudo_ctx->full_refresh_done = false;
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen ret = ldap_get_sudo_options(id_ctx, be_ctx->cdb,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen be_ctx->conf_path, id_ctx->opts,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen &sudo_ctx->use_host_filter,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen &sudo_ctx->include_regexp,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen &sudo_ctx->include_netgroups);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen if (ret != EOK) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("Cannot get SUDO options [%d]: %s\n",
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen ret, strerror(ret)));
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen return ret;
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen }
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen req = sdap_sudo_get_hostinfo_send(sudo_ctx, id_ctx->opts, be_ctx);
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen if (req == NULL) {
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to retrieve host information - "
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen "(host filter will be disabled)\n"));
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen sudo_ctx->use_host_filter = false;
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen ret = sdap_sudo_setup_periodical_refresh(sudo_ctx);
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen if (ret != EOK) {
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen DEBUG(SSSDBG_OP_FAILURE,
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen ("Unable to setup periodical refresh"
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen "of sudo rules [%d]: %s\n", ret, strerror(ret)));
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen /* periodical updates will not work, but specific-rule update
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen * is no affected by this, therefore we don't have to fail here */
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen }
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen } else {
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen tevent_req_set_callback(req, sdap_sudo_get_hostinfo_done, sudo_ctx);
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen }
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen return EOK;
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen}
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainenstatic void sdap_sudo_get_hostinfo_done(struct tevent_req *req)
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen{
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen struct sdap_sudo_ctx *sudo_ctx = NULL;
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen char **hostnames = NULL;
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen char **ip_addr = NULL;
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen int ret;
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen sudo_ctx = tevent_req_callback_data(req, struct sdap_sudo_ctx);
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen ret = sdap_sudo_get_hostinfo_recv(sudo_ctx, req, &hostnames, &ip_addr);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen talloc_zfree(req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen if (ret != EOK) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to retrieve host information - "
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen "(host filter will be disabled) [%d]: %s\n", ret, strerror(ret)));
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sudo_ctx->use_host_filter = false;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen return;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen }
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen talloc_zfree(sudo_ctx->hostnames);
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen talloc_zfree(sudo_ctx->ip_addr);
7d6389e4053c2dac1fb37180b5756b00785983dcTimo Sirainen
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen sudo_ctx->hostnames = talloc_move(sudo_ctx, &hostnames);
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen sudo_ctx->ip_addr = talloc_move(sudo_ctx, &ip_addr);
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen ret = sdap_sudo_setup_periodical_refresh(sudo_ctx);
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen if (ret != EOK) {
7d6389e4053c2dac1fb37180b5756b00785983dcTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("Unable to setup periodical refresh"
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen "of sudo rules [%d]: %s\n", ret, strerror(ret)));
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen }
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen}
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainenstatic int sdap_sudo_setup_periodical_refresh(struct sdap_sudo_ctx *sudo_ctx)
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen{
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen time_t smart_default;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen time_t smart_interval;
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen time_t full_interval;
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen time_t last_full;
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen time_t delay;
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen int ret;
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen smart_interval = dp_opt_get_int(id_ctx->opts->basic,
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen SDAP_SUDO_SMART_REFRESH_INTERVAL);
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen full_interval = dp_opt_get_int(id_ctx->opts->basic,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen SDAP_SUDO_FULL_REFRESH_INTERVAL);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen if (smart_interval == 0 && full_interval == 0) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen smart_default = id_ctx->opts->basic[SDAP_SUDO_SMART_REFRESH_INTERVAL].def_val.number;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen DEBUG(SSSDBG_MINOR_FAILURE, ("At least one periodical update has to be "
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen "enabled. Setting smart refresh interval to default value (%d).\n",
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen smart_default));
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen ret = dp_opt_set_int(id_ctx->opts->basic,
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen SDAP_SUDO_SMART_REFRESH_INTERVAL,
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen smart_default);
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen if (ret != EOK) {
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen return ret;
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen }
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen }
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen if (full_interval <= smart_interval) {
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen DEBUG(SSSDBG_MINOR_FAILURE, ("Full refresh interval has to be greater"
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen "than smart refresh interval. Periodical full refresh will be "
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen "disabled.\n"));
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen ret = dp_opt_set_int(id_ctx->opts->basic,
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen SDAP_SUDO_FULL_REFRESH_INTERVAL,
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen 0);
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen if (ret != EOK) {
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen return ret;
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen }
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen }
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen ret = sysdb_sudo_get_last_full_refresh(id_ctx->be->sysdb, &last_full);
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen if (ret != EOK) {
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen return ret;
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen }
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen if (last_full == 0) {
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen /* If this is the first startup, we need to kick off
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen * an refresh immediately, to close a window where
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen * clients requesting sudo information won't get an
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen * immediate reply with no entries
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen delay = 0;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen } else {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* At least one update has previously run,
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen * so clients will get cached data.
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen * We will delay the refresh so we don't slow
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen * down the startup process if this is happening
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen * during system boot.
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen /* delay at least by 10s */
48559742084e98049335c21c53dfd1ff95f11cd8Timo Sirainen delay = 10;
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen }
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen
48559742084e98049335c21c53dfd1ff95f11cd8Timo Sirainen ret = sdap_sudo_schedule_refresh(sudo_ctx, sudo_ctx,
48559742084e98049335c21c53dfd1ff95f11cd8Timo Sirainen SDAP_SUDO_REFRESH_FULL,
48559742084e98049335c21c53dfd1ff95f11cd8Timo Sirainen sdap_sudo_periodical_first_refresh_done,
48559742084e98049335c21c53dfd1ff95f11cd8Timo Sirainen delay, full_interval, NULL);
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen if (ret != EOK) {
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("Unable to schedule full refresh of sudo "
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen "rules! Periodical updates will not work!\n"));
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen return ret;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen }
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen return EOK;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen}
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, char *usn)
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen{
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen unsigned int usn_number;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen char *endptr = NULL;
b567e0172c73dcf7642462e86962060358dd5f28Timo Sirainen
b567e0172c73dcf7642462e86962060358dd5f28Timo Sirainen if (srv_opts != NULL && usn != NULL) {
b567e0172c73dcf7642462e86962060358dd5f28Timo Sirainen talloc_zfree(srv_opts->max_sudo_value);
b567e0172c73dcf7642462e86962060358dd5f28Timo Sirainen srv_opts->max_sudo_value = talloc_steal(srv_opts, usn);
b567e0172c73dcf7642462e86962060358dd5f28Timo Sirainen
b567e0172c73dcf7642462e86962060358dd5f28Timo Sirainen usn_number = strtoul(usn, &endptr, 10);
b567e0172c73dcf7642462e86962060358dd5f28Timo Sirainen if ((endptr == NULL || (*endptr == '\0' && endptr != usn))
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen && (usn_number > srv_opts->last_usn)) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen srv_opts->last_usn = usn_number;
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen }
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen DEBUG(SSSDBG_FUNC_DATA, ("SUDO higher USN value: [%s]\n",
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen srv_opts->max_sudo_value));
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen } else {
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen DEBUG(SSSDBG_TRACE_FUNC, ("srv_opts is NULL\n"));
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen }
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen}
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainenstatic char *sdap_sudo_build_host_filter(TALLOC_CTX *mem_ctx,
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen struct sdap_attr_map *map,
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen char **hostnames,
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen char **ip_addr,
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen bool netgroups,
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen bool regexp)
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen{
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen TALLOC_CTX *tmp_ctx = NULL;
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen char *filter = NULL;
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen int i;
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen tmp_ctx = talloc_new(NULL);
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen if (tmp_ctx == NULL) {
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen return NULL;
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen }
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainen
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen filter = talloc_strdup(tmp_ctx, "(|");
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen if (filter == NULL) {
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen goto done;
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen }
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen /* sudoHost is not specified */
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen filter = talloc_asprintf_append_buffer(filter, "(!(%s=*))",
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen map[SDAP_AT_SUDO_HOST].name);
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen if (filter == NULL) {
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen goto done;
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen }
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen /* ALL */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen filter = talloc_asprintf_append_buffer(filter, "(%s=ALL)",
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen map[SDAP_AT_SUDO_HOST].name);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen if (filter == NULL) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen goto done;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen }
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* hostnames */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen if (hostnames != NULL) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen for (i = 0; hostnames[i] != NULL; i++) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen filter = talloc_asprintf_append_buffer(filter, "(%s=%s)",
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen map[SDAP_AT_SUDO_HOST].name,
7d6389e4053c2dac1fb37180b5756b00785983dcTimo Sirainen hostnames[i]);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen if (filter == NULL) {
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen goto done;
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen }
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen }
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen }
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* ip addresses and networks */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen if (ip_addr != NULL) {
095034a7699bfc464a07883f633551b5c313c4e7Timo Sirainen for (i = 0; ip_addr[i] != NULL; i++) {
9e7182d6fa1940ec14cc2938699820b68ee1dc0dTimo Sirainen filter = talloc_asprintf_append_buffer(filter, "(%s=%s)",
9e7182d6fa1940ec14cc2938699820b68ee1dc0dTimo Sirainen map[SDAP_AT_SUDO_HOST].name,
095034a7699bfc464a07883f633551b5c313c4e7Timo Sirainen ip_addr[i]);
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen if (filter == NULL) {
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen goto done;
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen }
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen }
095034a7699bfc464a07883f633551b5c313c4e7Timo Sirainen }
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen /* sudoHost contains netgroup - will be filtered more by sudo */
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen if (netgroups) {
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen filter = talloc_asprintf_append_buffer(filter, SDAP_SUDO_FILTER_NETGROUP,
9e7182d6fa1940ec14cc2938699820b68ee1dc0dTimo Sirainen map[SDAP_AT_SUDO_HOST].name,
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen "*");
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen if (filter == NULL) {
ebfcfd258acc89633c47d9c3b0b40a1a3f75cdcbTimo Sirainen goto done;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen }
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* sudoHost contains regexp - will be filtered more by sudo */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* from sudo match.c :
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen * #define has_meta(s) (strpbrk(s, "\\?*[]") != NULL)
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen if (regexp) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen filter = talloc_asprintf_append_buffer(filter,
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen "(|(%s=*\\\\*)(%s=*?*)(%s=*\\**)"
0d7d27765267594a5870892268ab345148306d49Timo Sirainen "(%s=*[*]*))",
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen map[SDAP_AT_SUDO_HOST].name,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen map[SDAP_AT_SUDO_HOST].name,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen map[SDAP_AT_SUDO_HOST].name,
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen map[SDAP_AT_SUDO_HOST].name);
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen if (filter == NULL) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen goto done;
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen }
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen }
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen filter = talloc_strdup_append_buffer(filter, ")");
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen if (filter == NULL) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen goto done;
0e90e1b11b699166a4a4c5e01d132a28c3e26affTimo Sirainen }
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen
0d7d27765267594a5870892268ab345148306d49Timo Sirainen talloc_steal(mem_ctx, filter);
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainendone:
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen talloc_free(tmp_ctx);
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen return filter;
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen}
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainenstatic char *sdap_sudo_get_filter(TALLOC_CTX *mem_ctx,
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen struct sdap_attr_map *map,
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen struct sdap_sudo_ctx *sudo_ctx,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen const char *rule_filter)
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen{
0d7d27765267594a5870892268ab345148306d49Timo Sirainen TALLOC_CTX *tmp_ctx = NULL;
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen char *host_filter = NULL;
0d7d27765267594a5870892268ab345148306d49Timo Sirainen char *filter = NULL;
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen if (!sudo_ctx->use_host_filter) {
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen return talloc_strdup(mem_ctx, rule_filter);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen }
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen tmp_ctx = talloc_new(NULL);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen if (tmp_ctx == NULL) {
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen return NULL;
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen }
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen host_filter = sdap_sudo_build_host_filter(tmp_ctx, map,
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen sudo_ctx->hostnames,
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen sudo_ctx->ip_addr,
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen sudo_ctx->include_netgroups,
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen sudo_ctx->include_regexp);
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen if (host_filter == NULL) {
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen goto done;
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen }
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen filter = sdap_get_id_specific_filter(tmp_ctx, rule_filter, host_filter);
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen if (filter == NULL) {
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen goto done;
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen }
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen talloc_steal(mem_ctx, filter);
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainendone:
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen talloc_free(tmp_ctx);
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen return filter;
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen}
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainenstatic void sdap_sudo_reply(struct tevent_req *req)
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen{
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen struct be_req *be_req = NULL;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct be_sudo_req *sudo_req = NULL;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen int dp_error = DP_ERR_OK;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen int error = EOK;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen int ret;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen be_req = tevent_req_callback_data(req, struct be_req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sudo_req = talloc_get_type(be_req->req_data, struct be_sudo_req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen switch (sudo_req->type) {
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen case BE_REQ_SUDO_FULL:
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen ret = sdap_sudo_full_refresh_recv(req, &dp_error, &error);
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen break;
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen case BE_REQ_SUDO_RULES:
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen ret = sdap_sudo_rules_refresh_recv(req, &dp_error, &error);
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen break;
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen default:
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid request type: %d\n",
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen sudo_req->type));
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen ret = EINVAL;
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen }
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen talloc_zfree(req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen if (ret != EOK) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sdap_handler_done(be_req, DP_ERR_FATAL, ret, strerror(ret));
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen return;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen }
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen sdap_handler_done(be_req, dp_error, error, strerror(error));
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen}
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen
c4457e497e01b57565d24da624968699b166e02aTimo Sirainenvoid sdap_sudo_handler(struct be_req *be_req)
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen{
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen struct tevent_req *req = NULL;
2e1e493b248dec0127b1eabeea5a8bc330378fcdTimo Sirainen struct be_sudo_req *sudo_req = NULL;
2e1e493b248dec0127b1eabeea5a8bc330378fcdTimo Sirainen struct sdap_sudo_ctx *sudo_ctx = NULL;
2e1e493b248dec0127b1eabeea5a8bc330378fcdTimo Sirainen struct sdap_id_ctx *id_ctx = NULL;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen int ret = EOK;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sudo_ctx = talloc_get_type(be_req->be_ctx->bet_info[BET_SUDO].pvt_bet_data,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct sdap_sudo_ctx);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen id_ctx = sudo_ctx->id_ctx;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sudo_req = talloc_get_type(be_req->req_data, struct be_sudo_req);
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen switch (sudo_req->type) {
0cb57ee35d4cab9c03434d7abf312c081ed554d4Timo Sirainen case BE_REQ_SUDO_FULL:
0cb57ee35d4cab9c03434d7abf312c081ed554d4Timo Sirainen DEBUG(SSSDBG_TRACE_FUNC, ("Issuing a full refresh of sudo rules\n"));
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen req = sdap_sudo_full_refresh_send(be_req, sudo_ctx);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen break;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen case BE_REQ_SUDO_RULES:
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen DEBUG(SSSDBG_TRACE_FUNC, ("Issuing a refresh of specific sudo rules\n"));
b1504ccfa93e77d906e39e6aa31a592d69f6b5b4Timo Sirainen req = sdap_sudo_rules_refresh_send(be_req, sudo_ctx, id_ctx->be,
b1504ccfa93e77d906e39e6aa31a592d69f6b5b4Timo Sirainen id_ctx->opts, id_ctx->conn_cache,
b1504ccfa93e77d906e39e6aa31a592d69f6b5b4Timo Sirainen sudo_req->rules);
3c9e09fa412f62259e3a10bfe9ac6afb1becc2f0Timo Sirainen break;
b1504ccfa93e77d906e39e6aa31a592d69f6b5b4Timo Sirainen default:
b1504ccfa93e77d906e39e6aa31a592d69f6b5b4Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid request type: %d\n",
b1504ccfa93e77d906e39e6aa31a592d69f6b5b4Timo Sirainen sudo_req->type));
b1504ccfa93e77d906e39e6aa31a592d69f6b5b4Timo Sirainen ret = EINVAL;
b1504ccfa93e77d906e39e6aa31a592d69f6b5b4Timo Sirainen goto fail;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen }
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen if (req == NULL) {
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to send request: %d\n",
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen sudo_req->type));
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen ret = ENOMEM;
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen goto fail;
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen }
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen tevent_req_set_callback(req, sdap_sudo_reply, be_req);
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen return;
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainenfail:
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen sdap_handler_done(be_req, DP_ERR_FATAL, ret, NULL);
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen}
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen/* issue full refresh of sudo rules */
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainenstatic struct tevent_req *sdap_sudo_full_refresh_send(TALLOC_CTX *mem_ctx,
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen struct sdap_sudo_ctx *sudo_ctx)
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen{
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen struct tevent_req *req = NULL;
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen struct tevent_req *subreq = NULL;
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct sdap_sudo_full_refresh_state *state = NULL;
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen char *ldap_filter = NULL;
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen char *ldap_full_filter = NULL;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen char *sysdb_filter = NULL;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen int ret;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_full_refresh_state);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen if (req == NULL) {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen return NULL;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen sudo_ctx->full_refresh_in_progress = true;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen state->sudo_ctx = sudo_ctx;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen state->id_ctx = id_ctx;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen state->sysdb = id_ctx->be->sysdb;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen /* Download all rules from LDAP */
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen ldap_filter = talloc_asprintf(state, SDAP_SUDO_FILTER_CLASS,
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen id_ctx->opts->sudorule_map[SDAP_OC_SUDORULE].name);
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen if (ldap_filter == NULL) {
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen ret = ENOMEM;
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen goto immediately;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen }
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
0d7d27765267594a5870892268ab345148306d49Timo Sirainen ldap_full_filter = sdap_sudo_get_filter(state, id_ctx->opts->sudorule_map,
0d7d27765267594a5870892268ab345148306d49Timo Sirainen sudo_ctx, ldap_filter);
0d7d27765267594a5870892268ab345148306d49Timo Sirainen if (ldap_full_filter == NULL) {
0d7d27765267594a5870892268ab345148306d49Timo Sirainen ret = ENOMEM;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen goto immediately;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen }
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* Remove all rules from cache */
sysdb_filter = talloc_asprintf(state, "(%s=%s)",
SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC);
if (sysdb_filter == NULL) {
ret = ENOMEM;
goto immediately;
}
DEBUG(SSSDBG_TRACE_FUNC, ("Issuing a full refresh of sudo rules\n"));
subreq = sdap_sudo_refresh_send(state, id_ctx->be, id_ctx->opts,
id_ctx->conn_cache,
ldap_full_filter, sysdb_filter);
if (subreq == NULL) {
ret = ENOMEM;
goto immediately;
}
tevent_req_set_callback(subreq, sdap_sudo_full_refresh_done, req);
/* free filters */
talloc_free(ldap_filter);
talloc_free(ldap_full_filter);
talloc_free(sysdb_filter);
return req;
immediately:
if (ret == EOK) {
tevent_req_done(req);
} else {
tevent_req_error(req, ret);
}
tevent_req_post(req, id_ctx->be->ev);
return req;
}
static void sdap_sudo_full_refresh_done(struct tevent_req *subreq)
{
struct tevent_req *req = NULL;
struct sdap_sudo_full_refresh_state *state = NULL;
char *highest_usn = NULL;
int ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_sudo_full_refresh_state);
ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error,
&state->error, &highest_usn, NULL);
talloc_zfree(subreq);
if (ret != EOK || state->dp_error != DP_ERR_OK || state->error != EOK) {
goto done;
}
state->sudo_ctx->full_refresh_done = true;
/* save the time in the sysdb */
ret = sysdb_sudo_set_last_full_refresh(state->sysdb, time(NULL));
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Unable to save time of "
"a successful full refresh\n"));
/* this is only a minor error that does not affect the functionality,
* therefore there is no need to report it with tevent_req_error()
* which would cause problems in the consumers */
}
DEBUG(SSSDBG_TRACE_FUNC, ("Successful full refresh of sudo rules\n"));
/* set highest usn */
if (highest_usn != NULL) {
sdap_sudo_set_usn(state->id_ctx->srv_opts, highest_usn);
}
done:
state->sudo_ctx->full_refresh_in_progress = false;
if (ret != EOK) {
tevent_req_error(req, ret);
return;
}
tevent_req_done(req);
}
static int sdap_sudo_full_refresh_recv(struct tevent_req *req,
int *dp_error,
int *error)
{
struct sdap_sudo_full_refresh_state *state = NULL;
state = tevent_req_data(req, struct sdap_sudo_full_refresh_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
*dp_error = state->dp_error;
*error = state->error;
return EOK;
}
/* issue refresh of specific sudo rules */
static struct tevent_req *sdap_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx,
struct sdap_sudo_ctx *sudo_ctx,
struct be_ctx *be_ctx,
struct sdap_options *opts,
struct sdap_id_conn_cache *conn_cache,
char **rules)
{
struct tevent_req *req = NULL;
struct tevent_req *subreq = NULL;
struct sdap_sudo_rules_refresh_state *state = NULL;
TALLOC_CTX *tmp_ctx = NULL;
char *ldap_filter = NULL;
char *ldap_full_filter = NULL;
char *sysdb_filter = NULL;
char *safe_rule = NULL;
int ret;
int i;
if (rules == NULL) {
return NULL;
}
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
return NULL;
}
req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_rules_refresh_state);
if (req == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
return NULL;
}
ldap_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */
sysdb_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */
/* Download only selected rules from LDAP */
/* Remove all selected rules from cache */
for (i = 0; rules[i] != NULL; i++) {
ret = sss_filter_sanitize(tmp_ctx, rules[i], &safe_rule);
if (ret != EOK) {
ret = ENOMEM;
goto immediately;
}
ldap_filter = talloc_asprintf_append_buffer(ldap_filter, "(%s=%s)",
opts->sudorule_map[SDAP_AT_SUDO_NAME].name,
safe_rule);
if (ldap_filter == NULL) {
ret = ENOMEM;
goto immediately;
}
sysdb_filter = talloc_asprintf_append_buffer(sysdb_filter, "(%s=%s)",
SYSDB_SUDO_CACHE_AT_CN,
safe_rule);
if (sysdb_filter == NULL) {
ret = ENOMEM;
goto immediately;
}
}
state->id_ctx = sudo_ctx->id_ctx;
state->num_rules = i;
ldap_filter = talloc_asprintf(tmp_ctx, "(&"SDAP_SUDO_FILTER_CLASS"(|%s))",
opts->sudorule_map[SDAP_OC_SUDORULE].name,
ldap_filter);
if (ldap_filter == NULL) {
ret = ENOMEM;
goto immediately;
}
ldap_full_filter = sdap_sudo_get_filter(tmp_ctx, opts->sudorule_map,
sudo_ctx, ldap_filter);
if (ldap_full_filter == NULL) {
ret = ENOMEM;
goto immediately;
}
sysdb_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(|%s))",
SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC,
sysdb_filter);
if (sysdb_filter == NULL) {
ret = ENOMEM;
goto immediately;
}
subreq = sdap_sudo_refresh_send(req, be_ctx, opts, conn_cache,
ldap_full_filter, sysdb_filter);
if (subreq == NULL) {
ret = ENOMEM;
goto immediately;
}
tevent_req_set_callback(subreq, sdap_sudo_rules_refresh_done, req);
ret = EOK;
immediately:
talloc_free(tmp_ctx);
if (ret != EOK) {
tevent_req_error(req, ret);
tevent_req_post(req, be_ctx->ev);
}
return req;
}
static void sdap_sudo_rules_refresh_done(struct tevent_req *subreq)
{
struct tevent_req *req = NULL;
struct sdap_sudo_rules_refresh_state *state = NULL;
char *highest_usn = NULL;
size_t downloaded_rules_num;
int ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_sudo_rules_refresh_state);
ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error, &state->error,
&highest_usn, &downloaded_rules_num);
talloc_zfree(subreq);
if (ret != EOK || state->dp_error != DP_ERR_OK || state->error != EOK) {
goto done;
}
/* set highest usn */
if (highest_usn != NULL) {
sdap_sudo_set_usn(state->id_ctx->srv_opts, highest_usn);
}
if (downloaded_rules_num != state->num_rules) {
state->error = ENOENT;
}
done:
if (ret != EOK) {
tevent_req_error(req, ret);
return;
}
tevent_req_done(req);
}
static int sdap_sudo_rules_refresh_recv(struct tevent_req *req,
int *dp_error,
int *error)
{
struct sdap_sudo_rules_refresh_state *state = NULL;
state = tevent_req_data(req, struct sdap_sudo_rules_refresh_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
*dp_error = state->dp_error;
*error = state->error;
return EOK;
}
/* issue smart refresh of sudo rules */
static struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
struct sdap_sudo_ctx *sudo_ctx)
{
struct tevent_req *req = NULL;
struct tevent_req *subreq = NULL;
struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx;
struct sdap_attr_map *map = id_ctx->opts->sudorule_map;
struct sdap_server_opts *srv_opts = id_ctx->srv_opts;
struct sdap_sudo_smart_refresh_state *state = NULL;
char *ldap_filter = NULL;
char *ldap_full_filter = NULL;
const char *usn;
int ret;
req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_smart_refresh_state);
if (req == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
return NULL;
}
if (!sudo_ctx->full_refresh_done
&& (srv_opts == NULL || srv_opts->max_sudo_value == 0)) {
/* Perform full refresh first */
DEBUG(SSSDBG_TRACE_FUNC, ("USN value is unknown, "
"waiting for full refresh!\n"));
ret = EINVAL;
goto immediately;
}
state->id_ctx = id_ctx;
state->sysdb = id_ctx->be->sysdb;
/* Download all rules from LDAP that are newer than usn */
usn = srv_opts->max_sudo_value;
if (usn != NULL) {
ldap_filter = talloc_asprintf(state,
"(&(objectclass=%s)(%s>=%s)(!(%s=%s)))",
map[SDAP_OC_SUDORULE].name,
map[SDAP_AT_SUDO_USN].name, usn,
map[SDAP_AT_SUDO_USN].name, usn);
} else {
/* no valid USN value known */
ldap_filter = talloc_asprintf(state, SDAP_SUDO_FILTER_CLASS,
map[SDAP_OC_SUDORULE].name);
}
if (ldap_filter == NULL) {
ret = ENOMEM;
goto immediately;
}
ldap_full_filter = sdap_sudo_get_filter(state, map, sudo_ctx, ldap_filter);
if (ldap_full_filter == NULL) {
ret = ENOMEM;
goto immediately;
}
/* Do not remove any rules that are already in the sysdb
* sysdb_filter = NULL; */
DEBUG(SSSDBG_TRACE_FUNC, ("Issuing a smart refresh of sudo rules "
"(USN > %s)\n", (usn == NULL ? "0" : usn)));
subreq = sdap_sudo_refresh_send(state, id_ctx->be, id_ctx->opts,
id_ctx->conn_cache,
ldap_full_filter, NULL);
if (subreq == NULL) {
ret = ENOMEM;
goto immediately;
}
state->subreq = subreq;
tevent_req_set_callback(subreq, sdap_sudo_smart_refresh_done, req);
/* free filters */
talloc_free(ldap_filter);
talloc_free(ldap_full_filter);
return req;
immediately:
if (ret == EOK) {
tevent_req_done(req);
} else {
tevent_req_error(req, ret);
}
tevent_req_post(req, id_ctx->be->ev);
return req;
}
static void sdap_sudo_smart_refresh_done(struct tevent_req *subreq)
{
struct tevent_req *req = NULL;
struct sdap_sudo_smart_refresh_state *state = NULL;
char *highest_usn = NULL;
int dp_error;
int error;
int ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_sudo_smart_refresh_state);
ret = sdap_sudo_refresh_recv(state, subreq, &dp_error, &error,
&highest_usn, NULL);
if (ret != EOK || dp_error != DP_ERR_OK || error != EOK) {
goto done;
}
DEBUG(SSSDBG_TRACE_FUNC, ("Successful smart refresh of sudo rules\n"));
/* set highest usn */
if (highest_usn != NULL) {
sdap_sudo_set_usn(state->id_ctx->srv_opts, highest_usn);
}
done:
if (ret != EOK) {
tevent_req_error(req, ret);
return;
}
tevent_req_done(req);
}
static int sdap_sudo_smart_refresh_recv(struct tevent_req *req,
int *dp_error,
int *error)
{
struct sdap_sudo_smart_refresh_state *state = NULL;
state = tevent_req_data(req, struct sdap_sudo_smart_refresh_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
return sdap_sudo_refresh_recv(state, state->subreq, dp_error, error,
NULL, NULL);
}
static void sdap_sudo_full_refresh_online_cb(void *pvt)
{
struct sdap_sudo_ctx *sudo_ctx = NULL;
time_t timeout;
int ret;
sudo_ctx = talloc_get_type(pvt, struct sdap_sudo_ctx);
/* remove online callback */
talloc_zfree(sudo_ctx->first_refresh_online_cb);
/* schedule new first refresh only if this callback wasn't triggered
* by ongoing full refresh */
if (sudo_ctx->full_refresh_in_progress) {
return;
}
/* otherwise cancel the concurrent timer for full refresh */
talloc_zfree(sudo_ctx->first_refresh_timer);
/* and fire full refresh immediately */
timeout = dp_opt_get_int(sudo_ctx->id_ctx->opts->basic,
SDAP_SUDO_FULL_REFRESH_INTERVAL);
if (timeout == 0) {
/* runtime configuration change? */
DEBUG(SSSDBG_TRACE_FUNC, ("Periodical full refresh of sudo rules "
"is disabled\n"));
return;
}
ret = sdap_sudo_schedule_refresh(sudo_ctx, sudo_ctx,
SDAP_SUDO_REFRESH_FULL,
sdap_sudo_periodical_first_refresh_done,
0, timeout, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Unable to schedule full refresh of sudo "
"rules! Periodical updates will not work!\n"));
}
}
static void sdap_sudo_periodical_first_refresh_done(struct tevent_req *req)
{
struct tevent_req *subreq = NULL; /* req from sdap_sudo_full_refresh_send() */
struct sdap_sudo_ctx *sudo_ctx = NULL;
time_t delay;
time_t timeout;
int dp_error = DP_ERR_OK;
int error = EOK;
int ret;
ret = sdap_sudo_timer_recv(req, req, &subreq);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
("Sudo timer failed [%d]: %s\n", ret, strerror(ret)));
goto schedule;
}
ret = sdap_sudo_full_refresh_recv(subreq, &dp_error, &error);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Periodical full refresh of sudo rules "
"failed [%d]: %s)\n", ret, strerror(ret)));
goto schedule;
}
if (dp_error != DP_ERR_OK || error != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Periodical full refresh of sudo rules "
"failed [dp_error: %d] ([%d]: %s)\n",
dp_error, error, strerror(error)));
goto schedule;
}
schedule:
sudo_ctx = tevent_req_callback_data(req, struct sdap_sudo_ctx);
if (sudo_ctx->first_refresh_timer == req) {
sudo_ctx->first_refresh_timer = NULL;
}
talloc_zfree(req);
/* full refresh */
delay = dp_opt_get_int(sudo_ctx->id_ctx->opts->basic,
SDAP_SUDO_FULL_REFRESH_INTERVAL);
if (delay == 0) {
/* runtime configuration change? */
DEBUG(SSSDBG_TRACE_FUNC, ("Periodical full refresh of sudo rules "
"is disabled\n"));
return;
}
/* if we are offline, we will try to perform another full refresh */
if (dp_error == DP_ERR_OFFLINE) {
sudo_ctx->full_refresh_attempts++;
timeout = delay;
delay = sudo_ctx->full_refresh_attempts << 1;
if (delay > SUDO_MAX_FIRST_REFRESH_DELAY) {
delay = SUDO_MAX_FIRST_REFRESH_DELAY;
}
DEBUG(SSSDBG_TRACE_FUNC, ("Data provider is offline. "
"Scheduling another full refresh in %lld minutes.\n", delay));
ret = sdap_sudo_schedule_refresh(sudo_ctx, sudo_ctx,
SDAP_SUDO_REFRESH_FULL,
sdap_sudo_periodical_first_refresh_done,
delay * 60, timeout,
&sudo_ctx->first_refresh_timer);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Unable to schedule full refresh of sudo "
"rules! Periodical updates will not work!\n"));
}
/* also setup online callback to make sure the refresh is fired as soon
* as possible */
ret = be_add_online_cb(sudo_ctx->id_ctx->be, sudo_ctx->id_ctx->be,
sdap_sudo_full_refresh_online_cb,
sudo_ctx, &sudo_ctx->first_refresh_online_cb);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Could not set up online callback\n"));
}
return;
}
ret = sdap_sudo_schedule_full_refresh(sudo_ctx, delay);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Full periodical refresh will not work.\n"));
}
/* smart refresh */
delay = dp_opt_get_int(sudo_ctx->id_ctx->opts->basic,
SDAP_SUDO_SMART_REFRESH_INTERVAL);
if (delay == 0) {
/* runtime configuration change? */
DEBUG(SSSDBG_TRACE_FUNC, ("Periodical smart refresh of sudo rules "
"is disabled\n"));
return;
}
ret = sdap_sudo_schedule_smart_refresh(sudo_ctx, delay);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Smart periodical refresh will not work.\n"));
}
}
static void sdap_sudo_periodical_full_refresh_done(struct tevent_req *req)
{
struct tevent_req *subreq = NULL; /* req from sdap_sudo_full_refresh_send() */
struct sdap_sudo_ctx *sudo_ctx = NULL;
time_t delay;
int dp_error = DP_ERR_FATAL;
int error = EFAULT;
int ret;
ret = sdap_sudo_timer_recv(req, req, &subreq);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
("Sudo timer failed [%d]: %s\n", ret, strerror(ret)));
goto schedule;
}
ret = sdap_sudo_full_refresh_recv(subreq, &dp_error, &error);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Periodical full refresh of sudo rules "
"failed [%d]: %s)\n", ret, strerror(ret)));
goto schedule;
}
if (dp_error != DP_ERR_OK || error != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Periodical full refresh of sudo rules "
"failed [dp_error: %d] ([%d]: %s)\n",
dp_error, error, strerror(error)));
goto schedule;
}
schedule:
sudo_ctx = tevent_req_callback_data(req, struct sdap_sudo_ctx);
talloc_zfree(req);
delay = dp_opt_get_int(sudo_ctx->id_ctx->opts->basic,
SDAP_SUDO_FULL_REFRESH_INTERVAL);
if (delay == 0) {
/* runtime configuration change? */
DEBUG(SSSDBG_TRACE_FUNC, ("Periodical full refresh of sudo rules "
"is disabled\n"));
return;
}
ret = sdap_sudo_schedule_full_refresh(sudo_ctx, delay);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Full periodical refresh will not work.\n"));
}
}
static void sdap_sudo_periodical_smart_refresh_done(struct tevent_req *req)
{
struct tevent_req *subreq = NULL; /* req from sdap_sudo_smart_refresh_send() */
struct sdap_sudo_ctx *sudo_ctx = NULL;
time_t delay;
int dp_error;
int error;
int ret;
ret = sdap_sudo_timer_recv(req, req, &subreq);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
("Sudo timer failed [%d]: %s\n", ret, strerror(ret)));
goto schedule;
}
ret = sdap_sudo_smart_refresh_recv(subreq, &dp_error, &error);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Periodical smart refresh of sudo rules "
"failed [%d]: %s\n", ret, strerror(ret)));
}
if (dp_error != DP_ERR_OK || error != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Periodical smart refresh of sudo rules "
"failed [dp_error: %d] ([%d]: %s)\n",
dp_error, error, strerror(error)));
goto schedule;
}
schedule:
sudo_ctx = tevent_req_callback_data(req, struct sdap_sudo_ctx);
talloc_zfree(req);
delay = dp_opt_get_int(sudo_ctx->id_ctx->opts->basic,
SDAP_SUDO_SMART_REFRESH_INTERVAL);
if (delay == 0) {
/* runtime configuration change? */
DEBUG(SSSDBG_TRACE_FUNC, ("Periodical smart refresh of sudo rules "
"is disabled\n"));
return;
}
ret = sdap_sudo_schedule_smart_refresh(sudo_ctx, delay);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Smart periodical refresh will not work.\n"));
}
}
static int sdap_sudo_schedule_refresh(TALLOC_CTX *mem_ctx,
struct sdap_sudo_ctx *sudo_ctx,
enum sdap_sudo_refresh_type refresh,
tevent_req_fn callback,
time_t delay,
time_t timeout,
struct tevent_req **_req)
{
struct tevent_req *req = NULL;
sdap_sudo_timer_fn_t send_fn = NULL;
const char *name = NULL;
struct timeval when;
when = tevent_timeval_current_ofs(delay, 0);
switch (refresh) {
case SDAP_SUDO_REFRESH_FULL:
send_fn = sdap_sudo_full_refresh_send;
name = "Full refresh";
break;
case SDAP_SUDO_REFRESH_SMART:
send_fn = sdap_sudo_smart_refresh_send;
name = "Smart refresh";
break;
case SDAP_SUDO_REFRESH_RULES:
DEBUG(SSSDBG_OP_FAILURE, ("Rules refresh can't be scheduled!\n"));
return EINVAL;
default:
DEBUG(SSSDBG_CRIT_FAILURE, ("Unknown refresh type [%d].\n", refresh));
return EINVAL;
}
req = sdap_sudo_timer_send(mem_ctx, sudo_ctx->id_ctx->be->ev, sudo_ctx,
when, timeout, send_fn);
if (req == NULL) {
return ENOMEM;
}
tevent_req_set_callback(req, callback, sudo_ctx);
DEBUG(SSSDBG_TRACE_FUNC, ("%s scheduled at: %lld\n",
name, (long long)when.tv_sec));
if (_req != NULL) {
*_req = req;
}
return EOK;
}
static int sdap_sudo_schedule_full_refresh(struct sdap_sudo_ctx *sudo_ctx,
time_t delay)
{
int ret;
ret = sdap_sudo_schedule_refresh(sudo_ctx, sudo_ctx,
SDAP_SUDO_REFRESH_FULL,
sdap_sudo_periodical_full_refresh_done,
delay, delay, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Unable to schedule full refresh of sudo "
"rules!\n"));
return ret;
}
return EOK;
}
static int sdap_sudo_schedule_smart_refresh(struct sdap_sudo_ctx *sudo_ctx,
time_t delay)
{
int ret;
ret = sdap_sudo_schedule_refresh(sudo_ctx, sudo_ctx,
SDAP_SUDO_REFRESH_SMART,
sdap_sudo_periodical_smart_refresh_done,
delay, delay, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Unable to schedule smart refresh of sudo "
"rules!\n"));
return ret;
}
return EOK;
}