10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*11262SRajagopal.Andra@Sun.COM * Common Development and Distribution License (the "License").
6*11262SRajagopal.Andra@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*11262SRajagopal.Andra@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate
270Sstevel@tonic-gate #include <lber.h>
280Sstevel@tonic-gate #include <ldap.h>
290Sstevel@tonic-gate #include <strings.h>
300Sstevel@tonic-gate #include <errno.h>
310Sstevel@tonic-gate
320Sstevel@tonic-gate #include "nisdb_mt.h"
330Sstevel@tonic-gate
340Sstevel@tonic-gate #include "ldap_util.h"
350Sstevel@tonic-gate #include "ldap_op.h"
360Sstevel@tonic-gate #include "ldap_ruleval.h"
370Sstevel@tonic-gate #include "ldap_attr.h"
380Sstevel@tonic-gate #include "ldap_val.h"
390Sstevel@tonic-gate #include "ldap_ldap.h"
400Sstevel@tonic-gate
410Sstevel@tonic-gate extern int yp2ldap;
420Sstevel@tonic-gate
430Sstevel@tonic-gate
440Sstevel@tonic-gate __nis_mapping_format_t *
cloneMappingFormat(__nis_mapping_format_t * m)450Sstevel@tonic-gate cloneMappingFormat(__nis_mapping_format_t *m) {
460Sstevel@tonic-gate __nis_mapping_format_t *new;
470Sstevel@tonic-gate int i, nf, err;
480Sstevel@tonic-gate char *myself = "cloneMappingFormat";
490Sstevel@tonic-gate
500Sstevel@tonic-gate if (m == 0)
510Sstevel@tonic-gate return (0);
520Sstevel@tonic-gate
530Sstevel@tonic-gate for (nf = 0; m[nf].type != mmt_end; nf++);
540Sstevel@tonic-gate nf++;
550Sstevel@tonic-gate
560Sstevel@tonic-gate new = am(myself, nf * sizeof (new[0]));
570Sstevel@tonic-gate if (new == 0)
580Sstevel@tonic-gate return (0);
590Sstevel@tonic-gate
600Sstevel@tonic-gate /* Copy the whole array */
610Sstevel@tonic-gate memcpy(new, m, nf * sizeof (new[0]));
620Sstevel@tonic-gate
630Sstevel@tonic-gate /* Make copies of allocated stuff */
640Sstevel@tonic-gate for (i = 0, err = 0; i < nf; i++) {
650Sstevel@tonic-gate switch (m[i].type) {
660Sstevel@tonic-gate case mmt_string:
670Sstevel@tonic-gate new[i].match.string = sdup(myself, T,
680Sstevel@tonic-gate m[i].match.string);
690Sstevel@tonic-gate if (new[i].match.string == 0 && m[i].match.string != 0)
700Sstevel@tonic-gate err++;
710Sstevel@tonic-gate break;
720Sstevel@tonic-gate case mmt_single:
730Sstevel@tonic-gate new[i].match.single.lo =
740Sstevel@tonic-gate am(myself, m[i].match.single.numRange *
750Sstevel@tonic-gate sizeof (new[i].match.single.lo[0]));
760Sstevel@tonic-gate new[i].match.single.hi =
770Sstevel@tonic-gate am(myself, m[i].match.single.numRange *
780Sstevel@tonic-gate sizeof (new[i].match.single.hi[0]));
790Sstevel@tonic-gate if (new[i].match.single.lo != 0)
800Sstevel@tonic-gate memcpy(new[i].match.single.lo,
810Sstevel@tonic-gate m[i].match.single.lo,
820Sstevel@tonic-gate m[i].match.single.numRange);
830Sstevel@tonic-gate else if (m[i].match.single.lo != 0)
840Sstevel@tonic-gate err++;
850Sstevel@tonic-gate if (new[i].match.single.hi != 0)
860Sstevel@tonic-gate memcpy(new[i].match.single.hi,
870Sstevel@tonic-gate m[i].match.single.hi,
880Sstevel@tonic-gate m[i].match.single.numRange);
890Sstevel@tonic-gate else if (m[i].match.single.hi != 0)
900Sstevel@tonic-gate err++;
910Sstevel@tonic-gate break;
920Sstevel@tonic-gate case mmt_berstring:
930Sstevel@tonic-gate new[i].match.berString = sdup(myself, T,
940Sstevel@tonic-gate m[i].match.berString);
950Sstevel@tonic-gate if (new[i].match.berString == 0 &&
960Sstevel@tonic-gate m[i].match.berString != 0)
970Sstevel@tonic-gate err++;
980Sstevel@tonic-gate break;
990Sstevel@tonic-gate case mmt_item:
1000Sstevel@tonic-gate case mmt_limit:
1010Sstevel@tonic-gate case mmt_any:
1020Sstevel@tonic-gate case mmt_begin:
1030Sstevel@tonic-gate case mmt_end:
1040Sstevel@tonic-gate default:
1050Sstevel@tonic-gate break;
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate }
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate /* If there were memory allocation errors, free the copy */
1100Sstevel@tonic-gate if (err > 0) {
1110Sstevel@tonic-gate freeMappingFormat(new);
1120Sstevel@tonic-gate new = 0;
1130Sstevel@tonic-gate }
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate return (new);
1160Sstevel@tonic-gate }
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate void
freeMappingFormat(__nis_mapping_format_t * m)1190Sstevel@tonic-gate freeMappingFormat(__nis_mapping_format_t *m) {
1200Sstevel@tonic-gate int i;
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate if (m == 0)
1230Sstevel@tonic-gate return;
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate for (i = 0; m[i].type != mmt_end; i++) {
1260Sstevel@tonic-gate switch (m[i].type) {
1270Sstevel@tonic-gate case mmt_string:
1280Sstevel@tonic-gate sfree(m[i].match.string);
1290Sstevel@tonic-gate break;
1300Sstevel@tonic-gate case mmt_single:
1310Sstevel@tonic-gate sfree(m[i].match.single.lo);
1320Sstevel@tonic-gate sfree(m[i].match.single.hi);
1330Sstevel@tonic-gate break;
1340Sstevel@tonic-gate case mmt_berstring:
1350Sstevel@tonic-gate sfree(m[i].match.berString);
1360Sstevel@tonic-gate break;
1370Sstevel@tonic-gate case mmt_item:
1380Sstevel@tonic-gate case mmt_limit:
1390Sstevel@tonic-gate case mmt_any:
1400Sstevel@tonic-gate case mmt_begin:
1410Sstevel@tonic-gate case mmt_end:
1420Sstevel@tonic-gate default:
1430Sstevel@tonic-gate break;
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate free(m);
1480Sstevel@tonic-gate }
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate void
copyIndex(__nis_index_t * old,__nis_index_t * new,int * err)1520Sstevel@tonic-gate copyIndex(__nis_index_t *old, __nis_index_t *new, int *err) {
1530Sstevel@tonic-gate int i;
1540Sstevel@tonic-gate char *myself = "copyIndex";
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate if (old == 0 || new == 0) {
1570Sstevel@tonic-gate *err = EINVAL;
1580Sstevel@tonic-gate return;
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate for (i = 0; i < old->numIndexes; i++) {
1620Sstevel@tonic-gate new->name[i] = sdup(myself, T, old->name[i]);
1630Sstevel@tonic-gate if (new->name[i] == 0 && old->name[i] != 0) {
1640Sstevel@tonic-gate *err = ENOMEM;
1650Sstevel@tonic-gate return;
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate new->value[i] = cloneMappingFormat(old->value[i]);
1680Sstevel@tonic-gate if (new->value[i] == 0 && old->value[i] != 0) {
1690Sstevel@tonic-gate *err = ENOMEM;
1700Sstevel@tonic-gate return;
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate }
1730Sstevel@tonic-gate
1740Sstevel@tonic-gate new->numIndexes = old->numIndexes;
1750Sstevel@tonic-gate }
1760Sstevel@tonic-gate
1770Sstevel@tonic-gate __nis_index_t *
cloneIndex(__nis_index_t * old)1780Sstevel@tonic-gate cloneIndex(__nis_index_t *old) {
1790Sstevel@tonic-gate char *myself = "cloneIndex";
1800Sstevel@tonic-gate int err = 0;
1810Sstevel@tonic-gate __nis_index_t *new = am(myself, sizeof (*new));
1820Sstevel@tonic-gate
1830Sstevel@tonic-gate if (old == 0)
1840Sstevel@tonic-gate return (0);
1850Sstevel@tonic-gate
1860Sstevel@tonic-gate if (new != 0) {
1870Sstevel@tonic-gate copyIndex(old, new, &err);
1880Sstevel@tonic-gate if (err != 0) {
1890Sstevel@tonic-gate freeIndex(new, 1);
1900Sstevel@tonic-gate new = 0;
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate }
1930Sstevel@tonic-gate
1940Sstevel@tonic-gate return (new);
1950Sstevel@tonic-gate }
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate void
freeIndex(__nis_index_t * old,bool_t doFree)1980Sstevel@tonic-gate freeIndex(__nis_index_t *old, bool_t doFree) {
1990Sstevel@tonic-gate int i;
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate if (old == 0)
2020Sstevel@tonic-gate return;
2030Sstevel@tonic-gate
2040Sstevel@tonic-gate for (i = 0; i < old->numIndexes; i++) {
2050Sstevel@tonic-gate sfree(old->name[i]);
2060Sstevel@tonic-gate freeMappingFormat(old->value[i]);
2070Sstevel@tonic-gate }
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate if (doFree)
2100Sstevel@tonic-gate free(old);
2110Sstevel@tonic-gate }
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate char **
cloneName(char ** name,int numNames)2140Sstevel@tonic-gate cloneName(char **name, int numNames) {
2150Sstevel@tonic-gate char **new;
2160Sstevel@tonic-gate int i;
2170Sstevel@tonic-gate char *myself = "cloneName";
2180Sstevel@tonic-gate
2190Sstevel@tonic-gate if (name == 0 || numNames <= 0)
2200Sstevel@tonic-gate return (0);
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate new = am(myself, numNames * sizeof (new[0]));
2230Sstevel@tonic-gate if (new == 0)
2240Sstevel@tonic-gate return (0);
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate for (i = 0; i < numNames; i++) {
2270Sstevel@tonic-gate if (name[i] != 0) {
2280Sstevel@tonic-gate new[i] = sdup(myself, T, name[i]);
2290Sstevel@tonic-gate if (new[i] == 0) {
2300Sstevel@tonic-gate for (i--; i >= 0; i--) {
2310Sstevel@tonic-gate sfree(new[i]);
2320Sstevel@tonic-gate }
2330Sstevel@tonic-gate sfree(new);
2340Sstevel@tonic-gate return (0);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate } else {
2370Sstevel@tonic-gate new[i] = 0;
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate return (new);
2420Sstevel@tonic-gate }
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate void
freeValue(__nis_value_t * val,int count)2450Sstevel@tonic-gate freeValue(__nis_value_t *val, int count) {
2460Sstevel@tonic-gate int c, i;
2470Sstevel@tonic-gate
2480Sstevel@tonic-gate if (val == 0)
2490Sstevel@tonic-gate return;
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate for (c = 0; c < count; c++) {
2520Sstevel@tonic-gate if (val[c].val != 0) {
2530Sstevel@tonic-gate for (i = 0; i < val[c].numVals; i++) {
2540Sstevel@tonic-gate sfree(val[c].val[i].value);
2550Sstevel@tonic-gate }
2560Sstevel@tonic-gate free(val[c].val);
2570Sstevel@tonic-gate }
2580Sstevel@tonic-gate }
2590Sstevel@tonic-gate
2600Sstevel@tonic-gate free(val);
2610Sstevel@tonic-gate }
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate __nis_value_t *
cloneValue(__nis_value_t * val,int count)2640Sstevel@tonic-gate cloneValue(__nis_value_t *val, int count) {
2650Sstevel@tonic-gate __nis_value_t *n;
2660Sstevel@tonic-gate int c, i;
2670Sstevel@tonic-gate char *myself = "cloneValue";
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate if (count <= 0 || val == 0)
2700Sstevel@tonic-gate return (0);
2710Sstevel@tonic-gate
2720Sstevel@tonic-gate n = am(myself, count * sizeof (*n));
2730Sstevel@tonic-gate if (n == 0)
2740Sstevel@tonic-gate return (0);
2750Sstevel@tonic-gate
2760Sstevel@tonic-gate for (c = 0; c < count; c++) {
2770Sstevel@tonic-gate n[c].type = val[c].type;
2780Sstevel@tonic-gate n[c].repeat = val[c].repeat;
2790Sstevel@tonic-gate n[c].numVals = val[c].numVals;
2800Sstevel@tonic-gate if (n[c].numVals > 0) {
2810Sstevel@tonic-gate n[c].val = am(myself, n[c].numVals *
2820Sstevel@tonic-gate sizeof (n[c].val[0]));
2830Sstevel@tonic-gate if (n[c].val == 0) {
2840Sstevel@tonic-gate freeValue(n, c);
2850Sstevel@tonic-gate return (0);
2860Sstevel@tonic-gate }
2870Sstevel@tonic-gate } else {
2880Sstevel@tonic-gate n[c].val = 0;
2890Sstevel@tonic-gate }
2900Sstevel@tonic-gate for (i = 0; i < n[c].numVals; i++) {
2910Sstevel@tonic-gate int amlen = val[c].val[i].length;
2920Sstevel@tonic-gate
2930Sstevel@tonic-gate /*
2940Sstevel@tonic-gate * The functions that create string values try to
2950Sstevel@tonic-gate * make sure that there's a NUL at the end. However,
2960Sstevel@tonic-gate * both NIS+ and LDAP have a tendency to store strings
2970Sstevel@tonic-gate * without a NUL, so the value length may not include
2980Sstevel@tonic-gate * the NUL (even though it's there). In order to
2990Sstevel@tonic-gate * preserve that NUL, we add a byte to the length if
3000Sstevel@tonic-gate * the type is vt_string, and there isn't already a
3010Sstevel@tonic-gate * NUL at the end. The memory allocation function
3020Sstevel@tonic-gate * (am()) will take care of actually putting the NUL
3030Sstevel@tonic-gate * in place, since it allocates zero-initialized
3040Sstevel@tonic-gate * memory.
3050Sstevel@tonic-gate */
3060Sstevel@tonic-gate n[c].val[i].length = val[c].val[i].length;
3070Sstevel@tonic-gate if (n[c].type == vt_string && amlen > 0 &&
3080Sstevel@tonic-gate ((char *)val[c].val[i].value)[amlen-1] !=
3090Sstevel@tonic-gate '\0') {
3100Sstevel@tonic-gate amlen++;
3110Sstevel@tonic-gate }
3120Sstevel@tonic-gate n[c].val[i].value = am(myself, amlen);
3130Sstevel@tonic-gate if (amlen > 0 && n[c].val[i].value == 0) {
3140Sstevel@tonic-gate freeValue(n, c);
3150Sstevel@tonic-gate return (0);
3160Sstevel@tonic-gate }
3170Sstevel@tonic-gate memcpy(n[c].val[i].value, val[c].val[i].value,
3180Sstevel@tonic-gate n[c].val[i].length);
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate }
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate return (n);
3230Sstevel@tonic-gate }
3240Sstevel@tonic-gate
3250Sstevel@tonic-gate /* Define LBER_USE_DER per ber_decode(3LDAP) */
3260Sstevel@tonic-gate #ifndef LBER_USE_DER
3270Sstevel@tonic-gate #define LBER_USE_DER 0x01
3280Sstevel@tonic-gate #endif /* LBER_USE_DER */
3290Sstevel@tonic-gate
3300Sstevel@tonic-gate /*
3310Sstevel@tonic-gate * Return a copy of 'valIn' where each value has been replaced by the
3320Sstevel@tonic-gate * BER encoded equivalent specified by 'berstring'. 'valIn' is unchanged.
3330Sstevel@tonic-gate */
3340Sstevel@tonic-gate __nis_value_t *
berEncode(__nis_value_t * valIn,char * berstring)3350Sstevel@tonic-gate berEncode(__nis_value_t *valIn, char *berstring) {
3360Sstevel@tonic-gate char *myself = "berEncode";
3370Sstevel@tonic-gate __nis_value_t *val;
3380Sstevel@tonic-gate int i;
3390Sstevel@tonic-gate
3400Sstevel@tonic-gate if (valIn == 0 || berstring == 0)
3410Sstevel@tonic-gate return (0);
3420Sstevel@tonic-gate
3430Sstevel@tonic-gate val = cloneValue(valIn, 1);
3440Sstevel@tonic-gate if (val == 0)
3450Sstevel@tonic-gate return (0);
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate for (i = 0; i < val->numVals; i++) {
3480Sstevel@tonic-gate BerElement *ber = ber_alloc();
3490Sstevel@tonic-gate struct berval *bv = 0;
3500Sstevel@tonic-gate int ret;
3510Sstevel@tonic-gate
3520Sstevel@tonic-gate if (ber == 0) {
3530Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, "%s: ber_alloc() => NULL",
3540Sstevel@tonic-gate myself);
3550Sstevel@tonic-gate freeValue(val, 1);
3560Sstevel@tonic-gate return (0);
3570Sstevel@tonic-gate }
3580Sstevel@tonic-gate
3590Sstevel@tonic-gate if ((strcmp("b", berstring) == 0 ||
3600Sstevel@tonic-gate strcmp("i", berstring) == 0)) {
3610Sstevel@tonic-gate if (val->val[i].length >= sizeof (int)) {
3620Sstevel@tonic-gate ret = ber_printf(ber, berstring,
3630Sstevel@tonic-gate *((int *)(val->val[i].value)));
3640Sstevel@tonic-gate } else {
3650Sstevel@tonic-gate ret = -1;
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate } else if (strcmp("B", berstring) == 0) {
3680Sstevel@tonic-gate ret = ber_printf(ber, berstring,
3690Sstevel@tonic-gate val->val[i].value,
3700Sstevel@tonic-gate val->val[i].length * 8);
3710Sstevel@tonic-gate } else if (strcmp("n", berstring) == 0) {
3720Sstevel@tonic-gate ret = ber_printf(ber, berstring);
3730Sstevel@tonic-gate } else if (strcmp("o", berstring) == 0) {
3740Sstevel@tonic-gate ret = ber_printf(ber, berstring,
3750Sstevel@tonic-gate val->val[i].value, val->val[i].length);
3760Sstevel@tonic-gate } else if (strcmp("s", berstring) == 0) {
3770Sstevel@tonic-gate char *str = am(myself, val->val[i].length + 1);
3780Sstevel@tonic-gate
3790Sstevel@tonic-gate if (str != 0) {
3800Sstevel@tonic-gate ret = ber_printf(ber, berstring, str);
3810Sstevel@tonic-gate free(str);
3820Sstevel@tonic-gate } else {
3830Sstevel@tonic-gate ret = -1;
3840Sstevel@tonic-gate }
3850Sstevel@tonic-gate } else {
3860Sstevel@tonic-gate ret = -1;
3870Sstevel@tonic-gate }
3880Sstevel@tonic-gate
3890Sstevel@tonic-gate if (ret == -1) {
3900Sstevel@tonic-gate reportError(NPL_BERENCODE, "%s: BER encoding error",
3910Sstevel@tonic-gate myself);
3920Sstevel@tonic-gate ber_free(ber, 1);
3930Sstevel@tonic-gate freeValue(val, 1);
3940Sstevel@tonic-gate return (0);
3950Sstevel@tonic-gate }
3960Sstevel@tonic-gate
3970Sstevel@tonic-gate if (ber_flatten(ber, &bv) != 0 || bv == 0) {
3980Sstevel@tonic-gate reportError(NPL_BERENCODE, "%s: ber_flatten() error",
3990Sstevel@tonic-gate myself);
4000Sstevel@tonic-gate ber_free(ber, 1);
4010Sstevel@tonic-gate freeValue(val, 1);
4020Sstevel@tonic-gate return (0);
4030Sstevel@tonic-gate }
4040Sstevel@tonic-gate
4050Sstevel@tonic-gate sfree(val->val[i].value);
4060Sstevel@tonic-gate val->val[i].length = bv->bv_len;
4070Sstevel@tonic-gate val->val[i].value = bv->bv_val;
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate ber_free(ber, 1);
4100Sstevel@tonic-gate }
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate val->type = vt_ber;
4130Sstevel@tonic-gate
4140Sstevel@tonic-gate return (val);
4150Sstevel@tonic-gate }
4160Sstevel@tonic-gate
4170Sstevel@tonic-gate __nis_value_t *
berDecode(__nis_value_t * valIn,char * berstring)4180Sstevel@tonic-gate berDecode(__nis_value_t *valIn, char *berstring) {
4190Sstevel@tonic-gate __nis_value_t *val;
4200Sstevel@tonic-gate int i;
4210Sstevel@tonic-gate char *myself = "berDecode";
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate if (valIn == 0 || berstring == 0)
4240Sstevel@tonic-gate return (0);
4250Sstevel@tonic-gate
4260Sstevel@tonic-gate val = cloneValue(valIn, 1);
4270Sstevel@tonic-gate if (val == 0)
4280Sstevel@tonic-gate return (0);
4290Sstevel@tonic-gate
4300Sstevel@tonic-gate for (i = 0; i < val->numVals; i++) {
4310Sstevel@tonic-gate void *v = 0;
4320Sstevel@tonic-gate int ret, len = 0;
4330Sstevel@tonic-gate struct berval bv;
4340Sstevel@tonic-gate BerElement *ber;
4350Sstevel@tonic-gate
4360Sstevel@tonic-gate if (val->val[i].value == 0 || val->val[i].length <= 0)
4370Sstevel@tonic-gate continue;
4380Sstevel@tonic-gate
4390Sstevel@tonic-gate bv.bv_val = val->val[i].value;
4400Sstevel@tonic-gate bv.bv_len = val->val[i].length;
4410Sstevel@tonic-gate ber = ber_init(&bv);
4420Sstevel@tonic-gate if (ber == 0) {
4430Sstevel@tonic-gate reportError(NPL_BERDECODE, "%s: ber_init() error",
4440Sstevel@tonic-gate myself);
4450Sstevel@tonic-gate freeValue(val, 1);
4460Sstevel@tonic-gate return (0);
4470Sstevel@tonic-gate }
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate if ((strcmp("b", berstring) == 0 ||
4500Sstevel@tonic-gate strcmp("i", berstring) == 0)) {
4510Sstevel@tonic-gate len = sizeof (int);
4520Sstevel@tonic-gate v = am(myself, len);
4530Sstevel@tonic-gate if (v != 0) {
4540Sstevel@tonic-gate ret = ber_scanf(ber, berstring, v);
4550Sstevel@tonic-gate } else {
4560Sstevel@tonic-gate ret = -1;
4570Sstevel@tonic-gate }
4580Sstevel@tonic-gate } else if (strcmp("B", berstring) == 0) {
4590Sstevel@tonic-gate long llen;
4600Sstevel@tonic-gate
4610Sstevel@tonic-gate ret = ber_scanf(ber, berstring, &v, &llen);
4620Sstevel@tonic-gate if (ret != -1) {
4630Sstevel@tonic-gate len = llen/8;
4640Sstevel@tonic-gate }
4650Sstevel@tonic-gate } else if (strcmp("n", berstring) == 0) {
4660Sstevel@tonic-gate ret = 0;
4670Sstevel@tonic-gate } else if (strcmp("o", berstring) == 0) {
4680Sstevel@tonic-gate struct berval *bv = am(myself, sizeof (*bv));
4690Sstevel@tonic-gate
4700Sstevel@tonic-gate if (bv != 0) {
4710Sstevel@tonic-gate ret = ber_scanf(ber, "O", &bv);
4720Sstevel@tonic-gate if (ret != -1 && bv != 0) {
4730Sstevel@tonic-gate v = bv->bv_val;
4740Sstevel@tonic-gate len = bv->bv_len;
4750Sstevel@tonic-gate } else {
4760Sstevel@tonic-gate ret = -1;
4770Sstevel@tonic-gate }
4780Sstevel@tonic-gate /* Only free 'bv' itself */
4790Sstevel@tonic-gate free(bv);
4800Sstevel@tonic-gate } else {
4810Sstevel@tonic-gate ret = -1;
4820Sstevel@tonic-gate }
4830Sstevel@tonic-gate } else if (strcmp("s", berstring) == 0) {
4840Sstevel@tonic-gate ret = ber_scanf(ber, "a", &v);
4850Sstevel@tonic-gate if (ret != -1) {
4860Sstevel@tonic-gate len = slen(v);
4870Sstevel@tonic-gate }
4880Sstevel@tonic-gate } else {
4890Sstevel@tonic-gate ret = -1;
4900Sstevel@tonic-gate }
4910Sstevel@tonic-gate
4920Sstevel@tonic-gate if (ret == -1) {
4930Sstevel@tonic-gate reportError(NPL_BERDECODE, "%s: BER decoding error",
4940Sstevel@tonic-gate myself);
4950Sstevel@tonic-gate freeValue(val, 1);
4960Sstevel@tonic-gate return (0);
4970Sstevel@tonic-gate }
4980Sstevel@tonic-gate
4990Sstevel@tonic-gate /* Free the old value, and replace it with the decoded one */
5000Sstevel@tonic-gate sfree(val->val[i].value);
5010Sstevel@tonic-gate val->val[i].value = v;
5020Sstevel@tonic-gate val->val[i].length = len;
5030Sstevel@tonic-gate }
5040Sstevel@tonic-gate
5050Sstevel@tonic-gate return (val);
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate
5080Sstevel@tonic-gate /*
5090Sstevel@tonic-gate * Return the value of the specified item.
5100Sstevel@tonic-gate */
5110Sstevel@tonic-gate __nis_value_t *
getMappingItemVal(__nis_mapping_item_t * item,__nis_mapping_item_type_t native,__nis_rule_value_t * rv,char * berstring,int * np_ldap_stat)5120Sstevel@tonic-gate getMappingItemVal(__nis_mapping_item_t *item, __nis_mapping_item_type_t native,
5130Sstevel@tonic-gate __nis_rule_value_t *rv, char *berstring, int *np_ldap_stat) {
5140Sstevel@tonic-gate __nis_value_t *val = 0, *nameVal, *exVal = 0;
5150Sstevel@tonic-gate int numName, caseInsens, cmp;
5160Sstevel@tonic-gate int i, j, k;
5170Sstevel@tonic-gate char **name;
5180Sstevel@tonic-gate enum {rvOnly, rvThenLookup, lookupOnly} check;
5190Sstevel@tonic-gate unsigned char fromldap = '\0';
5200Sstevel@tonic-gate
5210Sstevel@tonic-gate if (item == 0)
5220Sstevel@tonic-gate return (0);
5230Sstevel@tonic-gate
5240Sstevel@tonic-gate /*
5250Sstevel@tonic-gate * First, we decide if we should look for the value in 'rv',
5260Sstevel@tonic-gate * directly from NIS+/LDAP, or both.
5270Sstevel@tonic-gate */
5280Sstevel@tonic-gate switch (item->type) {
5290Sstevel@tonic-gate case mit_nisplus:
5300Sstevel@tonic-gate /* Do we have a valid index/object spec ? */
5310Sstevel@tonic-gate if (item->searchSpec.obj.index.numIndexes <= 0 &&
5320Sstevel@tonic-gate item->searchSpec.obj.name == 0) {
5330Sstevel@tonic-gate /*
5340Sstevel@tonic-gate * No valid index/object. If we have a rule-value,
5350Sstevel@tonic-gate * use it. Otherwise, return error.
5360Sstevel@tonic-gate */
5370Sstevel@tonic-gate if (rv != 0) {
5380Sstevel@tonic-gate name = rv->colName;
5390Sstevel@tonic-gate nameVal = rv->colVal;
5400Sstevel@tonic-gate numName = rv->numColumns;
5410Sstevel@tonic-gate caseInsens = 0;
5420Sstevel@tonic-gate check = rvOnly;
5430Sstevel@tonic-gate } else {
5440Sstevel@tonic-gate return (0);
5450Sstevel@tonic-gate }
5460Sstevel@tonic-gate } else {
5470Sstevel@tonic-gate /*
5480Sstevel@tonic-gate * Valid index, so skip the rule-value and do
5490Sstevel@tonic-gate * a direct NIS+ lookup.
5500Sstevel@tonic-gate */
5510Sstevel@tonic-gate check = lookupOnly;
5520Sstevel@tonic-gate }
5530Sstevel@tonic-gate break;
5540Sstevel@tonic-gate case mit_ldap:
5550Sstevel@tonic-gate if (rv != 0) {
5560Sstevel@tonic-gate name = rv->attrName;
5570Sstevel@tonic-gate nameVal = rv->attrVal;
5580Sstevel@tonic-gate numName = rv->numAttrs;
5590Sstevel@tonic-gate caseInsens = 1;
5600Sstevel@tonic-gate fromldap = '1';
5610Sstevel@tonic-gate }
5620Sstevel@tonic-gate /* Do we have a valid triple ? */
5630Sstevel@tonic-gate if (item->searchSpec.triple.scope == LDAP_SCOPE_UNKNOWN) {
5640Sstevel@tonic-gate /*
5650Sstevel@tonic-gate * No valid triple. If we have a rule-value, use it.
5660Sstevel@tonic-gate * Otherwise, return error.
5670Sstevel@tonic-gate */
5680Sstevel@tonic-gate if (rv != 0) {
5690Sstevel@tonic-gate check = rvOnly;
5700Sstevel@tonic-gate } else {
5710Sstevel@tonic-gate return (0);
5720Sstevel@tonic-gate }
5730Sstevel@tonic-gate } else if (item->searchSpec.triple.base == 0 &&
5740Sstevel@tonic-gate item->searchSpec.triple.scope ==
5750Sstevel@tonic-gate LDAP_SCOPE_ONELEVEL &&
5760Sstevel@tonic-gate item->searchSpec.triple.attrs == 0 &&
5770Sstevel@tonic-gate item->searchSpec.triple.element == 0) {
5780Sstevel@tonic-gate /*
5790Sstevel@tonic-gate * We have a valid triple, but it points to the
5800Sstevel@tonic-gate * current LDAP container. Thus, first look in
5810Sstevel@tonic-gate * the rule-value; if that fails, perform a direct
5820Sstevel@tonic-gate * LDAP lookup.
5830Sstevel@tonic-gate */
5840Sstevel@tonic-gate if (rv != 0) {
5850Sstevel@tonic-gate check = rvThenLookup;
5860Sstevel@tonic-gate } else {
5870Sstevel@tonic-gate check = lookupOnly;
5880Sstevel@tonic-gate }
5890Sstevel@tonic-gate } else {
5900Sstevel@tonic-gate /*
5910Sstevel@tonic-gate * Valid triple, and it's not the current container
5920Sstevel@tonic-gate * (at least not in the trivial sense). Hence, do
5930Sstevel@tonic-gate * a direct LDAP lookup.
5940Sstevel@tonic-gate */
5950Sstevel@tonic-gate check = lookupOnly;
5960Sstevel@tonic-gate }
5970Sstevel@tonic-gate break;
5980Sstevel@tonic-gate default:
5990Sstevel@tonic-gate return (0);
6000Sstevel@tonic-gate }
6010Sstevel@tonic-gate
6020Sstevel@tonic-gate /* Check the rule-value */
6030Sstevel@tonic-gate if (check == rvOnly || check == rvThenLookup) {
6040Sstevel@tonic-gate for (i = 0; i < numName; i++) {
6050Sstevel@tonic-gate if (caseInsens)
6060Sstevel@tonic-gate cmp = strcasecmp(item->name, name[i]);
6070Sstevel@tonic-gate else
6080Sstevel@tonic-gate cmp = strcmp(item->name, name[i]);
6090Sstevel@tonic-gate if (cmp == 0) {
6100Sstevel@tonic-gate if (nameVal[i].numVals <= 0)
6110Sstevel@tonic-gate break;
6120Sstevel@tonic-gate if (berstring == 0) {
6130Sstevel@tonic-gate val = cloneValue(&nameVal[i], 1);
6140Sstevel@tonic-gate } else if (yp2ldap && berstring[0] == 'a') {
6150Sstevel@tonic-gate val = cloneValue(&nameVal[i], 1);
6160Sstevel@tonic-gate } else {
6170Sstevel@tonic-gate val = berDecode(&nameVal[i],
6180Sstevel@tonic-gate berstring);
6190Sstevel@tonic-gate }
6200Sstevel@tonic-gate if (val != 0) {
6210Sstevel@tonic-gate val->repeat = item->repeat;
6220Sstevel@tonic-gate /*
6230Sstevel@tonic-gate * If value for nis+ column is
6240Sstevel@tonic-gate * passed with value, val is
6250Sstevel@tonic-gate * manipulated in cloneValue().
6260Sstevel@tonic-gate * To decide whether there are
6270Sstevel@tonic-gate * enough nis+ column values
6280Sstevel@tonic-gate * for rule to produce a value,
6290Sstevel@tonic-gate * we need nis+ column values
6300Sstevel@tonic-gate * as well as nis_mapping_element
6310Sstevel@tonic-gate * from the rule. If we are here,
6320Sstevel@tonic-gate * it indicates that the 'val has
6330Sstevel@tonic-gate * an valid value for the column
6340Sstevel@tonic-gate * item-> name. So set
6350Sstevel@tonic-gate * NP_LDAP_MAP_SUCCESS
6360Sstevel@tonic-gate * to np_ldap-stat.
6370Sstevel@tonic-gate */
6380Sstevel@tonic-gate
6390Sstevel@tonic-gate if (np_ldap_stat != NULL)
6400Sstevel@tonic-gate *np_ldap_stat =
6410Sstevel@tonic-gate NP_LDAP_MAP_SUCCESS;
6420Sstevel@tonic-gate }
6430Sstevel@tonic-gate break;
6440Sstevel@tonic-gate }
6450Sstevel@tonic-gate }
6460Sstevel@tonic-gate }
6470Sstevel@tonic-gate
6480Sstevel@tonic-gate /* Do a direct lookup ? */
6490Sstevel@tonic-gate if (val == 0 && (check == rvThenLookup || check == lookupOnly)) {
650*11262SRajagopal.Andra@Sun.COM if (item->type == mit_ldap) {
6510Sstevel@tonic-gate int err = 0;
6520Sstevel@tonic-gate __nis_search_triple_t triple;
6530Sstevel@tonic-gate char *baseDN;
6540Sstevel@tonic-gate
6550Sstevel@tonic-gate /*
6560Sstevel@tonic-gate * If item->searchSpec.triple.base is NULL, or ends
6570Sstevel@tonic-gate * in a comma, append the current search base from
6580Sstevel@tonic-gate * the TSD (put there by an upper layer).
6590Sstevel@tonic-gate *
6600Sstevel@tonic-gate * Special case for N2L mode:
6610Sstevel@tonic-gate * if item->searchSpec.triple.base ends in a comma,
6620Sstevel@tonic-gate * the current domain Context is used.
6630Sstevel@tonic-gate */
6640Sstevel@tonic-gate if (yp2ldap && item->searchSpec.triple.base &&
6650Sstevel@tonic-gate strlen(item->searchSpec.triple.base) > 0) {
6660Sstevel@tonic-gate baseDN = __nisdb_get_tsd()->domainContext;
6670Sstevel@tonic-gate } else {
6680Sstevel@tonic-gate baseDN = __nisdb_get_tsd()->searchBase;
6690Sstevel@tonic-gate }
6700Sstevel@tonic-gate triple.base = appendBase(item->searchSpec.triple.base,
6710Sstevel@tonic-gate baseDN, &err, 0);
6720Sstevel@tonic-gate if (err == 0) {
6730Sstevel@tonic-gate triple.scope = item->searchSpec.triple.scope;
6740Sstevel@tonic-gate triple.attrs = item->searchSpec.triple.attrs;
6750Sstevel@tonic-gate triple.element =
6760Sstevel@tonic-gate item->searchSpec.triple.element;
6770Sstevel@tonic-gate val = lookupLDAP(&triple, item->name, rv, 0,
6780Sstevel@tonic-gate np_ldap_stat);
6790Sstevel@tonic-gate fromldap = '1';
6800Sstevel@tonic-gate } else {
6810Sstevel@tonic-gate val = 0;
6820Sstevel@tonic-gate }
6830Sstevel@tonic-gate sfree(triple.base);
6840Sstevel@tonic-gate }
6850Sstevel@tonic-gate }
6860Sstevel@tonic-gate
6870Sstevel@tonic-gate
6880Sstevel@tonic-gate /* Special processing for NIS to LDAP mode */
6890Sstevel@tonic-gate if (yp2ldap && val != 0) {
6900Sstevel@tonic-gate
6910Sstevel@tonic-gate /*
6920Sstevel@tonic-gate * Escape special chars from dn before sending to DIT,
6930Sstevel@tonic-gate * provided val is not ldap-based
6940Sstevel@tonic-gate */
6950Sstevel@tonic-gate if (fromldap == '\0' && __nisdb_get_tsd()->escapeFlag == '1') {
6960Sstevel@tonic-gate if (escapeSpecialChars(val) < 0) {
6970Sstevel@tonic-gate freeValue(val, 1);
6980Sstevel@tonic-gate return (0);
6990Sstevel@tonic-gate }
7000Sstevel@tonic-gate } else if (__nisdb_get_tsd()->escapeFlag == '2') {
7010Sstevel@tonic-gate /* Remove escape chars from data received from DIT */
7020Sstevel@tonic-gate (void) removeEscapeChars(val);
7030Sstevel@tonic-gate }
7040Sstevel@tonic-gate
7050Sstevel@tonic-gate /*
7060Sstevel@tonic-gate * Remove from 'val', any values obtained using
7070Sstevel@tonic-gate * the 'removespec' syntax
7080Sstevel@tonic-gate */
7090Sstevel@tonic-gate
7100Sstevel@tonic-gate /* Obtain exVal */
7110Sstevel@tonic-gate if (item->exItem)
7120Sstevel@tonic-gate exVal = getMappingItemVal(item->exItem, native, rv,
7130Sstevel@tonic-gate berstring, NULL);
7140Sstevel@tonic-gate
7150Sstevel@tonic-gate /* delete */
7160Sstevel@tonic-gate if (exVal != 0) {
7170Sstevel@tonic-gate for (i = 0; i < val->numVals; ) {
7180Sstevel@tonic-gate for (j = 0; j < exVal->numVals; j++) {
7190Sstevel@tonic-gate if (sstrncmp(val->val[i].value,
7200Sstevel@tonic-gate exVal->val[j].value,
7210Sstevel@tonic-gate MAX(val->val[i].length,
7220Sstevel@tonic-gate exVal->val[j].length))
7230Sstevel@tonic-gate == 0)
7240Sstevel@tonic-gate break;
7250Sstevel@tonic-gate }
7260Sstevel@tonic-gate if (j < exVal->numVals) {
7270Sstevel@tonic-gate sfree(val->val[i].value);
7280Sstevel@tonic-gate val->val[i].value = 0;
7290Sstevel@tonic-gate val->val[i].length = 0;
7300Sstevel@tonic-gate for (k = i; k < val->numVals - 1; k++) {
7310Sstevel@tonic-gate val->val[k] = val->val[k + 1];
7320Sstevel@tonic-gate val->val[k + 1].value = 0;
7330Sstevel@tonic-gate val->val[k + 1].length = 0;
7340Sstevel@tonic-gate }
7350Sstevel@tonic-gate val->numVals--;
7360Sstevel@tonic-gate } else
7370Sstevel@tonic-gate i++;
7380Sstevel@tonic-gate }
7390Sstevel@tonic-gate
7400Sstevel@tonic-gate freeValue(exVal, 1);
7410Sstevel@tonic-gate
7420Sstevel@tonic-gate /*
7430Sstevel@tonic-gate * If val->numVals <= 0, then we have no val to
7440Sstevel@tonic-gate * return. So free up stuff.
7450Sstevel@tonic-gate */
7460Sstevel@tonic-gate if (val->numVals <= 0) {
7470Sstevel@tonic-gate free(val->val);
7480Sstevel@tonic-gate val->val = 0;
7490Sstevel@tonic-gate free(val);
7500Sstevel@tonic-gate return (0);
7510Sstevel@tonic-gate }
7520Sstevel@tonic-gate }
7530Sstevel@tonic-gate }
7540Sstevel@tonic-gate
7550Sstevel@tonic-gate return (val);
7560Sstevel@tonic-gate }
7570Sstevel@tonic-gate
7580Sstevel@tonic-gate __nis_value_t *
getMappingFormat(__nis_mapping_format_t * f,__nis_rule_value_t * rv,__nis_format_arg_t at,void * a,int * numArg)7590Sstevel@tonic-gate getMappingFormat(__nis_mapping_format_t *f, __nis_rule_value_t *rv,
7600Sstevel@tonic-gate __nis_format_arg_t at, void *a, int *numArg) {
7610Sstevel@tonic-gate char *myself = "getMappingFormat";
7620Sstevel@tonic-gate __nis_value_t *val = 0;
7630Sstevel@tonic-gate __nis_buffer_t b = {0, 0};
7640Sstevel@tonic-gate int i;
7650Sstevel@tonic-gate
7660Sstevel@tonic-gate if (f == 0)
7670Sstevel@tonic-gate return (0);
7680Sstevel@tonic-gate
7690Sstevel@tonic-gate if (rv == 0) {
7700Sstevel@tonic-gate val = am(myself, sizeof (*val));
7710Sstevel@tonic-gate if (val == 0)
7720Sstevel@tonic-gate return (0);
7730Sstevel@tonic-gate
7740Sstevel@tonic-gate switch (f->type) {
7750Sstevel@tonic-gate case mmt_item:
7760Sstevel@tonic-gate bp2buf(myself, &b, "%%s");
7770Sstevel@tonic-gate break;
7780Sstevel@tonic-gate case mmt_string:
7790Sstevel@tonic-gate bp2buf(myself, &b, "%s", NIL(f->match.string));
7800Sstevel@tonic-gate break;
7810Sstevel@tonic-gate case mmt_single:
7820Sstevel@tonic-gate bp2buf(myself, &b, "[");
7830Sstevel@tonic-gate for (i = 0; i < f->match.single.numRange; i++) {
7840Sstevel@tonic-gate if (f->match.single.lo[i] ==
7850Sstevel@tonic-gate f->match.single.hi[i])
7860Sstevel@tonic-gate bp2buf(myself, &b, "%c",
7870Sstevel@tonic-gate f->match.single.lo[i]);
7880Sstevel@tonic-gate else
7890Sstevel@tonic-gate bp2buf(myself, &b, "%c-%c",
7900Sstevel@tonic-gate f->match.single.lo[i],
7910Sstevel@tonic-gate f->match.single.hi[i]);
7920Sstevel@tonic-gate }
7930Sstevel@tonic-gate bp2buf(myself, &b, "]");
7940Sstevel@tonic-gate break;
7950Sstevel@tonic-gate case mmt_limit:
7960Sstevel@tonic-gate break;
7970Sstevel@tonic-gate case mmt_any:
7980Sstevel@tonic-gate bp2buf(myself, &b, "*");
7990Sstevel@tonic-gate break;
8000Sstevel@tonic-gate case mmt_berstring:
8010Sstevel@tonic-gate bp2buf(myself, &b, "%s", NIL(f->match.berString));
8020Sstevel@tonic-gate break;
8030Sstevel@tonic-gate case mmt_begin:
8040Sstevel@tonic-gate case mmt_end:
8050Sstevel@tonic-gate bp2buf(myself, &b, "\"");
8060Sstevel@tonic-gate break;
8070Sstevel@tonic-gate default:
8080Sstevel@tonic-gate bp2buf(myself, &b, "<unknown>");
8090Sstevel@tonic-gate }
8100Sstevel@tonic-gate val->type = vt_string;
8110Sstevel@tonic-gate val->numVals = 1;
8120Sstevel@tonic-gate val->val = am(myself, sizeof (val->val[0]));
8130Sstevel@tonic-gate if (val->val == 0) {
8140Sstevel@tonic-gate sfree(val);
8150Sstevel@tonic-gate return (0);
8160Sstevel@tonic-gate }
8170Sstevel@tonic-gate val->val[0].value = b.buf;
8180Sstevel@tonic-gate val->val[0].length = b.len;
8190Sstevel@tonic-gate } else {
8200Sstevel@tonic-gate switch (f->type) {
8210Sstevel@tonic-gate case mmt_item:
8220Sstevel@tonic-gate case mmt_berstring:
8230Sstevel@tonic-gate if (a != 0) {
8240Sstevel@tonic-gate if (at == fa_item) {
8250Sstevel@tonic-gate val = getMappingItemVal(
8260Sstevel@tonic-gate (__nis_mapping_item_t *)a,
8270Sstevel@tonic-gate mit_any, rv,
8280Sstevel@tonic-gate (f->type == mmt_berstring) ? f->match.berString : 0, NULL);
8290Sstevel@tonic-gate if (numArg != 0)
8300Sstevel@tonic-gate (*numArg)++;
8310Sstevel@tonic-gate } else {
8320Sstevel@tonic-gate val = cloneValue(
8330Sstevel@tonic-gate (__nis_value_t *)a, 1);
8340Sstevel@tonic-gate if (numArg != 0)
8350Sstevel@tonic-gate (*numArg)++;
8360Sstevel@tonic-gate }
8370Sstevel@tonic-gate }
8380Sstevel@tonic-gate break;
8390Sstevel@tonic-gate case mmt_string:
8400Sstevel@tonic-gate val = am(myself, sizeof (*val));
8410Sstevel@tonic-gate if (val == 0)
8420Sstevel@tonic-gate return (0);
8430Sstevel@tonic-gate val->type = vt_string;
8440Sstevel@tonic-gate val->numVals = 1;
8450Sstevel@tonic-gate val->val = am(myself, sizeof (val->val[0]));
8460Sstevel@tonic-gate if (val->val == 0) {
8470Sstevel@tonic-gate sfree(val);
8480Sstevel@tonic-gate return (0);
8490Sstevel@tonic-gate }
8500Sstevel@tonic-gate val->val[0].value = sdup(myself, T, f->match.string);
8510Sstevel@tonic-gate val->val[0].length = strlen(val->val[0].value);
8520Sstevel@tonic-gate break;
8530Sstevel@tonic-gate case mmt_single:
8540Sstevel@tonic-gate case mmt_limit:
8550Sstevel@tonic-gate case mmt_any:
8560Sstevel@tonic-gate case mmt_begin:
8570Sstevel@tonic-gate case mmt_end:
8580Sstevel@tonic-gate /* Not an error, so return an empty value */
8590Sstevel@tonic-gate val = am(myself, sizeof (*val));
8600Sstevel@tonic-gate if (val == 0)
8610Sstevel@tonic-gate return (0);
8620Sstevel@tonic-gate val->type = vt_string;
8630Sstevel@tonic-gate val->numVals = 0;
8640Sstevel@tonic-gate val->val = 0;
8650Sstevel@tonic-gate break;
8660Sstevel@tonic-gate default:
8670Sstevel@tonic-gate /* Do nothing */
8680Sstevel@tonic-gate val = 0;
8690Sstevel@tonic-gate break;
8700Sstevel@tonic-gate }
8710Sstevel@tonic-gate }
8720Sstevel@tonic-gate return (val);
8730Sstevel@tonic-gate }
8740Sstevel@tonic-gate
8750Sstevel@tonic-gate /*
8760Sstevel@tonic-gate * Used when evaluating an expression. Typically, the value of the
8770Sstevel@tonic-gate * expression so far will be kept in 'v1', and 'v2' is the value
8780Sstevel@tonic-gate * of the current component of the expression. In the general case,
8790Sstevel@tonic-gate * both will be multi-valued, and the result is an "explosion"
8800Sstevel@tonic-gate * resulting in N*M new values (if 'v1' had N values, and 'v2'
8810Sstevel@tonic-gate * M ditto).
8820Sstevel@tonic-gate *
8830Sstevel@tonic-gate * For example, if v1 = {"ab", "cd", "ef"}, and v2 = {"gh", "ij", "kl"},
8840Sstevel@tonic-gate * the result will be {"abgh", "abij", "abkl", "cdgh", "cdij", "cdkl",
8850Sstevel@tonic-gate * "efgh", "efij", "efkl"}.
8860Sstevel@tonic-gate *
8870Sstevel@tonic-gate * There are special cases when v1->repeat and/or v2->repeat are set.
8880Sstevel@tonic-gate * Repeat mostly makes sense with single values; for example, if
8890Sstevel@tonic-gate * v1 = {"x="} with repeat on, and v2 = {"1", "2", "3"}, the result
8900Sstevel@tonic-gate * is {"x=1", "x=2", "x=3"}.
8910Sstevel@tonic-gate *
8920Sstevel@tonic-gate * The result if v2 also had repeat on would be {"x=1x=2x=3"}. It's
8930Sstevel@tonic-gate * not clear if there's a useful application for this, but the code's
8940Sstevel@tonic-gate * there for the sake of orthogonality.
8950Sstevel@tonic-gate */
8960Sstevel@tonic-gate __nis_value_t *
explodeValues(__nis_value_t * v1,__nis_value_t * v2)8970Sstevel@tonic-gate explodeValues(__nis_value_t *v1, __nis_value_t *v2) {
8980Sstevel@tonic-gate int i1, i2, n, nv;
8990Sstevel@tonic-gate __nis_value_t *v;
9000Sstevel@tonic-gate __nis_buffer_t b = {0, 0};
9010Sstevel@tonic-gate char *myself = "explodeValues";
9020Sstevel@tonic-gate
9030Sstevel@tonic-gate if (v1 == 0 || v1->numVals <= 0)
9040Sstevel@tonic-gate return (cloneValue(v2, 1));
9050Sstevel@tonic-gate if (v2 == 0 || v2->numVals <= 0)
9060Sstevel@tonic-gate return (cloneValue(v1, 1));
9070Sstevel@tonic-gate
9080Sstevel@tonic-gate /*
9090Sstevel@tonic-gate * XXX What should we do if (v1->type != v2->type) ?
9100Sstevel@tonic-gate * Policy: Just explode anyway, even though the result is
9110Sstevel@tonic-gate * unlikely to be very useful.
9120Sstevel@tonic-gate */
9130Sstevel@tonic-gate
9140Sstevel@tonic-gate v = am(myself, sizeof (*v));
9150Sstevel@tonic-gate if (v == 0)
9160Sstevel@tonic-gate return (0);
9170Sstevel@tonic-gate
9180Sstevel@tonic-gate if (!v1->repeat && !v2->repeat)
9190Sstevel@tonic-gate nv = v1->numVals * v2->numVals;
9200Sstevel@tonic-gate else if (v1->repeat && !v2->repeat)
9210Sstevel@tonic-gate nv = v2->numVals;
9220Sstevel@tonic-gate else if (!v1->repeat && v2->repeat)
9230Sstevel@tonic-gate nv = v1->numVals;
9240Sstevel@tonic-gate else /* v1->repeat && v2->repeat */
9250Sstevel@tonic-gate nv = 1;
9260Sstevel@tonic-gate
9270Sstevel@tonic-gate v->val = am(myself, nv * sizeof (v->val[0]));
9280Sstevel@tonic-gate if (v->val == 0) {
9290Sstevel@tonic-gate free(v);
9300Sstevel@tonic-gate return (0);
9310Sstevel@tonic-gate }
9320Sstevel@tonic-gate
9330Sstevel@tonic-gate /*
9340Sstevel@tonic-gate * Four different cases, depending on the 'repeat' flags.
9350Sstevel@tonic-gate */
9360Sstevel@tonic-gate if (!v1->repeat && !v2->repeat) {
9370Sstevel@tonic-gate for (i1 = 0, n = 0; i1 < v1->numVals; i1++) {
9380Sstevel@tonic-gate for (i2 = 0; i2 < v2->numVals; i2++) {
9390Sstevel@tonic-gate if (v1->type == vt_string)
9400Sstevel@tonic-gate sbc2buf(myself, v1->val[i1].value,
9410Sstevel@tonic-gate v1->val[i1].length,
9420Sstevel@tonic-gate &b);
9430Sstevel@tonic-gate else
9440Sstevel@tonic-gate bc2buf(myself, v1->val[i1].value,
9450Sstevel@tonic-gate v1->val[i1].length,
9460Sstevel@tonic-gate &b);
9470Sstevel@tonic-gate if (v2->type == vt_string)
9480Sstevel@tonic-gate sbc2buf(myself, v2->val[i2].value,
9490Sstevel@tonic-gate v2->val[i2].length,
9500Sstevel@tonic-gate &b);
9510Sstevel@tonic-gate else
9520Sstevel@tonic-gate bc2buf(myself, v2->val[i2].value,
9530Sstevel@tonic-gate v2->val[i2].length,
9540Sstevel@tonic-gate &b);
9550Sstevel@tonic-gate v->val[n].value = b.buf;
9560Sstevel@tonic-gate v->val[n].length = b.len;
9570Sstevel@tonic-gate n++;
9580Sstevel@tonic-gate b.buf = 0;
9590Sstevel@tonic-gate b.len = 0;
9600Sstevel@tonic-gate }
9610Sstevel@tonic-gate }
9620Sstevel@tonic-gate } else if (v1->repeat && !v2->repeat) {
9630Sstevel@tonic-gate for (i2 = 0; i2 < v2->numVals; i2++) {
9640Sstevel@tonic-gate for (i1 = 0, n = 0; i1 < v1->numVals; i1++) {
9650Sstevel@tonic-gate if (v1->type == vt_string)
9660Sstevel@tonic-gate sbc2buf(myself, v1->val[i1].value,
9670Sstevel@tonic-gate v1->val[i1].length,
9680Sstevel@tonic-gate &b);
9690Sstevel@tonic-gate else
9700Sstevel@tonic-gate bc2buf(myself, v1->val[i1].value,
9710Sstevel@tonic-gate v1->val[i1].length,
9720Sstevel@tonic-gate &b);
9730Sstevel@tonic-gate if (v2->type == vt_string)
9740Sstevel@tonic-gate sbc2buf(myself, v2->val[i2].value,
9750Sstevel@tonic-gate v2->val[i2].length,
9760Sstevel@tonic-gate &b);
9770Sstevel@tonic-gate else
9780Sstevel@tonic-gate bc2buf(myself, v2->val[i2].value,
9790Sstevel@tonic-gate v2->val[i2].length,
9800Sstevel@tonic-gate &b);
9810Sstevel@tonic-gate }
9820Sstevel@tonic-gate v->val[n].value = b.buf;
9830Sstevel@tonic-gate v->val[n].length = b.len;
9840Sstevel@tonic-gate n++;
9850Sstevel@tonic-gate b.buf = 0;
9860Sstevel@tonic-gate b.len = 0;
9870Sstevel@tonic-gate }
9880Sstevel@tonic-gate } else if (!v1->repeat && v2->repeat) {
9890Sstevel@tonic-gate for (i1 = 0, n = 0; i1 < v1->numVals; i1++) {
9900Sstevel@tonic-gate for (i2 = 0; i2 < v2->numVals; i2++) {
9910Sstevel@tonic-gate if (v1->type == vt_string)
9920Sstevel@tonic-gate sbc2buf(myself, v1->val[i1].value,
9930Sstevel@tonic-gate v1->val[i1].length,
9940Sstevel@tonic-gate &b);
9950Sstevel@tonic-gate else
9960Sstevel@tonic-gate bc2buf(myself, v1->val[i1].value,
9970Sstevel@tonic-gate v1->val[i1].length,
9980Sstevel@tonic-gate &b);
9990Sstevel@tonic-gate if (v2->type == vt_string)
10000Sstevel@tonic-gate sbc2buf(myself, v2->val[i2].value,
10010Sstevel@tonic-gate v2->val[i2].length,
10020Sstevel@tonic-gate &b);
10030Sstevel@tonic-gate else
10040Sstevel@tonic-gate bc2buf(myself, v2->val[i2].value,
10050Sstevel@tonic-gate v2->val[i2].length,
10060Sstevel@tonic-gate &b);
10070Sstevel@tonic-gate }
10080Sstevel@tonic-gate v->val[n].value = b.buf;
10090Sstevel@tonic-gate v->val[n].length = b.len;
10100Sstevel@tonic-gate n++;
10110Sstevel@tonic-gate b.buf = 0;
10120Sstevel@tonic-gate b.len = 0;
10130Sstevel@tonic-gate }
10140Sstevel@tonic-gate } else { /* v1->repeat && v2->repeat */
10150Sstevel@tonic-gate for (i1 = 0, n = 0; i1 < v1->numVals; i1++) {
10160Sstevel@tonic-gate for (i2 = 0; i2 < v2->numVals; i2++) {
10170Sstevel@tonic-gate if (v1->type == vt_string)
10180Sstevel@tonic-gate sbc2buf(myself, v1->val[i1].value,
10190Sstevel@tonic-gate v1->val[i1].length,
10200Sstevel@tonic-gate &b);
10210Sstevel@tonic-gate else
10220Sstevel@tonic-gate bc2buf(myself, v1->val[i1].value,
10230Sstevel@tonic-gate v1->val[i1].length,
10240Sstevel@tonic-gate &b);
10250Sstevel@tonic-gate if (v2->type == vt_string)
10260Sstevel@tonic-gate sbc2buf(myself, v2->val[i2].value,
10270Sstevel@tonic-gate v2->val[i2].length,
10280Sstevel@tonic-gate &b);
10290Sstevel@tonic-gate else
10300Sstevel@tonic-gate bc2buf(myself, v2->val[i2].value,
10310Sstevel@tonic-gate v2->val[i2].length,
10320Sstevel@tonic-gate &b);
10330Sstevel@tonic-gate }
10340Sstevel@tonic-gate }
10350Sstevel@tonic-gate v->val[n].value = b.buf;
10360Sstevel@tonic-gate v->val[n].length = b.len;
10370Sstevel@tonic-gate n++;
10380Sstevel@tonic-gate b.buf = 0;
10390Sstevel@tonic-gate b.len = 0;
10400Sstevel@tonic-gate }
10410Sstevel@tonic-gate
10420Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG
10430Sstevel@tonic-gate /* Sanity check */
10440Sstevel@tonic-gate if (n != nv)
10450Sstevel@tonic-gate abort();
10460Sstevel@tonic-gate #endif /* NISD__LDAP_DEBUG */
10470Sstevel@tonic-gate
10480Sstevel@tonic-gate v->type = (v1->type == vt_string) ?
10490Sstevel@tonic-gate ((v2->type == vt_string) ?
10500Sstevel@tonic-gate vt_string : vt_ber) : vt_ber;
10510Sstevel@tonic-gate v->repeat = 0;
10520Sstevel@tonic-gate v->numVals = n;
10530Sstevel@tonic-gate
10540Sstevel@tonic-gate return (v);
10550Sstevel@tonic-gate }
10560Sstevel@tonic-gate
10570Sstevel@tonic-gate __nis_value_t *
getMappingFormatArray(__nis_mapping_format_t * a,__nis_rule_value_t * rv,__nis_format_arg_t at,int numArgs,void * arg)10580Sstevel@tonic-gate getMappingFormatArray(__nis_mapping_format_t *a, __nis_rule_value_t *rv,
10590Sstevel@tonic-gate __nis_format_arg_t at, int numArgs, void *arg) {
10600Sstevel@tonic-gate int i, ia = 0;
10610Sstevel@tonic-gate __nis_value_t *val, *v = 0;
10620Sstevel@tonic-gate bool_t moreFormat = (a != 0);
10630Sstevel@tonic-gate bool_t moreArgs = (numArgs > 0);
10640Sstevel@tonic-gate
10650Sstevel@tonic-gate while (moreFormat && (arg == 0 || ia < numArgs)) {
10660Sstevel@tonic-gate for (i = 0; moreFormat; i++) {
10670Sstevel@tonic-gate moreFormat = (a[i].type != mmt_end);
10680Sstevel@tonic-gate if (at == fa_item) {
10690Sstevel@tonic-gate __nis_mapping_item_t *item = arg;
10700Sstevel@tonic-gate val = getMappingFormat(&a[i], rv, at,
10710Sstevel@tonic-gate ((item != 0) ? &item[ia] : 0), &ia);
10720Sstevel@tonic-gate } else {
10730Sstevel@tonic-gate __nis_value_t **ival = arg;
10740Sstevel@tonic-gate val = getMappingFormat(&a[i], rv, at,
10750Sstevel@tonic-gate ((ival != 0) ? ival[ia] : 0), &ia);
10760Sstevel@tonic-gate }
10770Sstevel@tonic-gate if (val != 0) {
10780Sstevel@tonic-gate __nis_value_t *new = explodeValues(v, val);
10790Sstevel@tonic-gate
10800Sstevel@tonic-gate freeValue(v, 1);
10810Sstevel@tonic-gate freeValue(val, 1);
10820Sstevel@tonic-gate if (new == 0)
10830Sstevel@tonic-gate return (0);
10840Sstevel@tonic-gate
10850Sstevel@tonic-gate v = new;
10860Sstevel@tonic-gate } else {
10870Sstevel@tonic-gate freeValue(v, 1);
10880Sstevel@tonic-gate return (0);
10890Sstevel@tonic-gate }
10900Sstevel@tonic-gate /*
10910Sstevel@tonic-gate * If we run out of arguments, but still have format
10920Sstevel@tonic-gate * remaining, repeat the last argument. Keep track of
10930Sstevel@tonic-gate * the fact that we've really consumed all arguments.
10940Sstevel@tonic-gate */
10950Sstevel@tonic-gate if (moreFormat && ia >= numArgs) {
10960Sstevel@tonic-gate ia = (numArgs > 0) ? numArgs - 1 : 0;
10970Sstevel@tonic-gate moreArgs = FALSE;
10980Sstevel@tonic-gate }
10990Sstevel@tonic-gate }
11000Sstevel@tonic-gate /*
11010Sstevel@tonic-gate * We've run out of format, so if we still have arguments
11020Sstevel@tonic-gate * left, start over on the format.
11030Sstevel@tonic-gate */
11040Sstevel@tonic-gate if (ia < numArgs && moreArgs) {
11050Sstevel@tonic-gate /*
11060Sstevel@tonic-gate * However, if we didn't consume any arguments going
11070Sstevel@tonic-gate * through the format once, abort to avoid an infinite
11080Sstevel@tonic-gate * loop.
11090Sstevel@tonic-gate */
11100Sstevel@tonic-gate if (numArgs > 0 && ia <= 0) {
11110Sstevel@tonic-gate freeValue(v, 1);
11120Sstevel@tonic-gate return (0);
11130Sstevel@tonic-gate }
11140Sstevel@tonic-gate moreFormat = 1;
11150Sstevel@tonic-gate }
11160Sstevel@tonic-gate }
11170Sstevel@tonic-gate
11180Sstevel@tonic-gate return (v);
11190Sstevel@tonic-gate }
11200Sstevel@tonic-gate
11210Sstevel@tonic-gate /*
11220Sstevel@tonic-gate * Returns a string representation (such as "[name=foo, value=bar]")
11230Sstevel@tonic-gate * of a nis_index_t.
11240Sstevel@tonic-gate */
11250Sstevel@tonic-gate char *
getIndex(__nis_index_t * i,int * len)11260Sstevel@tonic-gate getIndex(__nis_index_t *i, int *len) {
11270Sstevel@tonic-gate int n;
11280Sstevel@tonic-gate __nis_buffer_t b = {0, 0};
11290Sstevel@tonic-gate char *myself = "getIndex";
11300Sstevel@tonic-gate
11310Sstevel@tonic-gate if (i == 0)
11320Sstevel@tonic-gate return (0);
11330Sstevel@tonic-gate
11340Sstevel@tonic-gate if (i->numIndexes > 0) {
11350Sstevel@tonic-gate bp2buf(myself, &b, "[");
11360Sstevel@tonic-gate for (n = 0; n < i->numIndexes; n++) {
11370Sstevel@tonic-gate __nis_value_t *val;
11380Sstevel@tonic-gate int j;
11390Sstevel@tonic-gate
11400Sstevel@tonic-gate val = getMappingFormatArray(i->value[n],
11410Sstevel@tonic-gate 0, fa_any, 0, 0);
11420Sstevel@tonic-gate if (n > 0)
11430Sstevel@tonic-gate bp2buf(myself, &b, ", ");
11440Sstevel@tonic-gate bp2buf(myself, &b, "%s=", i->name[n]);
11450Sstevel@tonic-gate if (val != 0) {
11460Sstevel@tonic-gate for (j = 0; j < val->numVals; j++) {
11470Sstevel@tonic-gate bc2buf(myself, val->val[j].value,
11480Sstevel@tonic-gate val->val[j].length, &b);
11490Sstevel@tonic-gate }
11500Sstevel@tonic-gate } else {
11510Sstevel@tonic-gate bp2buf(myself, &b, "<no-vals>");
11520Sstevel@tonic-gate }
11530Sstevel@tonic-gate freeValue(val, 1);
11540Sstevel@tonic-gate }
11550Sstevel@tonic-gate bp2buf(myself, &b, "]");
11560Sstevel@tonic-gate }
11570Sstevel@tonic-gate if (len != 0)
11580Sstevel@tonic-gate *len = b.len;
11590Sstevel@tonic-gate return (b.buf);
11600Sstevel@tonic-gate }
11610Sstevel@tonic-gate
11620Sstevel@tonic-gate char *
getObjSpec(__nis_obj_spec_t * o,int * len)11630Sstevel@tonic-gate getObjSpec(__nis_obj_spec_t *o, int *len) {
11640Sstevel@tonic-gate __nis_buffer_t b = {0, 0};
11650Sstevel@tonic-gate char *myself = "getObjSpec";
11660Sstevel@tonic-gate
11670Sstevel@tonic-gate if (o == 0)
11680Sstevel@tonic-gate return (0);
11690Sstevel@tonic-gate
11700Sstevel@tonic-gate b.buf = getIndex(&o->index, &b.len);
11710Sstevel@tonic-gate sbc2buf(myself, o->name, slen(o->name), &b);
11720Sstevel@tonic-gate if (len != 0)
11730Sstevel@tonic-gate *len = b.len;
11740Sstevel@tonic-gate return (b.buf);
11750Sstevel@tonic-gate }
11760Sstevel@tonic-gate
11770Sstevel@tonic-gate /*
11780Sstevel@tonic-gate * Returns a string representation of the LDAP scope. Note that the
11790Sstevel@tonic-gate * returned value is a static entity, and must be copied by the
11800Sstevel@tonic-gate * caller (but, obviously, must not be freed).
11810Sstevel@tonic-gate */
11820Sstevel@tonic-gate char *
getScope(int scope)11830Sstevel@tonic-gate getScope(int scope) {
11840Sstevel@tonic-gate switch (scope) {
11850Sstevel@tonic-gate case LDAP_SCOPE_BASE:
11860Sstevel@tonic-gate return ("base");
11870Sstevel@tonic-gate case LDAP_SCOPE_ONELEVEL:
11880Sstevel@tonic-gate return ("one");
11890Sstevel@tonic-gate case LDAP_SCOPE_SUBTREE:
11900Sstevel@tonic-gate return ("sub");
11910Sstevel@tonic-gate default:
11920Sstevel@tonic-gate return ("one");
11930Sstevel@tonic-gate }
11940Sstevel@tonic-gate }
11950Sstevel@tonic-gate
11960Sstevel@tonic-gate /*
11970Sstevel@tonic-gate * Return a string representation of an LDAP search triple (such as
11980Sstevel@tonic-gate * "ou=Hosts,dc=eng,dc=sun,dc=com?one?cn=xyzzy").
11990Sstevel@tonic-gate */
12000Sstevel@tonic-gate char *
getSearchTriple(__nis_search_triple_t * s,int * len)12010Sstevel@tonic-gate getSearchTriple(__nis_search_triple_t *s, int *len) {
12020Sstevel@tonic-gate __nis_buffer_t b = {0, 0};
12030Sstevel@tonic-gate char *a;
12040Sstevel@tonic-gate int l;
12050Sstevel@tonic-gate char *myself = "getSearchTriple";
12060Sstevel@tonic-gate
12070Sstevel@tonic-gate /* If the scope is LDAP_SCOPE_UNKNOWN, the search triple is unused */
12080Sstevel@tonic-gate if (s == 0 || s->scope == LDAP_SCOPE_UNKNOWN) {
12090Sstevel@tonic-gate if (len != 0)
12100Sstevel@tonic-gate *len = 0;
12110Sstevel@tonic-gate return (0);
12120Sstevel@tonic-gate }
12130Sstevel@tonic-gate
12140Sstevel@tonic-gate if (s->base != 0)
12150Sstevel@tonic-gate sbc2buf(myself, s->base, slen(s->base), &b);
12160Sstevel@tonic-gate if (!(s->scope == LDAP_SCOPE_ONELEVEL &&
12170Sstevel@tonic-gate (s->base == 0 || s->base[0] == '\0'))) {
12180Sstevel@tonic-gate bp2buf(myself, &b, "?%s?", getScope(s->scope));
12190Sstevel@tonic-gate }
12200Sstevel@tonic-gate if ((l = slen(s->attrs)) > 0) {
12210Sstevel@tonic-gate /*
12220Sstevel@tonic-gate * Remove white space from the filter/attribute list.
12230Sstevel@tonic-gate * The parser usually keeps any white space from the
12240Sstevel@tonic-gate * config file (or LDAP/command line), but we don't
12250Sstevel@tonic-gate * want it.
12260Sstevel@tonic-gate */
12270Sstevel@tonic-gate a = am(myself, l+1);
12280Sstevel@tonic-gate if (a != 0) {
12290Sstevel@tonic-gate int i, la;
12300Sstevel@tonic-gate
12310Sstevel@tonic-gate for (i = 0, la = 0; i < l; i++) {
12320Sstevel@tonic-gate if (s->attrs[i] != ' ' &&
12330Sstevel@tonic-gate s->attrs[i] != '\t')
12340Sstevel@tonic-gate a[la++] = s->attrs[i];
12350Sstevel@tonic-gate }
12360Sstevel@tonic-gate sbc2buf(myself, a, la, &b);
12370Sstevel@tonic-gate sfree(a);
12380Sstevel@tonic-gate } else {
12390Sstevel@tonic-gate sbc2buf(myself, s->attrs, slen(s->attrs), &b);
12400Sstevel@tonic-gate }
12410Sstevel@tonic-gate }
12420Sstevel@tonic-gate
12430Sstevel@tonic-gate if (len != 0)
12440Sstevel@tonic-gate *len = b.len;
12450Sstevel@tonic-gate return (b.buf);
12460Sstevel@tonic-gate }
12470Sstevel@tonic-gate
12480Sstevel@tonic-gate __nis_value_t *
getMappingItem(__nis_mapping_item_t * i,__nis_mapping_item_type_t native,__nis_rule_value_t * rv,char * berstring,int * np_ldap_stat)12490Sstevel@tonic-gate getMappingItem(__nis_mapping_item_t *i, __nis_mapping_item_type_t native,
12500Sstevel@tonic-gate __nis_rule_value_t *rv, char *berstring, int *np_ldap_stat) {
12510Sstevel@tonic-gate char *myself = "getMappingItem";
12520Sstevel@tonic-gate __nis_value_t *val = 0;
12530Sstevel@tonic-gate __nis_buffer_t b = {0, 0};
12540Sstevel@tonic-gate int len = 0;
12550Sstevel@tonic-gate char *buf;
12560Sstevel@tonic-gate
12570Sstevel@tonic-gate if (i == 0)
12580Sstevel@tonic-gate return (0);
12590Sstevel@tonic-gate
12600Sstevel@tonic-gate if (rv != 0)
12610Sstevel@tonic-gate return (getMappingItemVal(i, native, rv, berstring,
12620Sstevel@tonic-gate np_ldap_stat));
12630Sstevel@tonic-gate
12640Sstevel@tonic-gate val = am(myself, sizeof (*val));
12650Sstevel@tonic-gate if (val == 0)
12660Sstevel@tonic-gate return (0);
12670Sstevel@tonic-gate
12680Sstevel@tonic-gate switch (i->type) {
12690Sstevel@tonic-gate case mit_nisplus:
12700Sstevel@tonic-gate if (native != mit_nisplus)
12710Sstevel@tonic-gate bp2buf(myself, &b, "nis+:");
12720Sstevel@tonic-gate bp2buf(myself, &b, "%s", NIL(i->name));
12730Sstevel@tonic-gate buf = getObjSpec(&i->searchSpec.obj, &len);
12740Sstevel@tonic-gate if (buf != 0 && len > 0) {
12750Sstevel@tonic-gate bc2buf(myself, ":", 1, &b);
12760Sstevel@tonic-gate sbc2buf(myself, buf, len, &b);
12770Sstevel@tonic-gate }
12780Sstevel@tonic-gate sfree(buf);
12790Sstevel@tonic-gate val->type = vt_string;
12800Sstevel@tonic-gate val->repeat = i->repeat;
12810Sstevel@tonic-gate val->numVals = 1;
12820Sstevel@tonic-gate val->val = am(myself, sizeof (val->val[0]));
12830Sstevel@tonic-gate if (val->val == 0) {
12840Sstevel@tonic-gate sfree(b.buf);
12850Sstevel@tonic-gate free(val);
12860Sstevel@tonic-gate return (0);
12870Sstevel@tonic-gate }
12880Sstevel@tonic-gate val->val[0].value = b.buf;
12890Sstevel@tonic-gate val->val[0].length = b.len;
12900Sstevel@tonic-gate break;
12910Sstevel@tonic-gate case mit_ldap:
12920Sstevel@tonic-gate if (native != mit_ldap)
12930Sstevel@tonic-gate bp2buf(myself, &b, "ldap:");
12940Sstevel@tonic-gate bp2buf(myself, &b, "%s", NIL(i->name));
12950Sstevel@tonic-gate buf = getSearchTriple(&i->searchSpec.triple, &len);
12960Sstevel@tonic-gate if (buf != 0 && len > 0) {
12970Sstevel@tonic-gate bc2buf(myself, ":", 1, &b);
12980Sstevel@tonic-gate sbc2buf(myself, buf, len, &b);
12990Sstevel@tonic-gate }
13000Sstevel@tonic-gate sfree(buf);
13010Sstevel@tonic-gate val->type = vt_string;
13020Sstevel@tonic-gate val->repeat = i->repeat;
13030Sstevel@tonic-gate val->numVals = 1;
13040Sstevel@tonic-gate val->val = am(myself, sizeof (val->val[0]));
13050Sstevel@tonic-gate if (val->val == 0) {
13060Sstevel@tonic-gate sfree(b.buf);
13070Sstevel@tonic-gate free(val);
13080Sstevel@tonic-gate return (0);
13090Sstevel@tonic-gate }
13100Sstevel@tonic-gate val->val[0].value = b.buf;
13110Sstevel@tonic-gate val->val[0].length = b.len;
13120Sstevel@tonic-gate break;
13130Sstevel@tonic-gate default:
13140Sstevel@tonic-gate p2buf(myself, "<unknown>:");
13150Sstevel@tonic-gate p2buf(myself, "%s", NIL(i->name));
13160Sstevel@tonic-gate break;
13170Sstevel@tonic-gate }
13180Sstevel@tonic-gate
13190Sstevel@tonic-gate return (val);
13200Sstevel@tonic-gate }
13210Sstevel@tonic-gate
13220Sstevel@tonic-gate void
copyObjSpec(__nis_obj_spec_t * old,__nis_obj_spec_t * new,int * err)13230Sstevel@tonic-gate copyObjSpec(__nis_obj_spec_t *old, __nis_obj_spec_t *new, int *err) {
13240Sstevel@tonic-gate char *myself = "copyObjSpec";
13250Sstevel@tonic-gate
13260Sstevel@tonic-gate if (old == 0 || new == 0) {
13270Sstevel@tonic-gate *err = EINVAL;
13280Sstevel@tonic-gate return;
13290Sstevel@tonic-gate }
13300Sstevel@tonic-gate
13310Sstevel@tonic-gate if (new->index.name == 0) {
13320Sstevel@tonic-gate new->index.name = am(myself, old->index.numIndexes *
13330Sstevel@tonic-gate sizeof (new->index.name[0]));
13340Sstevel@tonic-gate if (old->index.numIndexes > 0 && new->index.name == 0) {
13350Sstevel@tonic-gate *err = ENOMEM;
13360Sstevel@tonic-gate return;
13370Sstevel@tonic-gate }
13380Sstevel@tonic-gate new->index.value = am(myself, old->index.numIndexes *
13390Sstevel@tonic-gate sizeof (new->index.value[0]));
13400Sstevel@tonic-gate if (old->index.numIndexes > 0 && new->index.value == 0) {
13410Sstevel@tonic-gate *err = ENOMEM;
13420Sstevel@tonic-gate return;
13430Sstevel@tonic-gate }
13440Sstevel@tonic-gate }
13450Sstevel@tonic-gate new->name = sdup(myself, T, old->name);
13460Sstevel@tonic-gate if (new->name == 0 && old->name != 0) {
13470Sstevel@tonic-gate *err = ENOMEM;
13480Sstevel@tonic-gate return;
13490Sstevel@tonic-gate }
13500Sstevel@tonic-gate copyIndex(&old->index, &new->index, err);
13510Sstevel@tonic-gate }
13520Sstevel@tonic-gate
13530Sstevel@tonic-gate __nis_obj_spec_t *
cloneObjSpec(__nis_obj_spec_t * old)13540Sstevel@tonic-gate cloneObjSpec(__nis_obj_spec_t *old) {
13550Sstevel@tonic-gate char *myself = "cloneObjSpec";
13560Sstevel@tonic-gate int err = 0;
13570Sstevel@tonic-gate __nis_obj_spec_t *new = am(myself, sizeof (*new));
13580Sstevel@tonic-gate
13590Sstevel@tonic-gate if (new != 0) {
13600Sstevel@tonic-gate copyObjSpec(old, new, &err);
13610Sstevel@tonic-gate if (err != 0) {
13620Sstevel@tonic-gate freeObjSpec(new, 1);
13630Sstevel@tonic-gate new = 0;
13640Sstevel@tonic-gate }
13650Sstevel@tonic-gate }
13660Sstevel@tonic-gate
13670Sstevel@tonic-gate return (new);
13680Sstevel@tonic-gate }
13690Sstevel@tonic-gate
13700Sstevel@tonic-gate void
freeObjSpec(__nis_obj_spec_t * old,bool_t doFree)13710Sstevel@tonic-gate freeObjSpec(__nis_obj_spec_t *old, bool_t doFree) {
13720Sstevel@tonic-gate
13730Sstevel@tonic-gate if (old == 0)
13740Sstevel@tonic-gate return;
13750Sstevel@tonic-gate
13760Sstevel@tonic-gate sfree(old->name);
13770Sstevel@tonic-gate freeIndex(&old->index, FALSE);
13780Sstevel@tonic-gate if (doFree)
13790Sstevel@tonic-gate free(old);
13800Sstevel@tonic-gate }
13810Sstevel@tonic-gate
13820Sstevel@tonic-gate void
copySearchTriple(__nis_search_triple_t * old,__nis_search_triple_t * new,int * err)13830Sstevel@tonic-gate copySearchTriple(__nis_search_triple_t *old, __nis_search_triple_t *new,
13840Sstevel@tonic-gate int *err) {
13850Sstevel@tonic-gate char *myself = "copySearchTriple";
13860Sstevel@tonic-gate
13870Sstevel@tonic-gate *err = 0;
13880Sstevel@tonic-gate
13890Sstevel@tonic-gate if (old == 0 || new == 0) {
13900Sstevel@tonic-gate *err = EINVAL;
13910Sstevel@tonic-gate return;
13920Sstevel@tonic-gate }
13930Sstevel@tonic-gate
13940Sstevel@tonic-gate if (old->base != NULL)
13950Sstevel@tonic-gate new->base = sdup(myself, T, old->base);
13960Sstevel@tonic-gate else
13970Sstevel@tonic-gate new->base = NULL;
13980Sstevel@tonic-gate if (old->attrs != NULL)
13990Sstevel@tonic-gate new->attrs = sdup(myself, T, old->attrs);
14000Sstevel@tonic-gate else
14010Sstevel@tonic-gate new->attrs = NULL;
14020Sstevel@tonic-gate if ((new->base == 0 && old->base != 0) ||
14030Sstevel@tonic-gate (new->attrs == 0 && old->attrs != 0)) {
14040Sstevel@tonic-gate sfree(new->base);
14050Sstevel@tonic-gate new->base = 0;
14060Sstevel@tonic-gate sfree(new->attrs);
14070Sstevel@tonic-gate new->attrs = 0;
14080Sstevel@tonic-gate *err = ENOMEM;
14090Sstevel@tonic-gate return;
14100Sstevel@tonic-gate }
14110Sstevel@tonic-gate new->scope = old->scope;
14120Sstevel@tonic-gate /*
14130Sstevel@tonic-gate * XXX Really should have a cloneMappingElement() function.
14140Sstevel@tonic-gate * However, since whatever the 'element' field points to
14150Sstevel@tonic-gate * is allocated at parse time, and never is freed or modified,
14160Sstevel@tonic-gate * it's sufficient to copy the pointer value.
14170Sstevel@tonic-gate */
14180Sstevel@tonic-gate new->element = old->element;
14190Sstevel@tonic-gate }
14200Sstevel@tonic-gate
14210Sstevel@tonic-gate __nis_search_triple_t *
cloneSearchTriple(__nis_search_triple_t * old)14220Sstevel@tonic-gate cloneSearchTriple(__nis_search_triple_t *old) {
14230Sstevel@tonic-gate char *myself = "cloneSearchTriple";
14240Sstevel@tonic-gate int err = 0;
14250Sstevel@tonic-gate __nis_search_triple_t *new = am(myself, sizeof (*new));
14260Sstevel@tonic-gate
14270Sstevel@tonic-gate if (new != 0) {
14280Sstevel@tonic-gate copySearchTriple(old, new, &err);
14290Sstevel@tonic-gate if (err != 0) {
14300Sstevel@tonic-gate freeSearchTriple(new, 1);
14310Sstevel@tonic-gate new = 0;
14320Sstevel@tonic-gate }
14330Sstevel@tonic-gate }
14340Sstevel@tonic-gate
14350Sstevel@tonic-gate return (new);
14360Sstevel@tonic-gate }
14370Sstevel@tonic-gate
14380Sstevel@tonic-gate void
freeSearchTriple(__nis_search_triple_t * old,bool_t doFree)14390Sstevel@tonic-gate freeSearchTriple(__nis_search_triple_t *old, bool_t doFree) {
14400Sstevel@tonic-gate
14410Sstevel@tonic-gate if (old == 0)
14420Sstevel@tonic-gate return;
14430Sstevel@tonic-gate
14440Sstevel@tonic-gate sfree(old->base);
14450Sstevel@tonic-gate sfree(old->attrs);
14460Sstevel@tonic-gate /*
14470Sstevel@tonic-gate * Since we only copied the element pointer when this structure
14480Sstevel@tonic-gate * was created, we don't free old->element.
14490Sstevel@tonic-gate */
14500Sstevel@tonic-gate if (doFree)
14510Sstevel@tonic-gate free(old);
14520Sstevel@tonic-gate }
14530Sstevel@tonic-gate
14540Sstevel@tonic-gate void
copyTripleOrObj(__nis_mapping_item_type_t type,__nis_triple_or_obj_t * old,__nis_triple_or_obj_t * new,int * err)14550Sstevel@tonic-gate copyTripleOrObj(__nis_mapping_item_type_t type,
14560Sstevel@tonic-gate __nis_triple_or_obj_t *old, __nis_triple_or_obj_t *new,
14570Sstevel@tonic-gate int *err) {
14580Sstevel@tonic-gate
14590Sstevel@tonic-gate *err = 0;
14600Sstevel@tonic-gate
14610Sstevel@tonic-gate if (old == 0 || new == 0) {
14620Sstevel@tonic-gate *err = EINVAL;
14630Sstevel@tonic-gate return;
14640Sstevel@tonic-gate }
14650Sstevel@tonic-gate
14660Sstevel@tonic-gate if (type == mit_nisplus) {
14670Sstevel@tonic-gate copyObjSpec(&old->obj, &new->obj, err);
14680Sstevel@tonic-gate } else if (type == mit_ldap) {
14690Sstevel@tonic-gate copySearchTriple(&old->triple, &new->triple, err);
14700Sstevel@tonic-gate }
14710Sstevel@tonic-gate }
14720Sstevel@tonic-gate
14730Sstevel@tonic-gate __nis_triple_or_obj_t *
cloneTripleOrObj(__nis_mapping_item_type_t type,__nis_triple_or_obj_t * old)14740Sstevel@tonic-gate cloneTripleOrObj(__nis_mapping_item_type_t type, __nis_triple_or_obj_t *old) {
14750Sstevel@tonic-gate char *myself = "cloneTripleOrObj";
14760Sstevel@tonic-gate int err = 0;
14770Sstevel@tonic-gate __nis_triple_or_obj_t *new = am(myself, sizeof (*new));
14780Sstevel@tonic-gate
14790Sstevel@tonic-gate if (new != 0) {
14800Sstevel@tonic-gate copyTripleOrObj(type, old, new, &err);
14810Sstevel@tonic-gate if (err != 0) {
14820Sstevel@tonic-gate freeTripleOrObj(type, new, 1);
14830Sstevel@tonic-gate new = 0;
14840Sstevel@tonic-gate }
14850Sstevel@tonic-gate }
14860Sstevel@tonic-gate
14870Sstevel@tonic-gate return (new);
14880Sstevel@tonic-gate }
14890Sstevel@tonic-gate
14900Sstevel@tonic-gate void
freeTripleOrObj(__nis_mapping_item_type_t type,__nis_triple_or_obj_t * old,bool_t doFree)14910Sstevel@tonic-gate freeTripleOrObj(__nis_mapping_item_type_t type, __nis_triple_or_obj_t *old,
14920Sstevel@tonic-gate bool_t doFree) {
14930Sstevel@tonic-gate
14940Sstevel@tonic-gate if (old == 0)
14950Sstevel@tonic-gate return;
14960Sstevel@tonic-gate
14970Sstevel@tonic-gate if (type == mit_nisplus)
14980Sstevel@tonic-gate freeObjSpec(&old->obj, doFree);
14990Sstevel@tonic-gate else if (type == mit_ldap)
15000Sstevel@tonic-gate freeSearchTriple(&old->triple, doFree);
15010Sstevel@tonic-gate
15020Sstevel@tonic-gate if (doFree)
15030Sstevel@tonic-gate free(old);
15040Sstevel@tonic-gate }
15050Sstevel@tonic-gate
15060Sstevel@tonic-gate void
copyItem(__nis_mapping_item_t * old,__nis_mapping_item_t * new,int * err)15070Sstevel@tonic-gate copyItem(__nis_mapping_item_t *old, __nis_mapping_item_t *new, int *err) {
15080Sstevel@tonic-gate
15090Sstevel@tonic-gate *err = 0;
15100Sstevel@tonic-gate
15110Sstevel@tonic-gate if (old == 0 || new == 0) {
15120Sstevel@tonic-gate *err = EINVAL;
15130Sstevel@tonic-gate return;
15140Sstevel@tonic-gate }
15150Sstevel@tonic-gate
15160Sstevel@tonic-gate new->type = old->type;
15170Sstevel@tonic-gate new->repeat = old->repeat;
15180Sstevel@tonic-gate if (old->name != 0) {
15190Sstevel@tonic-gate new->name = strdup(old->name);
15200Sstevel@tonic-gate if (new->name == 0) {
15210Sstevel@tonic-gate *err = ENOMEM;
15220Sstevel@tonic-gate return;
15230Sstevel@tonic-gate }
15240Sstevel@tonic-gate } else {
15250Sstevel@tonic-gate new->name = 0;
15260Sstevel@tonic-gate }
15270Sstevel@tonic-gate if (old->type == mit_nisplus || old->type == mit_ldap)
15280Sstevel@tonic-gate copyTripleOrObj(old->type, &old->searchSpec, &new->searchSpec,
15290Sstevel@tonic-gate err);
15300Sstevel@tonic-gate else
15310Sstevel@tonic-gate memset(&new->searchSpec, 0, sizeof (new->searchSpec));
15320Sstevel@tonic-gate }
15330Sstevel@tonic-gate
15340Sstevel@tonic-gate __nis_mapping_item_t *
cloneItem(__nis_mapping_item_t * old)15350Sstevel@tonic-gate cloneItem(__nis_mapping_item_t *old) {
15360Sstevel@tonic-gate __nis_mapping_item_t *new;
15370Sstevel@tonic-gate int err = 0;
15380Sstevel@tonic-gate char *myself = "cloneItem";
15390Sstevel@tonic-gate
15400Sstevel@tonic-gate if (old == 0)
15410Sstevel@tonic-gate return (0);
15420Sstevel@tonic-gate
15430Sstevel@tonic-gate new = am(myself, sizeof (*new));
15440Sstevel@tonic-gate if (new == 0)
15450Sstevel@tonic-gate return (0);
15460Sstevel@tonic-gate
15470Sstevel@tonic-gate copyItem(old, new, &err);
15480Sstevel@tonic-gate if (err != 0) {
15490Sstevel@tonic-gate freeMappingItem(new, 1);
15500Sstevel@tonic-gate return (0);
15510Sstevel@tonic-gate }
15520Sstevel@tonic-gate
15530Sstevel@tonic-gate return (new);
15540Sstevel@tonic-gate }
15550Sstevel@tonic-gate
15560Sstevel@tonic-gate void
freeMappingItem(__nis_mapping_item_t * item,int numItems)15570Sstevel@tonic-gate freeMappingItem(__nis_mapping_item_t *item, int numItems) {
15580Sstevel@tonic-gate int i;
15590Sstevel@tonic-gate
15600Sstevel@tonic-gate if (item == 0)
15610Sstevel@tonic-gate return;
15620Sstevel@tonic-gate
15630Sstevel@tonic-gate for (i = 0; i < numItems; i++) {
15640Sstevel@tonic-gate sfree(item[i].name);
15650Sstevel@tonic-gate freeTripleOrObj(item[i].type, &item[i].searchSpec, FALSE);
15660Sstevel@tonic-gate }
15670Sstevel@tonic-gate sfree(item);
15680Sstevel@tonic-gate }
15690Sstevel@tonic-gate
15700Sstevel@tonic-gate __nis_mapping_item_t *
concatenateMappingItem(__nis_mapping_item_t * old,int numItems,__nis_mapping_item_t * cat)15710Sstevel@tonic-gate concatenateMappingItem(__nis_mapping_item_t *old, int numItems,
15720Sstevel@tonic-gate __nis_mapping_item_t *cat) {
15730Sstevel@tonic-gate __nis_mapping_item_t *new;
15740Sstevel@tonic-gate int i, err = 0;
15750Sstevel@tonic-gate char *myself = "concatenateMappingItem";
15760Sstevel@tonic-gate
15770Sstevel@tonic-gate if (old == 0 || numItems < 1)
15780Sstevel@tonic-gate return (cloneItem(cat));
15790Sstevel@tonic-gate
15800Sstevel@tonic-gate new = am(myself, (numItems + 1) * sizeof (*new));
15810Sstevel@tonic-gate if (new == 0)
15820Sstevel@tonic-gate return (0);
15830Sstevel@tonic-gate
15840Sstevel@tonic-gate for (i = 0; i < numItems; i++) {
15850Sstevel@tonic-gate copyItem(&old[i], &new[i], &err);
15860Sstevel@tonic-gate if (err != 0) {
15870Sstevel@tonic-gate freeMappingItem(new, i);
15880Sstevel@tonic-gate return (0);
15890Sstevel@tonic-gate }
15900Sstevel@tonic-gate }
15910Sstevel@tonic-gate copyItem(cat, &new[numItems], &err);
15920Sstevel@tonic-gate if (err != 0) {
15930Sstevel@tonic-gate freeMappingItem(new, numItems);
15940Sstevel@tonic-gate new = 0;
15950Sstevel@tonic-gate }
15960Sstevel@tonic-gate
15970Sstevel@tonic-gate return (new);
15980Sstevel@tonic-gate }
15990Sstevel@tonic-gate
16000Sstevel@tonic-gate __nis_value_t *
concatenateValues(__nis_value_t * v1,__nis_value_t * v2)16010Sstevel@tonic-gate concatenateValues(__nis_value_t *v1, __nis_value_t *v2) {
16020Sstevel@tonic-gate int i, n, a;
16030Sstevel@tonic-gate __nis_value_t *v;
16040Sstevel@tonic-gate char *myself = "concatenateValues";
16050Sstevel@tonic-gate
16060Sstevel@tonic-gate if (v1 == 0 || v1->numVals <= 0)
16070Sstevel@tonic-gate return (cloneValue(v2, 1));
16080Sstevel@tonic-gate if (v2 == 0 || v2->numVals <= 0)
16090Sstevel@tonic-gate return (cloneValue(v1, 1));
16100Sstevel@tonic-gate
16110Sstevel@tonic-gate if (v1->type != v2->type)
16120Sstevel@tonic-gate return (0);
16130Sstevel@tonic-gate
16140Sstevel@tonic-gate n = v1->numVals + v2->numVals;
16150Sstevel@tonic-gate v = am(myself, sizeof (*v));
16160Sstevel@tonic-gate if (v == 0)
16170Sstevel@tonic-gate return (0);
16180Sstevel@tonic-gate v->val = am(myself, n * sizeof (v->val[0]));
16190Sstevel@tonic-gate if (v->val == 0) {
16200Sstevel@tonic-gate free(v);
16210Sstevel@tonic-gate return (0);
16220Sstevel@tonic-gate }
16230Sstevel@tonic-gate v->type = v1->type;
16240Sstevel@tonic-gate v->numVals = 0;
16250Sstevel@tonic-gate
16260Sstevel@tonic-gate for (a = 0; a < 2; a++) {
16270Sstevel@tonic-gate __nis_single_value_t *val = (a == 0) ? v1->val : v2->val;
16280Sstevel@tonic-gate int numv = (a == 0) ? v1->numVals :
16290Sstevel@tonic-gate v2->numVals;
16300Sstevel@tonic-gate for (i = 0; i < numv; i++) {
16310Sstevel@tonic-gate int clen, alen = val[i].length;
16320Sstevel@tonic-gate
16330Sstevel@tonic-gate clen = alen;
16340Sstevel@tonic-gate
16350Sstevel@tonic-gate /*
16360Sstevel@tonic-gate * Make sure there's a NUL at the end of a string,
16370Sstevel@tonic-gate * but avoid adding to the allocated length if there's
16380Sstevel@tonic-gate * already a NUL at the end.
16390Sstevel@tonic-gate */
16400Sstevel@tonic-gate if (alen > 0 && v->type == vt_string &&
16410Sstevel@tonic-gate ((char *)val[i].value)[alen-1] != '\0')
16420Sstevel@tonic-gate alen += 1;
16430Sstevel@tonic-gate v->val[v->numVals].value = am(myself, alen);
16440Sstevel@tonic-gate if (v->val[v->numVals].value == 0) {
16450Sstevel@tonic-gate freeValue(v, 1);
16460Sstevel@tonic-gate return (0);
16470Sstevel@tonic-gate }
16480Sstevel@tonic-gate memcpy(v->val[v->numVals].value, val[i].value, clen);
16490Sstevel@tonic-gate v->val[v->numVals].length = val[i].length;
16500Sstevel@tonic-gate v->numVals++;
16510Sstevel@tonic-gate }
16520Sstevel@tonic-gate }
16530Sstevel@tonic-gate
16540Sstevel@tonic-gate return (v);
16550Sstevel@tonic-gate }
16560Sstevel@tonic-gate
16570Sstevel@tonic-gate __nis_value_t *
splitMappingItem(__nis_mapping_item_t * item,char delim,__nis_rule_value_t * rv)16580Sstevel@tonic-gate splitMappingItem(__nis_mapping_item_t *item, char delim,
16590Sstevel@tonic-gate __nis_rule_value_t *rv) {
16600Sstevel@tonic-gate __nis_value_t *val = getMappingItem(item, mit_any,
16610Sstevel@tonic-gate rv, 0, NULL);
16620Sstevel@tonic-gate __nis_single_value_t *nval;
16630Sstevel@tonic-gate int i, n, nv;
16640Sstevel@tonic-gate
16650Sstevel@tonic-gate if (val == 0)
16660Sstevel@tonic-gate return (0);
16670Sstevel@tonic-gate else if (delim == 0 || val->val == 0 || val->numVals <= 0 ||
16680Sstevel@tonic-gate val->type != vt_string) {
16690Sstevel@tonic-gate freeValue(val, 1);
16700Sstevel@tonic-gate return (0);
16710Sstevel@tonic-gate }
16720Sstevel@tonic-gate
16730Sstevel@tonic-gate nval = val->val;
16740Sstevel@tonic-gate nv = val->numVals;
16750Sstevel@tonic-gate val->repeat = FALSE;
16760Sstevel@tonic-gate val->val = 0;
16770Sstevel@tonic-gate val->numVals = 0;
16780Sstevel@tonic-gate
16790Sstevel@tonic-gate /* In N2L, space and tab delimiters are treated the same */
16800Sstevel@tonic-gate if (yp2ldap && delim == '\t')
16810Sstevel@tonic-gate delim = ' ';
16820Sstevel@tonic-gate
16830Sstevel@tonic-gate /* If the item has multiple values, we split each one independently */
16840Sstevel@tonic-gate for (i = 0; i < nv; i++) {
16850Sstevel@tonic-gate char *str;
16860Sstevel@tonic-gate int s, e;
16870Sstevel@tonic-gate char *newstr;
16880Sstevel@tonic-gate __nis_single_value_t *newval;
16890Sstevel@tonic-gate
16900Sstevel@tonic-gate if (yp2ldap && delim == ' ')
16910Sstevel@tonic-gate nval[i].value = trimWhiteSpaces(nval[i].value,
16920Sstevel@tonic-gate &nval[i].length, 1);
16930Sstevel@tonic-gate
16940Sstevel@tonic-gate str = nval[i].value;
16950Sstevel@tonic-gate
16960Sstevel@tonic-gate if (nval[i].value == 0)
16970Sstevel@tonic-gate continue;
16980Sstevel@tonic-gate
16990Sstevel@tonic-gate for (s = 0; s < nval[i].length; s = e+1) {
17000Sstevel@tonic-gate /* Find the next delimiter, or end-of-string */
17010Sstevel@tonic-gate for (e = s; str[e] != '\0' && str[e] != delim; e++);
17020Sstevel@tonic-gate /*
17030Sstevel@tonic-gate * 'str[e]' is either a delimiter, or the concluding
17040Sstevel@tonic-gate * NUL. Make sure it's NUL.
17050Sstevel@tonic-gate */
17060Sstevel@tonic-gate str[e] = '\0';
17070Sstevel@tonic-gate /* Add to val->val */
17080Sstevel@tonic-gate newstr = strdup(&str[s]);
17090Sstevel@tonic-gate newval = realloc(val->val,
17100Sstevel@tonic-gate (val->numVals+1) *
17110Sstevel@tonic-gate sizeof (val->val[0]));
17120Sstevel@tonic-gate if (newval != 0)
17130Sstevel@tonic-gate val->val = newval;
17140Sstevel@tonic-gate if (newstr == 0 || newval == 0) {
17150Sstevel@tonic-gate freeValue(val, 1);
17160Sstevel@tonic-gate for (n = i; n < nv; n++) {
17170Sstevel@tonic-gate sfree(nval[n].value);
17180Sstevel@tonic-gate }
17190Sstevel@tonic-gate free(nval);
17200Sstevel@tonic-gate sfree(newstr);
17210Sstevel@tonic-gate return (0);
17220Sstevel@tonic-gate }
17230Sstevel@tonic-gate val->val[val->numVals].value = newstr;
17240Sstevel@tonic-gate val->val[val->numVals].length = strlen(newstr) + 1;
17250Sstevel@tonic-gate val->numVals++;
17260Sstevel@tonic-gate }
17270Sstevel@tonic-gate free(nval[i].value);
17280Sstevel@tonic-gate nval[i].value = 0;
17290Sstevel@tonic-gate }
17300Sstevel@tonic-gate /* Already freed the nval[i].value's as we traversed nval */
17310Sstevel@tonic-gate free(nval);
17320Sstevel@tonic-gate
17330Sstevel@tonic-gate return (val);
17340Sstevel@tonic-gate }
17350Sstevel@tonic-gate
17360Sstevel@tonic-gate /*
17370Sstevel@tonic-gate * Match the format spec 'f[curf]' to the input value string 'str'.
17380Sstevel@tonic-gate *
17390Sstevel@tonic-gate * If successful, returns the updated position in the value string 'str'.
17400Sstevel@tonic-gate * Otherwise, NULL is returned.
17410Sstevel@tonic-gate *
17420Sstevel@tonic-gate * curf Current index (i.e., the one we should look at) in 'f'
17430Sstevel@tonic-gate * nf Number of elements in 'f', including 'mmt_end'
17440Sstevel@tonic-gate * str The value string we're scanning
17450Sstevel@tonic-gate * val Pointer to where an item value (if any) should be returned
17460Sstevel@tonic-gate * Set to NULL if not an 'mmt_item'.
17470Sstevel@tonic-gate * fmtstart If non-zero on entry, skip characters in 'str' until we find
17480Sstevel@tonic-gate * the f[curf].type data, if doing so makes any sense. On exit,
17490Sstevel@tonic-gate * set to the start of the fmt element data (which will be 'str',
17500Sstevel@tonic-gate * unless we did skip characters)
17510Sstevel@tonic-gate * sepset List of separators
17520Sstevel@tonic-gate */
17530Sstevel@tonic-gate char *
scanMappingFormat(__nis_mapping_format_t * f,int curf,int nf,char * str,char ** val,char ** fmtstart,char * sepset)17540Sstevel@tonic-gate scanMappingFormat(__nis_mapping_format_t *f, int curf, int nf, char *str,
17550Sstevel@tonic-gate char **val, char **fmtstart, char *sepset) {
17560Sstevel@tonic-gate char *mstr, *next, *start = 0, *tmpstr;
17570Sstevel@tonic-gate int i, len;
17580Sstevel@tonic-gate bool_t match;
17590Sstevel@tonic-gate char *myself = "scanMappingFormat";
17600Sstevel@tonic-gate /* N2L variables */
17610Sstevel@tonic-gate int af, skipspaces = 0;
17620Sstevel@tonic-gate bool_t ipaddr = FALSE;
17630Sstevel@tonic-gate char *spacestr = " ", *emptystr = "";
17640Sstevel@tonic-gate
17650Sstevel@tonic-gate
17660Sstevel@tonic-gate if (f == 0 || curf < 0 || nf <= 0 || str == 0)
17670Sstevel@tonic-gate return (0);
17680Sstevel@tonic-gate
17690Sstevel@tonic-gate /*
17700Sstevel@tonic-gate * If separator list is NULL (which will be the case for
17710Sstevel@tonic-gate * nis+2ldap), then simply use empty string
17720Sstevel@tonic-gate */
17730Sstevel@tonic-gate if (sepset == 0)
17740Sstevel@tonic-gate sepset = emptystr;
17750Sstevel@tonic-gate
17760Sstevel@tonic-gate if (curf >= nf) {
17770Sstevel@tonic-gate /* OK if the string also is exhausted */
17780Sstevel@tonic-gate if (strchr(sepset, *str) != 0)
17790Sstevel@tonic-gate return (str);
17800Sstevel@tonic-gate else
17810Sstevel@tonic-gate return (0);
17820Sstevel@tonic-gate }
17830Sstevel@tonic-gate
17840Sstevel@tonic-gate switch (f[curf].type) {
17850Sstevel@tonic-gate case mmt_berstring:
17860Sstevel@tonic-gate if (f[curf].match.berString[0] != 'a') {
17870Sstevel@tonic-gate /* Not a matchable element */
17880Sstevel@tonic-gate return (0);
17890Sstevel@tonic-gate }
17900Sstevel@tonic-gate
17910Sstevel@tonic-gate /*
17920Sstevel@tonic-gate * If here, it means it's an IP address (N2L case)
17930Sstevel@tonic-gate * So continue processing as if it was mmt_item
17940Sstevel@tonic-gate */
17950Sstevel@tonic-gate ipaddr = TRUE;
17960Sstevel@tonic-gate
17970Sstevel@tonic-gate case mmt_item:
17980Sstevel@tonic-gate /*
17990Sstevel@tonic-gate * In order to find the end of the item value, we must look
18000Sstevel@tonic-gate * ahead and determine the start of the next formatting element.
18010Sstevel@tonic-gate * If successful, 'next' will be the start of the fmt element
18020Sstevel@tonic-gate * after the next one; we don't care about that, other than to
18030Sstevel@tonic-gate * check for error.
18040Sstevel@tonic-gate *
18050Sstevel@tonic-gate * Since an item match is somewhat like an any match, in that
18060Sstevel@tonic-gate * we don't know a priori if the first occurence of the next
18070Sstevel@tonic-gate * element really is the one we want, we have to scan ahead
18080Sstevel@tonic-gate * until we've reached the end.
18090Sstevel@tonic-gate */
18100Sstevel@tonic-gate tmpstr = str;
18110Sstevel@tonic-gate while ((next = scanMappingFormat(f, curf+1, nf, tmpstr, 0,
18120Sstevel@tonic-gate &start, sepset)) != 0) {
18130Sstevel@tonic-gate char *tmp = next;
18140Sstevel@tonic-gate int cf;
18150Sstevel@tonic-gate
18160Sstevel@tonic-gate for (cf = curf+2; cf < nf; cf++) {
18170Sstevel@tonic-gate tmp = scanMappingFormat(f, cf, nf, tmp, 0,
18180Sstevel@tonic-gate 0, sepset);
18190Sstevel@tonic-gate if (tmp == 0)
18200Sstevel@tonic-gate break;
18210Sstevel@tonic-gate }
18220Sstevel@tonic-gate if (tmp == 0) {
18230Sstevel@tonic-gate tmpstr = next;
18240Sstevel@tonic-gate } else if (strchr(sepset, *tmp) != 0) {
18250Sstevel@tonic-gate break;
18260Sstevel@tonic-gate } else {
18270Sstevel@tonic-gate return (0);
18280Sstevel@tonic-gate }
18290Sstevel@tonic-gate
18300Sstevel@tonic-gate }
18310Sstevel@tonic-gate if (next == 0 || start == 0)
18320Sstevel@tonic-gate return (0);
18330Sstevel@tonic-gate
18340Sstevel@tonic-gate if (val != 0) {
18350Sstevel@tonic-gate len = (int)((long)start - (long)str);
18360Sstevel@tonic-gate *val = am(myself, len + 1);
18370Sstevel@tonic-gate if (*val == 0)
18380Sstevel@tonic-gate return (0);
18390Sstevel@tonic-gate memcpy(*val, str, len);
18400Sstevel@tonic-gate (*val)[len] = '\0';
18410Sstevel@tonic-gate
18420Sstevel@tonic-gate if (ipaddr == TRUE) {
18430Sstevel@tonic-gate /*
18440Sstevel@tonic-gate * In N2L, we need to check if *val is truly an
18450Sstevel@tonic-gate * IP address
18460Sstevel@tonic-gate */
18470Sstevel@tonic-gate af = checkIPaddress(*val, len, &tmpstr);
18480Sstevel@tonic-gate
18490Sstevel@tonic-gate if (af == -2) {
18500Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING,
18510Sstevel@tonic-gate "%s:Internal error while "
18520Sstevel@tonic-gate "processing IPaddress %s",
18530Sstevel@tonic-gate myself, *val);
18540Sstevel@tonic-gate sfree(*val);
18550Sstevel@tonic-gate return (0);
18560Sstevel@tonic-gate } else if (af == -1) {
18570Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING,
18580Sstevel@tonic-gate "%s:%s is not an IP address",
18590Sstevel@tonic-gate myself, *val);
18600Sstevel@tonic-gate sfree(*val);
18610Sstevel@tonic-gate return (0);
18620Sstevel@tonic-gate } else if (af == 0) {
18630Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING,
18640Sstevel@tonic-gate "%s:IP address %s is not "
18650Sstevel@tonic-gate "supported by rfc2307bis",
18660Sstevel@tonic-gate myself, *val);
18670Sstevel@tonic-gate sfree(*val);
18680Sstevel@tonic-gate return (0);
18690Sstevel@tonic-gate } else if (sstrncmp(*val, tmpstr, len) != 0) {
18700Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING,
18710Sstevel@tonic-gate "%s:IPaddress %s converted "
18720Sstevel@tonic-gate "to %s", myself, *val, tmpstr);
18730Sstevel@tonic-gate }
18740Sstevel@tonic-gate
18750Sstevel@tonic-gate sfree(*val);
18760Sstevel@tonic-gate *val = tmpstr;
18770Sstevel@tonic-gate }
18780Sstevel@tonic-gate }
18790Sstevel@tonic-gate
18800Sstevel@tonic-gate if (fmtstart != 0)
18810Sstevel@tonic-gate *fmtstart = str;
18820Sstevel@tonic-gate
18830Sstevel@tonic-gate return (start);
18840Sstevel@tonic-gate
18850Sstevel@tonic-gate case mmt_string:
18860Sstevel@tonic-gate if ((mstr = f[curf].match.string) == 0 || *mstr == '\0') {
18870Sstevel@tonic-gate /*
18880Sstevel@tonic-gate * Count this as a successful match of an empty
18890Sstevel@tonic-gate * string.
18900Sstevel@tonic-gate */
18910Sstevel@tonic-gate if (fmtstart != 0)
18920Sstevel@tonic-gate *fmtstart = str;
18930Sstevel@tonic-gate return (str);
18940Sstevel@tonic-gate }
18950Sstevel@tonic-gate
18960Sstevel@tonic-gate /*
18970Sstevel@tonic-gate * In N2L, if the format string 'mstr' contains only
18980Sstevel@tonic-gate * whitespaces (spaces and tabs), then it should
18990Sstevel@tonic-gate * match one or more whitespaces from the input
19000Sstevel@tonic-gate * string 'str'.
19010Sstevel@tonic-gate */
19020Sstevel@tonic-gate if (yp2ldap && strspn(mstr, " \t") == strlen(mstr)) {
19030Sstevel@tonic-gate mstr = spacestr;
19040Sstevel@tonic-gate skipspaces = 1;
19050Sstevel@tonic-gate next = str + strcspn(str, " \t");
19060Sstevel@tonic-gate /*
19070Sstevel@tonic-gate * Even if there is no whitespace in 'str',
19080Sstevel@tonic-gate * it's OK. This is to allow formats like
19090Sstevel@tonic-gate * "%s %s %s" to match inputs like "foo bar".
19100Sstevel@tonic-gate */
19110Sstevel@tonic-gate if (*next == '\0')
19120Sstevel@tonic-gate mstr = emptystr;
19130Sstevel@tonic-gate } else {
19140Sstevel@tonic-gate /* No match string in 'str' => failure */
19150Sstevel@tonic-gate if ((next = strstr(str, mstr)) == 0)
19160Sstevel@tonic-gate return (0);
19170Sstevel@tonic-gate }
19180Sstevel@tonic-gate
19190Sstevel@tonic-gate /* If 'fmtstart' == 0, we require 'next' == 'str' */
19200Sstevel@tonic-gate if (fmtstart == 0 && next != str)
19210Sstevel@tonic-gate return (0);
19220Sstevel@tonic-gate /* Success; save start of match string if requested */
19230Sstevel@tonic-gate if (fmtstart != 0)
19240Sstevel@tonic-gate *fmtstart = next;
19250Sstevel@tonic-gate /* Update position in the value string */
19260Sstevel@tonic-gate str = (char *)((long)next + (long)strlen(mstr));
19270Sstevel@tonic-gate
19280Sstevel@tonic-gate /* Skip whitespaces for N2L */
19290Sstevel@tonic-gate if (skipspaces == 1)
19300Sstevel@tonic-gate for (; *str == ' ' || *str == '\t'; str++);
19310Sstevel@tonic-gate
19320Sstevel@tonic-gate return (str);
19330Sstevel@tonic-gate
19340Sstevel@tonic-gate case mmt_single:
19350Sstevel@tonic-gate if (fmtstart != 0) {
19360Sstevel@tonic-gate match = FALSE;
19370Sstevel@tonic-gate /* Skip ahead until we match */
19380Sstevel@tonic-gate for (next = str; *next != '\0'; next++) {
19390Sstevel@tonic-gate unsigned char *lo = f[curf].match.single.lo;
19400Sstevel@tonic-gate unsigned char *hi = f[curf].match.single.hi;
19410Sstevel@tonic-gate
19420Sstevel@tonic-gate for (i = 0; i < f[curf].match.single.numRange;
19430Sstevel@tonic-gate i++) {
19440Sstevel@tonic-gate if (*next >= lo[i] && *next <= hi[i]) {
19450Sstevel@tonic-gate match = TRUE;
19460Sstevel@tonic-gate break;
19470Sstevel@tonic-gate }
19480Sstevel@tonic-gate }
19490Sstevel@tonic-gate if (match)
19500Sstevel@tonic-gate break;
19510Sstevel@tonic-gate }
19520Sstevel@tonic-gate if (!match)
19530Sstevel@tonic-gate return (0);
19540Sstevel@tonic-gate *fmtstart = next;
19550Sstevel@tonic-gate str = next;
19560Sstevel@tonic-gate } else {
19570Sstevel@tonic-gate match = FALSE;
19580Sstevel@tonic-gate for (i = 0; i < f[curf].match.single.numRange; i++) {
19590Sstevel@tonic-gate if (*str >= f[curf].match.single.lo[i] &&
19600Sstevel@tonic-gate *str <= f[curf].match.single.hi[i]) {
19610Sstevel@tonic-gate match = TRUE;
19620Sstevel@tonic-gate break;
19630Sstevel@tonic-gate }
19640Sstevel@tonic-gate }
19650Sstevel@tonic-gate if (!match)
19660Sstevel@tonic-gate return (0);
19670Sstevel@tonic-gate }
19680Sstevel@tonic-gate /* Step over the matched character */
19690Sstevel@tonic-gate str++;
19700Sstevel@tonic-gate return (str);
19710Sstevel@tonic-gate
19720Sstevel@tonic-gate case mmt_any:
19730Sstevel@tonic-gate /*
19740Sstevel@tonic-gate * Look ahead to find the beginning of the next element.
19750Sstevel@tonic-gate * Because a wildcard-match isn't necessarily uniquely
19760Sstevel@tonic-gate * determined until we've reached the end, we then continue
19770Sstevel@tonic-gate * to scan ahead.
19780Sstevel@tonic-gate */
19790Sstevel@tonic-gate while ((next = scanMappingFormat(f, curf+1, nf, str, 0,
19800Sstevel@tonic-gate &start, sepset)) != 0) {
19810Sstevel@tonic-gate char *tmp = next;
19820Sstevel@tonic-gate int cf;
19830Sstevel@tonic-gate
19840Sstevel@tonic-gate for (cf = curf+2; cf < nf; cf++) {
19850Sstevel@tonic-gate tmp = scanMappingFormat(f, cf, nf, tmp, 0,
19860Sstevel@tonic-gate 0, sepset);
19870Sstevel@tonic-gate if (tmp == 0)
19880Sstevel@tonic-gate break;
19890Sstevel@tonic-gate }
19900Sstevel@tonic-gate if (tmp == 0) {
19910Sstevel@tonic-gate str = next;
19920Sstevel@tonic-gate } else if (*tmp == '\0') {
19930Sstevel@tonic-gate break;
19940Sstevel@tonic-gate } else {
19950Sstevel@tonic-gate return (0);
19960Sstevel@tonic-gate }
19970Sstevel@tonic-gate }
19980Sstevel@tonic-gate if (next == 0 || start == 0)
19990Sstevel@tonic-gate return (0);
20000Sstevel@tonic-gate
20010Sstevel@tonic-gate if (fmtstart != 0)
20020Sstevel@tonic-gate *fmtstart = str;
20030Sstevel@tonic-gate
20040Sstevel@tonic-gate return (start);
20050Sstevel@tonic-gate
20060Sstevel@tonic-gate case mmt_limit:
20070Sstevel@tonic-gate if (f[curf].match.limit == eos) {
20080Sstevel@tonic-gate if (fmtstart != 0) {
20090Sstevel@tonic-gate /* Skip to the end */
20100Sstevel@tonic-gate str = str + strcspn(str, sepset);
20110Sstevel@tonic-gate *fmtstart = str;
20120Sstevel@tonic-gate } else if (strchr(sepset, *str) == 0) {
20130Sstevel@tonic-gate return (0);
20140Sstevel@tonic-gate }
20150Sstevel@tonic-gate }
20160Sstevel@tonic-gate return (str);
20170Sstevel@tonic-gate
20180Sstevel@tonic-gate case mmt_begin:
20190Sstevel@tonic-gate if (fmtstart != 0)
20200Sstevel@tonic-gate *fmtstart = str;
20210Sstevel@tonic-gate return (str);
20220Sstevel@tonic-gate
20230Sstevel@tonic-gate case mmt_end:
20240Sstevel@tonic-gate if (fmtstart != 0) {
20250Sstevel@tonic-gate /* Skip to the end */
20260Sstevel@tonic-gate str = str + strcspn(str, sepset);
20270Sstevel@tonic-gate *fmtstart = str;
20280Sstevel@tonic-gate return (str);
20290Sstevel@tonic-gate }
20300Sstevel@tonic-gate /* No skipping, so we must be at the end of the value */
20310Sstevel@tonic-gate if (strchr(sepset, *str) == 0)
20320Sstevel@tonic-gate return (0);
20330Sstevel@tonic-gate return (str);
20340Sstevel@tonic-gate
20350Sstevel@tonic-gate default:
20360Sstevel@tonic-gate break;
20370Sstevel@tonic-gate }
20380Sstevel@tonic-gate
20390Sstevel@tonic-gate return (0);
20400Sstevel@tonic-gate }
20410Sstevel@tonic-gate
20420Sstevel@tonic-gate /*
20430Sstevel@tonic-gate * Verify that the string 'str' matches the mapping format array 'f'.
20440Sstevel@tonic-gate * Returns 1 in case of a match, 0 otherwise.
20450Sstevel@tonic-gate */
20460Sstevel@tonic-gate int
verifyMappingMatch(__nis_mapping_format_t * f,char * str)20470Sstevel@tonic-gate verifyMappingMatch(__nis_mapping_format_t *f, char *str) {
20480Sstevel@tonic-gate int n, nf;
20490Sstevel@tonic-gate __nis_mapping_format_t *ftmp;
20500Sstevel@tonic-gate
20510Sstevel@tonic-gate /* Count the number of format elements in the format */
20520Sstevel@tonic-gate for (nf = 0, ftmp = f; ftmp->type != mmt_end; ftmp++) {
20530Sstevel@tonic-gate nf++;
20540Sstevel@tonic-gate }
20550Sstevel@tonic-gate /* Count the mmt_end as well */
20560Sstevel@tonic-gate nf++;
20570Sstevel@tonic-gate
20580Sstevel@tonic-gate for (n = 0; n < nf; n++) {
20590Sstevel@tonic-gate str = scanMappingFormat(f, n, nf, str, 0, 0, 0);
20600Sstevel@tonic-gate if (str == 0)
20610Sstevel@tonic-gate break;
20620Sstevel@tonic-gate }
20630Sstevel@tonic-gate
20640Sstevel@tonic-gate return ((str != 0) ? 1 : 0);
20650Sstevel@tonic-gate }
20660Sstevel@tonic-gate
20670Sstevel@tonic-gate /*
20680Sstevel@tonic-gate * Perform a match operation. For example, given the rule
20690Sstevel@tonic-gate * ("{%s}%s", auth_name, public_data)=nisPublicKey
20700Sstevel@tonic-gate * and assuming that 'nisPublicKey' has the value "{dh640-0}abcdef12345",
20710Sstevel@tonic-gate * assign "dh640-0" to 'auth_name' and "abcdef12345" to 'public_data'.
20720Sstevel@tonic-gate *
20730Sstevel@tonic-gate * Note that this function doesn't perform the actual assignment. Rather,
20740Sstevel@tonic-gate * it returns an array of __nis_value_t's, with element zero of the value
20750Sstevel@tonic-gate * array being the new value of the first matched item, element one the
20760Sstevel@tonic-gate * value of the second matched item, etc. In the example above, we'd
20770Sstevel@tonic-gate * return a value array with two elements.
20780Sstevel@tonic-gate *
20790Sstevel@tonic-gate * If there is more than one input value (inVal->numVals > 1), the
20800Sstevel@tonic-gate * output array elements will also be multi-valued.
20810Sstevel@tonic-gate *
20820Sstevel@tonic-gate * f The match format
20830Sstevel@tonic-gate * inVal Input value(s)
20840Sstevel@tonic-gate * numVal Number of elements in the output value array
20850Sstevel@tonic-gate * sepset List of separators
20860Sstevel@tonic-gate * outstr Points to the updated position upto which the
20870Sstevel@tonic-gate * input string has been matched
20880Sstevel@tonic-gate */
20890Sstevel@tonic-gate __nis_value_t **
matchMappingItem(__nis_mapping_format_t * f,__nis_value_t * inVal,int * numVals,char * sepset,char ** outstr)20900Sstevel@tonic-gate matchMappingItem(__nis_mapping_format_t *f, __nis_value_t *inVal,
20910Sstevel@tonic-gate int *numVals, char *sepset, char **outstr) {
20920Sstevel@tonic-gate __nis_value_t **v = 0;
20930Sstevel@tonic-gate int i, n, ni, numItems, nf, nv = 0;
20940Sstevel@tonic-gate char *str, *valstr;
20950Sstevel@tonic-gate __nis_mapping_format_t *ftmp;
20960Sstevel@tonic-gate char *myself = "matchMappingItem";
20970Sstevel@tonic-gate
20980Sstevel@tonic-gate if (f == 0 ||
20990Sstevel@tonic-gate inVal == 0 || inVal->numVals < 1 || inVal->type != vt_string)
21000Sstevel@tonic-gate return (0);
21010Sstevel@tonic-gate
21020Sstevel@tonic-gate /* Count the number of format elements and items in the format */
21030Sstevel@tonic-gate for (nf = numItems = 0, ftmp = f; ftmp->type != mmt_end; ftmp++) {
21040Sstevel@tonic-gate nf++;
21050Sstevel@tonic-gate
21060Sstevel@tonic-gate /*
21070Sstevel@tonic-gate * Count mmt_item and mmt_berstring (used by N2L to
21080Sstevel@tonic-gate * represent address %a)
21090Sstevel@tonic-gate */
21100Sstevel@tonic-gate if (ftmp->type == mmt_item)
21110Sstevel@tonic-gate numItems++;
21120Sstevel@tonic-gate else if (ftmp->type == mmt_berstring && ftmp->match.berString &&
21130Sstevel@tonic-gate ftmp->match.berString[0] == 'a')
21140Sstevel@tonic-gate numItems++;
21150Sstevel@tonic-gate }
21160Sstevel@tonic-gate /* Count the mmt_end as well */
21170Sstevel@tonic-gate nf++;
21180Sstevel@tonic-gate
21190Sstevel@tonic-gate /*
21200Sstevel@tonic-gate * If no items, there will be no values. This isn't exactly an error
21210Sstevel@tonic-gate * from the limited point of view of this function, so we return a
21220Sstevel@tonic-gate * __nis_value_t with zero values.
21230Sstevel@tonic-gate */
21240Sstevel@tonic-gate if (numItems <= 0) {
21250Sstevel@tonic-gate v = am(myself, sizeof (v[0]));
21260Sstevel@tonic-gate if (v == 0)
21270Sstevel@tonic-gate return (0);
21280Sstevel@tonic-gate v[0] = am(myself, sizeof (*v[0]));
21290Sstevel@tonic-gate if (v[0] == 0) {
21300Sstevel@tonic-gate sfree(v);
21310Sstevel@tonic-gate return (0);
21320Sstevel@tonic-gate }
21330Sstevel@tonic-gate v[0]->type = vt_string;
21340Sstevel@tonic-gate v[0]->numVals = 0;
21350Sstevel@tonic-gate v[0]->val = 0;
21360Sstevel@tonic-gate if (numVals != 0)
21370Sstevel@tonic-gate *numVals = 1;
21380Sstevel@tonic-gate return (v);
21390Sstevel@tonic-gate }
21400Sstevel@tonic-gate
21410Sstevel@tonic-gate /* Allocate and initialize the return array */
21420Sstevel@tonic-gate v = am(myself, numItems * sizeof (v[0]));
21430Sstevel@tonic-gate if (v == 0)
21440Sstevel@tonic-gate return (0);
21450Sstevel@tonic-gate for (n = 0; n < numItems; n++) {
21460Sstevel@tonic-gate v[n] = am(myself, sizeof (*v[n]));
21470Sstevel@tonic-gate if (v[n] == 0) {
21480Sstevel@tonic-gate int j;
21490Sstevel@tonic-gate
21500Sstevel@tonic-gate for (j = 0; j < n; j++)
21510Sstevel@tonic-gate freeValue(v[j], 1);
21520Sstevel@tonic-gate sfree(v);
21530Sstevel@tonic-gate return (0);
21540Sstevel@tonic-gate }
21550Sstevel@tonic-gate v[n]->type = vt_string;
21560Sstevel@tonic-gate v[n]->numVals = 0;
21570Sstevel@tonic-gate v[n]->val = am(myself, inVal->numVals * sizeof (v[n]->val[0]));
21580Sstevel@tonic-gate if (v[n]->val == 0) {
21590Sstevel@tonic-gate int j;
21600Sstevel@tonic-gate
21610Sstevel@tonic-gate for (j = 0; j < n; j++)
21620Sstevel@tonic-gate freeValue(v[j], 1);
21630Sstevel@tonic-gate sfree(v);
21640Sstevel@tonic-gate return (0);
21650Sstevel@tonic-gate }
21660Sstevel@tonic-gate for (i = 0; i < inVal->numVals; i++) {
21670Sstevel@tonic-gate v[n]->val[i].length = 0;
21680Sstevel@tonic-gate v[n]->val[i].value = 0;
21690Sstevel@tonic-gate }
21700Sstevel@tonic-gate }
21710Sstevel@tonic-gate
21720Sstevel@tonic-gate /* For each input value, perform the match operation */
21730Sstevel@tonic-gate for (i = 0; i < inVal->numVals; i++) {
21740Sstevel@tonic-gate str = inVal->val[i].value;
21750Sstevel@tonic-gate if (str == 0)
21760Sstevel@tonic-gate continue;
21770Sstevel@tonic-gate for (n = 0, ni = 0; n < nf; n++) {
21780Sstevel@tonic-gate valstr = 0;
21790Sstevel@tonic-gate str = scanMappingFormat(f, n, nf, str, &valstr,
21800Sstevel@tonic-gate 0, sepset);
21810Sstevel@tonic-gate if (str == 0)
21820Sstevel@tonic-gate break;
21830Sstevel@tonic-gate if (valstr != 0 && ni < numItems &&
21840Sstevel@tonic-gate v[ni]->numVals < inVal->numVals) {
21850Sstevel@tonic-gate v[ni]->val[v[ni]->numVals].value = valstr;
21860Sstevel@tonic-gate v[ni]->val[v[ni]->numVals].length =
21870Sstevel@tonic-gate strlen(valstr) + 1;
21880Sstevel@tonic-gate v[ni]->numVals++;
21890Sstevel@tonic-gate ni++;
21900Sstevel@tonic-gate } else if (valstr != 0) {
21910Sstevel@tonic-gate sfree(valstr);
21920Sstevel@tonic-gate }
21930Sstevel@tonic-gate }
21940Sstevel@tonic-gate if (str == 0) {
21950Sstevel@tonic-gate for (n = 0; n < numItems; n++)
21960Sstevel@tonic-gate freeValue(v[n], 1);
21970Sstevel@tonic-gate sfree(v);
21980Sstevel@tonic-gate return (0);
21990Sstevel@tonic-gate }
22000Sstevel@tonic-gate }
22010Sstevel@tonic-gate
22020Sstevel@tonic-gate if (numVals != 0)
22030Sstevel@tonic-gate *numVals = numItems;
22040Sstevel@tonic-gate
22050Sstevel@tonic-gate /*
22060Sstevel@tonic-gate * Update the return string upto the point it has been matched
22070Sstevel@tonic-gate * This string will be used by the N2L code in its next call
22080Sstevel@tonic-gate * to this function
22090Sstevel@tonic-gate */
22100Sstevel@tonic-gate if (outstr != 0)
22110Sstevel@tonic-gate *outstr = str;
22120Sstevel@tonic-gate
22130Sstevel@tonic-gate return (v);
22140Sstevel@tonic-gate }
22150Sstevel@tonic-gate
22160Sstevel@tonic-gate /*
22170Sstevel@tonic-gate * Perform an extract operation. For example, given the expression
22180Sstevel@tonic-gate * (name, "%s.*")
22190Sstevel@tonic-gate * and assuming 'name' is an item with the value "some.thing", the
22200Sstevel@tonic-gate * value returned by the extract is "some".
22210Sstevel@tonic-gate */
22220Sstevel@tonic-gate __nis_value_t *
extractMappingItem(__nis_mapping_item_t * item,__nis_mapping_format_t * f,__nis_rule_value_t * rv,int * stat)22230Sstevel@tonic-gate extractMappingItem(__nis_mapping_item_t *item, __nis_mapping_format_t *f,
22240Sstevel@tonic-gate __nis_rule_value_t *rv, int *stat) {
22250Sstevel@tonic-gate __nis_value_t *val = getMappingItem(item, mit_any,
22260Sstevel@tonic-gate rv, 0, stat);
22270Sstevel@tonic-gate __nis_single_value_t *nval;
22280Sstevel@tonic-gate int i, n, nv, nf;
22290Sstevel@tonic-gate __nis_mapping_format_t *ftmp;
22300Sstevel@tonic-gate
22310Sstevel@tonic-gate if (val == 0)
22320Sstevel@tonic-gate return (0);
22330Sstevel@tonic-gate else if (f == 0 || rv == 0 || val->val == 0 ||
22340Sstevel@tonic-gate val->numVals <= 0 || val->type != vt_string) {
22350Sstevel@tonic-gate freeValue(val, 1);
22360Sstevel@tonic-gate return (0);
22370Sstevel@tonic-gate }
22380Sstevel@tonic-gate
22390Sstevel@tonic-gate /* Sanity check the format; it must have one and only one mmt_item */
22400Sstevel@tonic-gate {
22410Sstevel@tonic-gate int numitem;
22420Sstevel@tonic-gate
22430Sstevel@tonic-gate for (nf = numitem = 0, ftmp = f; ftmp->type != mmt_end;
22440Sstevel@tonic-gate ftmp++) {
22450Sstevel@tonic-gate nf++;
22460Sstevel@tonic-gate if (ftmp->type == mmt_item)
22470Sstevel@tonic-gate numitem++;
22480Sstevel@tonic-gate }
22490Sstevel@tonic-gate /* Count the mmt_end as well */
22500Sstevel@tonic-gate nf++;
22510Sstevel@tonic-gate if (numitem != 1) {
22520Sstevel@tonic-gate freeValue(val, 1);
22530Sstevel@tonic-gate return (0);
22540Sstevel@tonic-gate }
22550Sstevel@tonic-gate }
22560Sstevel@tonic-gate
22570Sstevel@tonic-gate nval = val->val;
22580Sstevel@tonic-gate nv = val->numVals;
22590Sstevel@tonic-gate val->repeat = FALSE;
22600Sstevel@tonic-gate val->val = 0;
22610Sstevel@tonic-gate val->numVals = 0;
22620Sstevel@tonic-gate
22630Sstevel@tonic-gate /* If the item has multiple values, we extract each one independently */
22640Sstevel@tonic-gate for (i = 0; i < nv; i++) {
22650Sstevel@tonic-gate char *str = nval[i].value;
22660Sstevel@tonic-gate char *newstr = 0;
22670Sstevel@tonic-gate __nis_single_value_t *newval;
22680Sstevel@tonic-gate
22690Sstevel@tonic-gate if (nval[i].value == 0)
22700Sstevel@tonic-gate continue;
22710Sstevel@tonic-gate
22720Sstevel@tonic-gate /*
22730Sstevel@tonic-gate * We match the whole string, even if we find a value for
22740Sstevel@tonic-gate * the item before exhausting all format elements. By doing
22750Sstevel@tonic-gate * this, we ensure that the string really matches the complete
22760Sstevel@tonic-gate * format specification.
22770Sstevel@tonic-gate */
22780Sstevel@tonic-gate for (n = 0; n < nf; n++) {
22790Sstevel@tonic-gate str = scanMappingFormat(f, n, nf, str, &newstr, 0, 0);
22800Sstevel@tonic-gate if (str == 0)
22810Sstevel@tonic-gate break;
22820Sstevel@tonic-gate }
22830Sstevel@tonic-gate
22840Sstevel@tonic-gate /*
22850Sstevel@tonic-gate * *str should now be NUL, meaning we've reached the end of
22860Sstevel@tonic-gate * the string (value), and it completely matched the format.
22870Sstevel@tonic-gate * If 'str' is NULL, there was an error, and if 'newstr' is
22880Sstevel@tonic-gate * 0, we somehow failed to obtain a value.
22890Sstevel@tonic-gate */
22900Sstevel@tonic-gate if (str == 0 || *str != '\0' || newstr == 0 ||
22910Sstevel@tonic-gate (newval = realloc(val->val,
22920Sstevel@tonic-gate (val->numVals+1) *
22930Sstevel@tonic-gate sizeof (val->val[0]))) == 0) {
22940Sstevel@tonic-gate freeValue(val, 1);
22950Sstevel@tonic-gate for (n = 0; n < nv; n++) {
22960Sstevel@tonic-gate sfree(nval[n].value);
22970Sstevel@tonic-gate }
22980Sstevel@tonic-gate free(nval);
22990Sstevel@tonic-gate sfree(newstr);
23000Sstevel@tonic-gate return (0);
23010Sstevel@tonic-gate }
23020Sstevel@tonic-gate
23030Sstevel@tonic-gate val->val = newval;
23040Sstevel@tonic-gate val->val[val->numVals].value = newstr;
23050Sstevel@tonic-gate val->val[val->numVals].length = strlen(newstr) + 1;
23060Sstevel@tonic-gate val->numVals++;
23070Sstevel@tonic-gate
23080Sstevel@tonic-gate free(nval[i].value);
23090Sstevel@tonic-gate nval[i].value = 0;
23100Sstevel@tonic-gate }
23110Sstevel@tonic-gate free(nval);
23120Sstevel@tonic-gate
23130Sstevel@tonic-gate return (val);
23140Sstevel@tonic-gate }
23150Sstevel@tonic-gate
23160Sstevel@tonic-gate /*
23170Sstevel@tonic-gate * For each value in 'val', remove the last character, provided that
23180Sstevel@tonic-gate * it matches 'elide'.
23190Sstevel@tonic-gate */
23200Sstevel@tonic-gate void
stringElide(__nis_value_t * val,char elide)23210Sstevel@tonic-gate stringElide(__nis_value_t *val, char elide) {
23220Sstevel@tonic-gate
23230Sstevel@tonic-gate if (val != 0 && val->type == vt_string) {
23240Sstevel@tonic-gate int i;
23250Sstevel@tonic-gate
23260Sstevel@tonic-gate for (i = 0; i < val->numVals; i++) {
23270Sstevel@tonic-gate int end = val->val[i].length;
23280Sstevel@tonic-gate char *str = val->val[i].value;
23290Sstevel@tonic-gate
23300Sstevel@tonic-gate if (str == 0 || end <= 0)
23310Sstevel@tonic-gate continue;
23320Sstevel@tonic-gate
23330Sstevel@tonic-gate /*
23340Sstevel@tonic-gate * If the NUL was counted in the length, step back
23350Sstevel@tonic-gate * over it.
23360Sstevel@tonic-gate */
23370Sstevel@tonic-gate if (str[end-1] == '\0')
23380Sstevel@tonic-gate end--;
23390Sstevel@tonic-gate if (end > 0 && str[end-1] == elide) {
23400Sstevel@tonic-gate str[end-1] = '\0';
23410Sstevel@tonic-gate val->val[i].length--;
23420Sstevel@tonic-gate }
23430Sstevel@tonic-gate }
23440Sstevel@tonic-gate }
23450Sstevel@tonic-gate }
23460Sstevel@tonic-gate
23470Sstevel@tonic-gate /*
23480Sstevel@tonic-gate * Obtain the value for the mapping sub-element 'e', given the input
23490Sstevel@tonic-gate * rule-value 'rv'.
23500Sstevel@tonic-gate */
23510Sstevel@tonic-gate __nis_value_t *
getMappingSubElement(__nis_mapping_sub_element_t * e,__nis_rule_value_t * rv,int * np_ldap_stat)23520Sstevel@tonic-gate getMappingSubElement(__nis_mapping_sub_element_t *e,
23530Sstevel@tonic-gate __nis_rule_value_t *rv, int *np_ldap_stat) {
23540Sstevel@tonic-gate __nis_value_t *val;
23550Sstevel@tonic-gate
23560Sstevel@tonic-gate if (e == 0)
23570Sstevel@tonic-gate return (0);
23580Sstevel@tonic-gate
23590Sstevel@tonic-gate switch (e->type) {
23600Sstevel@tonic-gate case me_item:
23610Sstevel@tonic-gate val = getMappingItem(&e->element.item, mit_any, rv, 0,
23620Sstevel@tonic-gate np_ldap_stat);
23630Sstevel@tonic-gate break;
23640Sstevel@tonic-gate case me_print:
23650Sstevel@tonic-gate val = getMappingFormatArray(e->element.print.fmt, rv,
23660Sstevel@tonic-gate fa_item,
23670Sstevel@tonic-gate e->element.print.numItems,
23680Sstevel@tonic-gate e->element.print.item);
23690Sstevel@tonic-gate if (e->element.print.doElide)
23700Sstevel@tonic-gate stringElide(val, e->element.print.elide);
23710Sstevel@tonic-gate break;
23720Sstevel@tonic-gate case me_split:
23730Sstevel@tonic-gate val = splitMappingItem(&e->element.split.item,
23740Sstevel@tonic-gate e->element.split.delim,
23750Sstevel@tonic-gate rv);
23760Sstevel@tonic-gate break;
23770Sstevel@tonic-gate case me_extract:
23780Sstevel@tonic-gate val = extractMappingItem(&e->element.extract.item,
23790Sstevel@tonic-gate e->element.extract.fmt,
23800Sstevel@tonic-gate rv, np_ldap_stat);
23810Sstevel@tonic-gate break;
23820Sstevel@tonic-gate case me_match:
23830Sstevel@tonic-gate default:
23840Sstevel@tonic-gate val = 0;
23850Sstevel@tonic-gate break;
23860Sstevel@tonic-gate }
23870Sstevel@tonic-gate
23880Sstevel@tonic-gate return (val);
23890Sstevel@tonic-gate }
23900Sstevel@tonic-gate
23910Sstevel@tonic-gate /*
23920Sstevel@tonic-gate * Obtain the value of the mapping element 'e', given the input rule-
23930Sstevel@tonic-gate * value 'rv'. The 'native' mapping type is used when 'rv' is NULL,
23940Sstevel@tonic-gate * and the result is a string representation of the mapping element;
23950Sstevel@tonic-gate * in that case, items of the 'native' type are printed without their
23960Sstevel@tonic-gate * type designation ("nis+" or "ldap").
23970Sstevel@tonic-gate */
23980Sstevel@tonic-gate __nis_value_t *
getMappingElement(__nis_mapping_element_t * e,__nis_mapping_item_type_t native,__nis_rule_value_t * rv,int * stat)23990Sstevel@tonic-gate getMappingElement(__nis_mapping_element_t *e, __nis_mapping_item_type_t native,
24000Sstevel@tonic-gate __nis_rule_value_t *rv, int *stat) {
24010Sstevel@tonic-gate __nis_value_t *val, **tv;
24020Sstevel@tonic-gate int i, success = 0, novalue = 0;
24030Sstevel@tonic-gate int *np_ldap_stat;
24040Sstevel@tonic-gate char *myself = "getMappingElement";
24050Sstevel@tonic-gate
24060Sstevel@tonic-gate switch (e->type) {
24070Sstevel@tonic-gate case me_item:
24080Sstevel@tonic-gate val = getMappingItem(&e->element.item, native, rv, 0, NULL);
24090Sstevel@tonic-gate break;
24100Sstevel@tonic-gate case me_print:
24110Sstevel@tonic-gate tv = am(myself, e->element.print.numSubElements *
24120Sstevel@tonic-gate sizeof (tv[0]));
24130Sstevel@tonic-gate np_ldap_stat = am(myself,
24140Sstevel@tonic-gate e->element.print.numSubElements * sizeof (int));
24150Sstevel@tonic-gate if ((e->element.print.numSubElements > 0) &&
24160Sstevel@tonic-gate (tv == 0 || np_ldap_stat == 0)) {
24170Sstevel@tonic-gate val = 0;
24180Sstevel@tonic-gate sfree(tv);
24190Sstevel@tonic-gate sfree(np_ldap_stat);
24200Sstevel@tonic-gate break;
24210Sstevel@tonic-gate }
24220Sstevel@tonic-gate for (i = 0; i < e->element.print.numSubElements; i++) {
24230Sstevel@tonic-gate np_ldap_stat[i] = 0;
24240Sstevel@tonic-gate tv[i] = getMappingSubElement(
24250Sstevel@tonic-gate &e->element.print.subElement[i],
24260Sstevel@tonic-gate rv, &np_ldap_stat[i]);
24270Sstevel@tonic-gate }
24280Sstevel@tonic-gate /*
24290Sstevel@tonic-gate * if we get NP_LDAP_NO_VALUE to any of the subelement
24300Sstevel@tonic-gate * and we get NP_LDAP_MAP_SUCCESS to all other subelement
24310Sstevel@tonic-gate * then we had enough nis+ column values which can
24320Sstevel@tonic-gate * produce value for this rule, but didn't. So return
24330Sstevel@tonic-gate * NP_LDAP_RULES_NO_VALUE to indicate to proceed to
24340Sstevel@tonic-gate * next database id.
24350Sstevel@tonic-gate */
24360Sstevel@tonic-gate for (i = 0; i < e->element.print.numSubElements; i++) {
24370Sstevel@tonic-gate if (np_ldap_stat[i] == NP_LDAP_MAP_SUCCESS)
24380Sstevel@tonic-gate success++;
24390Sstevel@tonic-gate if (np_ldap_stat[i] == NP_LDAP_NO_VALUE)
24400Sstevel@tonic-gate novalue++;
24410Sstevel@tonic-gate }
24420Sstevel@tonic-gate if (stat != NULL && novalue > 0 &&
24430Sstevel@tonic-gate ((novalue+success) ==
24440Sstevel@tonic-gate e->element.print.numSubElements))
24450Sstevel@tonic-gate *stat = NP_LDAP_RULES_NO_VALUE;
24460Sstevel@tonic-gate val = getMappingFormatArray(e->element.print.fmt, rv,
24470Sstevel@tonic-gate fa_value,
24480Sstevel@tonic-gate e->element.print.numSubElements,
24490Sstevel@tonic-gate tv);
24500Sstevel@tonic-gate for (i = 0; i < e->element.print.numSubElements; i++) {
24510Sstevel@tonic-gate freeValue(tv[i], 1);
24520Sstevel@tonic-gate }
24530Sstevel@tonic-gate sfree(tv);
24540Sstevel@tonic-gate sfree(np_ldap_stat);
24550Sstevel@tonic-gate if (e->element.print.doElide)
24560Sstevel@tonic-gate stringElide(val, e->element.print.elide);
24570Sstevel@tonic-gate break;
24580Sstevel@tonic-gate case me_split:
24590Sstevel@tonic-gate val = splitMappingItem(&e->element.split.item,
24600Sstevel@tonic-gate e->element.split.delim,
24610Sstevel@tonic-gate rv);
24620Sstevel@tonic-gate break;
24630Sstevel@tonic-gate case me_match:
24640Sstevel@tonic-gate /*
24650Sstevel@tonic-gate * A match doesn't produce an assignable value per se,
24660Sstevel@tonic-gate * so we shouldn't get one here.
24670Sstevel@tonic-gate */
24680Sstevel@tonic-gate val = 0;
24690Sstevel@tonic-gate break;
24700Sstevel@tonic-gate case me_extract:
24710Sstevel@tonic-gate val = extractMappingItem(&e->element.extract.item,
24720Sstevel@tonic-gate e->element.extract.fmt,
24730Sstevel@tonic-gate rv, NULL);
24740Sstevel@tonic-gate break;
24750Sstevel@tonic-gate default:
24760Sstevel@tonic-gate val = 0;
24770Sstevel@tonic-gate break;
24780Sstevel@tonic-gate }
24790Sstevel@tonic-gate
24800Sstevel@tonic-gate return (val);
24810Sstevel@tonic-gate }
2482