nss_mc_group.c revision 8a5931bcc8e9034e4beb92fc9addf3f7fcf83fd6
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * System Security Services Daemon. NSS client interface
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * Copyright (C) Simo Sorce 2011
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 * 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 * 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/* GROUP database NSS interface using mmap cache */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinastruct sss_cli_mc_ctx gr_mc_ctx = { false, -1, 0, NULL, 0, NULL, 0, NULL, 0 };
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinastatic errno_t sss_nss_mc_parse_result(struct sss_mc_rec *rec,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* additional checks before filling result*/
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* entry is now invalid */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina memsize = (data->members + 1) * sizeof(char *);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* fill in glibc provided structs */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* copy in buffer */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* fill in group */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_str_ptr_from_buffer(&result->gr_name, &cookie,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_str_ptr_from_buffer(&result->gr_passwd, &cookie,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_str_ptr_from_buffer(&result->gr_mem[i], &cookie,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinaerrno_t sss_nss_mc_getgrnam(const char *name, size_t name_len,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_mc_get_ctx("group", &gr_mc_ctx);
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 /* 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 if (slot > MC_SIZE_TO_SLOTS(gr_mc_ctx.dt_size)) {
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 ret = sss_nss_mc_get_record(&gr_mc_ctx, slot, &rec);
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina /* check record matches what we are searching for */
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina /* if name hash does not match we can skip this immediately */
41ef946f3f74a46b9e26118116e4811e259b30efPavel Březina strs_offset = offsetof(struct sss_mc_grp_data, strs);
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 || (data->name + name_len) > (strs_offset + data->strs_len)
c9aab1c04c399ca2d1abef74f6df22ced34983dcPavel Březina || (uint8_t *)data->strs + data->strs_len > max_addr) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_mc_parse_result(rec, result, buffer, buflen);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sss_nss_mc_get_ctx("group", &gr_mc_ctx);
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 if (slot > MC_SIZE_TO_SLOTS(gr_mc_ctx.dt_size)) {
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 ret = sss_nss_mc_get_record(&gr_mc_ctx, slot, &rec);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* check record matches what we are searching for */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* if uid hash does not match we can skip this immediately */
goto done;
done:
return ret;