nss_mc_group.c revision 8a5931bcc8e9034e4beb92fc9addf3f7fcf83fd6
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina/*
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * System Security Services Daemon. NSS client interface
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina *
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * Copyright (C) Simo Sorce 2011
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina *
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * This program is free software; you can redistribute it and/or modify
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * it under the terms of the GNU Lesser General Public License as
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * published by the Free Software Foundation; either version 2.1 of the
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * License, or (at your option) any later version.
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina *
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * This program is distributed in the hope that it will be useful,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * but WITHOUT ANY WARRANTY; without even the implied warranty of
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * GNU Lesser General Public License for more details.
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina *
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * You should have received a copy of the GNU Lesser General Public License
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * along with this program. If not, see <http://www.gnu.org/licenses/>.
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina/* GROUP database NSS interface using mmap cache */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include <errno.h>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include <stdio.h>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include <string.h>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include <stdlib.h>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include <stddef.h>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include <sys/mman.h>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include <time.h>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include "nss_mc.h"
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinastruct sss_cli_mc_ctx gr_mc_ctx = { false, -1, 0, NULL, 0, NULL, 0, NULL, 0 };
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinastatic errno_t sss_nss_mc_parse_result(struct sss_mc_rec *rec,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina struct group *result,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina char *buffer, size_t buflen)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina{
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina struct sss_mc_grp_data *data;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina time_t expire;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina void *cookie;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina char *membuf;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina size_t memsize;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina int ret;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina int i;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* additional checks before filling result*/
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina expire = rec->expire;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (expire < time(NULL)) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* entry is now invalid */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return EINVAL;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina data = (struct sss_mc_grp_data *)rec->data;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina memsize = (data->members + 1) * sizeof(char *);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (data->strs_len + memsize > buflen) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ERANGE;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* fill in glibc provided structs */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* copy in buffer */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina membuf = buffer + memsize;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina memcpy(membuf, data->strs, data->strs_len);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* fill in group */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina result->gr_gid = data->gid;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina result->gr_mem = (char **)buffer;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina result->gr_mem[data->members] = NULL;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina cookie = NULL;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_str_ptr_from_buffer(&result->gr_name, &cookie,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina membuf, data->strs_len);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (ret) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ret;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_str_ptr_from_buffer(&result->gr_passwd, &cookie,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina membuf, data->strs_len);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (ret) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ret;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina for (i = 0; i < data->members; i++) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_str_ptr_from_buffer(&result->gr_mem[i], &cookie,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina membuf, data->strs_len);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (ret) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ret;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (cookie != NULL) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return EINVAL;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return 0;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina}
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinaerrno_t sss_nss_mc_getgrnam(const char *name, size_t name_len,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina struct group *result,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina char *buffer, size_t buflen)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina{
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina struct sss_mc_rec *rec = NULL;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina struct sss_mc_grp_data *data;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina char *rec_name;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina uint32_t hash;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina uint32_t slot;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina int ret;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina size_t strs_offset;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina uint8_t *max_addr;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_mc_get_ctx("group", &gr_mc_ctx);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (ret) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ret;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* Get max address of data table. */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina max_addr = gr_mc_ctx.data_table + gr_mc_ctx.dt_size;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* hashes are calculated including the NULL terminator */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina hash = sss_nss_mc_hash(&gr_mc_ctx, name, name_len + 1);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina slot = gr_mc_ctx.hash_table[hash];
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (slot > MC_SIZE_TO_SLOTS(gr_mc_ctx.dt_size)) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ENOENT;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina while (slot != MC_INVALID_VAL) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (slot > MC_SIZE_TO_SLOTS(gr_mc_ctx.dt_size)) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* This probably means that the memory cache was corrupted. */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ENOENT;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_mc_get_record(&gr_mc_ctx, slot, &rec);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (ret) {
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina goto done;
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina }
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina /* check record matches what we are searching for */
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina if (hash != rec->hash1) {
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina /* if name hash does not match we can skip this immediately */
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina slot = rec->next;
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina continue;
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina }
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina strs_offset = offsetof(struct sss_mc_grp_data, strs);
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina data = (struct sss_mc_grp_data *)rec->data;
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina /* Integrity check
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina * - name_len cannot be longer than all strings
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina * - data->name cannot point outside strings
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina * - all strings must be within data_table */
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina if (name_len > data->strs_len
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina || (data->name + name_len) > (strs_offset + data->strs_len)
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina || (uint8_t *)data->strs + data->strs_len > max_addr) {
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina ret = ENOENT;
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina goto done;
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina }
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina rec_name = (char *)data + data->name;
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina if (strcmp(name, rec_name) == 0) {
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina break;
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina }
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina slot = rec->next;
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina }
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina if (slot == MC_INVALID_VAL) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = ENOENT;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina goto done;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_mc_parse_result(rec, result, buffer, buflen);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinadone:
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina free(rec);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ret;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina}
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinaerrno_t sss_nss_mc_getgrgid(gid_t gid,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina struct group *result,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina char *buffer, size_t buflen)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina{
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina struct sss_mc_rec *rec = NULL;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina struct sss_mc_grp_data *data;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina char gidstr[11];
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina uint32_t hash;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina uint32_t slot;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina int len;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina int ret;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_mc_get_ctx("group", &gr_mc_ctx);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (ret) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ret;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina len = snprintf(gidstr, 11, "%ld", (long)gid);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (len > 10) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return EINVAL;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* hashes are calculated including the NULL terminator */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina hash = sss_nss_mc_hash(&gr_mc_ctx, gidstr, len+1);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina slot = gr_mc_ctx.hash_table[hash];
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (slot > MC_SIZE_TO_SLOTS(gr_mc_ctx.dt_size)) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ENOENT;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina while (slot != MC_INVALID_VAL) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (slot > MC_SIZE_TO_SLOTS(gr_mc_ctx.dt_size)) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* This probably means that the memory cache was corrupted. */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ENOENT;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_mc_get_record(&gr_mc_ctx, slot, &rec);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (ret) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina goto done;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* check record matches what we are searching for */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (hash != rec->hash2) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* if uid hash does not match we can skip this immediately */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina slot = rec->next;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina continue;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina data = (struct sss_mc_grp_data *)rec->data;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (gid == data->gid) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina break;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
slot = rec->next;
}
if (slot == MC_INVALID_VAL) {
ret = ENOENT;
goto done;
}
ret = sss_nss_mc_parse_result(rec, result, buffer, buflen);
done:
free(rec);
return ret;
}