nss_mc_common.c revision 0ed6114c6b2cc9d7e0c09842d19f0987e9ebbb4a
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer/*
e9458b1a7a19a63aa4c179f9ab20f4d50681c168Jens Elkner * System Security Services Daemon. NSS client interface
6b26240dca29e026900a83d51c75ca230a072a16Thiemo Wiedemeyer *
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * Copyright (C) Simo Sorce 2011
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu *
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * This program is free software; you can redistribute it and/or modify
2eeec5240b424984e3ee26296da1eeab6c6d739eChristian Maeder * it under the terms of the GNU Lesser General Public License as
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * published by the Free Software Foundation; either version 2.1 of the
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * License, or (at your option) any later version.
7520452bb30b5abbd471f82352fc4c1c937e02c5Till Mossakowski *
7520452bb30b5abbd471f82352fc4c1c937e02c5Till Mossakowski * This program is distributed in the hope that it will be useful,
7520452bb30b5abbd471f82352fc4c1c937e02c5Till Mossakowski * but WITHOUT ANY WARRANTY; without even the implied warranty of
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * GNU Lesser General Public License for more details.
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer *
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * You should have received a copy of the GNU Lesser General Public License
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer * along with this program. If not, see <http://www.gnu.org/licenses/>.
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer */
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer/* NSS interfaces to mmap cache */
8bdd8707c8e341f1fc57fcbf884520bfe06a5028Christian Maeder
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer#include "config.h"
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer#include <stdio.h>
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer#include <errno.h>
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer#include <sys/types.h>
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer#include <sys/stat.h>
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer#include <fcntl.h>
b0adcc203b4267d5535b430372935a5f36726db1Simon Ulbricht#include <unistd.h>
38122cbf09ad3dcc31a826cc4093f630515a5cfcChristian Maeder#include <sys/mman.h>
83263d411f611d9902ef4d98c93be6ad9361c833Christian Maeder#include <string.h>
abea93ed557b22ea833e1524ee5ca11afc12208aSimon Ulbricht#include <stdlib.h>
521045d36343cd17dd217a81d4b9422ad6ab6a07Christian Maeder#include "nss_mc.h"
9a9860760c6f30558e5e60049692b6fc63904590Markus Gross#include "sss_cli.h"
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer#include "util/io.h"
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer/* FIXME: hook up to library destructor to avoid leaks */
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer/* FIXME: temporarily open passwd file on our own, later we will probably
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer * use socket passing from the main process */
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer/* FIXME: handle name upper/lower casing ? Maybe a flag passed down by
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer * sssd or a flag in sss_mc_header ? per domain ? */
7ae38566aaf40710cd83ffa3ba25655c4ad22741Thiemo Wiedemeyer
1a389234e68da7c3d087b038307ed8c66fc6dc32Thiemo Wiedemeyer#define MEMCPY_WITH_BARRIERS(res, dest, src, len) \
f059d29e63508be7316ac161428eee7fc804736eChristian Maederdo { \
1c039dc13801bb9c90ad6a1bac0e56af19fd2fbfMihai Codescu uint32_t _b1; \
38122cbf09ad3dcc31a826cc4093f630515a5cfcChristian Maeder res = false; \
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer _b1 = (src)->b1; \
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer if (MC_VALID_BARRIER(_b1)) { \
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer __sync_synchronize(); \
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer memcpy(dest, src, len); \
3a6decfd748f532d5cb03fbcb7a42fa37b0faab3Christian Maeder __sync_synchronize(); \
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer if ((src)->b2 == _b1) { \
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer res = true; \
1842453990fed8a1bd7a5ac792d7982c1d2bfcd5Christian Maeder } \
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer } \
c208973c890b8f993297720fd0247bc7481d4304Christian Maeder} while(0)
b6a59f004903ac7bc96323ee3ef09c01fd221157Christian Maeder
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyererrno_t sss_nss_check_header(struct sss_cli_mc_ctx *ctx)
55c5e901b5c3466300009135585bc70bd576dcb6Christian Maeder{
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer struct sss_mc_header h;
ec25781c1180ea07f66b48c34f93cf5634e9277cChristian Maeder bool copy_ok;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer int count;
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer /* retry barrier protected reading max 5 times then give up */
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer for (count = 5; count > 0; count--) {
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder MEMCPY_WITH_BARRIERS(copy_ok, &h,
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer (struct sss_mc_header *)ctx->mmap_base,
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer sizeof(struct sss_mc_header));
d1066b8fb69179973dcab47154858d77e72760a7Thiemo Wiedemeyer if (copy_ok) {
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer /* record is consistent so we can proceed */
4e9e95ba35a68f3c767bc0b23ebf9e904e442517Christian Maeder break;
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer }
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer }
3587928ae948e8505f5af052dd4dc7cd97b6638eChristian Maeder if (count == 0) {
a7e5c17a679fa2dae5998cd04c7e9e06c05c8164Christian Maeder /* couldn't successfully read header we have to give up */
f9e0b18852b238ddb649d341194e05d7200d1bbeChristian Maeder return EIO;
697e63e30aa3c309a1ef1f9357745111f8dfc5a9Christian Maeder }
1e3aca4178372af672efb237d16087c603fe5564Christian Maeder
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer if (h.major_vno != SSS_MC_MAJOR_VNO ||
4b136ad539bd9f4e115dff4eee4d552a42d4437eChristian Maeder h.minor_vno != SSS_MC_MINOR_VNO ||
f456529a89bfb620d39e5fd5b0a53b24643db96dDominik Luecke h.status == SSS_MC_HEADER_RECYCLED) {
a79266feb130561fa1a95ae0429d0574f625f6ceChristian Maeder return EINVAL;
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer }
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer /* first time we check the header, let's fill our own struct */
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer if (ctx->data_table == NULL) {
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer ctx->seed = h.seed;
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer ctx->data_table = MC_PTR_ADD(ctx->mmap_base, h.data_table);
0d0278c34a374b29c2d6c58b39b8b56e283d48e8Christian Maeder ctx->hash_table = MC_PTR_ADD(ctx->mmap_base, h.hash_table);
2028dc2c091bb60343e15985948a59b955276cbfChristian Maeder ctx->dt_size = h.dt_size;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer ctx->ht_size = h.ht_size;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer } else {
16e45483b5ce48f0b92d01c817242a8c9b8bae02Christian Maeder if (ctx->seed != h.seed ||
ddc662fdf0207eae2034d7b68ae5e2225c575207Thiemo Wiedemeyer ctx->data_table != MC_PTR_ADD(ctx->mmap_base, h.data_table) ||
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer ctx->hash_table != MC_PTR_ADD(ctx->mmap_base, h.hash_table) ||
28ca54b0d63d1d26a991711c8c7e85c474994715Christian Maeder ctx->dt_size != h.dt_size ||
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu ctx->ht_size != h.ht_size) {
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu return EINVAL;
02a84229da51532505a93fc2abfca1ccf81b4446Razvan Pascanu }
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu }
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer return 0;
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer}
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyerstatic void sss_nss_mc_destroy_ctx(struct sss_cli_mc_ctx *ctx)
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer{
32d98ca5e560cf6c1062a0463be4c350af32bed5Thiemo Wiedemeyer if ((ctx->mmap_base != NULL) && (ctx->mmap_size != 0)) {
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer munmap(ctx->mmap_base, ctx->mmap_size);
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer }
32d98ca5e560cf6c1062a0463be4c350af32bed5Thiemo Wiedemeyer if (ctx->fd != -1) {
32d98ca5e560cf6c1062a0463be4c350af32bed5Thiemo Wiedemeyer close(ctx->fd);
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer }
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer memset(ctx, 0, sizeof(struct sss_cli_mc_ctx));
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer ctx->fd = -1;
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer}
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyerstatic errno_t sss_nss_mc_init_ctx(const char *name,
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer struct sss_cli_mc_ctx *ctx)
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu{
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer struct stat fdstat;
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer char *file = NULL;
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer int ret;
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer sss_nss_mc_lock();
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer /* check if ctx is initialised by previous thread. */
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer if (ctx->initialized != UNINITIALIZED) {
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer ret = sss_nss_check_header(ctx);
e49fd57c63845c7806860a9736ad09f6d44dbaedChristian Maeder goto done;
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer }
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer
0b8b26a22f136a9b2a8e99d655f6fe6b0b96008cThiemo Wiedemeyer ret = asprintf(&file, "%s/%s", SSS_NSS_MCACHE_DIR, name);
0b8b26a22f136a9b2a8e99d655f6fe6b0b96008cThiemo Wiedemeyer if (ret == -1) {
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer ret = ENOMEM;
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer goto done;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer }
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer ctx->fd = sss_open_cloexec(file, O_RDONLY, &ret);
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder if (ctx->fd == -1) {
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer goto done;
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer }
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer ret = fstat(ctx->fd, &fdstat);
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer if (ret == -1) {
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer ret = EIO;
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer goto done;
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer }
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer if (fdstat.st_size < MC_HEADER_SIZE) {
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer ret = ENOMEM;
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer goto done;
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer }
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer ctx->mmap_size = fdstat.st_size;
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer ctx->mmap_base = mmap(NULL, ctx->mmap_size,
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer PROT_READ, MAP_SHARED, ctx->fd, 0);
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer if (ctx->mmap_base == MAP_FAILED) {
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer ret = ENOMEM;
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder goto done;
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder }
0b8b26a22f136a9b2a8e99d655f6fe6b0b96008cThiemo Wiedemeyer
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer ret = sss_nss_check_header(ctx);
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer if (ret != 0) {
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer goto done;
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer }
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer ctx->initialized = INITIALIZED;
ea76e25262c3325f293fbdd6560f180ca18f9be4Thiemo Wiedemeyer
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer ret = 0;
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyerdone:
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer if (ret) {
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer sss_nss_mc_destroy_ctx(ctx);
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer }
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer free(file);
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer sss_nss_mc_unlock();
39a2520d13a7d43f0c0fa71b94255c3f7c500005Christian Maeder
39a2520d13a7d43f0c0fa71b94255c3f7c500005Christian Maeder return ret;
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer}
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyererrno_t sss_nss_mc_get_ctx(const char *name, struct sss_cli_mc_ctx *ctx)
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer{
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer char *envval;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer int ret;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer bool need_decrement = false;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer envval = getenv("SSS_NSS_USE_MEMCACHE");
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer if (envval && strcasecmp(envval, "NO") == 0) {
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer return EPERM;
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer }
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer switch (ctx->initialized) {
92e96be605537638d75e9d3023ab698bd89cf889Thiemo Wiedemeyer case UNINITIALIZED:
92e96be605537638d75e9d3023ab698bd89cf889Thiemo Wiedemeyer __sync_add_and_fetch(&ctx->active_threads, 1);
fa1bf658051ac503f27ff1b59edb093398eed6edThiemo Wiedemeyer ret = sss_nss_mc_init_ctx(name, ctx);
fa1bf658051ac503f27ff1b59edb093398eed6edThiemo Wiedemeyer if (ret) {
fa1bf658051ac503f27ff1b59edb093398eed6edThiemo Wiedemeyer need_decrement = true;
d24317c8197e565e60c8f41309de246249c1e57eChristian Maeder }
fa1bf658051ac503f27ff1b59edb093398eed6edThiemo Wiedemeyer break;
92e96be605537638d75e9d3023ab698bd89cf889Thiemo Wiedemeyer case INITIALIZED:
92e96be605537638d75e9d3023ab698bd89cf889Thiemo Wiedemeyer __sync_add_and_fetch(&ctx->active_threads, 1);
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder ret = sss_nss_check_header(ctx);
0d0278c34a374b29c2d6c58b39b8b56e283d48e8Christian Maeder if (ret) {
92e96be605537638d75e9d3023ab698bd89cf889Thiemo Wiedemeyer need_decrement = true;
92e96be605537638d75e9d3023ab698bd89cf889Thiemo Wiedemeyer }
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer break;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer case RECYCLED:
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer /* we need to safely destroy memory cache */
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer ret = EAGAIN;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer break;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer default:
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer ret = EFAULT;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer }
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer
d7aa4e1cbe00f7f3add4da911673b3b176b140c3Thiemo Wiedemeyer if (ret) {
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer if (ctx->initialized == INITIALIZED) {
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer ctx->initialized = RECYCLED;
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer }
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer if (ctx->initialized == RECYCLED && ctx->active_threads == 0) {
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder /* just one thread should call munmap */
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder sss_nss_mc_lock();
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer if (ctx->initialized == RECYCLED) {
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer sss_nss_mc_destroy_ctx(ctx);
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer }
39a2520d13a7d43f0c0fa71b94255c3f7c500005Christian Maeder sss_nss_mc_unlock();
4014fb09362f3e38a91d7bb11b1484a4790e9297Thiemo Wiedemeyer }
da1f9fa9339a0115d0559411929835bcff74e5f5Thiemo Wiedemeyer if (need_decrement) {
39a2520d13a7d43f0c0fa71b94255c3f7c500005Christian Maeder /* In case of error, we will not touch mmapped area => decrement */
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer __sync_sub_and_fetch(&ctx->active_threads, 1);
da1f9fa9339a0115d0559411929835bcff74e5f5Thiemo Wiedemeyer }
da1f9fa9339a0115d0559411929835bcff74e5f5Thiemo Wiedemeyer }
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder return ret;
4014fb09362f3e38a91d7bb11b1484a4790e9297Thiemo Wiedemeyer}
da1f9fa9339a0115d0559411929835bcff74e5f5Thiemo Wiedemeyer
4014fb09362f3e38a91d7bb11b1484a4790e9297Thiemo Wiedemeyeruint32_t sss_nss_mc_hash(struct sss_cli_mc_ctx *ctx,
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer const char *key, size_t len)
3e3efd4ce838940032e875e6d08712a177c9c1d0Thiemo Wiedemeyer{
3e3efd4ce838940032e875e6d08712a177c9c1d0Thiemo Wiedemeyer return murmurhash3(key, len, ctx->seed) % MC_HT_ELEMS(ctx->ht_size);
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder}
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder
239991d3955da0cfb760af4d506069446e1676b7Christian Maedererrno_t sss_nss_mc_get_record(struct sss_cli_mc_ctx *ctx,
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder uint32_t slot, struct sss_mc_rec **_rec)
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder{
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer struct sss_mc_rec *rec;
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer struct sss_mc_rec *copy_rec = NULL;
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer size_t buf_size = 0;
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder size_t rec_len;
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer uint32_t b1;
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer uint32_t b2;
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer bool copy_ok;
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder int count;
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer int ret;
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer /* try max 5 times */
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder for (count = 5; count > 0; count--) {
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer rec = MC_SLOT_TO_PTR(ctx->data_table, slot, struct sss_mc_rec);
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer /* fetch record length */
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder b1 = rec->b1;
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer __sync_synchronize();
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder rec_len = rec->len;
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder __sync_synchronize();
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder b2 = rec->b2;
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer if (!MC_VALID_BARRIER(b1) || b1 != b2) {
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer /* record is inconsistent, retry */
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder continue;
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder }
84ba39232a012abf2085c8a421ebce6abc52d56eThiemo Wiedemeyer
80df5ce65c2bad7a0643106e524fe33cdcfab5b6Thiemo Wiedemeyer if (!MC_CHECK_RECORD_LENGTH(ctx, rec)) {
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer /* record has invalid length */
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder free(copy_rec);
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder return EINVAL;
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder }
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder if (rec_len > buf_size) {
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer free(copy_rec);
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer copy_rec = malloc(rec_len);
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer if (!copy_rec) {
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer ret = ENOMEM;
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer goto done;
32d98ca5e560cf6c1062a0463be4c350af32bed5Thiemo Wiedemeyer }
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder buf_size = rec_len;
788bd3c33ec5aaeb90a1932c341ff837116410cfThiemo Wiedemeyer }
32d98ca5e560cf6c1062a0463be4c350af32bed5Thiemo Wiedemeyer /* we cannot access data directly, we must copy data and then
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer * access the copy */
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder MEMCPY_WITH_BARRIERS(copy_ok, copy_rec, rec, rec_len);
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer /* we must check data is consistent again after the copy */
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer if (copy_ok && b1 == copy_rec->b2) {
84ba39232a012abf2085c8a421ebce6abc52d56eThiemo Wiedemeyer /* record is consistent, use it */
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder break;
84ba39232a012abf2085c8a421ebce6abc52d56eThiemo Wiedemeyer }
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder }
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer if (count == 0) {
84ba39232a012abf2085c8a421ebce6abc52d56eThiemo Wiedemeyer /* couldn't successfully read header we have to give up */
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer ret = EIO;
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder goto done;
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder }
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder
545d0cd78159cade346b579d06052638b19b0f72Thiemo Wiedemeyer *_rec = copy_rec;
1a389234e68da7c3d087b038307ed8c66fc6dc32Thiemo Wiedemeyer ret = 0;
1a389234e68da7c3d087b038307ed8c66fc6dc32Thiemo Wiedemeyer
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyerdone:
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer if (ret) {
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu free(copy_rec);
a4e6fb26100f53e3b1e9f5b97c2e0a0c129294e5Christian Maeder *_rec = NULL;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu }
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu return ret;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu}
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer/*
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu * returns strings froma a buffer.
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu *
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu * Call first time with *cookie set to null, then call again
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer * with the returned cookie.
1a389234e68da7c3d087b038307ed8c66fc6dc32Thiemo Wiedemeyer * On the last string the cookie will be reset to null and
1a389234e68da7c3d087b038307ed8c66fc6dc32Thiemo Wiedemeyer * all strings will have been returned.
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer * In case the last string is not zero terminated EINVAL is returned.
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer */
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyererrno_t sss_nss_str_ptr_from_buffer(char **str, void **cookie,
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer char *buf, size_t len)
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer{
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer char *max = buf + len;
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer char *ret;
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer char *p;
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu if (*cookie == NULL) {
a4e6fb26100f53e3b1e9f5b97c2e0a0c129294e5Christian Maeder p = buf;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu } else {
a4e6fb26100f53e3b1e9f5b97c2e0a0c129294e5Christian Maeder p = *((char **)cookie);
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu }
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer ret = p;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer while (p < max) {
109b67ffce2bad83667e2f4a319d2d7f380f91afThiemo Wiedemeyer if (*p == '\0') {
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer break;
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer }
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer p++;
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer }
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer if (p >= max) {
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer return EINVAL;
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer }
2a9702a373738717c83824512bd9389b5870fc92Christian Maeder p++;
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer if (p == max) {
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer *cookie = NULL;
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer } else {
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer *cookie = p;
f39c70229e74147a02d15bd45c05a0b1b325532dChristian Maeder }
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer *str = ret;
d1066b8fb69179973dcab47154858d77e72760a7Thiemo Wiedemeyer return 0;
d1066b8fb69179973dcab47154858d77e72760a7Thiemo Wiedemeyer}
239991d3955da0cfb760af4d506069446e1676b7Christian Maeder
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyeruint32_t sss_nss_mc_next_slot_with_hash(struct sss_mc_rec *rec,
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer uint32_t hash)
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer{
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer if (rec->hash1 == hash) {
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer return rec->next1;
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer } else if (rec->hash2 == hash) {
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer return rec->next2;
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer } else {
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer /* it should never happen. */
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer return MC_INVALID_VAL;
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer }
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer
8bdd8707c8e341f1fc57fcbf884520bfe06a5028Christian Maeder}
f7b9d64160c23654b7288a3b0ee3e2b95af3e752Thiemo Wiedemeyer