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; }
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; }
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; }
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; }