6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina/*
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina Authors:
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina Pavel Březina <pbrezina@redhat.com>
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina Copyright (C) 2011 Red Hat
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina This program is free software; you can redistribute it and/or modify
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina it under the terms of the GNU General Public License as published by
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina the Free Software Foundation; either version 3 of the License, or
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina (at your option) any later version.
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina This program is distributed in the hope that it will be useful,
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina GNU General Public License for more details.
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina You should have received a copy of the GNU General Public License
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina*/
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina#include "config.h"
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina#include <stdlib.h>
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina#include <stdio.h>
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina#include <string.h>
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina#include <errno.h>
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina#include "util/util.h"
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina#include "sss_client/sss_cli.h"
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina#include "sss_client/sudo/sss_sudo.h"
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina#include "sss_client/sudo/sss_sudo_private.h"
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březinaint sss_sudo_create_query(uid_t uid,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina const char *username,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina uint8_t **_query,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina size_t *_query_len);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březinastatic void sss_sudo_free_rules(unsigned int num_rules,
968e2bc3bb28458b25c3b19868ea50f0325d8b0aPavel Březina struct sss_sudo_rule *rules);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březinastatic void sss_sudo_free_attrs(unsigned int num_attrs,
968e2bc3bb28458b25c3b19868ea50f0325d8b0aPavel Březina struct sss_sudo_attr *attrs);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březinastatic int sss_sudo_send_recv_generic(enum sss_cli_command command,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina uid_t uid,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina const char *username,
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina uint32_t *_error,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina char **_domainname,
968e2bc3bb28458b25c3b19868ea50f0325d8b0aPavel Březina struct sss_sudo_result **_result)
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina{
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina struct sss_cli_req_data request;
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina uint8_t *query_buf = NULL;
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina size_t query_len = 0;
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina uint8_t *reply_buf = NULL;
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina size_t reply_len = 0;
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina int errnop = 0;
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina int ret = 0;
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina /* create query */
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina ret = sss_sudo_create_query(uid, username, &query_buf, &query_len);
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina if (ret != EOK) {
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina goto done;
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina }
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina request.len = query_len;
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina request.data = (const void*)query_buf;
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina /* send query and receive response */
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina errnop = 0;
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina ret = sss_sudo_make_request(command, &request,
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina &reply_buf, &reply_len, &errnop);
dc2750954d694eeef46ec9bf31c7f675b2b1fb27Pavel Březina if (ret != SSS_STATUS_SUCCESS) {
dc2750954d694eeef46ec9bf31c7f675b2b1fb27Pavel Březina ret = errnop;
dc2750954d694eeef46ec9bf31c7f675b2b1fb27Pavel Březina goto done;
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina }
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina /* parse structure */
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina ret = sss_sudo_parse_response((const char*)reply_buf, reply_len,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina _domainname, _result, _error);
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina
dc2750954d694eeef46ec9bf31c7f675b2b1fb27Pavel Březinadone:
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina free(query_buf);
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina free(reply_buf);
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina return ret;
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina}
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březinaint sss_sudo_send_recv(uid_t uid,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina const char *username,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina const char *domainname,
f643754db81eeade60485bbe3d80324d889cc4f3Pavel Březina uint32_t *_error,
968e2bc3bb28458b25c3b19868ea50f0325d8b0aPavel Březina struct sss_sudo_result **_result)
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina{
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina int ret;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina if (username == NULL || strlen(username) == 0) {
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina return EINVAL;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina /* send query and receive response */
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
7379170a0860790f2739e07fffe3d6ec85264566Pavel Březina ret = sss_sudo_send_recv_generic(SSS_SUDO_GET_SUDORULES, uid, username,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina _error, NULL, _result);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina return ret;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina}
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březinaint sss_sudo_send_recv_defaults(uid_t uid,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina const char *username,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina uint32_t *_error,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina char **_domainname,
968e2bc3bb28458b25c3b19868ea50f0325d8b0aPavel Březina struct sss_sudo_result **_result)
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina{
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina if (username == NULL || strlen(username) == 0) {
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina return EINVAL;
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina }
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina return sss_sudo_send_recv_generic(SSS_SUDO_GET_DEFAULTS, uid, username,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina _error, _domainname, _result);
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina}
9c6b680e55e00642bc3e644fd63e18e6c09ff110Pavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březinaint sss_sudo_create_query(uid_t uid, const char *username,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina uint8_t **_query, size_t *_query_len)
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina{
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina uint8_t *data = NULL;
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina size_t username_len = strlen(username) * sizeof(char) + 1;
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina size_t data_len = sizeof(uid_t) + username_len;
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina size_t offset = 0;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina data = (uint8_t*)malloc(data_len * sizeof(uint8_t));
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina if (data == NULL) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina return ENOMEM;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina SAFEALIGN_SET_VALUE(data, uid, uid_t, &offset);
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina memcpy(data + offset, username, username_len);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina *_query = data;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina *_query_len = data_len;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina return EOK;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina}
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
968e2bc3bb28458b25c3b19868ea50f0325d8b0aPavel Březinaint sss_sudo_get_values(struct sss_sudo_rule *e,
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina const char *attrname, char ***_values)
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina{
968e2bc3bb28458b25c3b19868ea50f0325d8b0aPavel Březina struct sss_sudo_attr *attr = NULL;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina char **values = NULL;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina int i, j;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina for (i = 0; i < e->num_attrs; i++) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina attr = e->attrs + i;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina if (strcasecmp(attr->name, attrname) == 0) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina values = calloc(attr->num_values + 1, sizeof(char*));
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina if (values == NULL) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina return ENOMEM;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina for (j = 0; j < attr->num_values; j++) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina values[j] = strdup(attr->values[j]);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina if (values[j] == NULL) {
ea155efa0408f84171d28c1f733ea08888dfbe51Pavel Březina sss_sudo_free_values(values);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina return ENOMEM;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina values[attr->num_values] = NULL;
ea155efa0408f84171d28c1f733ea08888dfbe51Pavel Březina
ea155efa0408f84171d28c1f733ea08888dfbe51Pavel Březina break;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
ea155efa0408f84171d28c1f733ea08888dfbe51Pavel Březina if (values == NULL) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina return ENOENT;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina *_values = values;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina return EOK;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina}
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březinavoid sss_sudo_free_values(char **values)
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina{
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina char **value = NULL;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina if (values == NULL) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina return;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina for (value = values; *value != NULL; value++) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina free(*value);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina free(values);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina}
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
968e2bc3bb28458b25c3b19868ea50f0325d8b0aPavel Březinavoid sss_sudo_free_result(struct sss_sudo_result *result)
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina{
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina if (result == NULL) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina return;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina sss_sudo_free_rules(result->num_rules, result->rules);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina free(result);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina}
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
968e2bc3bb28458b25c3b19868ea50f0325d8b0aPavel Březinavoid sss_sudo_free_rules(unsigned int num_rules, struct sss_sudo_rule *rules)
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina{
968e2bc3bb28458b25c3b19868ea50f0325d8b0aPavel Březina struct sss_sudo_rule *rule = NULL;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina int i;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina if (rules == NULL) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina return;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina for (i = 0; i < num_rules; i++) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina rule = rules + i;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina sss_sudo_free_attrs(rule->num_attrs, rule->attrs);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina rule->attrs = NULL;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina free(rules);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina}
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
968e2bc3bb28458b25c3b19868ea50f0325d8b0aPavel Březinavoid sss_sudo_free_attrs(unsigned int num_attrs, struct sss_sudo_attr *attrs)
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina{
b9941359b3181c42f415530d5ccad0f4664d85faLukas Slebodnik struct sss_sudo_attr *attr = NULL;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina int i, j;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina if (attrs == NULL) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina return;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina for (i = 0; i < num_attrs; i++) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina attr = attrs + i;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina free(attr->name);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina attr->name = NULL;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina for (j = 0; j < attr->num_values; j++) {
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina free(attr->values[j]);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina attr->values[j] = NULL;
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina free(attr->values);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina }
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina free(attrs);
6f701a4dc295ddc997ba5190a3cd72d948d799dcPavel Březina}