sdap_sudo.c revision 7ed683eba94b5bcdc4fe3f9037d80d0fedcddfd0
2fbc2a7c65d30e46803195ebb4547176b85c22c7Timo Sirainen Pavel Březina <pbrezina@redhat.com>
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen Copyright (C) 2011 Red Hat
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.
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.
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/>.
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainenstatic struct tevent_req *sdap_sudo_full_refresh_send(TALLOC_CTX *mem_ctx,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic void sdap_sudo_full_refresh_done(struct tevent_req *subreq);
10c5fd417af4ee30b68c967f5e7d5a49f4f149b5Timo Sirainenstatic int sdap_sudo_full_refresh_recv(struct tevent_req *req,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic struct tevent_req *sdap_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx,
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainenstatic void sdap_sudo_rules_refresh_done(struct tevent_req *subreq);
a399486f2d8d5bed51bc6344baba61a7f2b0dcdbTimo Sirainenstatic int sdap_sudo_rules_refresh_recv(struct tevent_req *req,
5a8b0ce25f7838652b4a0cb9dab0ad19ec0fab25Timo Sirainenstatic struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainenstatic void sdap_sudo_smart_refresh_done(struct tevent_req *subreq);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic int sdap_sudo_smart_refresh_recv(struct tevent_req *req,
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenstatic void sdap_sudo_periodical_first_refresh_done(struct tevent_req *req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic void sdap_sudo_periodical_full_refresh_done(struct tevent_req *req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic void sdap_sudo_periodical_smart_refresh_done(struct tevent_req *req);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic int sdap_sudo_schedule_refresh(TALLOC_CTX *mem_ctx,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic int sdap_sudo_schedule_full_refresh(struct sdap_sudo_ctx *sudo_ctx,
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainenstatic int sdap_sudo_schedule_smart_refresh(struct sdap_sudo_ctx *sudo_ctx,
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);
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen DEBUG(SSSDBG_TRACE_INTERNAL, ("Initializing sudo LDAP back end\n"));
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sudo_ctx = talloc_zero(be_ctx, struct sdap_sudo_ctx);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("talloc() failed\n"));
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen /* we didn't do any full refresh now,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen * so we don't have current usn values available */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen ret = ldap_get_sudo_options(id_ctx, be_ctx->cdb,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("Cannot get SUDO options [%d]: %s\n",
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen req = sdap_sudo_get_hostinfo_send(sudo_ctx, id_ctx->opts, be_ctx);
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to retrieve host information - "
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen "(host filter will be disabled)\n"));
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen ret = sdap_sudo_setup_periodical_refresh(sudo_ctx);
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 tevent_req_set_callback(req, sdap_sudo_get_hostinfo_done, sudo_ctx);
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainenstatic void sdap_sudo_get_hostinfo_done(struct tevent_req *req)
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen sudo_ctx = tevent_req_callback_data(req, struct sdap_sudo_ctx);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen ret = sdap_sudo_get_hostinfo_recv(sudo_ctx, req, &hostnames, &ip_addr);
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to retrieve host information - "
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen "(host filter will be disabled) [%d]: %s\n", ret, strerror(ret)));
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen sudo_ctx->hostnames = talloc_move(sudo_ctx, &hostnames);
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen sudo_ctx->ip_addr = talloc_move(sudo_ctx, &ip_addr);
a8fc29f19ea6e2d472ba779b2dd5ca4e1f3dac79Timo Sirainen ret = sdap_sudo_setup_periodical_refresh(sudo_ctx);
7d6389e4053c2dac1fb37180b5756b00785983dcTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("Unable to setup periodical refresh"
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen "of sudo rules [%d]: %s\n", ret, strerror(ret)));
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainenstatic int sdap_sudo_setup_periodical_refresh(struct sdap_sudo_ctx *sudo_ctx)
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen smart_interval = dp_opt_get_int(id_ctx->opts->basic,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen full_interval = dp_opt_get_int(id_ctx->opts->basic,
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;
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",
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 = sysdb_sudo_get_last_full_refresh(id_ctx->be->sysdb, &last_full);
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
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.
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen /* delay at least by 10s */
48559742084e98049335c21c53dfd1ff95f11cd8Timo Sirainen ret = sdap_sudo_schedule_refresh(sudo_ctx, sudo_ctx,
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, ("Unable to schedule full refresh of sudo "
e65cc79f80577e83c706f0678c78e2c0bd91434fTimo Sirainen "rules! Periodical updates will not work!\n"));
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainenstatic void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, char *usn)
b567e0172c73dcf7642462e86962060358dd5f28Timo Sirainen srv_opts->max_sudo_value = talloc_steal(srv_opts, usn);
b567e0172c73dcf7642462e86962060358dd5f28Timo Sirainen if ((endptr == NULL || (*endptr == '\0' && endptr != usn))
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen DEBUG(SSSDBG_FUNC_DATA, ("SUDO higher USN value: [%s]\n",
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainen DEBUG(SSSDBG_TRACE_FUNC, ("srv_opts is NULL\n"));
40992309053d51192ae1b36d1dd6c057f2d37257Timo Sirainenstatic char *sdap_sudo_build_host_filter(TALLOC_CTX *mem_ctx,
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen /* sudoHost is not specified */
23f8c5356cacdbd1cc09a39a08ef37a39125bb74Timo Sirainen filter = talloc_asprintf_append_buffer(filter, "(!(%s=*))",
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen filter = talloc_asprintf_append_buffer(filter, "(%s=ALL)",
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* hostnames */
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen filter = talloc_asprintf_append_buffer(filter, "(%s=%s)",
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* ip addresses and networks */
9e7182d6fa1940ec14cc2938699820b68ee1dc0dTimo Sirainen filter = talloc_asprintf_append_buffer(filter, "(%s=%s)",
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen /* sudoHost contains netgroup - will be filtered more by sudo */
ed5e91e58dfc372c2135c55427bf6f25a7725042Timo Sirainen filter = talloc_asprintf_append_buffer(filter, SDAP_SUDO_FILTER_NETGROUP,
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 filter = talloc_asprintf_append_buffer(filter,
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen "(|(%s=*\\\\*)(%s=*?*)(%s=*\\**)"
0d7d27765267594a5870892268ab345148306d49Timo Sirainen "(%s=*[*]*))",
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen filter = talloc_strdup_append_buffer(filter, ")");
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainenstatic char *sdap_sudo_get_filter(TALLOC_CTX *mem_ctx,
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen host_filter = sdap_sudo_build_host_filter(tmp_ctx, map,
d1f0acc7fc722e13e8296228703adfe8a884d59eTimo Sirainen filter = sdap_get_id_specific_filter(tmp_ctx, rule_filter, host_filter);
1c38a95332f1945c9806d7d83175a0d948f51291Timo Sirainenstatic void sdap_sudo_reply(struct tevent_req *req)
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);
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen ret = sdap_sudo_full_refresh_recv(req, &dp_error, &error);
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen ret = sdap_sudo_rules_refresh_recv(req, &dp_error, &error);
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid request type: %d\n",
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sdap_handler_done(be_req, DP_ERR_FATAL, ret, strerror(ret));
c4457e497e01b57565d24da624968699b166e02aTimo Sirainen sdap_handler_done(be_req, dp_error, error, strerror(error));
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sudo_ctx = talloc_get_type(be_req->be_ctx->bet_info[BET_SUDO].pvt_bet_data,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen sudo_req = talloc_get_type(be_req->req_data, struct be_sudo_req);
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 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 DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid request type: %d\n",
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to send request: %d\n",
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen tevent_req_set_callback(req, sdap_sudo_reply, be_req);
e714eed72515794c46c6712a611e5ab924d903daTimo Sirainen sdap_handler_done(be_req, DP_ERR_FATAL, ret, NULL);
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_id_ctx *id_ctx = sudo_ctx->id_ctx;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen struct sdap_sudo_full_refresh_state *state = NULL;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_full_refresh_state);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
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);
0d7d27765267594a5870892268ab345148306d49Timo Sirainen ldap_full_filter = sdap_sudo_get_filter(state, id_ctx->opts->sudorule_map,
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen /* Remove all rules from cache */
goto immediately;
goto immediately;
return req;
return req;
int ret;
goto done;
done:
int *dp_error,
int *error)
return EOK;
char **rules)
int ret;
return NULL;
return NULL;
return NULL;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
return req;
int ret;
goto done;
done:
int *dp_error,
int *error)
return EOK;
const char *usn;
int ret;
return NULL;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
return req;
return req;
int dp_error;
int error;
int ret;
goto done;
done:
int *dp_error,
int *error)
int ret;
if (timeout == 0) {
int ret;
goto schedule;
goto schedule;
goto schedule;
if (delay == 0) {
if (delay == 0) {
int ret;
goto schedule;
goto schedule;
goto schedule;
if (delay == 0) {
int dp_error;
int error;
int ret;
goto schedule;
goto schedule;
if (delay == 0) {
switch (refresh) {
case SDAP_SUDO_REFRESH_FULL:
case SDAP_SUDO_REFRESH_SMART:
case SDAP_SUDO_REFRESH_RULES:
return EINVAL;
return EINVAL;
return ENOMEM;
return EOK;
int ret;
return ret;
return EOK;
int ret;
return ret;
return EOK;