示例#1
0
static errno_t
process_rulemember(TALLOC_CTX *mem_ctx,
                   struct ipa_sudo_conv *conv,
                   struct ipa_sudo_rulemember *rulemember,
                   struct sysdb_attrs *rule,
                   const char *attr)
{
    TALLOC_CTX *tmp_ctx;
    const char **members;
    errno_t ret;
    int i;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        return ENOMEM;
    }

    ret = sysdb_attrs_get_string_array(rule, attr, tmp_ctx, &members);
    if (ret == ENOENT) {
        ret = EOK;
        goto done;
    } else if (ret != EOK) {
        goto done;
    }

    for (i = 0; members[i] != NULL; i++) {
        if (is_ipacmdgroup(conv, members[i])) {
            ret = store_rulemember(mem_ctx, &rulemember->cmdgroups,
                                   conv->cmdgroups, members[i]);
            if (ret == EOK) {
                DEBUG(SSSDBG_TRACE_INTERNAL, "Found sudo command group %s\n",
                      members[i]);
            } else if (ret != EEXIST) {
                goto done;
            }
        } else if (is_ipacmd(conv, members[i])) {
            ret = store_rulemember(mem_ctx, &rulemember->cmds,
                                   conv->cmds, members[i]);
            if (ret == EOK) {
                DEBUG(SSSDBG_TRACE_INTERNAL, "Found sudo command %s\n",
                      members[i]);
            } else if (ret != EEXIST) {
                goto done;
            }
        } else {
            DEBUG(SSSDBG_MINOR_FAILURE, "Invalid member DN %s, skipping...\n",
                  members[i]);
            continue;
        }
    }

    ret = EOK;

done:
    talloc_free(tmp_ctx);
    return ret;
}
示例#2
0
static errno_t
process_cmdgroupmember(struct ipa_sudo_conv *conv,
                       struct ipa_sudo_cmdgroup *cmdgroup,
                       struct sysdb_attrs *attrs)
{
    TALLOC_CTX *tmp_ctx;
    struct ipa_sudo_dn_list *item;
    const char **members;
    errno_t ret;
    int i;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        return ENOMEM;
    }

    ret = sysdb_attrs_get_string_array(attrs, SYSDB_MEMBER, tmp_ctx, &members);
    if (ret == ENOENT) {
        ret = EOK;
        goto done;
    } else if (ret != EOK) {
        goto done;
    }

    for (i = 0; members[i] != NULL; i++) {
        ret = ipa_sudo_conv_store(conv->cmds, members[i], NULL);
        if (ret == EOK) {
            DEBUG(SSSDBG_TRACE_INTERNAL, "Found sudo command %s\n",
                  members[i]);
        } else if (ret != EEXIST) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Unable to store DN [%d]: %s\n",
                  ret, sss_strerror(ret));
            goto done;
        }

        item = talloc_zero(tmp_ctx, struct ipa_sudo_dn_list);
        if (item == NULL) {
            ret = ENOMEM;
            goto done;
        }

        item->dn = talloc_steal(item, members[i]);
        DLIST_ADD(cmdgroup->cmds, item);
        talloc_steal(cmdgroup, item);
    }

    ret = EOK;

done:
    talloc_free(tmp_ctx);
    return ret;
}
示例#3
0
static errno_t sysdb_sudo_check_time(struct sysdb_attrs *rule,
                                     time_t now,
                                     bool *result)
{
    TALLOC_CTX *tmp_ctx = NULL;
    const char **values = NULL;
    const char *name = NULL;
    time_t notBefore = 0;
    time_t notAfter = 0;
    time_t converted;
    errno_t ret;
    int i;

    if (!result) return EINVAL;
    *result = false;

    tmp_ctx = talloc_new(NULL);
    NULL_CHECK(tmp_ctx, ret, done);

    ret = sysdb_attrs_get_string(rule, SYSDB_SUDO_CACHE_AT_CN, &name);
    if (ret == ENOENT) {
        name = "<missing>";
    } else if(ret != EOK) {
        goto done;
    }

    /*
     * From man sudoers.ldap:
     *
     * If multiple sudoNotBefore entries are present, the *earliest* is used.
     * If multiple sudoNotAfter entries are present, the *last one* is used.
     *
     * From sudo sources, ldap.c:
     * If either the sudoNotAfter or sudoNotBefore attributes are missing,
     * no time restriction shall be imposed.
     */

    /* check for sudoNotBefore */
    ret = sysdb_attrs_get_string_array(rule, SYSDB_SUDO_CACHE_AT_NOTBEFORE,
                                       tmp_ctx, &values);
    if (ret == EOK) {
        for (i=0; values[i] ; i++) {
            ret = sysdb_sudo_convert_time(values[i], &converted);
            if (ret != EOK) {
                DEBUG(SSSDBG_MINOR_FAILURE, "Invalid time format in rule [%s]!\n",
                      name);
                goto done;
            }

            /* Grab the earliest */
            if (!notBefore) {
                notBefore = converted;
            } else if (notBefore > converted) {
                notBefore = converted;
            }
        }
    } else if (ret != ENOENT) {
        goto done;
    }

    /* check for sudoNotAfter */
    ret = sysdb_attrs_get_string_array(rule, SYSDB_SUDO_CACHE_AT_NOTAFTER,
                                       tmp_ctx, &values);
    if (ret == EOK) {
        for (i=0; values[i] ; i++) {
            ret = sysdb_sudo_convert_time(values[i], &converted);
            if (ret != EOK) {
                DEBUG(SSSDBG_MINOR_FAILURE, "Invalid time format in rule [%s]!\n",
                      name);
                goto done;
            }

            /* Grab the latest */
            if (!notAfter) {
                notAfter = converted;
            } else if (notAfter < converted) {
                notAfter = converted;
            }
        }
    } else if (ret != ENOENT) {
        goto done;
    }

    if ((notBefore == 0 || now >= notBefore)
        && (notAfter == 0 || now <= notAfter)) {
        *result = true;
    }

    if (*result) {
        DEBUG(SSSDBG_TRACE_ALL, "Rule [%s] matches time restrictions\n",
                                 name);
    } else {
        DEBUG(SSSDBG_TRACE_ALL, "Rule [%s] does not match time "
                                 "restrictions\n", name);
    }

    ret = EOK;
done:
    talloc_free(tmp_ctx);
    return ret;
}
static errno_t process_ext_groups(TALLOC_CTX *mem_ctx, size_t reply_count,
                                  struct sysdb_attrs **reply,
                                  hash_table_t **_ext_group_hash)
{
    int ret;
    hash_table_t *ext_group_hash = NULL;
    hash_key_t key;
    hash_value_t value;
    hash_table_t *m_hash = NULL;
    hash_key_t m_key;
    hash_value_t m_value;
    size_t g;
    size_t s;
    size_t m;
    TALLOC_CTX *tmp_ctx = NULL;
    const char **ext_sids;
    const char **mof;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
        ret = ENOMEM;
        goto done;
    }

    ret = sss_hash_create(mem_ctx, reply_count, &ext_group_hash);
    if (ret != HASH_SUCCESS) {
        DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n");
        goto done;
    }

    key.type = HASH_KEY_STRING;
    m_key.type = HASH_KEY_STRING;
    m_value.type = HASH_VALUE_PTR;
    m_value.ptr = NULL;

    for (g = 0; g < reply_count; g++) {
        ret = sysdb_attrs_get_string_array(reply[g], "ipaExternalMember",
                                           tmp_ctx, &ext_sids);
        if (ret == ENOENT) {
            /* no external members, try next external group. */
            continue;
        }
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "sysdb_attrs_get_string_array failed.\n");
            goto done;
        }

        ret = sysdb_attrs_get_string_array(reply[g], "memberOf",
                                           tmp_ctx, &mof);
        if (ret == ENOENT) {
            /* no IPA groups, try next external group. */
            continue;
        }
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "sysdb_attrs_get_string_array failed.\n");
            goto done;
        }

        for (s = 0; ext_sids[s] != NULL; s++) {
            /* hash_lookup does not modify key.str. */
            key.str = discard_const(ext_sids[s]);
            ret = hash_lookup(ext_group_hash, &key, &value);
            if (ret == HASH_SUCCESS) {
                if (value.type != HASH_VALUE_PTR) {
                    DEBUG(SSSDBG_OP_FAILURE, "Unexpected value type.\n");
                    ret = EINVAL;
                    goto done;
                }

                for (m = 0; mof[m] != NULL; m++) {
                    /* hash_enter does not modify m_key.str. */
                    m_key.str = discard_const(mof[m]);
                    DEBUG(SSSDBG_TRACE_ALL, "Adding group [%s] to SID [%s].\n",
                                             m_key.str, key.str);
                    ret = hash_enter(value.ptr, &m_key, &m_value);
                    if (ret != HASH_SUCCESS) {
                        DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed.\n");
                        goto done;
                    }
                }
            } else if (ret == HASH_ERROR_KEY_NOT_FOUND) {
                ret = sss_hash_create(ext_group_hash, 5, &m_hash);
                if (ret != HASH_SUCCESS) {
                    DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n");
                    goto done;
                }

                value.type = HASH_VALUE_PTR;
                value.ptr = m_hash;

                DEBUG(SSSDBG_TRACE_ALL,
                      "Adding SID [%s] to external group hash.\n", key.str);
                ret = hash_enter(ext_group_hash, &key, &value);
                if (ret != HASH_SUCCESS) {
                    DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed.\n");
                    goto done;
                }

                for (m = 0; mof[m] != NULL; m++) {
                    /* hash_enter does not modify m_key.str. */
                    m_key.str = discard_const(mof[m]);
                    DEBUG(SSSDBG_TRACE_ALL, "Adding group [%s] to SID [%s].\n",
                                             m_key.str, key.str);
                    ret = hash_enter(m_hash, &m_key, &m_value);
                    if (ret != HASH_SUCCESS) {
                        DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed.\n");
                        goto done;
                    }
                }
            } else {
                DEBUG(SSSDBG_OP_FAILURE, "hash_lookup failed.\n");
                goto done;
            }
        }
    }

    ret = EOK;
done:
    if (ret != EOK) {
        talloc_free(ext_group_hash);
    } else {
        *_ext_group_hash = ext_group_hash;
    }

    talloc_free(tmp_ctx);

    return ret;
}
示例#5
0
static errno_t
convert_attributes(struct ipa_sudo_conv *conv,
                   struct ipa_sudo_rule *rule,
                   struct sysdb_attrs *attrs)
{
    TALLOC_CTX *tmp_ctx;
    const char **values;
    const char *value;
    errno_t ret;
    int i, j;
    static struct {
        const char *ipa;
        const char *sudo;
        const char *(*conv_fn)(TALLOC_CTX *mem_ctx,
                               struct ipa_sudo_conv *conv,
                               const char *value);
    } table[] = {{SYSDB_NAME,                            SYSDB_SUDO_CACHE_AT_CN         , NULL},
                 {SYSDB_IPA_SUDORULE_HOST,               SYSDB_SUDO_CACHE_AT_HOST       , convert_host},
                 {SYSDB_IPA_SUDORULE_USER,               SYSDB_SUDO_CACHE_AT_USER       , convert_user},
                 {SYSDB_IPA_SUDORULE_RUNASUSER,          SYSDB_SUDO_CACHE_AT_RUNASUSER  , convert_user},
                 {SYSDB_IPA_SUDORULE_RUNASGROUP,         SYSDB_SUDO_CACHE_AT_RUNASGROUP , convert_group},
                 {SYSDB_IPA_SUDORULE_OPTION,             SYSDB_SUDO_CACHE_AT_OPTION     , NULL},
                 {SYSDB_IPA_SUDORULE_NOTAFTER,           SYSDB_SUDO_CACHE_AT_NOTAFTER   , NULL},
                 {SYSDB_IPA_SUDORULE_NOTBEFORE,          SYSDB_SUDO_CACHE_AT_NOTBEFORE  , NULL},
                 {SYSDB_IPA_SUDORULE_SUDOORDER,          SYSDB_SUDO_CACHE_AT_ORDER      , NULL},
                 {SYSDB_IPA_SUDORULE_CMDCATEGORY,        SYSDB_SUDO_CACHE_AT_COMMAND    , convert_cat},
                 {SYSDB_IPA_SUDORULE_HOSTCATEGORY,       SYSDB_SUDO_CACHE_AT_HOST       , convert_cat},
                 {SYSDB_IPA_SUDORULE_USERCATEGORY,       SYSDB_SUDO_CACHE_AT_USER       , convert_cat},
                 {SYSDB_IPA_SUDORULE_RUNASUSERCATEGORY,  SYSDB_SUDO_CACHE_AT_RUNASUSER  , convert_cat},
                 {SYSDB_IPA_SUDORULE_RUNASGROUPCATEGORY, SYSDB_SUDO_CACHE_AT_RUNASGROUP , convert_cat},
                 {SYSDB_IPA_SUDORULE_RUNASEXTUSER,       SYSDB_SUDO_CACHE_AT_RUNASUSER  , NULL},
                 {SYSDB_IPA_SUDORULE_RUNASEXTGROUP,      SYSDB_SUDO_CACHE_AT_RUNASGROUP , NULL},
                 {SYSDB_IPA_SUDORULE_RUNASEXTUSERGROUP,  SYSDB_SUDO_CACHE_AT_RUNASUSER  , convert_runasextusergroup},
                 {SYSDB_IPA_SUDORULE_EXTUSER,            SYSDB_SUDO_CACHE_AT_USER       , NULL},
                 {SYSDB_IPA_SUDORULE_ALLOWCMD,           SYSDB_IPA_SUDORULE_ORIGCMD     , NULL},
                 {SYSDB_IPA_SUDORULE_DENYCMD,            SYSDB_IPA_SUDORULE_ORIGCMD     , NULL},
                 {NULL, NULL, NULL}};

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        return ENOMEM;
    }

    for (i = 0; table[i].ipa != NULL; i++) {
        ret = sysdb_attrs_get_string_array(rule->attrs, table[i].ipa,
                                           tmp_ctx, &values);
        if (ret == ENOENT) {
            continue;
        } else if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read attribute "
                  "%s [%d]: %s\n", table[i].ipa, ret, sss_strerror(ret));
            goto done;
        }

        for (j = 0; values[j] != NULL; j++) {
            if (table[i].conv_fn != NULL) {
                value = table[i].conv_fn(tmp_ctx, conv, values[j]);
                if (value == NULL) {
                    ret = ENOMEM;
                    goto done;
                }
            } else {
                value = values[j];
            }

            ret = sysdb_attrs_add_string_safe(attrs, table[i].sudo, value);
            if (ret != EOK) {
                DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add attribute "
                      "%s [%d]: %s\n", table[i].sudo, ret, sss_strerror(ret));
                goto done;
            }
        }
    }

    ret = EOK;

done:
    talloc_free(tmp_ctx);
    return ret;
}