sysdb_sudo.c revision dd7192379e5fc5bb852863e60ad4b6a20c5da183
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen Jakub Hrozek <jhrozek@redhat.com>
ff487c974815bdaa2d05a3b834f4c2c841f4cc34Timo Sirainen Copyright (C) 2011 Red Hat
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen This program is free software; you can redistribute it and/or modify
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen it under the terms of the GNU General Public License as published by
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen the Free Software Foundation; either version 3 of the License, or
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen (at your option) any later version.
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen This program is distributed in the hope that it will be useful,
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen GNU General Public License for more details.
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen You should have received a copy of the GNU General Public License
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen/* ==================== Utility functions ==================== */
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenstatic errno_t sysdb_sudo_convert_time(const char *str, time_t *unix_time)
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen /* SUDO requires times to be in generalized time format:
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen * YYYYMMDDHHMMSS[.|,fraction][(+|-HHMM)|Z]
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen * We need to use more format strings to parse this with strptime().
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen const char *formats[] = {"%Y%m%d%H%M%SZ", /* 201212121300Z */
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen "%Y%m%d%H%M%S.0Z",
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen "%Y%m%d%H%M%S.0%z",
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen "%Y%m%d%H%M%S,0Z",
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen "%Y%m%d%H%M%S,0%z",
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen for (format = formats; *format != NULL; format++) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainenstatic errno_t sysdb_sudo_check_time(struct sysdb_attrs *rule,
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen ret = sysdb_attrs_get_string(rule, SYSDB_SUDO_CACHE_AT_CN, &name);
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen * From man sudoers.ldap:
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen * If multiple sudoNotBefore entries are present, the *earliest* is used.
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen * If multiple sudoNotAfter entries are present, the *last one* is used.
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen * From sudo sources, ldap.c:
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen * If either the sudoNotAfter or sudoNotBefore attributes are missing,
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen * no time restriction shall be imposed.
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen /* check for sudoNotBefore */
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen ret = sysdb_attrs_get_string_array(rule, SYSDB_SUDO_CACHE_AT_NOTBEFORE,
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen ("notBefore attribute is missing, the rule [%s] is valid\n",
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen for (i=0; values[i] ; i++) {
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen ret = sysdb_sudo_convert_time(values[i], &converted);
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen DEBUG(SSSDBG_MINOR_FAILURE, ("Invalid time format in rule [%s]!\n",
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen /* Grab the earliest */
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen /* check for sudoNotAfter */
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen ret = sysdb_attrs_get_string_array(rule, SYSDB_SUDO_CACHE_AT_NOTAFTER,
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen ("notAfter attribute is missing, the rule [%s] is valid\n",
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen for (i=0; values[i] ; i++) {
157bce86d0a01477bb8ebd0d380e6b2297f326f7Timo Sirainen ret = sysdb_sudo_convert_time(values[i], &converted);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen DEBUG(SSSDBG_MINOR_FAILURE, ("Invalid time format in rule [%s]!\n",
0727e38ac12efb8963a339daf56255e2be1f29fcTimo Sirainen /* Grab the latest */
dd93aba1901a457346990f49c54a738947dc7128Timo Sirainenerrno_t sysdb_sudo_filter_rules_by_time(TALLOC_CTX *mem_ctx,
157bce86d0a01477bb8ebd0d380e6b2297f326f7Timo Sirainen bool allowed = false;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen for (i = 0; i < in_num_rules; i++) {
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen ret = sysdb_sudo_check_time(in_rules[i], now, &allowed);
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen rules = talloc_realloc(tmp_ctx, rules, struct sysdb_attrs *,
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainensysdb_get_sudo_filter(TALLOC_CTX *mem_ctx, const char *username,
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen uid_t uid, char **groupnames, unsigned int flags,
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen /* build specific filter */
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen specific_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */
username);
(unsigned long long) uid);
groupnames[i]);
done:
return ret;
char ***groupnames)
NULL };
NULL };
goto done;
if (!uid) {
goto done;
num_groups = 0;
&sysdb_groupnames[i]);
goto done;
if (gid != 0) {
NULL);
goto done;
num_groups++;
goto done;
done:
return ret;
const char *rule_name,
return ret;
return ret;
return ret;
return EOK;
const char *attr_name,
int lret;
if (!tmp_ctx) {
goto done;
if (!dn) {
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
done:
return ret;
const char *attr_name,
int lret;
return ENOMEM;
if (!dn) {
goto done;
goto done;
*value = 0;
goto done;
goto done;
done:
return ret;
value);
value);
goto done;
done:
return ret;
const char *name)
const char *filter)
const char *name;
bool in_transaction = false;
NULL };
if (!filter) {
goto done;
goto done;
goto done;
in_transaction = true;
for (i = 0; i < count; i++) {
goto done;
goto done;
in_transaction = false;
done:
if (in_transaction) {
return ret;