ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/*
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * CDDL HEADER START
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * The contents of this file are subject to the terms of the
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * Common Development and Distribution License (the "License").
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * You may not use this file except in compliance with the License.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * or http://www.opensolaris.org/os/licensing.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * See the License for the specific language governing permissions
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * and limitations under the License.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * When distributing Covered Code, include this CDDL HEADER in each
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * If applicable, add the following below this CDDL HEADER, with the
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * fields enclosed by brackets "[]" replaced with your own identifying
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * information: Portions Copyright [yyyy] [name of copyright owner]
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * CDDL HEADER END
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/*
6f269e977ae7318d374676a38d516ed59c43135eMark J. Nelson * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
1f2ca518aeecee8616fccc0c46a339773faea7d5Dan McDonald * Use is subject to license terms.
7b07063d906859b2be1e88791f801b3c96e432f6Igor Kozhukhov */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include "lint.h"
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <mtlib.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <ctype.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <stdio.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <stdlib.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <string.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <nss_dbdefs.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <limits.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <dlfcn.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <link.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <thread.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <atomic.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/* headers for key2str/str2key routines */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <sys/ethernet.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#include <exec_attr.h>
ae39239e04452933e89d03a1fb502e3e2836a332Mark J. Nelson#include <grp.h>
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/*
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * functions in nss_dbdefs.c deal more with the mechanics of
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * the data structures like nss_XbyY_args_t and the interaction
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * with the packed buffers etc. versus the mechanics of the
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * actual policy component operations such as nss_search sequencing.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/*
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * ALIGN? is there an official definition of this?
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * We use sizeof(long) to cover what we want
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * for both the 32-bit world and 64-bit world.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#define ALIGN(x) ((((long)(x)) + sizeof (long) - 1) & ~(sizeof (long) - 1))
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazanss_XbyY_buf_t *
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza_nss_XbyY_buf_alloc(int struct_size, int buffer_size)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza{
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza nss_XbyY_buf_t *b;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* Use one malloc for dbargs, result struct and buffer */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza b = (nss_XbyY_buf_t *)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza malloc(ALIGN(sizeof (*b)) + struct_size + buffer_size);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (b == 0) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (0);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza b->result = (void *)ALIGN(&b[1]);
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson b->buffer = (char *)(b->result) + struct_size;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza b->buflen = buffer_size;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson return (b);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza}
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazavoid
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza_nss_XbyY_buf_free(nss_XbyY_buf_t *b)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza{
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson if (b != 0) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza free(b);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza}
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/* === Comment: used by fget{gr,pw,sp}ent */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/* ==== Should do ye olde syslog()ing of suspiciously long lines */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazavoid
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza_nss_XbyY_fgets(FILE *f, nss_XbyY_args_t *b)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza{
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza char buf[LINE_MAX];
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza int len, parsestat;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (fgets(buf, LINE_MAX, f) == 0) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* End of file */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza b->returnval = 0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza b->erange = 0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = (int)strlen(buf);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* len >= 0 (otherwise we would have got EOF) */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (buf[len - 1] != '\n') {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if ((len + 1) == LINE_MAX) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* Line too long for buffer; too bad */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza while (fgets(buf, LINE_MAX, f) != 0 &&
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza buf[strlen(buf) - 1] != '\n') {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza ;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza b->returnval = 0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza b->erange = 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* case where the file is not terminated with a Newline */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len++;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza parsestat = (*b->str2ent)(buf, (len - 1), b->buf.result, b->buf.buffer,
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza b->buf.buflen);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (parsestat == NSS_STR_PARSE_ERANGE) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza b->returnval = 0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza b->erange = 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza } else if (parsestat == NSS_STR_PARSE_SUCCESS) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza b->returnval = b->buf.result;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza}
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/*
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * parse the aliases string into the buffer and if successful return
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * a char ** pointer to the beginning of the aliases.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * CAUTION: (instr, instr+lenstr) and (buffer, buffer+buflen) are
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * non-intersecting memory areas. Since this is an internal interface,
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson * we should be able to live with that.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazachar **
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza_nss_netdb_aliases(const char *instr, int lenstr, char *buffer, int buflen)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* "instr" is the beginning of the aliases string */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* "buffer" has the return val for success */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* "buflen" is the length of the buffer available for aliases */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza{
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /*
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * Build the alias-list in the start of the buffer, and copy
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * the strings to the end of the buffer.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza const char
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *instr_limit = instr + lenstr;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza char *copyptr = buffer + buflen;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza char **aliasp = (char **)ROUND_UP(buffer, sizeof (*aliasp));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza char **alias_start = aliasp;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza int nstrings = 0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza for (;;) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza const char *str_start;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza size_t str_len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza while (instr < instr_limit && isspace(*instr)) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza instr++;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (instr >= instr_limit || *instr == '#') {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza str_start = instr;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza while (instr < instr_limit && !isspace(*instr)) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza instr++;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza ++nstrings;
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe str_len = instr - str_start;
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe copyptr -= str_len + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (copyptr <= (char *)(&aliasp[nstrings + 1])) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* Has to be room for the pointer to */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* the alias we're about to add, */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* as well as the final NULL ptr. */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (0);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *aliasp++ = copyptr;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) memcpy(copyptr, str_start, str_len);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza copyptr[str_len] = '\0';
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *aliasp++ = 0;
33392354a001a7e6e504717bd3f249456d36cc00Alexander Pyhalov return (alias_start);
1f2ca518aeecee8616fccc0c46a339773faea7d5Dan McDonald}
33392354a001a7e6e504717bd3f249456d36cc00Alexander Pyhalov
9f9230833b50b8271840dc2c12bd1e94d9df7d12Alexander Pyhalov
9f9230833b50b8271840dc2c12bd1e94d9df7d12Alexander Pyhalovextern nss_status_t process_cstr(const char *, int, struct nss_groupsbymem *);
9f9230833b50b8271840dc2c12bd1e94d9df7d12Alexander Pyhalov
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/*
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * pack well known getXbyY keys to packed buffer prior to the door_call
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * to nscd. Some consideration is given to ordering the tests based on
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * usage. Note: buf is nssuint_t aligned.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazatypedef struct {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza const char *name; /* NSS_DBNAM_* */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza const char *defconf; /* NSS_DEFCONF_* */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza const char *initfn; /* init function name */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza const char *strfn; /* str2X function name */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza const char *cstrfn; /* cstr2X function name */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza void *initfnp; /* init function pointer */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza void *strfnp; /* str2X function pointer */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza uint32_t dbop; /* NSS_DBOP_* */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza const char *tostr; /* key2str cvt str */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza} getXbyY_to_dbop_t;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#define NSS_MK_GETXYDBOP(x, y, f, e) \
77c29b8ee88bf82021ff549b17b44e17f2ef7d7bRichard Lowe { NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, "str2" f, \
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NULL, NULL, NULL, NSS_DBOP_##x##_##y, (e) }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#define NSS_MK_GETXYDBOPA(x, a, f, e) \
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza { NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, "str2" f, \
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NULL, NULL, NULL, NSS_DBOP_##a, (e) }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#define NSS_MK_GETXYDBOPB(x, b, a, f, s, e) \
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza { NSS_DBNAM_##x, NSS_DEFCONF_##b, "_nss_initf_" f, s, \
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NULL, NULL, NULL, NSS_DBOP_##a, (e) }
b6805bf78d2bbbeeaea8909a05623587b42d58b3Gordon Ross
b6805bf78d2bbbeeaea8909a05623587b42d58b3Gordon Ross#define NSS_MK_GETXYDBOPC(x, a, f, s, e) \
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza { NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, s, \
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NULL, NULL, NULL, NSS_DBOP_##x##_##a, (e) }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#define NSS_MK_GETXYDBOPD(x, y, i, f, e) \
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza { NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" i, "str2" f, \
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross NULL, NULL, NULL, NSS_DBOP_##x##_##y, (e) }
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross#define NSS_MK_GETXYDBOPCSTR(x, a, f, s, e) \
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross { NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, s, \
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross "process_cstr", NULL, NULL, NSS_DBOP_##x##_##a, (e) }
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross/*
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross * The getXbyY_to_dbop structure is hashed on first call in order to
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross * reduce the search time for the well known getXbyY operations.
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross * A binary search was not fast enough. There were on average
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross * 3-4 tests (strcmps) per getXbyY call.
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross *
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross * DBOP_PRIME_HASH must be a prime number (reasonably small) but that
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross * is sufficient to uniquely map the entries in the following table
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross * without collision.
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross *
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross * The DBOP_PRIME_HASH was selected as the smallest hash value
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross * for this table without collisions. Changing this table WILL
14c3be3932e278c263b32fb17daff38fd4de18f8Gordon Ross * necessitate re-testing for possible collisions.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#define DBOP_PRIME_HASH 227
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza#define DBOP_HASH_TAG 0xf0000000
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazastatic int getXbyYdbopHASH[DBOP_PRIME_HASH] = { 0 };
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazastatic mutex_t getXbydbop_hash_lock = DEFAULTMUTEX;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazastatic int getXbyYdbop_hashed = 0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/*
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * If the size of getXbyY_to_dbop[] is changed then hash function must be
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * corrected to be without collisions in nss_dbop_search().
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazastatic getXbyY_to_dbop_t getXbyY_to_dbop[] = {
ac823a0f31ed9c8cbe505cee2def262ac92ea6cdJon Tibble /* NSS_MK_GETXYDBOP(ALIASES, ?, ?), */
ac823a0f31ed9c8cbe505cee2def262ac92ea6cdJon Tibble NSS_MK_GETXYDBOPD(AUDITUSER, BYNAME, "auuser", "audituser", "n"),
ac823a0f31ed9c8cbe505cee2def262ac92ea6cdJon Tibble NSS_MK_GETXYDBOP(AUTHATTR, BYNAME, "authattr", "n"),
ac823a0f31ed9c8cbe505cee2def262ac92ea6cdJon Tibble /* NSS_MK_GETXYDBOP(AUTOMOUNT, ?, ?), */
ac823a0f31ed9c8cbe505cee2def262ac92ea6cdJon Tibble NSS_MK_GETXYDBOP(BOOTPARAMS, BYNAME, "bootparams", "n"),
ac823a0f31ed9c8cbe505cee2def262ac92ea6cdJon Tibble NSS_MK_GETXYDBOPC(ETHERS, HOSTTON, "ethers", "str2ether", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(ETHERS, NTOHOST, "ethers", "str2ether", "e"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(EXECATTR, BYNAME, "execattr", "A"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(EXECATTR, BYID, "execattr", "A"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(EXECATTR, BYNAMEID, "execattr", "A"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(GROUP, BYNAME, "group", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(GROUP, BYGID, "group", "g"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPCSTR(GROUP, BYMEMBER, "group", "str2group", "I"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(HOSTS, BYNAME, "hosts", "str2hostent", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(HOSTS, BYADDR, "hosts", "str2hostent", "h"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(IPNODES, BYNAME, "ipnodes", "str2hostent", "i"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(IPNODES, BYADDR, "ipnodes", "str2hostent", "h"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(NETGROUP, IN, "netgroup", "t"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(NETGROUP, SET, "netgroup", "T"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(NETMASKS, BYNET, "netmasks", "str2addr", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(NETWORKS, BYNAME, "net", "str2netent", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(NETWORKS, BYADDR, "net", "str2netent", "a"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(PASSWD, BYNAME, "passwd", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(PASSWD, BYUID, "passwd", "u"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(PRINTERS, BYNAME, "printers", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(PROFATTR, BYNAME, "profattr", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(PROJECT, BYNAME, "project", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(PROJECT, BYID, "project", "p"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(PROTOCOLS, BYNAME, "proto", "str2protoent", "n"),
0ea64585698b885134cf212069f5ff7ebda376a6Liane Praza NSS_MK_GETXYDBOPC(PROTOCOLS, BYNUMBER, "proto", "str2protoent", "N"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPA(PUBLICKEY, KEYS_BYNAME, "publickey", "k"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(RPC, BYNAME, "rpc", "str2rpcent", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(RPC, BYNUMBER, "rpc", "str2rpcent", "N"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(SERVICES, BYNAME, "services", "str2servent", "s"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(SERVICES, BYPORT, "services", "str2servent", "S"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPB(SHADOW, PASSWD, PASSWD_BYNAME, "shadow",
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza "str2spwd", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(TSOL_RH, BYADDR, "tsol_rh", "str_to_rhstr", "h"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(TSOL_TP, BYNAME, "tsol_tp", "str_to_tpstr", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOPC(TSOL_ZC, BYNAME, "tsol_zc", "str_to_zcstr", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza NSS_MK_GETXYDBOP(USERATTR, BYNAME, "userattr", "n"),
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza};
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazastatic int
ae39239e04452933e89d03a1fb502e3e2836a332Mark J. Nelsonnss_dbop_search(const char *name, uint32_t dbop)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza{
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza getXbyY_to_dbop_t *hptr;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza int count = (sizeof (getXbyY_to_dbop) / sizeof (getXbyY_to_dbop_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza uint32_t hval, g;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza const char *cp;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza int i, idx;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza static const uint32_t hbits_tst = 0xf0000000;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* Uses a table size is known to have no collisions */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (getXbyYdbop_hashed == 0) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza lmutex_lock(&getXbydbop_hash_lock);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (getXbyYdbop_hashed == 0) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza for (i = 0; i < count; i++) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza cp = getXbyY_to_dbop[i].name;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval = 0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza while (*cp) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval = (hval << 4) + *cp++;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if ((g = (hval & hbits_tst)) != 0)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval ^= g >> 24;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval &= ~g;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval += getXbyY_to_dbop[i].dbop;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval %= DBOP_PRIME_HASH;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (getXbyYdbopHASH[hval] != 0) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* hash table collision-see above */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza lmutex_unlock(&getXbydbop_hash_lock);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (-1);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza getXbyYdbopHASH[hval] = i | DBOP_HASH_TAG;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza membar_producer();
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza getXbyYdbop_hashed = 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza lmutex_unlock(&getXbydbop_hash_lock);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza membar_consumer();
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza cp = name;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval = 0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza while (*cp) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval = (hval << 4) + *cp++;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if ((g = (hval & hbits_tst)) != 0)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval ^= g >> 24;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval &= ~g;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval += dbop;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hval %= DBOP_PRIME_HASH;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza idx = getXbyYdbopHASH[hval];
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if ((idx & DBOP_HASH_TAG) != DBOP_HASH_TAG)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (-1);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza idx &= ~DBOP_HASH_TAG;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (idx >= count)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (-1);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza hptr = &getXbyY_to_dbop[idx];
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (hptr->dbop != dbop || strcmp(name, hptr->name) != 0)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (-1);
07b48dbef2d1395c82edeccaf10e42ea7c0b6b36Yuri Pankov return (idx);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza}
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/*
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * nss_pack_key2str
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * Private key to string packing function for getXbyY routines
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * This routine performs a printf like parse over the argument
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * key, given a string of items to pack and assembles the key in
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * the packed structure. This routine is called (currently) by
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * nss_default_key2str, but will be used by other external
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * APIs in the future.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * buffer - Start of the key buffer location [in packed buffer]
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * length - Length of key buffer component
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * Key offsets are relative to start of key buffer location.
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson * Pack fields Key
e3c7c8f87921d6207a2ea7e79b31f9762e18116fMark J. Nelson * key.name n
e3c7c8f87921d6207a2ea7e79b31f9762e18116fMark J. Nelson * key.number N
e3c7c8f87921d6207a2ea7e79b31f9762e18116fMark J. Nelson * key.uid u
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * key.gid g
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * key.hostaddr h
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * key.ipnode i
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * key.projid p
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * key.serv(name) s
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * key.serv(port) S
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * key.ether e
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * key.pkey k
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * key.netaddr a
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * key.attrp A
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * groupsbymember I
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * innetgr_args t
3d312ee2210d825807c3486aa998ebd8bc2f3a43Mark J. Nelson * setnetgr_args T
3d312ee2210d825807c3486aa998ebd8bc2f3a43Mark J. Nelson */
3d312ee2210d825807c3486aa998ebd8bc2f3a43Mark J. Nelson
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza/*ARGSUSED*/
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazastatic nss_status_t
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Prazanss_pack_key2str(void *buffer, size_t length, nss_XbyY_args_t *arg,
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza const char *dbname, int dbop, size_t *rlen, const char *typestr)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza{
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza int i, j;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza size_t len, len2, len3, len4, len5, slop;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza nssuint_t *uptr, offv, offc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza struct nss_setnetgrent_args *sng;
ac823a0f31ed9c8cbe505cee2def262ac92ea6cdJon Tibble struct nss_innetgr_args *ing;
ac823a0f31ed9c8cbe505cee2def262ac92ea6cdJon Tibble struct nss_groupsbymem *gbm;
a01be845e9dee367d46c5b5e02e8f1e9d7c98be3Mark J. Nelson char **cv, *dptr;
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson nss_pnetgr_t *pptr;
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson _priv_execattr *pe;
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson if (buffer == NULL || length == 0 || arg == NULL ||
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson dbname == NULL || rlen == NULL || typestr == NULL)
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson return (NSS_ERROR);
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson while (typestr && *typestr) {
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson switch (*typestr++) {
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson case 'n':
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson if (arg->key.name == NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_NOTFOUND);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = strlen(arg->key.name) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
e3c7c8f87921d6207a2ea7e79b31f9762e18116fMark J. Nelson (void) strlcpy(buffer, arg->key.name, len);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 'N':
07b48dbef2d1395c82edeccaf10e42ea7c0b6b36Yuri Pankov len = sizeof (nssuint_t);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *(nssuint_t *)buffer = (nssuint_t)arg->key.number;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 'u':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = sizeof (nssuint_t);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *(nssuint_t *)buffer = (nssuint_t)arg->key.uid;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 'g':
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson len = sizeof (nssuint_t);
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson if (len >= length)
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson return (NSS_ERROR);
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson *(nssuint_t *)buffer = (nssuint_t)arg->key.gid;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson *rlen = len;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 'h':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (arg->key.hostaddr.addr == NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (-1);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = arg->key.hostaddr.len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = ROUND_UP(len, sizeof (nssuint_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len2 = (sizeof (nssuint_t) * 2) + len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len2 >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *(nssuint_t *)buffer =
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (nssuint_t)arg->key.hostaddr.len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza buffer = (void *)((char *)buffer + sizeof (nssuint_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *(nssuint_t *)buffer =
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (nssuint_t)arg->key.hostaddr.type;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza buffer = (void *)((char *)buffer + sizeof (nssuint_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) memcpy(buffer, arg->key.hostaddr.addr,
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza arg->key.hostaddr.len);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len2;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 'i':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (arg->key.ipnode.name == NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_NOTFOUND);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = strlen(arg->key.ipnode.name) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = ROUND_UP(len, sizeof (nssuint_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len2 = (sizeof (nssuint_t) * 2) + len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len2 >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *(nssuint_t *)buffer =
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (nssuint_t)arg->key.ipnode.af_family;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza buffer = (void *)((char *)buffer + sizeof (nssuint_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *(nssuint_t *)buffer =
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (nssuint_t)arg->key.ipnode.flags;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza buffer = (void *)((char *)buffer + sizeof (nssuint_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy(buffer, arg->key.ipnode.name, len);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len2;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 'p':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = sizeof (nssuint_t);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *(nssuint_t *)buffer = (nssuint_t)arg->key.projid;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 's':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (arg->key.serv.serv.name == NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_NOTFOUND);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = strlen(arg->key.serv.serv.name) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len2 = 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (arg->key.serv.proto != NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len2 += strlen(arg->key.serv.proto);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 = len + len2;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 = ROUND_UP(len3, sizeof (nssuint_t));
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price if (len3 >= length)
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price return (NSS_ERROR);
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price (void) strlcpy(buffer, arg->key.serv.serv.name, len);
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price buffer = (void *)((char *)buffer + len);
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price if (len2 > 1)
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price (void) strlcpy(buffer, arg->key.serv.proto,
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price len2);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza else
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *(char *)buffer = '\0';
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len3;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 'S':
77c29b8ee88bf82021ff549b17b44e17f2ef7d7bRichard Lowe len2 = 0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (arg->key.serv.proto != NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len2 = strlen(arg->key.serv.proto) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = sizeof (nssuint_t) + len2;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza uptr = (nssuint_t *)buffer;
efcb7078c2d1766a6682e861629cafbc6724c14aYuri Pankov *uptr++ = (nssuint_t)arg->key.serv.serv.port;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len2) {
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson (void) strlcpy((char *)uptr,
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price arg->key.serv.proto, len2);
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price }
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price *rlen = len;
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price break;
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price case 'e':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (arg->key.ether == NULL)
d34af1a4fea9785e1d7f8aff94fe157b2af0d2f5Mark J. Nelson return (NSS_NOTFOUND);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = sizeof (struct ether_addr);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = ROUND_UP(len, sizeof (nssuint_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *(struct ether_addr *)buffer =
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *(struct ether_addr *)arg->key.ether;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson case 'k':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (arg->key.pkey.name == NULL ||
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson arg->key.pkey.keytype == NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_NOTFOUND);
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price len = strlen(arg->key.pkey.name) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len2 = strlen(arg->key.pkey.keytype) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 = len + len2;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 = ROUND_UP(len3, sizeof (nssuint_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len3 >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy(buffer, arg->key.pkey.name, len);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza buffer = (void *)((char *)buffer + len);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy(buffer, arg->key.pkey.keytype, len2);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len3;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 'a':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza uptr = (nssuint_t *)buffer;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = sizeof (nssuint_t) * 2;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *uptr++ = (nssuint_t)arg->key.netaddr.net;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *uptr++ = (nssuint_t)arg->key.netaddr.type;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 'A':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza pe = (_priv_execattr *)(arg->key.attrp);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (pe == NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_NOTFOUND);
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson /* for search flag */
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson len = sizeof (nssuint_t);
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson /* for sizeof (_priv_execattr) static buffer */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* Plus lots of slop just in case... */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza slop = sizeof (nssuint_t) * 16;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len += slop;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len2 = len3 = len4 = len5 = 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (pe->name != NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len2 = strlen(pe->name) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (pe->type != NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 = strlen(pe->type) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (pe->id != NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len4 = strlen(pe->id) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (pe->policy != NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len5 = strlen(pe->policy) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /* head_exec, prev_exec - are client side only... */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len += len2 + len3 + len4 + len5;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = ROUND_UP(len, sizeof (nssuint_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price (void) memset((void *)buffer, 0, slop);
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price uptr = (nssuint_t *)((void *)((char *)buffer + slop));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *uptr++ = (nssuint_t)pe->search_flag;
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price dptr = (char *)uptr;
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price if (len2 == 1)
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price *dptr++ = '\0';
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza else {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy(dptr, pe->name, len2);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza dptr += len2;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len3 == 1)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *dptr++ = '\0';
ebbab6bbae913efeadfa3c6a1b082664a125f95bDan Price else {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy(dptr, pe->type, len3);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza dptr += len3;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len4 == 1)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *dptr++ = '\0';
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza else {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy(dptr, pe->id, len4);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza dptr += len4;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len5 == 1)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *dptr++ = '\0';
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza else
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy(dptr, pe->policy, len5);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 'I':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza gbm = (struct nss_groupsbymem *)arg;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (gbm->username == NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_NOTFOUND);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = strlen(gbm->username) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len2 = sizeof (nssuint_t) * 4;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len2 += ROUND_UP(len, sizeof (nssuint_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len2 >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza uptr = (nssuint_t *)buffer;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *uptr++ = (nssuint_t)gbm->force_slow_way;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *uptr++ = (nssuint_t)gbm->maxgids;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *uptr++ = (nssuint_t)gbm->numgids;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (gbm->numgids == 1) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *uptr++ = (nssuint_t)gbm->gid_array[0];
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza } else {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *uptr++ = (nssuint_t)0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy((void *)uptr, gbm->username, len);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len2;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 't':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza pptr = (nss_pnetgr_t *)buffer;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza ing = (struct nss_innetgr_args *)arg;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = sizeof (nss_pnetgr_t);
7b07063d906859b2be1e88791f801b3c96e432f6Igor Kozhukhov len2 = ing->arg[NSS_NETGR_MACHINE].argc +
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza ing->arg[NSS_NETGR_USER].argc +
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza ing->arg[NSS_NETGR_DOMAIN].argc +
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza ing->groups.argc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len2 *= sizeof (nssuint_t);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 = 0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza for (j = 0; j < NSS_NETGR_N; j++) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza cv = ing->arg[j].argv;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza for (i = ing->arg[j].argc; --i >= 0; ) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (*cv)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 += strlen(*cv++) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza cv = ing->groups.argv;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza for (i = ing->groups.argc; --i >= 0; ) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (*cv)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 += strlen(*cv++) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 = ROUND_UP(len3, sizeof (nssuint_t));
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza /*
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * Double argv space. Reason:
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * First 1/2 offsets
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * Second 1/2 for client side pointer arrays
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza * resolves malloc/free issues with unpacked argvs
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza */
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if ((len + (len2 << 1) + len3) >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len + (len2 << 1) + len3;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza pptr->machine_argc = ing->arg[NSS_NETGR_MACHINE].argc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza pptr->user_argc = ing->arg[NSS_NETGR_USER].argc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza pptr->domain_argc = ing->arg[NSS_NETGR_DOMAIN].argc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza pptr->groups_argc = ing->groups.argc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza offv = len;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson uptr = (nssuint_t *)((void *)((char *)buffer + offv));
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson offc = len + (len2 << 1);
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson dptr = (char *)buffer + offc;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson if (pptr->machine_argc == 0) {
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson pptr->machine_offv = (nssuint_t)0;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson } else {
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson pptr->machine_offv = offv;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson cv = ing->arg[NSS_NETGR_MACHINE].argv;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson i = pptr->machine_argc;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson offv += sizeof (nssuint_t) * i;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson for (; --i >= 0; ) {
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson *uptr++ = offc;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson len3 = strlen(*cv) + 1;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson (void) strlcpy(dptr, *cv++, len3);
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson offc += len3;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson dptr += len3;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson }
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson }
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson if (pptr->user_argc == 0) {
7b07063d906859b2be1e88791f801b3c96e432f6Igor Kozhukhov pptr->user_offv = (nssuint_t)0;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson } else {
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson pptr->user_offv = offv;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson cv = ing->arg[NSS_NETGR_USER].argv;
5084e753b79a753c8b532c06eb3ad1d025e8e472Mark J. Nelson i = pptr->user_argc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza offv += sizeof (nssuint_t) * i;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza for (; --i >= 0; ) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *uptr++ = offc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 = strlen(*cv) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy(dptr, *cv++, len3);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza offc += len3;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza dptr += len3;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (pptr->domain_argc == 0) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza pptr->domain_offv = (nssuint_t)0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza } else {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza pptr->domain_offv = offv;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza cv = ing->arg[NSS_NETGR_DOMAIN].argv;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza i = pptr->domain_argc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza offv += sizeof (nssuint_t) * i;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza for (; --i >= 0; ) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *uptr++ = offc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 = strlen(*cv) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy(dptr, *cv++, len3);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza offc += len3;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza dptr += len3;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (pptr->groups_argc == 0) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza pptr->groups_offv = (nssuint_t)0;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza } else {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza pptr->groups_offv = offv;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza cv = ing->groups.argv;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza i = pptr->groups_argc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza offv += sizeof (nssuint_t) * i;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza for (; --i >= 0; ) {
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *uptr++ = offc;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len3 = strlen(*cv) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy(dptr, *cv++, len3);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza offc += len3;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza dptr += len3;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza case 'T':
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza sng = (struct nss_setnetgrent_args *)arg;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (sng->netgroup == NULL)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_NOTFOUND);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza len = strlen(sng->netgroup) + 1;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza if (len >= length)
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza (void) strlcpy(buffer, sng->netgroup, len);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza *rlen = len;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza break;
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza default:
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_ERROR);
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza }
ead1f93ee620d7580f7e53350fe5a884fc4f158aLiane Praza return (NSS_SUCCESS);
}
nss_status_t
nss_default_key2str(void *buffer, size_t length, nss_XbyY_args_t *arg,
const char *dbname, int dbop, size_t *rlen)
{
int index;
if (buffer == NULL || length == 0 || arg == NULL ||
dbname == NULL || rlen == NULL)
return (NSS_ERROR);
/*
* If this is not one of the well known getXbyYs
* (IE _printers special processing etc.) use a
* local (non-nscd) getXbyY lookup.
*/
if ((index = nss_dbop_search(dbname, (uint32_t)dbop)) < 0)
return (NSS_TRYLOCAL);
return (nss_pack_key2str(buffer, length, arg, dbname,
dbop, rlen, getXbyY_to_dbop[index].tostr));
}
/*ARGSUSED*/
void
nss_packed_set_status(void *buffer, size_t length, nss_status_t status,
nss_XbyY_args_t *arg)
{
nss_pheader_t *pbuf = (nss_pheader_t *)buffer;
nss_dbd_t *pdbd;
char *dbn;
/* sidestep odd cases */
pdbd = (nss_dbd_t *)((void *)((char *)buffer + pbuf->dbd_off));
dbn = (char *)pdbd + pdbd->o_name;
if (pbuf->nss_dbop == NSS_DBOP_GROUP_BYMEMBER) {
if (strcmp(dbn, NSS_DBNAM_GROUP) == 0) {
struct nss_groupsbymem *in =
(struct nss_groupsbymem *)arg;
if (in->numgids >= 0) {
pbuf->p_status = NSS_SUCCESS;
pbuf->data_len = in->numgids *
sizeof (gid_t);
pbuf->p_herrno = 0;
} else {
pbuf->p_status = status;
pbuf->p_errno = errno;
pbuf->data_len = 0;
pbuf->p_herrno = (uint32_t)arg->h_errno;
}
return;
}
}
if (pbuf->nss_dbop == NSS_DBOP_NETGROUP_IN) {
if (strcmp(dbn, NSS_DBNAM_NETGROUP) == 0) {
struct nss_innetgr_args *in =
(struct nss_innetgr_args *)arg;
/* tell nss_unpack() operation is successful */
pbuf->data_len = 1;
if (status != NSS_SUCCESS && status != NSS_NOTFOUND) {
pbuf->p_status = status;
pbuf->p_errno = errno;
return;
}
if (in->status == NSS_NETGR_FOUND) {
pbuf->p_status = NSS_SUCCESS;
} else {
pbuf->p_status = NSS_NOTFOUND;
pbuf->p_errno = errno;
}
return;
}
}
/* process normal cases */
if ((pbuf->p_status = status) != NSS_SUCCESS) {
if (arg->erange == 1)
pbuf->p_errno = ERANGE;
else
pbuf->p_errno = errno;
} else
pbuf->p_errno = 0;
if (arg != NULL) {
pbuf->p_herrno = (uint32_t)arg->h_errno;
pbuf->data_len = (nssuint_t)arg->returnlen;
} else {
pbuf->p_herrno = 0;
pbuf->data_len = 0;
}
}
/*
* nss_upack_key2arg
* Private string to key unpacking function for getXbyY routines
* This routine performs a scanf/printf like parse over the packed
* string, to uppack and re-assemble the key in the args structure.
*
* buffer - Start of the key buffer location [in packed buffer]
* length - Length of key buffer component
* Key offsets are relative to start of key buffer location.
*
* Unpack fields Key
* key.name n
* key.number N
* key.uid u
* key.gid g
* key.hostaddr h
* key.ipnode i
* key.projid p
* key.serv(name) s
* key.serv(port) S
* key.ether e
* key.pkey k
* key.netaddr a
* key.attrp A
* groupsbymember I
* innetgr_args t
* setnetgr_args T
* Assumes arguments are all valid
*/
/*ARGSUSED*/
static nss_status_t
nss_upack_key2arg(void *buffer, size_t length, char **dbname,
int *dbop, nss_XbyY_args_t *arg, int index)
{
nss_pheader_t *pbuf = (nss_pheader_t *)buffer;
const char *strtype = NULL;
nssuint_t off, *uptr, keysize;
size_t len, slop;
int i, j;
char **cv, *bptr;
struct nss_setnetgrent_args *sng;
struct nss_innetgr_args *ing;
struct nss_groupsbymem *gbm;
nss_pnetgr_t *pptr;
_priv_execattr *pe;
/* keysize is length of the key area */
keysize = pbuf->data_off - pbuf->key_off;
off = pbuf->key_off;
bptr = (char *)buffer + off;
uptr = (nssuint_t *)((void *)bptr);
strtype = getXbyY_to_dbop[index].tostr;
if (strtype == NULL)
return (NSS_ERROR);
while (*strtype) {
switch (*strtype++) {
case 'n':
arg->key.name = (const char *)bptr;
break;
case 'N':
arg->key.number = (int)(*uptr);
break;
case 'u':
arg->key.uid = (uid_t)(*uptr);
break;
case 'g':
arg->key.gid = (gid_t)(*uptr);
break;
case 'h':
arg->key.hostaddr.len = (int)(*uptr++);
arg->key.hostaddr.type = (int)(*uptr++);
arg->key.hostaddr.addr = (const char *)uptr;
break;
case 'i':
arg->key.ipnode.af_family = (int)(*uptr++);
arg->key.ipnode.flags = (int)(*uptr++);
arg->key.ipnode.name = (const char *)uptr;
break;
case 'p':
arg->key.projid = (projid_t)(*uptr);
break;
case 's':
arg->key.serv.serv.name = (const char *)bptr;
len = strlen(arg->key.serv.serv.name) + 1;
bptr += len;
if (*(const char *)bptr == '\0')
arg->key.serv.proto = NULL;
else
arg->key.serv.proto = (const char *)bptr;
break;
case 'S':
arg->key.serv.serv.port = (int)(*uptr++);
if (pbuf->key_len == sizeof (nssuint_t)) {
arg->key.serv.proto = NULL;
} else {
bptr += sizeof (nssuint_t);
arg->key.serv.proto = (const char *)bptr;
}
break;
case 'e':
arg->key.ether = bptr;
break;
case 'k':
arg->key.pkey.name = (const char *)bptr;
len = strlen(arg->key.pkey.name) + 1;
bptr += len;
arg->key.pkey.keytype = (const char *)bptr;
break;
case 'a':
arg->key.netaddr.net = (uint32_t)(*uptr++);
arg->key.netaddr.type = (int)(*uptr++);
break;
case 'A':
pe = (_priv_execattr *)((void *)bptr);
/* use slop space as priv_execattr structure */
arg->key.attrp = (void *)pe;
/* skip over slop ... */
slop = sizeof (nssuint_t) * 16;
uptr = (nssuint_t *)((void *)((char *)bptr + slop));
pe->search_flag = (int)*uptr++;
bptr = (char *)uptr;
if (*bptr == '\0') {
pe->name = NULL;
bptr++;
} else {
pe->name = (char *)bptr;
bptr += strlen(pe->name) + 1;
}
if (*bptr == '\0') {
pe->type = NULL;
bptr++;
} else {
pe->type = (char *)bptr;
bptr += strlen(pe->type) + 1;
}
if (*bptr == '\0') {
pe->id = NULL;
bptr++;
} else {
pe->id = (char *)bptr;
bptr += strlen(pe->id) + 1;
}
if (*bptr == '\0') {
pe->policy = NULL;
} else {
pe->policy = (char *)bptr;
}
pe->head_exec = NULL;
pe->prev_exec = NULL;
break;
case 'I':
gbm = (struct nss_groupsbymem *)arg;
gbm->gid_array = (gid_t *)
((void *)((char *)pbuf + pbuf->data_off));
gbm->force_slow_way = (int)(*uptr++);
gbm->maxgids = (int)(*uptr++);
gbm->numgids = (int)(*uptr++);
if (gbm->numgids == 1) {
/* insert initial group into data area */
gbm->gid_array[0] = (gid_t)(*uptr++);
} else
uptr++;
gbm->username = (const char *)uptr;
break;
case 't':
pptr = (nss_pnetgr_t *)((void *)bptr);
ing = (struct nss_innetgr_args *)arg;
ing->arg[NSS_NETGR_MACHINE].argc = pptr->machine_argc;
ing->arg[NSS_NETGR_USER].argc = pptr->user_argc;
ing->arg[NSS_NETGR_DOMAIN].argc = pptr->domain_argc;
ing->groups.argc = pptr->groups_argc;
/*
* Start of argv pointer storage
*/
off = ing->arg[NSS_NETGR_MACHINE].argc +
ing->arg[NSS_NETGR_USER].argc +
ing->arg[NSS_NETGR_DOMAIN].argc +
ing->groups.argc;
off *= sizeof (nssuint_t);
off += sizeof (nss_pnetgr_t);
cv = (char **)((void *)(bptr + off));
uptr = (nssuint_t *)
((void *)(bptr + sizeof (nss_pnetgr_t)));
for (j = 0; j < NSS_NETGR_N; j++) {
ing->arg[j].argv = cv;
for (i = 0; i < ing->arg[j].argc; i++) {
if (*uptr >= keysize)
return (NSS_ERROR);
*cv++ = (bptr + *uptr++);
}
}
ing->groups.argv = cv;
for (i = 0; i < ing->groups.argc; i++) {
if (*uptr >= keysize)
return (NSS_ERROR);
*cv++ = (bptr + *uptr++);
}
break;
case 'T':
sng = (struct nss_setnetgrent_args *)arg;
sng->netgroup = (const char *)bptr;
sng->iterator = 0;
break;
default:
return (NSS_ERROR);
}
}
return (NSS_SUCCESS);
}
static nss_status_t
nss_pinit_funcs(int index, nss_db_initf_t *initf, nss_str2ent_t *s2e)
{
const char *name;
void *htmp = NULL;
void *sym;
static void *handle = NULL;
static mutex_t handle_lock = DEFAULTMUTEX;
static mutex_t initf_lock = DEFAULTMUTEX;
static mutex_t s2e_lock = DEFAULTMUTEX;
if (handle == NULL) {
htmp = dlopen((const char *)0, RTLD_LAZY);
lmutex_lock(&handle_lock);
if (handle == NULL) {
if (htmp == NULL) {
lmutex_unlock(&handle_lock);
return (NSS_ERROR);
} else {
membar_producer();
handle = htmp;
htmp = NULL;
}
}
lmutex_unlock(&handle_lock);
if (htmp)
(void) dlclose(htmp);
}
membar_consumer();
if (initf) {
if (getXbyY_to_dbop[index].initfnp == NULL) {
name = getXbyY_to_dbop[index].initfn;
if ((sym = dlsym(handle, name)) == NULL)
return (NSS_ERROR);
lmutex_lock(&initf_lock);
if (getXbyY_to_dbop[index].initfnp == NULL)
getXbyY_to_dbop[index].initfnp = sym;
membar_producer();
lmutex_unlock(&initf_lock);
}
membar_consumer();
*initf = (nss_db_initf_t)getXbyY_to_dbop[index].initfnp;
}
if (s2e) {
if (getXbyY_to_dbop[index].strfnp == NULL) {
name = getXbyY_to_dbop[index].strfn;
if ((sym = dlsym(handle, name)) == NULL)
return (NSS_ERROR);
lmutex_lock(&s2e_lock);
if (getXbyY_to_dbop[index].strfnp == NULL)
getXbyY_to_dbop[index].strfnp = sym;
membar_producer();
lmutex_unlock(&s2e_lock);
}
membar_consumer();
*s2e = (nss_str2ent_t)getXbyY_to_dbop[index].strfnp;
}
return (NSS_SUCCESS);
}
nss_status_t
nss_packed_getkey(void *buffer, size_t length, char **dbname,
int *dbop, nss_XbyY_args_t *arg)
{
nss_pheader_t *pbuf = (nss_pheader_t *)buffer;
nss_dbd_t *pdbd;
nssuint_t off, dbdsize;
int index;
if (buffer == NULL || length == 0 || dbop == NULL ||
arg == NULL || dbname == NULL)
return (NSS_ERROR);
*dbop = pbuf->nss_dbop;
off = pbuf->dbd_off;
pdbd = (nss_dbd_t *)((void *)((char *)buffer + off));
dbdsize = pbuf->key_off - pbuf->dbd_off;
if (pdbd->o_name >= dbdsize || pdbd->o_config_name >= dbdsize ||
pdbd->o_default_config >= dbdsize)
return (NSS_ERROR);
*dbname = (char *)buffer + off + pdbd->o_name;
if ((index = nss_dbop_search(*dbname, (uint32_t)*dbop)) < 0)
return (NSS_ERROR);
return (nss_upack_key2arg(buffer, length, dbname, dbop, arg, index));
}
/*
* str2packent: Standard format interposed str2X function for normal APIs
*
* Return values: 0 = success, 1 = parse error, 2 = erange ...
*
* The structure pointer is ignored since this is a nscd side packed request.
* The client side routine does all the real parsing; we just check limits and
* store the entry in the buffer we were passed by the caller.
*/
/*ARGSUSED*/
static int
str2packent(
const char *instr,
int lenstr,
void *ent, /* really (char *) */
char *buffer,
int buflen
)
{
if (buflen <= lenstr) { /* not enough buffer */
return (NSS_STR_PARSE_ERANGE);
}
(void) memmove(buffer, instr, lenstr);
buffer[lenstr] = '\0';
return (NSS_STR_PARSE_SUCCESS);
}
/*
* Initialize db_root, initf, dbop and arg from a packed buffer
*/
/*ARGSUSED*/
nss_status_t
nss_packed_arg_init(void *buffer, size_t length, nss_db_root_t *db_root,
nss_db_initf_t *initf, int *dbop, nss_XbyY_args_t *arg)
{
nss_pheader_t *pbuf = (nss_pheader_t *)buffer;
nss_str2ent_t s2e = str2packent;
nss_str2ent_t real_s2e = NULL;
nss_dbd_t *pdbd;
nssuint_t off, dbdsize;
char *dbname, *bptr;
size_t len;
int index;
if (buffer == NULL || length == 0 ||
dbop == NULL || arg == NULL)
return (NSS_ERROR);
/* init dbop */
*dbop = pbuf->nss_dbop;
off = pbuf->dbd_off;
pdbd = (nss_dbd_t *)((void *)((char *)buffer + off));
dbdsize = pbuf->key_off - pbuf->dbd_off;
if (pdbd->o_name >= dbdsize || pdbd->o_config_name >= dbdsize ||
pdbd->o_default_config >= dbdsize)
return (NSS_ERROR);
dbname = (char *)buffer + off + pdbd->o_name;
if ((index = nss_dbop_search(dbname, (uint32_t)*dbop)) < 0)
return (NSS_ERROR);
/* db_root is initialized by nscd's based on door info */
/* do nothing here */
/* init key information - (and get dbname dbop etc...) */
if (nss_upack_key2arg(buffer, length, &dbname,
dbop, arg, index) != NSS_SUCCESS)
return (NSS_ERROR);
/* possible audituser init */
if (strcmp(dbname, NSS_DBNAM_AUTHATTR) == 0)
arg->h_errno = (int)pbuf->p_herrno;
bptr = (char *)buffer + pbuf->data_off;
len = (size_t)pbuf->data_len;
/* sidestep odd arg cases */
if (*dbop == NSS_DBOP_GROUP_BYMEMBER &&
strcmp(dbname, NSS_DBNAM_GROUP) == 0) {
/* get initf and str2ent functions */
if (nss_pinit_funcs(index, initf, &real_s2e) != NSS_SUCCESS)
return (NSS_ERROR);
((struct nss_groupsbymem *)arg)->str2ent = real_s2e;
((struct nss_groupsbymem *)arg)->process_cstr = process_cstr;
return (NSS_SUCCESS);
}
if (pbuf->nss_dbop == NSS_DBOP_NETGROUP_IN &&
strcmp(dbname, NSS_DBNAM_NETGROUP) == 0) {
return (NSS_SUCCESS);
}
/* get initf and str2ent functions */
if (nss_pinit_funcs(index, initf, NULL) != NSS_SUCCESS)
return (NSS_ERROR);
/* init normal arg cases */
NSS_XbyY_INIT(arg, NULL, bptr, len, s2e);
arg->h_errno = 0;
return (NSS_SUCCESS);
}
/*
* Initialize db_root, initf, dbop, contextp and arg from a packed buffer
*/
/*ARGSUSED*/
nss_status_t
nss_packed_context_init(void *buffer, size_t length, nss_db_root_t *db_root,
nss_db_initf_t *initf, nss_getent_t **contextp,
nss_XbyY_args_t *arg)
{
nss_pheader_t *pbuf = (nss_pheader_t *)buffer;
nss_str2ent_t s2e = str2packent;
char *bptr;
size_t len;
/* init arg */
if (arg != NULL) {
bptr = (char *)buffer + pbuf->data_off;
len = (size_t)pbuf->data_len;
NSS_XbyY_INIT(arg, NULL, bptr, len, s2e);
}
return (NSS_SUCCESS);
}