nss_mc_common.c revision 3a4186ae40d0c3b7be46a4c973166f6048fcfe38
/*
* System Security Services Daemon. NSS client interface
*
* Copyright (C) Simo Sorce 2011
*
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* NSS interfaces to mmap cache */
#include "config.h"
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include "nss_mc.h"
/* FIXME: hook up to library destructor to avoid leaks */
/* FIXME: temporarily open passwd file on our own, later we will probably
* use socket passing from the main process */
* sssd or a flag in sss_mc_header ? per domain ? */
do { \
res = false; \
if (MC_VALID_BARRIER(_b1)) { \
__sync_synchronize(); \
__sync_synchronize(); \
res = true; \
} \
} \
} while(0)
{
struct sss_mc_header h;
bool copy_ok;
int count;
/* retry barrier protected reading max 5 times then give up */
sizeof(struct sss_mc_header));
if (copy_ok) {
/* record is consistent so we can proceed */
break;
}
}
if (count == 0) {
/* couldn't successfully read header we have to give up */
return EIO;
}
if (h.major_vno != SSS_MC_MAJOR_VNO ||
h.minor_vno != SSS_MC_MINOR_VNO ||
h.status == SSS_MC_HEADER_RECYCLED) {
return EINVAL;
}
/* first time we check the header, let's fill our own struct */
} else {
return EINVAL;
}
}
return 0;
}
{
char *envval;
int ret;
return EPERM;
}
if (ctx->initialized) {
goto done;
}
if (ret == -1) {
goto done;
}
goto done;
}
if (ret == -1) {
goto done;
}
goto done;
}
goto done;
}
if (ret != 0) {
goto done;
}
ctx->initialized = true;
ret = 0;
done:
if (ret) {
}
}
}
return ret;
}
{
}
{
struct sss_mc_rec *rec;
bool copy_ok;
int count;
int ret;
/* try max 5 times */
/* fetch record length */
/* record is inconsistent, retry */
continue;
}
/* record has invalid length */
return EINVAL;
}
if (!copy_rec) {
goto done;
}
}
/* we cannot access data directly, we must copy data and then
* access the copy */
/* we must check data is consistent again after the copy */
/* record is consistent, use it */
break;
}
}
if (count == 0) {
/* couldn't successfully read header we have to give up */
goto done;
}
ret = 0;
done:
if (ret) {
}
return ret;
}
/*
* returns strings froma a buffer.
*
* Call first time with *cookie set to null, then call again
* with the returned cookie.
* On the last string the cookie will be reset to null and
* all strings will have been returned.
* In case the last string is not zero terminated EINVAL is returned.
*/
{
char *ret;
char *p;
p = buf;
} else {
p = *((char **)cookie);
}
ret = p;
while (p < max) {
if (*p == '\0') {
break;
}
p++;
}
if (p >= max) {
return EINVAL;
}
p++;
if (p == max) {
} else {
*cookie = p;
}
return 0;
}