nis_multival.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1997-2001 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#ifndef LINT
static char SCCSID[] = "%Z%%M% %I% %E% SMI";
#endif
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <ctype.h>
#include "nis_proc.h"
#include "nis_mt.h"
/*
* TA_MULTIVAL and TA_SEARCHABLE are mutually exclusive. The
* separator character for multivalue searches is stored in the
* upper byte of tc_flags and is accessed with TA_MULTISEP.
*
*/
#define TA_MULTIVAL (0xff000000)
#ifndef _REENTRANT
#endif /* _REENTRANT */
/*
* If FORCE_GROUP is defined, then the members column of the group
* table is considered a multival column, even if TA_MULTIVAL
* isn't set on the column.
*/
#define FORCE_GROUP 1
struct dir_item {
};
struct tab_item {
};
struct col_item {
int colnum;
char sep[2];
int case_insensitive;
};
struct ent_item {
nis_object **obj;
int nobj;
};
static void free_table(tab_item *);
static void free_column(col_item *);
static void free_entry(ent_item *);
static void strlower(char *);
#define RW -1
#define NONE 0
#define RO 1
/*
* The find_table(), find_column(), and find_entry() functions leave the
* respective NIS_HASH_TABLE entries locked. The release_*() functions below
* unlock those tables in the correct order.
*/
static void
if (dir != 0)
}
static void
if (release_dir)
}
}
static void
if (release_tab)
}
}
static void
if (release_col)
}
}
/*
* Check to see if the attribute in 'attr' is a multival
* attribute.
*/
int
{
int i;
#ifdef FORCE_GROUP
return (1);
}
#endif /* FORCE_GROUP */
for (i = 0; i < ncols; i++) {
/* if column is searchable, then it is not multival */
return (0);
return (1);
}
}
return (0);
}
/*
* Determine which attributes refer to multival columns. All of
* the regular attributes are moved to the beginning of 'attr'
* and the multival attributes are moved to the end. The
* 'nattr' and 'nmulti' variables are set to the number of each
* type of attributes.
*
* We assume that most tables don't have multival columns, so do
* a quick scan and return if this is the case.
*/
{
int i;
int front;
int back;
int ncols;
int *is_multival;
int tmp;
*nmulti = 0;
return (NIS_SUCCESS);
}
for (i = 0; i < ncols; i++) {
break;
}
#ifdef FORCE_GROUP
i = 3; /* members column number */
}
#endif /* FORCE_GROUP */
if (i >= ncols) {
*nmulti = 0;
return (NIS_SUCCESS);
}
/* determine which elements of attr are multival */
if (is_multival == NULL) {
return (NIS_NOMEMORY);
}
for (i = 0; i < *nattr; i++) {
}
/* partition sort to put regular attributes first, multival last */
front = 0;
if (!is_multival[front])
front += 1;
else if (is_multival[back])
back -= 1;
else {
front += 1;
back -= 1;
}
}
} else {
*nmulti = 0;
}
free((void *)is_multival);
return (NIS_SUCCESS);
}
/*
* Do a multival search on nis_object. If all of the attributes
* in 'm' have matches, then the object should not be filtered out.
*/
int
{
int i;
int st;
int len;
char *p;
int vlen;
char *val;
char *last;
for (i = 0; i < nm; i++) {
return (1);
return (1);
}
/* make copy of value because strtok leaves trail of '\0' */
p = strdup(p);
if (p == NULL) {
return (1);
}
while (val) {
if (col->case_insensitive) {
m[i].zattr_val.zattr_val_val);
} else {
m[i].zattr_val.zattr_val_val);
}
if (st == 0)
break;
}
}
free((void *)p);
return (1);
}
/* found a match for all attributes, don't filter this object */
return (0);
}
/*
* Search the table specified by 'tobj' for all of the objects that
* are selected by the attributes in 'm'. This is basically a
* join operation. For the first attribute, we retrieve a list of
* objects. For subsequent attributes, we do a join and keep only
* the objects that occur in both lists.
*/
void
{
int i;
int j;
int k;
int n;
char *val;
int len;
int count = 0;
int nobj = 0;
for (i = 0; i < nm; i++) {
return;
}
if (!ent) {
return;
}
return;
}
}
} else {
for (j = 0; j < nobj; j++) {
continue;
break;
}
count -= 1;
}
}
}
}
if (count == 0) {
return;
}
n = 0;
for (i = 0; i < nobj; i++) {
if (objs[i]) {
n++;
}
}
if (n != count) {
"multival_list: miscounted objects (%d, %d)", n, count);
}
}
/*
* A table has been modified in some way, so we must free up
* the entries associated with it.
*/
void
{
return;
return;
if (tab)
}
static
tab_item *
{
int i;
int ncols;
return (NULL);
if (tab != 0)
return (tab);
}
static
col_item *
{
/*
* While loading the table, we need write access (at least
* to parts of it).
*/
/* remove any partially loaded table information */
return (NULL);
}
}
if (col != 0) {
} else {
}
return (col);
}
static
ent_item *
{
return (NULL);
if (col->case_insensitive)
if (ent != 0) {
} else {
}
return (ent);
}
static
col_item *
{
return (NULL);
return (NULL);
}
else
col->case_insensitive = 0;
return (NULL);
}
return (col);
}
/*
* load_entry()
*
* sure it is non-NULL, non-empty, length > 0, and NUL terminated.
*/
static
ent_item *
{
char *p;
char *val;
int len;
char *last;
return (NULL);
}
/* make a copy of p because strtok leaves a trail of '\0' */
p = strdup(p);
if (p == NULL)
return (NULL);
while (val) {
/*
* We're going to modify the entry, so we need RW access.
* XXX We expect the caller to be load_table(), and it
* doesn't use the return value other than to check for
* success (non-NULL). Thus, we make no attempt to return
* the (last created) entry with the requested access.
*/
if (ent != 0) {
/* Release entry from previous lap */
}
free((void *)p);
return (NULL);
}
free((void *)p);
return (NULL);
}
if (col->case_insensitive) {
}
free((void *)p);
return (NULL);
}
}
free((void *)p);
return (NULL);
}
}
free((void *)p);
return (ent);
}
static
tab_item *
{
int i;
int j;
int multival;
int ncols;
char name[NIS_MAXNAMELEN];
char *table;
int nobj;
/*
* Get directory item. Create it if it doesn't exist.
*/
return (NULL);
return (NULL);
}
return (NULL);
}
}
/* create table item and add to directory item */
return (NULL);
}
return (NULL);
}
return (NULL);
}
/*
* We keep a copy of each of the columns in an array so that
* we can load the entries for each one. Each element of the
* array is also stored in 'tab'.
*/
return (NULL);
}
for (i = 0; i < ncols; i++) {
multival = 0;
multival = 1;
}
#ifdef FORCE_GROUP
if (!multival) {
if (i == 3 &&
"group_tbl") == 0) {
multival = 1;
}
}
#endif /* FORCE_GROUP */
if (multival) {
int c;
for (c = 0; c++; c < i)
release_column(collist[c], 0);
return (NULL);
}
}
}
for (i = 0; i < ncols; i++)
release_column(collist[i], 0);
return (NULL);
}
if (res == 0 ||
for (i = 0; i < ncols; i++) {
release_column(collist[i], 0);
}
if (res != 0)
return (NULL);
}
for (j = 0; j < ncols; j++) {
if (collist[j]) {
char *p;
int len;
/*
* Make sure we have a valid column string
* before calling load_entry.
*/
continue;
int c;
for (c = 0; c < ncols; c++)
release_column(collist[c], 0);
return (NULL);
}
release_entry(tmpent, 0);
}
}
}
for (i = 0; i < ncols; i++)
release_column(collist[i], 0);
return (tab);
}
static
void
{
}
}
static
void
{
}
}
static
void
{
}
static
void
strlower(char *s)
{
while (*s) {
if (isupper(*s))
*s = tolower(*s);
s++;
}
}