17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*ea10ff14SBen Chang * Common Development and Distribution License (the "License"). 6*ea10ff14SBen Chang * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*ea10ff14SBen Chang * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate /* 267c478bd9Sstevel@tonic-gate * DESCRIPTION: Contains dit_access interface support functions. 277c478bd9Sstevel@tonic-gate */ 287c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 297c478bd9Sstevel@tonic-gate #include <unistd.h> 307c478bd9Sstevel@tonic-gate #include <stdlib.h> 317c478bd9Sstevel@tonic-gate #include <sys/types.h> 327c478bd9Sstevel@tonic-gate #include <sys/stat.h> 337c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 347c478bd9Sstevel@tonic-gate #include <unistd.h> 357c478bd9Sstevel@tonic-gate #include <stdlib.h> 367c478bd9Sstevel@tonic-gate #include <syslog.h> 377c478bd9Sstevel@tonic-gate #include <ndbm.h> 387c478bd9Sstevel@tonic-gate #include <strings.h> 397c478bd9Sstevel@tonic-gate #include <errno.h> 407c478bd9Sstevel@tonic-gate #include "../ldap_util.h" 417c478bd9Sstevel@tonic-gate #include "../ldap_map.h" 427c478bd9Sstevel@tonic-gate #include "../ldap_parse.h" 437c478bd9Sstevel@tonic-gate #include "../ldap_structs.h" 447c478bd9Sstevel@tonic-gate #include "../ldap_val.h" 457c478bd9Sstevel@tonic-gate #include "../ldap_ruleval.h" 467c478bd9Sstevel@tonic-gate #include "../ldap_op.h" 477c478bd9Sstevel@tonic-gate #include "../ldap_attr.h" 487c478bd9Sstevel@tonic-gate #include "../ldap_nisdbquery.h" 497c478bd9Sstevel@tonic-gate #include "../nisdb_mt.h" 507c478bd9Sstevel@tonic-gate #include "shim.h" 517c478bd9Sstevel@tonic-gate #include "yptol.h" 527c478bd9Sstevel@tonic-gate #include "dit_access_utils.h" 537c478bd9Sstevel@tonic-gate 54*ea10ff14SBen Chang #define YPMULTI "YP_MULTI_" 55*ea10ff14SBen Chang #define YPMULTISZ 9 /* == strlen(YPMULTI) */ 56*ea10ff14SBen Chang 577c478bd9Sstevel@tonic-gate /* 587c478bd9Sstevel@tonic-gate * Returns 'map,domain.' 597c478bd9Sstevel@tonic-gate */ 607c478bd9Sstevel@tonic-gate char * 617c478bd9Sstevel@tonic-gate getFullMapName(char *map, char *domain) { 627c478bd9Sstevel@tonic-gate char *myself = "getFullMapName"; 637c478bd9Sstevel@tonic-gate char *objPath; 647c478bd9Sstevel@tonic-gate if (map == 0 || domain == 0) { 657c478bd9Sstevel@tonic-gate return (0); 667c478bd9Sstevel@tonic-gate } 677c478bd9Sstevel@tonic-gate objPath = scat(myself, T, scat(myself, F, map, ","), 687c478bd9Sstevel@tonic-gate scat(myself, F, domain, ".")); 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate return (objPath); 717c478bd9Sstevel@tonic-gate } 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate /* 747c478bd9Sstevel@tonic-gate * Convert string to __nis_value_t 757c478bd9Sstevel@tonic-gate */ 767c478bd9Sstevel@tonic-gate __nis_value_t *stringToValue(char *dptr, int dsize) { 777c478bd9Sstevel@tonic-gate char *myself = "stringToValue"; 787c478bd9Sstevel@tonic-gate char *emptystr = ""; 797c478bd9Sstevel@tonic-gate __nis_value_t *val; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate if ((val = am(myself, sizeof (*val))) == 0) { 827c478bd9Sstevel@tonic-gate return (0); 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate val->type = vt_string; 867c478bd9Sstevel@tonic-gate val->repeat = 0; 877c478bd9Sstevel@tonic-gate val->numVals = 1; 887c478bd9Sstevel@tonic-gate if ((val->val = am(myself, sizeof (val->val[0]))) == 0) { 897c478bd9Sstevel@tonic-gate sfree(val); 907c478bd9Sstevel@tonic-gate return (0); 917c478bd9Sstevel@tonic-gate } 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate /* 947c478bd9Sstevel@tonic-gate * Null strings or strings with length 0 are treated 957c478bd9Sstevel@tonic-gate * as empty strings with length 1 967c478bd9Sstevel@tonic-gate */ 977c478bd9Sstevel@tonic-gate if (dptr == 0 || dsize <= 0) { 987c478bd9Sstevel@tonic-gate dptr = emptystr; 997c478bd9Sstevel@tonic-gate dsize = 1; 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate val->val->length = dsize; 1037c478bd9Sstevel@tonic-gate if (dptr[dsize - 1] != '\0') { 1047c478bd9Sstevel@tonic-gate val->val->length = dsize + 1; 1057c478bd9Sstevel@tonic-gate } 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate val->val->value = am(myself, val->val->length); 1087c478bd9Sstevel@tonic-gate if (val->val->value == 0) { 1097c478bd9Sstevel@tonic-gate freeValue(val, 1); 1107c478bd9Sstevel@tonic-gate return (0); 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate (void) memcpy(val->val->value, dptr, dsize); 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate return (val); 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate /* 1187c478bd9Sstevel@tonic-gate * Returns an array of rule-values corresponding to the 1197c478bd9Sstevel@tonic-gate * splitfields. 1207c478bd9Sstevel@tonic-gate */ 1217c478bd9Sstevel@tonic-gate __nis_rule_value_t * 1227c478bd9Sstevel@tonic-gate processSplitField(__nis_table_mapping_t *sf, __nis_value_t *inVal, 1237c478bd9Sstevel@tonic-gate int *nv, int *statP) { 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate char *sepset; 1267c478bd9Sstevel@tonic-gate __nis_rule_value_t *rvq; 1277c478bd9Sstevel@tonic-gate __nis_mapping_format_t *ftmp; 1287c478bd9Sstevel@tonic-gate __nis_value_t **valA, *tempVal; 1297c478bd9Sstevel@tonic-gate int i, j, res, numVals, oldlen, count; 1307c478bd9Sstevel@tonic-gate char *str, *oldstr; 1317c478bd9Sstevel@tonic-gate char *myself = "processSplitField"; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate /* sf will be non NULL */ 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate if (inVal == 0 || inVal->type != vt_string) { 1367c478bd9Sstevel@tonic-gate *statP = MAP_PARAM_ERROR; 1377c478bd9Sstevel@tonic-gate return (0); 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate /* Get the separator list */ 1417c478bd9Sstevel@tonic-gate sepset = sf->separatorStr; 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate /* Initialize rule-value */ 1447c478bd9Sstevel@tonic-gate rvq = 0; 1457c478bd9Sstevel@tonic-gate count = 0; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate if ((tempVal = stringToValue(inVal->val->value, 1487c478bd9Sstevel@tonic-gate inVal->val->length)) == 0) { 1497c478bd9Sstevel@tonic-gate *statP = MAP_NO_MEMORY; 1507c478bd9Sstevel@tonic-gate return (0); 1517c478bd9Sstevel@tonic-gate } 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate str = oldstr = tempVal->val->value; 1547c478bd9Sstevel@tonic-gate oldlen = tempVal->val->length; 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate while (str) { 1577c478bd9Sstevel@tonic-gate tempVal->val->value = str; 1587c478bd9Sstevel@tonic-gate tempVal->val->length = strlen(str) + 1; 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate /* Loop to check which format matches str */ 1617c478bd9Sstevel@tonic-gate for (i = 0; i <= sf->numSplits; i++) { 1627c478bd9Sstevel@tonic-gate valA = matchMappingItem(sf->e[i].element.match.fmt, 1637c478bd9Sstevel@tonic-gate tempVal, &numVals, sepset, &str); 1647c478bd9Sstevel@tonic-gate if (valA == 0) { 1657c478bd9Sstevel@tonic-gate /* The format didn't match. Try the next one */ 1667c478bd9Sstevel@tonic-gate continue; 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate /* 1707c478bd9Sstevel@tonic-gate * If we are here means we had a match. 1717c478bd9Sstevel@tonic-gate * Each new set of values obtained from the match is 1727c478bd9Sstevel@tonic-gate * added to a new rule-value. This is to preserve the 1737c478bd9Sstevel@tonic-gate * the distinction between each set. 1747c478bd9Sstevel@tonic-gate */ 1757c478bd9Sstevel@tonic-gate rvq = growRuleValue(count, count + 1, rvq, 0); 1767c478bd9Sstevel@tonic-gate if (rvq == 0) { 1777c478bd9Sstevel@tonic-gate *statP = MAP_INTERNAL_ERROR; 1787c478bd9Sstevel@tonic-gate for (j = 0; j < numVals; j++) 1797c478bd9Sstevel@tonic-gate freeValue(valA[j], 1); 1807c478bd9Sstevel@tonic-gate sfree(valA); 1817c478bd9Sstevel@tonic-gate tempVal->val->value = oldstr; 1827c478bd9Sstevel@tonic-gate tempVal->val->length = oldlen; 1837c478bd9Sstevel@tonic-gate freeValue(tempVal, 1); 1847c478bd9Sstevel@tonic-gate return (0); 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate count++; 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate for (j = 0; j < numVals; j++) { 1897c478bd9Sstevel@tonic-gate res = addCol2RuleValue(vt_string, 1907c478bd9Sstevel@tonic-gate sf->e[i].element.match.item[j].name, 1917c478bd9Sstevel@tonic-gate valA[j]->val->value, 1927c478bd9Sstevel@tonic-gate valA[j]->val->length, 1937c478bd9Sstevel@tonic-gate &rvq[count - 1]); 1947c478bd9Sstevel@tonic-gate if (res == -1) { 1957c478bd9Sstevel@tonic-gate *statP = MAP_INTERNAL_ERROR; 1967c478bd9Sstevel@tonic-gate for (; j < numVals; j++) 1977c478bd9Sstevel@tonic-gate freeValue(valA[j], 1); 1987c478bd9Sstevel@tonic-gate sfree(valA); 1997c478bd9Sstevel@tonic-gate tempVal->val->value = oldstr; 2007c478bd9Sstevel@tonic-gate tempVal->val->length = oldlen; 2017c478bd9Sstevel@tonic-gate freeValue(tempVal, 1); 2027c478bd9Sstevel@tonic-gate freeRuleValue(rvq, count); 2037c478bd9Sstevel@tonic-gate return (0); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate freeValue(valA[j], 1); 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate sfree(valA); 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate /* 2107c478bd9Sstevel@tonic-gate * Since we had a match, break out of this loop 2117c478bd9Sstevel@tonic-gate * to parse remainder of str 2127c478bd9Sstevel@tonic-gate */ 2137c478bd9Sstevel@tonic-gate break; 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate /* Didn't find any match, so get out of the loop */ 2177c478bd9Sstevel@tonic-gate if (i > sf->numSplits) { 2187c478bd9Sstevel@tonic-gate str = 0; 2197c478bd9Sstevel@tonic-gate break; 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate /* Skip the separators before looping back */ 2237c478bd9Sstevel@tonic-gate if (str) { 2247c478bd9Sstevel@tonic-gate str = str + strspn(str, sepset); 2257c478bd9Sstevel@tonic-gate if (*str == '\0') 2267c478bd9Sstevel@tonic-gate break; 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate tempVal->val->value = oldstr; 2317c478bd9Sstevel@tonic-gate tempVal->val->length = oldlen; 2327c478bd9Sstevel@tonic-gate freeValue(tempVal, 1); 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate if (str == 0) { 2357c478bd9Sstevel@tonic-gate freeRuleValue(rvq, count); 2367c478bd9Sstevel@tonic-gate return (0); 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate if (nv != 0) 2407c478bd9Sstevel@tonic-gate *nv = count; 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate return (rvq); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate /* 2467c478bd9Sstevel@tonic-gate * Convert the datum to an array of RuleValues 2477c478bd9Sstevel@tonic-gate */ 2487c478bd9Sstevel@tonic-gate __nis_rule_value_t * 2497c478bd9Sstevel@tonic-gate datumToRuleValue(datum *key, datum *value, __nis_table_mapping_t *t, 2507c478bd9Sstevel@tonic-gate int *nv, char *domain, bool_t readonly, int *statP) { 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate __nis_rule_value_t *rvq, *subrvq, *newrvq; 2537c478bd9Sstevel@tonic-gate __nis_value_t *val; 2547c478bd9Sstevel@tonic-gate __nis_value_t **valA; 2557c478bd9Sstevel@tonic-gate __nis_table_mapping_t *sf; 2567c478bd9Sstevel@tonic-gate int valueLen, comLen, numVals, nr, count = 1; 2577c478bd9Sstevel@tonic-gate int i, j, k, l, af; 2587c478bd9Sstevel@tonic-gate char *ipaddr, *ipvalue; 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate /* At this point, 't' is always non NULL */ 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate /* Initialize rule-value */ 2637c478bd9Sstevel@tonic-gate if ((rvq = initRuleValue(1, 0)) == 0) { 2647c478bd9Sstevel@tonic-gate *statP = MAP_INTERNAL_ERROR; 2657c478bd9Sstevel@tonic-gate return (0); 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate /* Add domainname to rule-value */ 2697c478bd9Sstevel@tonic-gate if (addCol2RuleValue(vt_string, N2LDOMAIN, domain, strlen(domain), 2707c478bd9Sstevel@tonic-gate rvq)) { 2717c478bd9Sstevel@tonic-gate freeRuleValue(rvq, 1); 2727c478bd9Sstevel@tonic-gate *statP = MAP_INTERNAL_ERROR; 2737c478bd9Sstevel@tonic-gate return (0); 2747c478bd9Sstevel@tonic-gate } 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate /* Handle key */ 2777c478bd9Sstevel@tonic-gate if (key != 0) { 2787c478bd9Sstevel@tonic-gate /* Add field=value pair for N2LKEY */ 2797c478bd9Sstevel@tonic-gate i = addCol2RuleValue(vt_string, N2LKEY, key->dptr, key->dsize, 2807c478bd9Sstevel@tonic-gate rvq); 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate /* For readonly, add field=value pair for N2LSEARCHKEY */ 2837c478bd9Sstevel@tonic-gate if (readonly == TRUE && i == 0) { 2847c478bd9Sstevel@tonic-gate i = addCol2RuleValue(vt_string, N2LSEARCHKEY, key->dptr, 2857c478bd9Sstevel@tonic-gate key->dsize, rvq); 2867c478bd9Sstevel@tonic-gate } 2877c478bd9Sstevel@tonic-gate if (i) { 2887c478bd9Sstevel@tonic-gate freeRuleValue(rvq, 1); 2897c478bd9Sstevel@tonic-gate *statP = MAP_INTERNAL_ERROR; 2907c478bd9Sstevel@tonic-gate return (0); 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate /* Add field=value pairs for IP addresses */ 2947c478bd9Sstevel@tonic-gate if (checkIPaddress(key->dptr, key->dsize, &ipaddr) > 0) { 2957c478bd9Sstevel@tonic-gate /* If key is IPaddress, use preferred format */ 2967c478bd9Sstevel@tonic-gate ipvalue = ipaddr; 2977c478bd9Sstevel@tonic-gate valueLen = strlen(ipaddr); 2987c478bd9Sstevel@tonic-gate i = addCol2RuleValue(vt_string, N2LIPKEY, ipvalue, 2997c478bd9Sstevel@tonic-gate valueLen, rvq); 3007c478bd9Sstevel@tonic-gate } else { 3017c478bd9Sstevel@tonic-gate /* If not, use original value for N2LSEARCHIPKEY */ 3027c478bd9Sstevel@tonic-gate ipaddr = 0; 3037c478bd9Sstevel@tonic-gate ipvalue = key->dptr; 3047c478bd9Sstevel@tonic-gate valueLen = key->dsize; 3057c478bd9Sstevel@tonic-gate i = 0; 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate if (readonly == TRUE && i == 0) { 3097c478bd9Sstevel@tonic-gate i = addCol2RuleValue(vt_string, N2LSEARCHIPKEY, ipvalue, 3107c478bd9Sstevel@tonic-gate valueLen, rvq); 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate sfree(ipaddr); 3137c478bd9Sstevel@tonic-gate if (i) { 3147c478bd9Sstevel@tonic-gate freeRuleValue(rvq, 1); 3157c478bd9Sstevel@tonic-gate *statP = MAP_INTERNAL_ERROR; 3167c478bd9Sstevel@tonic-gate return (0); 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate /* Handle datum value */ 3217c478bd9Sstevel@tonic-gate if (value != 0 && t->e) { 3227c478bd9Sstevel@tonic-gate valueLen = value->dsize; 3237c478bd9Sstevel@tonic-gate /* 3247c478bd9Sstevel@tonic-gate * Extract the comment, if any, and add it to 3257c478bd9Sstevel@tonic-gate * the rule-value. 3267c478bd9Sstevel@tonic-gate */ 3277c478bd9Sstevel@tonic-gate if (t->commentChar != '\0') { 3287c478bd9Sstevel@tonic-gate /* 3297c478bd9Sstevel@tonic-gate * We loop on value->dsize because value->dptr 3307c478bd9Sstevel@tonic-gate * may not be NULL-terminated. 3317c478bd9Sstevel@tonic-gate */ 3327c478bd9Sstevel@tonic-gate for (i = 0; i < value->dsize; i++) { 3337c478bd9Sstevel@tonic-gate if (value->dptr[i] == t->commentChar) { 3347c478bd9Sstevel@tonic-gate valueLen = i; 3357c478bd9Sstevel@tonic-gate comLen = value->dsize - i - 1; 3367c478bd9Sstevel@tonic-gate if (comLen == 0) 3377c478bd9Sstevel@tonic-gate break; 3387c478bd9Sstevel@tonic-gate if (addCol2RuleValue(vt_string, 3397c478bd9Sstevel@tonic-gate N2LCOMMENT, value->dptr + i + 1, 3407c478bd9Sstevel@tonic-gate comLen, rvq)) { 3417c478bd9Sstevel@tonic-gate freeRuleValue(rvq, 1); 3427c478bd9Sstevel@tonic-gate *statP = MAP_INTERNAL_ERROR; 3437c478bd9Sstevel@tonic-gate return (0); 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate break; 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate /* Skip trailing whitespaces */ 3517c478bd9Sstevel@tonic-gate for (; valueLen > 0 && (value->dptr[valueLen - 1] == ' ' || 3527c478bd9Sstevel@tonic-gate value->dptr[valueLen - 1] == '\t'); valueLen--); 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate /* 3557c478bd9Sstevel@tonic-gate * At this point valueLen is the effective length of 3567c478bd9Sstevel@tonic-gate * the data. Convert value into __nis_value_t so that 3577c478bd9Sstevel@tonic-gate * we can use the matchMappingItem function to break it 3587c478bd9Sstevel@tonic-gate * into fields. 3597c478bd9Sstevel@tonic-gate */ 3607c478bd9Sstevel@tonic-gate if ((val = stringToValue(value->dptr, valueLen)) == 0) { 3617c478bd9Sstevel@tonic-gate freeRuleValue(rvq, 1); 3627c478bd9Sstevel@tonic-gate *statP = MAP_NO_MEMORY; 3637c478bd9Sstevel@tonic-gate return (0); 3647c478bd9Sstevel@tonic-gate } 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate /* Perform namefield match */ 3677c478bd9Sstevel@tonic-gate valA = matchMappingItem(t->e->element.match.fmt, val, 3687c478bd9Sstevel@tonic-gate &numVals, 0, 0); 3697c478bd9Sstevel@tonic-gate if (valA == 0) { 3707c478bd9Sstevel@tonic-gate freeValue(val, 1); 3717c478bd9Sstevel@tonic-gate freeRuleValue(rvq, 1); 3727c478bd9Sstevel@tonic-gate *statP = MAP_NAMEFIELD_MATCH_ERROR; 3737c478bd9Sstevel@tonic-gate return (0); 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate /* We don't need val anymore, so free it */ 3777c478bd9Sstevel@tonic-gate freeValue(val, 1); 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate /* 3807c478bd9Sstevel@tonic-gate * Since matchMappingItem only returns us an array of 3817c478bd9Sstevel@tonic-gate * __nis_value_t's, we need to associate each value 3827c478bd9Sstevel@tonic-gate * in the array with the corresponding item name. 3837c478bd9Sstevel@tonic-gate * This code assumes that numVals will be less than or 3847c478bd9Sstevel@tonic-gate * equal to the number of item names associated with 3857c478bd9Sstevel@tonic-gate * the format. 3867c478bd9Sstevel@tonic-gate * These name=value pairs are added to rvq. 3877c478bd9Sstevel@tonic-gate */ 3887c478bd9Sstevel@tonic-gate for (i = 0, *statP = SUCCESS; i < numVals; i++) { 3897c478bd9Sstevel@tonic-gate for (j = 0; j < count; j++) { 3907c478bd9Sstevel@tonic-gate if (addCol2RuleValue(vt_string, 3917c478bd9Sstevel@tonic-gate t->e->element.match.item[i].name, 3927c478bd9Sstevel@tonic-gate valA[i]->val->value, 3937c478bd9Sstevel@tonic-gate valA[i]->val->length, &rvq[j])) { 3947c478bd9Sstevel@tonic-gate *statP = MAP_INTERNAL_ERROR; 3957c478bd9Sstevel@tonic-gate break; 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate } 3987c478bd9Sstevel@tonic-gate if (*statP == MAP_INTERNAL_ERROR) 3997c478bd9Sstevel@tonic-gate break; 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate /* 4027c478bd9Sstevel@tonic-gate * Check if splitField exists for the field. 4037c478bd9Sstevel@tonic-gate * Since splitfields are also stored as mapping 4047c478bd9Sstevel@tonic-gate * structures, we need to get the hash table entry 4057c478bd9Sstevel@tonic-gate * corresponding to the splitfield name 4067c478bd9Sstevel@tonic-gate */ 4077c478bd9Sstevel@tonic-gate sf = mappingFromMap(t->e->element.match.item[i].name, 4087c478bd9Sstevel@tonic-gate domain, statP); 4097c478bd9Sstevel@tonic-gate if (*statP == MAP_NO_MEMORY) 4107c478bd9Sstevel@tonic-gate break; 4117c478bd9Sstevel@tonic-gate *statP = SUCCESS; 4127c478bd9Sstevel@tonic-gate if (sf == 0) 4137c478bd9Sstevel@tonic-gate continue; 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate /* 4167c478bd9Sstevel@tonic-gate * Process and add splitFields to rule-value rvq 4177c478bd9Sstevel@tonic-gate */ 4187c478bd9Sstevel@tonic-gate subrvq = processSplitField(sf, valA[i], &nr, statP); 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate if (subrvq == 0) { 4217c478bd9Sstevel@tonic-gate /* statP would have been set */ 4227c478bd9Sstevel@tonic-gate break; 4237c478bd9Sstevel@tonic-gate } 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate /* 4267c478bd9Sstevel@tonic-gate * We merge 'count' rule-values in rvq with 'nr' 4277c478bd9Sstevel@tonic-gate * rule-values from subrvq to give us a whopping 4287c478bd9Sstevel@tonic-gate * 'count * nr' rule-values 4297c478bd9Sstevel@tonic-gate */ 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate /* Initialize the new rule-value array */ 4327c478bd9Sstevel@tonic-gate if ((newrvq = initRuleValue(count * nr, 0)) == 0) { 4337c478bd9Sstevel@tonic-gate *statP = MAP_INTERNAL_ERROR; 4347c478bd9Sstevel@tonic-gate freeRuleValue(subrvq, nr); 4357c478bd9Sstevel@tonic-gate break; 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate for (j = 0, l = 0; j < nr; j++) { 4397c478bd9Sstevel@tonic-gate for (k = 0; k < count; k++, l++) { 4407c478bd9Sstevel@tonic-gate if ((mergeRuleValue(&newrvq[l], 4417c478bd9Sstevel@tonic-gate &rvq[k]) == -1) || 4427c478bd9Sstevel@tonic-gate (mergeRuleValue( 4437c478bd9Sstevel@tonic-gate &newrvq[l], 4447c478bd9Sstevel@tonic-gate &subrvq[j]) == -1)) { 4457c478bd9Sstevel@tonic-gate *statP = MAP_INTERNAL_ERROR; 4467c478bd9Sstevel@tonic-gate for (i = 0; i < numVals; i++) 4477c478bd9Sstevel@tonic-gate freeValue(valA[i], 1); 4487c478bd9Sstevel@tonic-gate sfree(valA); 4497c478bd9Sstevel@tonic-gate freeRuleValue(rvq, count); 4507c478bd9Sstevel@tonic-gate freeRuleValue(newrvq, 4517c478bd9Sstevel@tonic-gate count * nr); 4527c478bd9Sstevel@tonic-gate freeRuleValue(subrvq, nr); 4537c478bd9Sstevel@tonic-gate return (0); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate freeRuleValue(rvq, count); 4597c478bd9Sstevel@tonic-gate rvq = newrvq; 4607c478bd9Sstevel@tonic-gate count = l; 4617c478bd9Sstevel@tonic-gate freeRuleValue(subrvq, nr); 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate /* We don't need valA anymore, so free it */ 4667c478bd9Sstevel@tonic-gate for (i = 0; i < numVals; i++) 4677c478bd9Sstevel@tonic-gate freeValue(valA[i], 1); 4687c478bd9Sstevel@tonic-gate sfree(valA); 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate if (*statP != SUCCESS) { 4717c478bd9Sstevel@tonic-gate freeRuleValue(rvq, count); 4727c478bd9Sstevel@tonic-gate return (0); 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate } /* if value */ 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate if (nv != 0) 4787c478bd9Sstevel@tonic-gate *nv = count; 4797c478bd9Sstevel@tonic-gate return (rvq); 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate /* 4847c478bd9Sstevel@tonic-gate * Generate name=values pairs for splitfield names 4857c478bd9Sstevel@tonic-gate * 4867c478bd9Sstevel@tonic-gate * Consider Example: 4877c478bd9Sstevel@tonic-gate * nisLDAPnameFields club: 4887c478bd9Sstevel@tonic-gate * ("%s %s %s", name, code, members) 4897c478bd9Sstevel@tonic-gate * nisLDAPsplitField members: 4907c478bd9Sstevel@tonic-gate * ("(%s,%s,%s)", host, user, domain), 4917c478bd9Sstevel@tonic-gate * ("%s", group) 4927c478bd9Sstevel@tonic-gate * On entry, 4937c478bd9Sstevel@tonic-gate * - rv is an array of numVals rule-values each containing 4947c478bd9Sstevel@tonic-gate * name=value pairs for names occuring in nisLDAPsplitField. 4957c478bd9Sstevel@tonic-gate * (i.e host, user, domain, group) 4967c478bd9Sstevel@tonic-gate * - trv contains name=value pairs for names occuring in 4977c478bd9Sstevel@tonic-gate * nisLDAPnameFields. (i.e name, code but not members) 4987c478bd9Sstevel@tonic-gate * 4997c478bd9Sstevel@tonic-gate * For every name in nisLDAPnamefields that is a splitfield, 5007c478bd9Sstevel@tonic-gate * this function applies the data in rv to the corresponding 5017c478bd9Sstevel@tonic-gate * splitfield formats (accessed thru t), to generate a single 5027c478bd9Sstevel@tonic-gate * string value for the corresponding splitfield (members). 5037c478bd9Sstevel@tonic-gate * This new name=value pair is then added to trv. 5047c478bd9Sstevel@tonic-gate * Besides, any uninitialized namefield names are set to empty strings. 5057c478bd9Sstevel@tonic-gate */ 5067c478bd9Sstevel@tonic-gate suc_code 5077c478bd9Sstevel@tonic-gate addSplitFieldValues(__nis_table_mapping_t *t, __nis_rule_value_t *rv, 5087c478bd9Sstevel@tonic-gate __nis_rule_value_t *trv, int numVals, char *domain) { 5097c478bd9Sstevel@tonic-gate __nis_table_mapping_t *sf; 5107c478bd9Sstevel@tonic-gate __nis_value_t *val; 5117c478bd9Sstevel@tonic-gate int i, j, k, nitems, res, statP; 5127c478bd9Sstevel@tonic-gate char *str, *tempstr; 5137c478bd9Sstevel@tonic-gate char delim[2] = {0, 0}; 5147c478bd9Sstevel@tonic-gate char *emptystr = ""; 5157c478bd9Sstevel@tonic-gate char *myself = "addSplitFieldValues"; 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate if (trv == 0) 5187c478bd9Sstevel@tonic-gate return (MAP_INTERNAL_ERROR); 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate if (t->e == 0) 5217c478bd9Sstevel@tonic-gate return (SUCCESS); 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate nitems = t->e->element.match.numItems; 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate /* 5267c478bd9Sstevel@tonic-gate * Procedure: 5277c478bd9Sstevel@tonic-gate * - Check each name in nisLDAPnamefield 5287c478bd9Sstevel@tonic-gate * - if it's a splifield, construct its value and add it to trv 5297c478bd9Sstevel@tonic-gate * - if not, check if it has a value 5307c478bd9Sstevel@tonic-gate * - if not, add empty string 5317c478bd9Sstevel@tonic-gate */ 5327c478bd9Sstevel@tonic-gate for (i = 0, sf = 0; i < nitems; i++) { 5337c478bd9Sstevel@tonic-gate if (rv) { 5347c478bd9Sstevel@tonic-gate /* 5357c478bd9Sstevel@tonic-gate * str will eventually contain the single string 5367c478bd9Sstevel@tonic-gate * value for the corresponding splitfield. 5377c478bd9Sstevel@tonic-gate * No point initializing str if rv == 0 because 5387c478bd9Sstevel@tonic-gate * splitfield cannot be constructed without rv. 5397c478bd9Sstevel@tonic-gate * So, only initialized here. 5407c478bd9Sstevel@tonic-gate */ 5417c478bd9Sstevel@tonic-gate str = 0; 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate /* Check if it's a splitfield name */ 5447c478bd9Sstevel@tonic-gate sf = mappingFromMap(t->e->element.match.item[i].name, 5457c478bd9Sstevel@tonic-gate domain, &statP); 5467c478bd9Sstevel@tonic-gate 5477c478bd9Sstevel@tonic-gate /* 5487c478bd9Sstevel@tonic-gate * Return only incase of memory allocation failure. 5497c478bd9Sstevel@tonic-gate * The other error case (MAP_NO_MAPPING_EXISTS), 5507c478bd9Sstevel@tonic-gate * indicates that the item name is not a splitfieldname 5517c478bd9Sstevel@tonic-gate * i.e it's a namefieldname. This case is handled by 5527c478bd9Sstevel@tonic-gate * the following if (sf == 0) 5537c478bd9Sstevel@tonic-gate */ 5547c478bd9Sstevel@tonic-gate if (statP == MAP_NO_MEMORY) 5557c478bd9Sstevel@tonic-gate return (statP); 5567c478bd9Sstevel@tonic-gate } 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate if (sf == 0) { 5597c478bd9Sstevel@tonic-gate /* 5607c478bd9Sstevel@tonic-gate * Not a splitfield name. Verify if it has a value 5617c478bd9Sstevel@tonic-gate */ 5627c478bd9Sstevel@tonic-gate if (findVal(t->e->element.match.item[i].name, 5637c478bd9Sstevel@tonic-gate trv, mit_nisplus) == 0) { 5647c478bd9Sstevel@tonic-gate /* if not, use empty string */ 5657c478bd9Sstevel@tonic-gate res = addCol2RuleValue(vt_string, 5667c478bd9Sstevel@tonic-gate t->e->element.match.item[i].name, 5677c478bd9Sstevel@tonic-gate emptystr, 0, trv); 5687c478bd9Sstevel@tonic-gate if (res == -1) { 5697c478bd9Sstevel@tonic-gate return (MAP_INTERNAL_ERROR); 5707c478bd9Sstevel@tonic-gate } 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate /* 5737c478bd9Sstevel@tonic-gate * If rv == 0 then sf == 0 so we will continue here 5747c478bd9Sstevel@tonic-gate * i.e. does not matter that str is not yet set up. 5757c478bd9Sstevel@tonic-gate */ 5767c478bd9Sstevel@tonic-gate continue; 5777c478bd9Sstevel@tonic-gate } 5787c478bd9Sstevel@tonic-gate 5797c478bd9Sstevel@tonic-gate /* Code to construct a single value */ 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate /* Use the first separator character as the delimiter */ 5827c478bd9Sstevel@tonic-gate delim[0] = sf->separatorStr[0]; 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate for (j = 0; j < numVals; j++) { 5857c478bd9Sstevel@tonic-gate /* sf->numSplits is zero-based */ 5867c478bd9Sstevel@tonic-gate for (k = 0; k <= sf->numSplits; k++) { 5877c478bd9Sstevel@tonic-gate val = getMappingFormatArray( 5887c478bd9Sstevel@tonic-gate sf->e[k].element.match.fmt, &rv[j], 5897c478bd9Sstevel@tonic-gate fa_item, 5907c478bd9Sstevel@tonic-gate sf->e[k].element.match.numItems, 5917c478bd9Sstevel@tonic-gate sf->e[k].element.match.item); 5927c478bd9Sstevel@tonic-gate if (val == 0) 5937c478bd9Sstevel@tonic-gate continue; 5947c478bd9Sstevel@tonic-gate if (val->numVals > 0) { 5957c478bd9Sstevel@tonic-gate if (str) { 5967c478bd9Sstevel@tonic-gate tempstr = scat(myself, 5977c478bd9Sstevel@tonic-gate 0, str, delim); 5987c478bd9Sstevel@tonic-gate sfree(str); 5997c478bd9Sstevel@tonic-gate if (tempstr) 6007c478bd9Sstevel@tonic-gate str = tempstr; 6017c478bd9Sstevel@tonic-gate else { 6027c478bd9Sstevel@tonic-gate freeValue(val, 1); 6037c478bd9Sstevel@tonic-gate return (MAP_NO_MEMORY); 6047c478bd9Sstevel@tonic-gate } 6057c478bd9Sstevel@tonic-gate } 6067c478bd9Sstevel@tonic-gate tempstr = scat(myself, 0, str, 6077c478bd9Sstevel@tonic-gate val->val->value); 6087c478bd9Sstevel@tonic-gate sfree(str); 6097c478bd9Sstevel@tonic-gate if (tempstr) 6107c478bd9Sstevel@tonic-gate str = tempstr; 6117c478bd9Sstevel@tonic-gate else { 6127c478bd9Sstevel@tonic-gate freeValue(val, 1); 6137c478bd9Sstevel@tonic-gate return (MAP_NO_MEMORY); 6147c478bd9Sstevel@tonic-gate } 6157c478bd9Sstevel@tonic-gate } 6167c478bd9Sstevel@tonic-gate freeValue(val, 1); 6177c478bd9Sstevel@tonic-gate } 6187c478bd9Sstevel@tonic-gate } 6197c478bd9Sstevel@tonic-gate if (str == 0) 6207c478bd9Sstevel@tonic-gate str = emptystr; 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate res = addCol2RuleValue(vt_string, 6237c478bd9Sstevel@tonic-gate t->e->element.match.item[i].name, 6247c478bd9Sstevel@tonic-gate str, strlen(str), trv); 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate if (str != emptystr) 6277c478bd9Sstevel@tonic-gate sfree(str); 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate if (res == -1) { 6307c478bd9Sstevel@tonic-gate return (MAP_INTERNAL_ERROR); 6317c478bd9Sstevel@tonic-gate } 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate return (SUCCESS); 6357c478bd9Sstevel@tonic-gate } 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate /* 6387c478bd9Sstevel@tonic-gate * Updates 'rv' with NIS name=value pairs suitable to 6397c478bd9Sstevel@tonic-gate * construct datum from namefield information. 6407c478bd9Sstevel@tonic-gate * Some part based on createNisPlusEntry (from ldap_nisdbquery.c) 6417c478bd9Sstevel@tonic-gate * This code assumes that from a given LDAP entry, applying the 6427c478bd9Sstevel@tonic-gate * mapping rules, would give us one or more NIS entries, differing 6437c478bd9Sstevel@tonic-gate * only in key. 6447c478bd9Sstevel@tonic-gate */ 6457c478bd9Sstevel@tonic-gate suc_code 6467c478bd9Sstevel@tonic-gate buildNISRuleValue(__nis_table_mapping_t *t, __nis_rule_value_t *rv, 6477c478bd9Sstevel@tonic-gate char *domain) { 6487c478bd9Sstevel@tonic-gate int r, i, j, k, l, index, nrq, res, len; 6497c478bd9Sstevel@tonic-gate int numItems, splitname, count, statP; 6507c478bd9Sstevel@tonic-gate __nis_value_t *rval; 6517c478bd9Sstevel@tonic-gate __nis_mapping_item_t *litem; 6527c478bd9Sstevel@tonic-gate __nis_mapping_rule_t *rl; 6537c478bd9Sstevel@tonic-gate __nis_rule_value_t *rvq; 6547c478bd9Sstevel@tonic-gate char *value, *emptystr = ""; 6557c478bd9Sstevel@tonic-gate 6567c478bd9Sstevel@tonic-gate statP = SUCCESS; 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate /* Initialize default base */ 6597c478bd9Sstevel@tonic-gate __nisdb_get_tsd()->searchBase = t->objectDN->read.base; 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate /* Initialize rule-value rvq */ 6627c478bd9Sstevel@tonic-gate rvq = 0; 6637c478bd9Sstevel@tonic-gate count = 0; 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate /* Add domainname to rule-value */ 6667c478bd9Sstevel@tonic-gate if (addCol2RuleValue(vt_string, N2LDOMAIN, domain, strlen(domain), 6677c478bd9Sstevel@tonic-gate rv)) { 6687c478bd9Sstevel@tonic-gate return (MAP_INTERNAL_ERROR); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate for (r = 0; r < t->numRulesFromLDAP; r++) { 6727c478bd9Sstevel@tonic-gate rl = t->ruleFromLDAP[r]; 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate /* Set escapeFlag if RHS is "dn" to remove escape chars */ 6757c478bd9Sstevel@tonic-gate if (rl->rhs.numElements == 1 && 6767c478bd9Sstevel@tonic-gate rl->rhs.element->type == me_item && 6777c478bd9Sstevel@tonic-gate rl->rhs.element->element.item.type == mit_ldap && 6787c478bd9Sstevel@tonic-gate strcasecmp(rl->rhs.element->element.item.name, "dn") 6797c478bd9Sstevel@tonic-gate == 0) { 6807c478bd9Sstevel@tonic-gate __nisdb_get_tsd()->escapeFlag = '2'; 6817c478bd9Sstevel@tonic-gate } 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate rval = buildRvalue(&rl->rhs, mit_ldap, rv, NULL); 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate /* Reset escapeFlag */ 6867c478bd9Sstevel@tonic-gate __nisdb_get_tsd()->escapeFlag = '\0'; 6877c478bd9Sstevel@tonic-gate 6887c478bd9Sstevel@tonic-gate if (rval == 0) { 6897c478bd9Sstevel@tonic-gate continue; 6907c478bd9Sstevel@tonic-gate } 6917c478bd9Sstevel@tonic-gate 6927c478bd9Sstevel@tonic-gate if (rval->numVals <= 0) { 6937c478bd9Sstevel@tonic-gate /* Treat as invalid */ 6947c478bd9Sstevel@tonic-gate freeValue(rval, 1); 6957c478bd9Sstevel@tonic-gate continue; 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate litem = buildLvalue(&rl->lhs, &rval, &numItems); 6997c478bd9Sstevel@tonic-gate if (litem == 0) { 7007c478bd9Sstevel@tonic-gate /* This will take care of numItems == 0 */ 7017c478bd9Sstevel@tonic-gate freeValue(rval, 1); 7027c478bd9Sstevel@tonic-gate continue; 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate if (rval->numVals > 1) { 7067c478bd9Sstevel@tonic-gate if (numItems == 1 && litem->repeat) 7077c478bd9Sstevel@tonic-gate nrq = rval->numVals; 7087c478bd9Sstevel@tonic-gate else if (numItems > 1 && rval->repeat) 7097c478bd9Sstevel@tonic-gate nrq = 1 + ((rval->numVals-1)/numItems); 7107c478bd9Sstevel@tonic-gate else 7117c478bd9Sstevel@tonic-gate nrq = 1; 7127c478bd9Sstevel@tonic-gate } else 7137c478bd9Sstevel@tonic-gate nrq = 1; 7147c478bd9Sstevel@tonic-gate 7157c478bd9Sstevel@tonic-gate /* Set splitname if splitfield names are specified */ 7167c478bd9Sstevel@tonic-gate for (i = 0; i < numItems; i++) { 7177c478bd9Sstevel@tonic-gate if (strcasecmp(litem[i].name, N2LKEY) == 0 || 7187c478bd9Sstevel@tonic-gate strcasecmp(litem[i].name, N2LIPKEY) == 0 || 7197c478bd9Sstevel@tonic-gate strcasecmp(litem[i].name, N2LCOMMENT) == 0) 7207c478bd9Sstevel@tonic-gate continue; 7217c478bd9Sstevel@tonic-gate for (j = 0; j < t->numColumns; j++) { 7227c478bd9Sstevel@tonic-gate if (strcmp(litem[i].name, t->column[j]) == 0) 7237c478bd9Sstevel@tonic-gate break; 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate if (j == t->numColumns) 7267c478bd9Sstevel@tonic-gate break; 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate splitname = (i < numItems)?1:0; 7307c478bd9Sstevel@tonic-gate 7317c478bd9Sstevel@tonic-gate for (j = 0; j < nrq; j++) { 7327c478bd9Sstevel@tonic-gate if (splitname == 1) { 7337c478bd9Sstevel@tonic-gate /* 7347c478bd9Sstevel@tonic-gate * Put every value of splitfieldname in a new 7357c478bd9Sstevel@tonic-gate * rule-value. Helps generating splitfields. 7367c478bd9Sstevel@tonic-gate */ 7377c478bd9Sstevel@tonic-gate rvq = growRuleValue(count, count + 1, rvq, 0); 7387c478bd9Sstevel@tonic-gate if (rvq == 0) { 7397c478bd9Sstevel@tonic-gate freeRuleValue(rvq, count); 7407c478bd9Sstevel@tonic-gate freeValue(rval, 1); 7417c478bd9Sstevel@tonic-gate freeMappingItem(litem, numItems); 7427c478bd9Sstevel@tonic-gate return (MAP_INTERNAL_ERROR); 7437c478bd9Sstevel@tonic-gate } 7447c478bd9Sstevel@tonic-gate count++; 7457c478bd9Sstevel@tonic-gate } 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate for (k = j % nrq, l = 0; l < numItems; k += nrq, l++) { 7487c478bd9Sstevel@tonic-gate /* If we run out of values, use empty strings */ 7497c478bd9Sstevel@tonic-gate if (k >= rval->numVals) { 7507c478bd9Sstevel@tonic-gate value = emptystr; 7517c478bd9Sstevel@tonic-gate len = 0; 7527c478bd9Sstevel@tonic-gate } else { 7537c478bd9Sstevel@tonic-gate value = rval->val[k].value; 7547c478bd9Sstevel@tonic-gate len = rval->val[k].length; 7557c478bd9Sstevel@tonic-gate } 7567c478bd9Sstevel@tonic-gate res = (splitname == 1)?addCol2RuleValue( 7577c478bd9Sstevel@tonic-gate vt_string, litem[l].name, value, 7587c478bd9Sstevel@tonic-gate len, &rvq[count - 1]):0; 7597c478bd9Sstevel@tonic-gate if (res != -1) 7607c478bd9Sstevel@tonic-gate res = addCol2RuleValue(vt_string, 7617c478bd9Sstevel@tonic-gate litem[l].name, value, len, rv); 7627c478bd9Sstevel@tonic-gate if (res == -1) { 7637c478bd9Sstevel@tonic-gate freeRuleValue(rvq, count); 7647c478bd9Sstevel@tonic-gate freeValue(rval, 1); 7657c478bd9Sstevel@tonic-gate freeMappingItem(litem, numItems); 7667c478bd9Sstevel@tonic-gate return (MAP_INTERNAL_ERROR); 7677c478bd9Sstevel@tonic-gate } 7687c478bd9Sstevel@tonic-gate } 7697c478bd9Sstevel@tonic-gate } 7707c478bd9Sstevel@tonic-gate freeValue(rval, 1); 7717c478bd9Sstevel@tonic-gate rval = 0; 7727c478bd9Sstevel@tonic-gate freeMappingItem(litem, numItems); 7737c478bd9Sstevel@tonic-gate litem = 0; 7747c478bd9Sstevel@tonic-gate numItems = 0; 7757c478bd9Sstevel@tonic-gate } /* for r < t->numRulesFromLDAP */ 7767c478bd9Sstevel@tonic-gate 7777c478bd9Sstevel@tonic-gate statP = addSplitFieldValues(t, rvq, rv, count, domain); 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate if (rvq) 7807c478bd9Sstevel@tonic-gate freeRuleValue(rvq, count); 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate if (verifyIndexMatch(t, 0, rv, 0, 0) == 0) 7837c478bd9Sstevel@tonic-gate return (MAP_INDEXLIST_ERROR); 7847c478bd9Sstevel@tonic-gate return (statP); 7857c478bd9Sstevel@tonic-gate 7867c478bd9Sstevel@tonic-gate } /* end of buildNISRuleValue */ 7877c478bd9Sstevel@tonic-gate 7887c478bd9Sstevel@tonic-gate /* 7897c478bd9Sstevel@tonic-gate * Convert rule-value to datum using namefield information 7907c478bd9Sstevel@tonic-gate */ 7917c478bd9Sstevel@tonic-gate datum * 7927c478bd9Sstevel@tonic-gate ruleValueToDatum(__nis_table_mapping_t *t, __nis_rule_value_t *rv, int *statP) { 7937c478bd9Sstevel@tonic-gate __nis_value_t *val; 7947c478bd9Sstevel@tonic-gate datum *value; 7957c478bd9Sstevel@tonic-gate char *str, *cstr, commentSep[3] = {' ', 0, 0}; 7967c478bd9Sstevel@tonic-gate char *myself = "ruleValueToDatum"; 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate /* No error yet */ 7997c478bd9Sstevel@tonic-gate *statP = 0; 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate /* Return empty datum if no namefield information available */ 8027c478bd9Sstevel@tonic-gate if (t->e == 0) { 8037c478bd9Sstevel@tonic-gate if ((value = am(myself, sizeof (*value))) == 0) 8047c478bd9Sstevel@tonic-gate *statP = MAP_NO_MEMORY; 8057c478bd9Sstevel@tonic-gate return (value); 8067c478bd9Sstevel@tonic-gate } 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate val = getMappingFormatArray(t->e->element.match.fmt, rv, 8097c478bd9Sstevel@tonic-gate fa_item, t->e->element.match.numItems, 8107c478bd9Sstevel@tonic-gate t->e->element.match.item); 8117c478bd9Sstevel@tonic-gate 8127c478bd9Sstevel@tonic-gate if (val && val->val && val->val->value) { 8137c478bd9Sstevel@tonic-gate if ((value = am(myself, sizeof (*value))) == 0) { 8147c478bd9Sstevel@tonic-gate *statP = MAP_NO_MEMORY; 8157c478bd9Sstevel@tonic-gate freeValue(val, 1); 8167c478bd9Sstevel@tonic-gate return (0); 8177c478bd9Sstevel@tonic-gate } 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate /* Strip trailing whitespaces */ 8207c478bd9Sstevel@tonic-gate cstr = (char *)val->val->value + val->val->length; 8217c478bd9Sstevel@tonic-gate for (; cstr >= (char *)val->val->value && 8227c478bd9Sstevel@tonic-gate (*cstr == ' ' || *cstr == '\t'); *cstr-- = '\0'); 8237c478bd9Sstevel@tonic-gate 8247c478bd9Sstevel@tonic-gate if (t->commentChar != '\0' && 8257c478bd9Sstevel@tonic-gate (str = findVal(N2LCOMMENT, rv, mit_nisplus)) != 0 && 8267c478bd9Sstevel@tonic-gate *str != '\0') { 8277c478bd9Sstevel@tonic-gate commentSep[1] = t->commentChar; 8287c478bd9Sstevel@tonic-gate cstr = scat(myself, F, commentSep, str); 8297c478bd9Sstevel@tonic-gate if (cstr) { 8307c478bd9Sstevel@tonic-gate value->dptr = scat(myself, F, 8317c478bd9Sstevel@tonic-gate val->val->value, cstr); 8327c478bd9Sstevel@tonic-gate sfree(cstr); 8337c478bd9Sstevel@tonic-gate } 8347c478bd9Sstevel@tonic-gate } else { 8357c478bd9Sstevel@tonic-gate value->dptr = sdup(myself, T, val->val->value); 8367c478bd9Sstevel@tonic-gate } 8377c478bd9Sstevel@tonic-gate freeValue(val, 1); 8387c478bd9Sstevel@tonic-gate if (value->dptr) { 8397c478bd9Sstevel@tonic-gate value->dsize = strlen(value->dptr); 8407c478bd9Sstevel@tonic-gate return (value); 8417c478bd9Sstevel@tonic-gate } else { 8427c478bd9Sstevel@tonic-gate *statP = MAP_NO_MEMORY; 8437c478bd9Sstevel@tonic-gate sfree(value); 8447c478bd9Sstevel@tonic-gate return (0); 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate } 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate *statP = MAP_NAMEFIELD_MATCH_ERROR; 8497c478bd9Sstevel@tonic-gate return (0); 8507c478bd9Sstevel@tonic-gate } 8517c478bd9Sstevel@tonic-gate 8527c478bd9Sstevel@tonic-gate datum * 8537c478bd9Sstevel@tonic-gate getKeyFromRuleValue(__nis_table_mapping_t *t, __nis_rule_value_t *rv, int *nv, 854*ea10ff14SBen Chang int *statP, bool_t xlate_to_lcase) 855*ea10ff14SBen Chang { 856*ea10ff14SBen Chang int i, j, k; 8577c478bd9Sstevel@tonic-gate datum *key = 0; 8587c478bd9Sstevel@tonic-gate char *str; 8597c478bd9Sstevel@tonic-gate char *myself = "getKeyFromRuleValue"; 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate /* No error yet */ 8627c478bd9Sstevel@tonic-gate *statP = 0; 8637c478bd9Sstevel@tonic-gate 8647c478bd9Sstevel@tonic-gate if (rv == 0 || nv == 0) 8657c478bd9Sstevel@tonic-gate return (0); 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate for (i = 0; i < rv->numColumns; i++) { 8687c478bd9Sstevel@tonic-gate if (rv->colName[i] == 0) 8697c478bd9Sstevel@tonic-gate continue; 8707c478bd9Sstevel@tonic-gate if (strcasecmp(N2LKEY, rv->colName[i]) == 0 || 8717c478bd9Sstevel@tonic-gate strcasecmp(N2LIPKEY, rv->colName[i]) == 0) { 8727c478bd9Sstevel@tonic-gate if ((*nv = rv->colVal[i].numVals) == 0) 8737c478bd9Sstevel@tonic-gate return (0); 8747c478bd9Sstevel@tonic-gate if ((key = am(myself, sizeof (key[0]) * *nv)) == 0) { 8757c478bd9Sstevel@tonic-gate *statP = MAP_NO_MEMORY; 8767c478bd9Sstevel@tonic-gate return (0); 8777c478bd9Sstevel@tonic-gate } 8787c478bd9Sstevel@tonic-gate for (j = 0; j < *nv; j++) { 8797c478bd9Sstevel@tonic-gate if ((str = rv->colVal[i].val[j].value) == 0) { 8807c478bd9Sstevel@tonic-gate key[j].dsize = 0; 8817c478bd9Sstevel@tonic-gate key[j].dptr = 0; 8827c478bd9Sstevel@tonic-gate } else { 8837c478bd9Sstevel@tonic-gate if (verifyIndexMatch(t, 0, 0, 884*ea10ff14SBen Chang rv->colName[i], str) == 0) { 8857c478bd9Sstevel@tonic-gate key[j].dsize = 0; 8867c478bd9Sstevel@tonic-gate key[j].dptr = 0; 8877c478bd9Sstevel@tonic-gate continue; 8887c478bd9Sstevel@tonic-gate } 889*ea10ff14SBen Chang 8907c478bd9Sstevel@tonic-gate key[j].dsize = strlen(str); 8917c478bd9Sstevel@tonic-gate key[j].dptr = am(myself, 8927c478bd9Sstevel@tonic-gate key[j].dsize + 1); 8937c478bd9Sstevel@tonic-gate if (key[j].dptr == 0) { 8947c478bd9Sstevel@tonic-gate *statP = MAP_NO_MEMORY; 8957c478bd9Sstevel@tonic-gate for (--j; j >= 0; j--) 8967c478bd9Sstevel@tonic-gate sfree(key[j].dptr); 8977c478bd9Sstevel@tonic-gate sfree(key); 8987c478bd9Sstevel@tonic-gate return (0); 8997c478bd9Sstevel@tonic-gate } 900*ea10ff14SBen Chang 901*ea10ff14SBen Chang /* transliterate key to lowercase */ 902*ea10ff14SBen Chang if (xlate_to_lcase == TRUE) { 903*ea10ff14SBen Chang 904*ea10ff14SBen Chang /* 905*ea10ff14SBen Chang * For multi-homed 906*ea10ff14SBen Chang * entries, skip over 907*ea10ff14SBen Chang * "YP_MULTI_" prefix. 908*ea10ff14SBen Chang */ 909*ea10ff14SBen Chang k = 0; 910*ea10ff14SBen Chang if (strncmp(YPMULTI, str, 911*ea10ff14SBen Chang YPMULTISZ) == 0) { 912*ea10ff14SBen Chang k = YPMULTISZ; 913*ea10ff14SBen Chang bcopy(str, key[j].dptr, 914*ea10ff14SBen Chang YPMULTISZ); 915*ea10ff14SBen Chang } 916*ea10ff14SBen Chang while (k < key[j].dsize) { 917*ea10ff14SBen Chang key[j].dptr[k] = 918*ea10ff14SBen Chang (char)tolower( 919*ea10ff14SBen Chang (int)(uchar_t) 920*ea10ff14SBen Chang str[k]); 921*ea10ff14SBen Chang k++; 922*ea10ff14SBen Chang } 923*ea10ff14SBen Chang } else { 924*ea10ff14SBen Chang bcopy(str, key[j].dptr, 925*ea10ff14SBen Chang key[j].dsize); 926*ea10ff14SBen Chang } 9277c478bd9Sstevel@tonic-gate } 9287c478bd9Sstevel@tonic-gate } 9297c478bd9Sstevel@tonic-gate return (key); 9307c478bd9Sstevel@tonic-gate } 9317c478bd9Sstevel@tonic-gate } 9327c478bd9Sstevel@tonic-gate return (0); 9337c478bd9Sstevel@tonic-gate } 9347c478bd9Sstevel@tonic-gate 9357c478bd9Sstevel@tonic-gate /* 9367c478bd9Sstevel@tonic-gate * Get the mapping structure corresponding to `map,domain.' 9377c478bd9Sstevel@tonic-gate */ 9387c478bd9Sstevel@tonic-gate __nis_table_mapping_t * 9397c478bd9Sstevel@tonic-gate mappingFromMap(char *map, char *domain, int *statP) { 9407c478bd9Sstevel@tonic-gate char *mapPath; 9417c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t; 9427c478bd9Sstevel@tonic-gate 9437c478bd9Sstevel@tonic-gate /* No error yet */ 9447c478bd9Sstevel@tonic-gate *statP = 0; 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate /* Construct map,domain. */ 9477c478bd9Sstevel@tonic-gate if ((mapPath = getFullMapName(map, domain)) == 0) { 9487c478bd9Sstevel@tonic-gate *statP = MAP_NO_MEMORY; 9497c478bd9Sstevel@tonic-gate return (0); 9507c478bd9Sstevel@tonic-gate } 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate /* Get the hash table entry for the mapPath */ 9537c478bd9Sstevel@tonic-gate if ((t = __nis_find_item_mt(mapPath, &ldapMappingList, 1, 0)) 9547c478bd9Sstevel@tonic-gate == 0) { 9557c478bd9Sstevel@tonic-gate *statP = MAP_NO_MAPPING_EXISTS; 9567c478bd9Sstevel@tonic-gate } 9577c478bd9Sstevel@tonic-gate sfree(mapPath); 9587c478bd9Sstevel@tonic-gate return (t); 9597c478bd9Sstevel@tonic-gate } 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate /* 9627c478bd9Sstevel@tonic-gate * Verify at least one key value obtained from DIT matches the search key 9637c478bd9Sstevel@tonic-gate * RETURNS: 1 MATCH 9647c478bd9Sstevel@tonic-gate * 0 NO MATCH 9657c478bd9Sstevel@tonic-gate * -1 NO KEY FOUND 9667c478bd9Sstevel@tonic-gate */ 9677c478bd9Sstevel@tonic-gate static int 9687c478bd9Sstevel@tonic-gate verifyKey(char *key, __nis_rule_value_t *rv) { 9697c478bd9Sstevel@tonic-gate int i, j; 9707c478bd9Sstevel@tonic-gate char *sipkey, *str; 9717c478bd9Sstevel@tonic-gate 9727c478bd9Sstevel@tonic-gate for (i = 0; i < rv->numColumns; i++) { 9737c478bd9Sstevel@tonic-gate if (rv->colName[i] == 0) 9747c478bd9Sstevel@tonic-gate continue; 9757c478bd9Sstevel@tonic-gate if (strcasecmp(N2LKEY, rv->colName[i]) == 0) { 9767c478bd9Sstevel@tonic-gate if (rv->colVal[i].val == 0) 9777c478bd9Sstevel@tonic-gate return (0); 9787c478bd9Sstevel@tonic-gate for (j = 0; j < rv->colVal[i].numVals; j++) { 9797c478bd9Sstevel@tonic-gate str = (char *)rv->colVal[i].val[j].value; 9807c478bd9Sstevel@tonic-gate if (str && strcmp(str, key) == 0) 9817c478bd9Sstevel@tonic-gate return (1); 9827c478bd9Sstevel@tonic-gate } 9837c478bd9Sstevel@tonic-gate return (0); 9847c478bd9Sstevel@tonic-gate } else if (strcasecmp(N2LIPKEY, rv->colName[i]) == 0) { 9857c478bd9Sstevel@tonic-gate if (checkIPaddress(key, strlen(key), &sipkey) > 0) { 9867c478bd9Sstevel@tonic-gate if (rv->colVal[i].val == 0) 9877c478bd9Sstevel@tonic-gate return (0); 9887c478bd9Sstevel@tonic-gate for (j = 0; j < rv->colVal[i].numVals; j++) { 9897c478bd9Sstevel@tonic-gate str = rv->colVal[i].val[j].value; 9907c478bd9Sstevel@tonic-gate if (str && strcmp(str, sipkey) == 0) { 9917c478bd9Sstevel@tonic-gate sfree(sipkey); 9927c478bd9Sstevel@tonic-gate return (1); 9937c478bd9Sstevel@tonic-gate } 9947c478bd9Sstevel@tonic-gate } 9957c478bd9Sstevel@tonic-gate sfree(sipkey); 9967c478bd9Sstevel@tonic-gate } 9977c478bd9Sstevel@tonic-gate return (0); 9987c478bd9Sstevel@tonic-gate } 9997c478bd9Sstevel@tonic-gate } 10007c478bd9Sstevel@tonic-gate return (-1); 10017c478bd9Sstevel@tonic-gate } 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate /* 10047c478bd9Sstevel@tonic-gate * Read (i.e get and map) a single NIS entry from the LDAP DIT 10057c478bd9Sstevel@tonic-gate */ 10067c478bd9Sstevel@tonic-gate bool_t 10077c478bd9Sstevel@tonic-gate singleReadFromDIT(char *map, char *domain, datum *key, datum *value, 10087c478bd9Sstevel@tonic-gate int *statP) { 10097c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t; 10107c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv_request = 0, *rv_result = 0; 10117c478bd9Sstevel@tonic-gate __nis_ldap_search_t *ls; 10127c478bd9Sstevel@tonic-gate __nis_object_dn_t *objectDN = NULL; 10137c478bd9Sstevel@tonic-gate int i, rc, nr = 0, nv = 0; 10147c478bd9Sstevel@tonic-gate datum *datval = 0; 10157c478bd9Sstevel@tonic-gate char *skey, *str, *sipkey; 10167c478bd9Sstevel@tonic-gate char *myself = "singleReadFromDIT"; 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate *statP = SUCCESS; 10197c478bd9Sstevel@tonic-gate 10207c478bd9Sstevel@tonic-gate if (!map || !domain || !key || !value) { 10217c478bd9Sstevel@tonic-gate *statP = MAP_PARAM_ERROR; 10227c478bd9Sstevel@tonic-gate return (FALSE); 10237c478bd9Sstevel@tonic-gate } 10247c478bd9Sstevel@tonic-gate 10257c478bd9Sstevel@tonic-gate 10267c478bd9Sstevel@tonic-gate /* Get the mapping information for the map */ 10277c478bd9Sstevel@tonic-gate if ((t = mappingFromMap(map, domain, statP)) == 0) { 10287c478bd9Sstevel@tonic-gate /* 10297c478bd9Sstevel@tonic-gate * No problem. We don't handle this map and domain. Maybe it's 10307c478bd9Sstevel@tonic-gate * handled by a service other than NIS. 10317c478bd9Sstevel@tonic-gate */ 10327c478bd9Sstevel@tonic-gate return (FALSE); 10337c478bd9Sstevel@tonic-gate } 10347c478bd9Sstevel@tonic-gate 10357c478bd9Sstevel@tonic-gate /* NULL-terminated version of datum key for logging */ 10367c478bd9Sstevel@tonic-gate if ((skey = am(myself, key->dsize + 1)) == 0) { 10377c478bd9Sstevel@tonic-gate *statP = MAP_NO_MEMORY; 10387c478bd9Sstevel@tonic-gate return (FALSE); 10397c478bd9Sstevel@tonic-gate } 10407c478bd9Sstevel@tonic-gate (void) memcpy(skey, key->dptr, key->dsize); 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate if ((str = getFullMapName(map, domain)) == 0) { 10437c478bd9Sstevel@tonic-gate *statP = MAP_NO_MEMORY; 10447c478bd9Sstevel@tonic-gate return (FALSE); 10457c478bd9Sstevel@tonic-gate } 10467c478bd9Sstevel@tonic-gate 10477c478bd9Sstevel@tonic-gate /* For each alternate mapping */ 10487c478bd9Sstevel@tonic-gate for (; t != 0; t = t->next) { 10497c478bd9Sstevel@tonic-gate /* Verify objName */ 10507c478bd9Sstevel@tonic-gate if (strcmp(str, t->objName) != 0) { 10517c478bd9Sstevel@tonic-gate continue; 10527c478bd9Sstevel@tonic-gate } 10537c478bd9Sstevel@tonic-gate 10547c478bd9Sstevel@tonic-gate /* Verify if key matches the index */ 10557c478bd9Sstevel@tonic-gate if (verifyIndexMatch(t, 0, 0, N2LKEY, skey) == 0 || 10567c478bd9Sstevel@tonic-gate verifyIndexMatch(t, 0, 0, N2LIPKEY, skey) == 0) 10577c478bd9Sstevel@tonic-gate continue; 10587c478bd9Sstevel@tonic-gate 10597c478bd9Sstevel@tonic-gate /* Check if rulesFromLDAP are provided */ 10607c478bd9Sstevel@tonic-gate if (t->numRulesFromLDAP == 0) { 10617c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_INFO, 10627c478bd9Sstevel@tonic-gate "%s: No rulesFromLDAP information available " 10637c478bd9Sstevel@tonic-gate "for %s (%s)", myself, t->dbId, map); 10647c478bd9Sstevel@tonic-gate continue; 10657c478bd9Sstevel@tonic-gate } 10667c478bd9Sstevel@tonic-gate 10677c478bd9Sstevel@tonic-gate /* Convert key into rule-value */ 10687c478bd9Sstevel@tonic-gate if ((rv_request = datumToRuleValue(key, 0, t, 0, domain, TRUE, 10697c478bd9Sstevel@tonic-gate statP)) == 0) { 10707c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 10717c478bd9Sstevel@tonic-gate "%s: Conversion error %d (NIS to name=value " 10727c478bd9Sstevel@tonic-gate "pairs) for NIS key (%s) for %s (%s)", 10737c478bd9Sstevel@tonic-gate myself, *statP, skey, t->dbId, map); 10747c478bd9Sstevel@tonic-gate continue; 10757c478bd9Sstevel@tonic-gate } 10767c478bd9Sstevel@tonic-gate /* Convert rule-value into ldap request */ 10777c478bd9Sstevel@tonic-gate for (objectDN = t->objectDN; objectDN && 10787c478bd9Sstevel@tonic-gate objectDN->read.base; 10797c478bd9Sstevel@tonic-gate objectDN = objectDN->next) { 10807c478bd9Sstevel@tonic-gate ls = createLdapRequest(t, rv_request, 0, 1, NULL, 10817c478bd9Sstevel@tonic-gate objectDN); 10827c478bd9Sstevel@tonic-gate if (ls == 0) { 10837c478bd9Sstevel@tonic-gate *statP = MAP_CREATE_LDAP_REQUEST_ERROR; 10847c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 10857c478bd9Sstevel@tonic-gate "%s: Failed to create ldapSearch " 10867c478bd9Sstevel@tonic-gate "request for " 10877c478bd9Sstevel@tonic-gate "NIS key (%s) for %s (%s) " 10887c478bd9Sstevel@tonic-gate "for base %s", 10897c478bd9Sstevel@tonic-gate myself, skey, t->dbId, map, 10907c478bd9Sstevel@tonic-gate objectDN->read.base); 10917c478bd9Sstevel@tonic-gate continue; 10927c478bd9Sstevel@tonic-gate } 10937c478bd9Sstevel@tonic-gate ls->timeout.tv_sec = SINGLE_ACCESS_TIMEOUT_SEC; 10947c478bd9Sstevel@tonic-gate ls->timeout.tv_usec = SINGLE_ACCESS_TIMEOUT_USEC; 10957c478bd9Sstevel@tonic-gate /* Query LDAP */ 10967c478bd9Sstevel@tonic-gate nr = (ls->isDN)?0:-1; 10977c478bd9Sstevel@tonic-gate rv_result = ldapSearch(ls, &nr, 0, statP); 10987c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 10997c478bd9Sstevel@tonic-gate if (rv_result == 0) { 11007c478bd9Sstevel@tonic-gate if (*statP == LDAP_NO_SUCH_OBJECT) { 11017c478bd9Sstevel@tonic-gate /* Entry does not exist in */ 11027c478bd9Sstevel@tonic-gate /* the ldap server */ 11037c478bd9Sstevel@tonic-gate } 11047c478bd9Sstevel@tonic-gate continue; 11057c478bd9Sstevel@tonic-gate } 11067c478bd9Sstevel@tonic-gate freeRuleValue(rv_request, 1); 11077c478bd9Sstevel@tonic-gate rv_request = 0; 11087c478bd9Sstevel@tonic-gate 11097c478bd9Sstevel@tonic-gate /* if result > 1, first match will be returned */ 11107c478bd9Sstevel@tonic-gate if (nr > 1) { 11117c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_INFO, 11127c478bd9Sstevel@tonic-gate "%s: %d ldapSearch results " 11137c478bd9Sstevel@tonic-gate "for NIS key (%s) " 11147c478bd9Sstevel@tonic-gate "for %s (%s) for base %s. " 11157c478bd9Sstevel@tonic-gate "First match will be returned ", 11167c478bd9Sstevel@tonic-gate myself, nr, skey, t->dbId, map, 11177c478bd9Sstevel@tonic-gate objectDN->read.base); 11187c478bd9Sstevel@tonic-gate } 11197c478bd9Sstevel@tonic-gate 11207c478bd9Sstevel@tonic-gate for (i = 0; i < nr; i++) { 11217c478bd9Sstevel@tonic-gate /* Convert LDAP data to NIS equivalents */ 11227c478bd9Sstevel@tonic-gate *statP = buildNISRuleValue(t, &rv_result[i], 11237c478bd9Sstevel@tonic-gate domain); 11247c478bd9Sstevel@tonic-gate if (*statP == MAP_INDEXLIST_ERROR) 11257c478bd9Sstevel@tonic-gate continue; 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate if (*statP != SUCCESS) { 11287c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 11297c478bd9Sstevel@tonic-gate "%s: Conversion error %d (LDAP to " 11307c478bd9Sstevel@tonic-gate "name=value pairs) for NIS key (%s) " 11317c478bd9Sstevel@tonic-gate "for %s (%s) for base %s", myself, 11327c478bd9Sstevel@tonic-gate *statP, skey, 11337c478bd9Sstevel@tonic-gate t->dbId, map, objectDN->read.base); 11347c478bd9Sstevel@tonic-gate continue; 11357c478bd9Sstevel@tonic-gate } 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate /* 11387c478bd9Sstevel@tonic-gate * Check if 'key' from the ldap result matches the key 11397c478bd9Sstevel@tonic-gate * provided by our caller 11407c478bd9Sstevel@tonic-gate */ 11417c478bd9Sstevel@tonic-gate if ((rc = verifyKey(skey, &rv_result[i])) 11427c478bd9Sstevel@tonic-gate == -1) { 11437c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_INFO, 11447c478bd9Sstevel@tonic-gate "%s: Cannot verify key from ldap " 11457c478bd9Sstevel@tonic-gate "result for NIS key (%s) for %s (%s) " 11467c478bd9Sstevel@tonic-gate "for base %s", 11477c478bd9Sstevel@tonic-gate myself, skey, t->dbId, map, 11487c478bd9Sstevel@tonic-gate objectDN->read.base); 11497c478bd9Sstevel@tonic-gate continue; 11507c478bd9Sstevel@tonic-gate } 11517c478bd9Sstevel@tonic-gate 11527c478bd9Sstevel@tonic-gate if (rc == 1) { 11537c478bd9Sstevel@tonic-gate datval = ruleValueToDatum(t, 11547c478bd9Sstevel@tonic-gate &rv_result[i], statP); 11557c478bd9Sstevel@tonic-gate if (datval == 0) { 11567c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 11577c478bd9Sstevel@tonic-gate LOG_WARNING, 11587c478bd9Sstevel@tonic-gate "%s: Conversion error %d " 11597c478bd9Sstevel@tonic-gate "(name=value pairs to NIS) " 11607c478bd9Sstevel@tonic-gate "for NIS key (%s) for %s (%s)" 11617c478bd9Sstevel@tonic-gate " for base %s", 11627c478bd9Sstevel@tonic-gate myself, 11637c478bd9Sstevel@tonic-gate *statP, skey, t->dbId, map, 11647c478bd9Sstevel@tonic-gate objectDN->read.base); 11657c478bd9Sstevel@tonic-gate continue; 11667c478bd9Sstevel@tonic-gate } 11677c478bd9Sstevel@tonic-gate if (value) { 11687c478bd9Sstevel@tonic-gate value->dptr = datval->dptr; 11697c478bd9Sstevel@tonic-gate value->dsize = datval->dsize; 11707c478bd9Sstevel@tonic-gate } 11717c478bd9Sstevel@tonic-gate sfree(datval); 11727c478bd9Sstevel@tonic-gate sfree(skey); 11737c478bd9Sstevel@tonic-gate freeRuleValue(rv_result, nr); 11747c478bd9Sstevel@tonic-gate rv_result = 0; 11757c478bd9Sstevel@tonic-gate *statP = SUCCESS; 11767c478bd9Sstevel@tonic-gate 11777c478bd9Sstevel@tonic-gate /* Free full map name */ 11787c478bd9Sstevel@tonic-gate sfree(str); 11797c478bd9Sstevel@tonic-gate 11807c478bd9Sstevel@tonic-gate return (TRUE); 11817c478bd9Sstevel@tonic-gate } 11827c478bd9Sstevel@tonic-gate } 11837c478bd9Sstevel@tonic-gate freeRuleValue(rv_result, nr); 11847c478bd9Sstevel@tonic-gate rv_result = 0; 11857c478bd9Sstevel@tonic-gate } /* end of for over objectDN */ 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate if (rv_request != 0) { 11887c478bd9Sstevel@tonic-gate freeRuleValue(rv_request, 1); 11897c478bd9Sstevel@tonic-gate rv_request = 0; 11907c478bd9Sstevel@tonic-gate } 11917c478bd9Sstevel@tonic-gate if (rv_result != 0) { 11927c478bd9Sstevel@tonic-gate freeRuleValue(rv_result, nr); 11937c478bd9Sstevel@tonic-gate rv_result = 0; 11947c478bd9Sstevel@tonic-gate } 11957c478bd9Sstevel@tonic-gate } 11967c478bd9Sstevel@tonic-gate sfree(skey); 11977c478bd9Sstevel@tonic-gate *statP = MAP_NO_MATCHING_KEY; 11987c478bd9Sstevel@tonic-gate 11997c478bd9Sstevel@tonic-gate /* Free full map name */ 12007c478bd9Sstevel@tonic-gate sfree(str); 12017c478bd9Sstevel@tonic-gate 12027c478bd9Sstevel@tonic-gate return (FALSE); 12037c478bd9Sstevel@tonic-gate } 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate 12067c478bd9Sstevel@tonic-gate /* 12077c478bd9Sstevel@tonic-gate * Maps and writes a single NIS entry to the LDAP DIT 12087c478bd9Sstevel@tonic-gate */ 12097c478bd9Sstevel@tonic-gate int 12107c478bd9Sstevel@tonic-gate singleWriteToDIT(char *map, char *domain, datum *key, datum *value, 12117c478bd9Sstevel@tonic-gate bool_t replace) { 12127c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t; 12137c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv, *frv; 12147c478bd9Sstevel@tonic-gate __nis_ldap_search_t *ls; 12157c478bd9Sstevel@tonic-gate int statP = SUCCESS, flag; 12167c478bd9Sstevel@tonic-gate int nv, nr, i, rc, collapse; 12177c478bd9Sstevel@tonic-gate char *dn = 0, *skey, *svalue, *str; 12187c478bd9Sstevel@tonic-gate char *myself = "singleWriteToDIT"; 12197c478bd9Sstevel@tonic-gate 12207c478bd9Sstevel@tonic-gate if (!map || !domain || !key || !value) { 12217c478bd9Sstevel@tonic-gate return (MAP_PARAM_ERROR); 12227c478bd9Sstevel@tonic-gate } 12237c478bd9Sstevel@tonic-gate 12247c478bd9Sstevel@tonic-gate /* Return SUCCESS for empty or whitespace key */ 12257c478bd9Sstevel@tonic-gate for (i = 0; i < key->dsize && (key->dptr[i] == 0 || 12267c478bd9Sstevel@tonic-gate key->dptr[i] == ' ' || key->dptr[i] == '\t'); i++); 12277c478bd9Sstevel@tonic-gate if (i >= key->dsize) 12287c478bd9Sstevel@tonic-gate return (SUCCESS); 12297c478bd9Sstevel@tonic-gate 12307c478bd9Sstevel@tonic-gate /* Get the mapping information for the map */ 12317c478bd9Sstevel@tonic-gate if ((t = mappingFromMap(map, domain, &statP)) == 0) { 12327c478bd9Sstevel@tonic-gate /* 12337c478bd9Sstevel@tonic-gate * No problem. We don't handle this map and domain. Maybe it's 12347c478bd9Sstevel@tonic-gate * handled by a service other than NIS. 12357c478bd9Sstevel@tonic-gate */ 12367c478bd9Sstevel@tonic-gate return (statP); 12377c478bd9Sstevel@tonic-gate } 12387c478bd9Sstevel@tonic-gate 12397c478bd9Sstevel@tonic-gate /* NULL-terminated version of key and value for logging */ 12407c478bd9Sstevel@tonic-gate if ((skey = am(myself, key->dsize + 1)) == 0) 12417c478bd9Sstevel@tonic-gate return (MAP_NO_MEMORY); 12427c478bd9Sstevel@tonic-gate (void) memcpy(skey, key->dptr, key->dsize); 12437c478bd9Sstevel@tonic-gate 12447c478bd9Sstevel@tonic-gate if ((svalue = am(myself, value->dsize + 1)) == 0) { 12457c478bd9Sstevel@tonic-gate sfree(skey); 12467c478bd9Sstevel@tonic-gate return (MAP_NO_MEMORY); 12477c478bd9Sstevel@tonic-gate } 12487c478bd9Sstevel@tonic-gate (void) memcpy(svalue, value->dptr, value->dsize); 12497c478bd9Sstevel@tonic-gate 12507c478bd9Sstevel@tonic-gate if ((str = getFullMapName(map, domain)) == 0) { 12517c478bd9Sstevel@tonic-gate sfree(skey); 12527c478bd9Sstevel@tonic-gate sfree(svalue); 12537c478bd9Sstevel@tonic-gate return (MAP_NO_MEMORY); 12547c478bd9Sstevel@tonic-gate } 12557c478bd9Sstevel@tonic-gate 12567c478bd9Sstevel@tonic-gate /* For each alternate mapping */ 12577c478bd9Sstevel@tonic-gate for (flag = 0; t != 0; t = t->next) { 12587c478bd9Sstevel@tonic-gate /* Verify objName */ 12597c478bd9Sstevel@tonic-gate if (strcmp(str, t->objName) != 0) { 12607c478bd9Sstevel@tonic-gate continue; 12617c478bd9Sstevel@tonic-gate } 12627c478bd9Sstevel@tonic-gate 12637c478bd9Sstevel@tonic-gate /* Verify if key matches the index */ 12647c478bd9Sstevel@tonic-gate if (verifyIndexMatch(t, 0, 0, N2LKEY, skey) == 0 || 12657c478bd9Sstevel@tonic-gate verifyIndexMatch(t, 0, 0, N2LIPKEY, skey) == 0) 12667c478bd9Sstevel@tonic-gate continue; 12677c478bd9Sstevel@tonic-gate 12687c478bd9Sstevel@tonic-gate /* Check the writespecs */ 12697c478bd9Sstevel@tonic-gate if (t->objectDN->write.base == 0) { 12707c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_INFO, 12717c478bd9Sstevel@tonic-gate "%s: No baseDN in writespec. Write disabled " 12727c478bd9Sstevel@tonic-gate "for %s (%s)", myself, t->dbId, map); 12737c478bd9Sstevel@tonic-gate continue; 12747c478bd9Sstevel@tonic-gate } 12757c478bd9Sstevel@tonic-gate 12767c478bd9Sstevel@tonic-gate /* Check if rulesToLDAP are provided */ 12777c478bd9Sstevel@tonic-gate if (t->numRulesToLDAP == 0) { 12787c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_INFO, 12797c478bd9Sstevel@tonic-gate "%s: No rulesToLDAP. Write disabled for " 12807c478bd9Sstevel@tonic-gate "%s (%s)", myself, t->dbId, map); 12817c478bd9Sstevel@tonic-gate continue; 12827c478bd9Sstevel@tonic-gate } 12837c478bd9Sstevel@tonic-gate 12847c478bd9Sstevel@tonic-gate /* Set flag to indicate write is enabled */ 12857c478bd9Sstevel@tonic-gate flag = 1; 12867c478bd9Sstevel@tonic-gate 12877c478bd9Sstevel@tonic-gate /* Convert key and value into an array of rule-values */ 12887c478bd9Sstevel@tonic-gate if ((rv = datumToRuleValue(key, value, t, &nv, domain, FALSE, 12897c478bd9Sstevel@tonic-gate &statP)) == 0) { 12907c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 12917c478bd9Sstevel@tonic-gate "%s: Conversion error %d (NIS to name=value " 12927c478bd9Sstevel@tonic-gate "pairs) for NIS data (key=%s, value=%s) " 12937c478bd9Sstevel@tonic-gate "for %s (%s)", 12947c478bd9Sstevel@tonic-gate myself, statP, skey, svalue, t->dbId, map); 12957c478bd9Sstevel@tonic-gate sfree(skey); 12967c478bd9Sstevel@tonic-gate sfree(svalue); 12977c478bd9Sstevel@tonic-gate 12987c478bd9Sstevel@tonic-gate /* Free full map name */ 12997c478bd9Sstevel@tonic-gate sfree(str); 13007c478bd9Sstevel@tonic-gate 13017c478bd9Sstevel@tonic-gate return (statP); 13027c478bd9Sstevel@tonic-gate } 13037c478bd9Sstevel@tonic-gate 13047c478bd9Sstevel@tonic-gate /* Convert NIS data to LDAP equivalents for each rule-value */ 13057c478bd9Sstevel@tonic-gate for (i = 0; i < nv; i++) { 13067c478bd9Sstevel@tonic-gate /* Verify indexlist with name=value pairs */ 13077c478bd9Sstevel@tonic-gate if (verifyIndexMatch(t, 0, &rv[i], 0, 0) == 0) 13087c478bd9Sstevel@tonic-gate break; 13097c478bd9Sstevel@tonic-gate 13107c478bd9Sstevel@tonic-gate /* Create LDAP request and LDAP name=value pairs */ 13117c478bd9Sstevel@tonic-gate if ((ls = createLdapRequest(t, &rv[i], 13127c478bd9Sstevel@tonic-gate 0, 0, NULL, NULL)) == 0) { 13137c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 13147c478bd9Sstevel@tonic-gate "%s: Conversion error (name=value pairs" 13157c478bd9Sstevel@tonic-gate " to LDAP) for NIS data " 13167c478bd9Sstevel@tonic-gate "(key=%s, value=%s) for %s (%s)", 13177c478bd9Sstevel@tonic-gate myself, skey, svalue, t->dbId, map); 13187c478bd9Sstevel@tonic-gate freeRuleValue(rv, nv); 13197c478bd9Sstevel@tonic-gate sfree(skey); 13207c478bd9Sstevel@tonic-gate sfree(svalue); 13217c478bd9Sstevel@tonic-gate 13227c478bd9Sstevel@tonic-gate /* Free full map name */ 13237c478bd9Sstevel@tonic-gate sfree(str); 13247c478bd9Sstevel@tonic-gate 13257c478bd9Sstevel@tonic-gate return (MAP_CREATE_LDAP_REQUEST_ERROR); 13267c478bd9Sstevel@tonic-gate } 13277c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 13287c478bd9Sstevel@tonic-gate /* printRuleValue(&rv[i]); */ 13297c478bd9Sstevel@tonic-gate } 13307c478bd9Sstevel@tonic-gate 13317c478bd9Sstevel@tonic-gate /* If i < nv then this alternate mapping isn't the one */ 13327c478bd9Sstevel@tonic-gate if (i < nv) 13337c478bd9Sstevel@tonic-gate continue; 13347c478bd9Sstevel@tonic-gate 13357c478bd9Sstevel@tonic-gate /* 13367c478bd9Sstevel@tonic-gate * Merge rule-values with the same DN so that we have 13377c478bd9Sstevel@tonic-gate * one ldap write request for each DN 13387c478bd9Sstevel@tonic-gate */ 13397c478bd9Sstevel@tonic-gate nr = nv; 13407c478bd9Sstevel@tonic-gate frv = mergeRuleValueWithSameDN(rv, &nr); 13417c478bd9Sstevel@tonic-gate freeRuleValue(rv, nv); 13427c478bd9Sstevel@tonic-gate if (frv == 0) { 13437c478bd9Sstevel@tonic-gate if (nr == -1) { 13447c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 13457c478bd9Sstevel@tonic-gate "%s: Unable to merge LDAP write " 13467c478bd9Sstevel@tonic-gate "requests to same DN for NIS data " 13477c478bd9Sstevel@tonic-gate "(key=%s, value=%s) for %s (%s)", 13487c478bd9Sstevel@tonic-gate myself, skey, svalue, t->dbId, map); 13497c478bd9Sstevel@tonic-gate statP = MAP_INTERNAL_ERROR; 13507c478bd9Sstevel@tonic-gate } else if (nr == 0) { 13517c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 13527c478bd9Sstevel@tonic-gate "%s: Cannot generate write DN due to " 13537c478bd9Sstevel@tonic-gate "missing information for NIS data " 13547c478bd9Sstevel@tonic-gate "(key=%s, value=%s) for %s (%s)", 13557c478bd9Sstevel@tonic-gate myself, skey, svalue, t->dbId, map); 13567c478bd9Sstevel@tonic-gate statP = MAP_NO_DN; 13577c478bd9Sstevel@tonic-gate } 13587c478bd9Sstevel@tonic-gate sfree(skey); 13597c478bd9Sstevel@tonic-gate sfree(svalue); 13607c478bd9Sstevel@tonic-gate 13617c478bd9Sstevel@tonic-gate /* Free full map name */ 13627c478bd9Sstevel@tonic-gate sfree(str); 13637c478bd9Sstevel@tonic-gate 13647c478bd9Sstevel@tonic-gate return (statP); 13657c478bd9Sstevel@tonic-gate } 13667c478bd9Sstevel@tonic-gate 13677c478bd9Sstevel@tonic-gate /* Write to the LDAP server */ 13687c478bd9Sstevel@tonic-gate for (collapse = 0, i = 0; i < nr; i++) { 13697c478bd9Sstevel@tonic-gate if ((dn = findVal("dn", &frv[i], mit_ldap)) != 0) { 13707c478bd9Sstevel@tonic-gate if (replace == FALSE) { 13717c478bd9Sstevel@tonic-gate /* ldap add */ 13727c478bd9Sstevel@tonic-gate rc = ldapAdd(dn, &frv[i], 13737c478bd9Sstevel@tonic-gate t->objectDN->write.attrs, 0); 13747c478bd9Sstevel@tonic-gate } else { 13757c478bd9Sstevel@tonic-gate /* ldap modify with addFirst set */ 13767c478bd9Sstevel@tonic-gate rc = ldapModify(dn, &frv[i], 13777c478bd9Sstevel@tonic-gate t->objectDN->write.attrs, 1); 13787c478bd9Sstevel@tonic-gate } 13797c478bd9Sstevel@tonic-gate 13807c478bd9Sstevel@tonic-gate /* if we get err=20, collapse and try again */ 13817c478bd9Sstevel@tonic-gate if (!collapse && 13827c478bd9Sstevel@tonic-gate (rc == LDAP_TYPE_OR_VALUE_EXISTS) && 13837c478bd9Sstevel@tonic-gate (collapseRuleValue(&frv[i]) == 1)) { 13847c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 13857c478bd9Sstevel@tonic-gate "%s: Ignoring values differing " 13867c478bd9Sstevel@tonic-gate "in case from NIS data (key=%s," 13877c478bd9Sstevel@tonic-gate " value=%s) for (dn: %s) for " 13887c478bd9Sstevel@tonic-gate "%s (%s)", myself, skey, 13897c478bd9Sstevel@tonic-gate svalue, dn, t->dbId, map); 13907c478bd9Sstevel@tonic-gate collapse = 1; 13917c478bd9Sstevel@tonic-gate i--; 13927c478bd9Sstevel@tonic-gate continue; 13937c478bd9Sstevel@tonic-gate } 13947c478bd9Sstevel@tonic-gate 13957c478bd9Sstevel@tonic-gate collapse = 0; 13967c478bd9Sstevel@tonic-gate if (rc != LDAP_SUCCESS) { 13977c478bd9Sstevel@tonic-gate /* Log error */ 13987c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 13997c478bd9Sstevel@tonic-gate "%s: %s error %d (%s) for " 14007c478bd9Sstevel@tonic-gate "(dn: %s) for NIS data " 14017c478bd9Sstevel@tonic-gate "(key=%s, value=%s) " 14027c478bd9Sstevel@tonic-gate "for %s (%s)", 14037c478bd9Sstevel@tonic-gate myself, (replace == TRUE) ? 14047c478bd9Sstevel@tonic-gate "ldapModify" : "ldapAdd", rc, 14057c478bd9Sstevel@tonic-gate ldap_err2string(rc), dn, skey, 14067c478bd9Sstevel@tonic-gate svalue, t->dbId, map); 14077c478bd9Sstevel@tonic-gate 14087c478bd9Sstevel@tonic-gate /* Dumping failed call may be useful */ 14097c478bd9Sstevel@tonic-gate /* printRuleValue(&frv[i]); */ 14107c478bd9Sstevel@tonic-gate 14117c478bd9Sstevel@tonic-gate /* 14127c478bd9Sstevel@tonic-gate * Return the error code and let wrapper 14137c478bd9Sstevel@tonic-gate * sort out if mapping should continue 14147c478bd9Sstevel@tonic-gate * or abort. 14157c478bd9Sstevel@tonic-gate */ 14167c478bd9Sstevel@tonic-gate statP = rc; 14177c478bd9Sstevel@tonic-gate sfree(skey); 14187c478bd9Sstevel@tonic-gate sfree(svalue); 14197c478bd9Sstevel@tonic-gate freeRuleValue(frv, nr); 14207c478bd9Sstevel@tonic-gate 14217c478bd9Sstevel@tonic-gate /* Free full map name */ 14227c478bd9Sstevel@tonic-gate sfree(str); 14237c478bd9Sstevel@tonic-gate 14247c478bd9Sstevel@tonic-gate return (statP); 14257c478bd9Sstevel@tonic-gate } 14267c478bd9Sstevel@tonic-gate } 14277c478bd9Sstevel@tonic-gate } 14287c478bd9Sstevel@tonic-gate 14297c478bd9Sstevel@tonic-gate freeRuleValue(frv, nr); 14307c478bd9Sstevel@tonic-gate } 14317c478bd9Sstevel@tonic-gate 14327c478bd9Sstevel@tonic-gate sfree(skey); 14337c478bd9Sstevel@tonic-gate sfree(svalue); 14347c478bd9Sstevel@tonic-gate 14357c478bd9Sstevel@tonic-gate /* Free full map name */ 14367c478bd9Sstevel@tonic-gate sfree(str); 14377c478bd9Sstevel@tonic-gate 14387c478bd9Sstevel@tonic-gate return ((flag)?SUCCESS:MAP_WRITE_DISABLED); 14397c478bd9Sstevel@tonic-gate } 14407c478bd9Sstevel@tonic-gate 14417c478bd9Sstevel@tonic-gate suc_code 14427c478bd9Sstevel@tonic-gate collapseRuleValue(__nis_rule_value_t *rv) { 14437c478bd9Sstevel@tonic-gate int i, j, k, flag; 14447c478bd9Sstevel@tonic-gate 14457c478bd9Sstevel@tonic-gate /* Using 'val' to appease cstyle's 80 chars/line limit */ 14467c478bd9Sstevel@tonic-gate __nis_value_t *val; 14477c478bd9Sstevel@tonic-gate 14487c478bd9Sstevel@tonic-gate for (i = 0, flag = 0; i < rv->numAttrs; i++) { 14497c478bd9Sstevel@tonic-gate val = &rv->attrVal[i]; 14507c478bd9Sstevel@tonic-gate for (j = 1; j < val->numVals; j++) { 14517c478bd9Sstevel@tonic-gate for (k = 0; k < j; k++) { 14527c478bd9Sstevel@tonic-gate if (val->val[j].length != val->val[k].length) 14537c478bd9Sstevel@tonic-gate continue; 14547c478bd9Sstevel@tonic-gate if (val->val[k].length == 0) 14557c478bd9Sstevel@tonic-gate continue; 14567c478bd9Sstevel@tonic-gate if (strncasecmp(val->val[j].value, 14577c478bd9Sstevel@tonic-gate val->val[k].value, 14587c478bd9Sstevel@tonic-gate val->val[j].length) != 0) 14597c478bd9Sstevel@tonic-gate continue; 14607c478bd9Sstevel@tonic-gate flag = 1; 14617c478bd9Sstevel@tonic-gate sfree(val->val[j].value); 14627c478bd9Sstevel@tonic-gate 14637c478bd9Sstevel@tonic-gate #ifdef ORDER_NOT_IMPORTANT 14647c478bd9Sstevel@tonic-gate val->val[j--] = val->val[--val->numVals]; 14657c478bd9Sstevel@tonic-gate #else 14667c478bd9Sstevel@tonic-gate /* Order needs to be maintained */ 14677c478bd9Sstevel@tonic-gate for (k = j + 1; k < val->numVals; k++) 14687c478bd9Sstevel@tonic-gate val->val[k - 1] = val->val[k]; 14697c478bd9Sstevel@tonic-gate j--; 14707c478bd9Sstevel@tonic-gate val->numVals--; 14717c478bd9Sstevel@tonic-gate #endif 14727c478bd9Sstevel@tonic-gate break; 14737c478bd9Sstevel@tonic-gate } 14747c478bd9Sstevel@tonic-gate } 14757c478bd9Sstevel@tonic-gate } 14767c478bd9Sstevel@tonic-gate return (flag); 14777c478bd9Sstevel@tonic-gate } 14787c478bd9Sstevel@tonic-gate 14797c478bd9Sstevel@tonic-gate /* ObjectClass lookup table */ 14807c478bd9Sstevel@tonic-gate static struct { 14817c478bd9Sstevel@tonic-gate const char *attrType; 14827c478bd9Sstevel@tonic-gate const char *objectClass; 14837c478bd9Sstevel@tonic-gate } oc_lookup[] = { 14847c478bd9Sstevel@tonic-gate { "o", "objectclass=organization"}, 14857c478bd9Sstevel@tonic-gate { "organizationname", "objectclass=organization"}, 14867c478bd9Sstevel@tonic-gate { "2.5.4.10", "objectclass=organization"}, 14877c478bd9Sstevel@tonic-gate { "ou", "objectclass=organizationalunit"}, 14887c478bd9Sstevel@tonic-gate { "organizationalunitname", "objectclass=organizationalunit"}, 14897c478bd9Sstevel@tonic-gate { "2.5.4.11", "objectclass=organizationalunit"}, 14907c478bd9Sstevel@tonic-gate { "c", "objectclass=country"}, 14917c478bd9Sstevel@tonic-gate { "countryname", "objectclass=country"}, 14927c478bd9Sstevel@tonic-gate { "2.5.4.6", "objectclass=country"}, 14937c478bd9Sstevel@tonic-gate { "dc", "objectclass=domain"}, 14947c478bd9Sstevel@tonic-gate { "domaincomponent", "objectclass=domain"}, 14957c478bd9Sstevel@tonic-gate { "0.9.2342.19200300.100.1.25", "objectclass=domain"}, 14967c478bd9Sstevel@tonic-gate { "nismapname", "objectclass=nismap"}, 14977c478bd9Sstevel@tonic-gate { "1.3.6.1.1.1.1.26", "objectclass=nismap"}, 14987c478bd9Sstevel@tonic-gate { "automountmapname", "objectclass=automountmap"}, 14997c478bd9Sstevel@tonic-gate { "1.3.6.1.1.1.1.31", "objectclass=automountmap"}, 15007c478bd9Sstevel@tonic-gate { 0, 0} 15017c478bd9Sstevel@tonic-gate }; 15027c478bd9Sstevel@tonic-gate 15037c478bd9Sstevel@tonic-gate /* 15047c478bd9Sstevel@tonic-gate * Returns the name of the objectclass to which the object 15057c478bd9Sstevel@tonic-gate * represented by the given 'rdn' will most likely belong to. 15067c478bd9Sstevel@tonic-gate * The return value is in static memory so it should not be 15077c478bd9Sstevel@tonic-gate * freed 15087c478bd9Sstevel@tonic-gate */ 15097c478bd9Sstevel@tonic-gate const char * 15107c478bd9Sstevel@tonic-gate getObjectClass(char *rdn) { 15117c478bd9Sstevel@tonic-gate 15127c478bd9Sstevel@tonic-gate char *attrtype, *p; 15137c478bd9Sstevel@tonic-gate int len, i; 15147c478bd9Sstevel@tonic-gate 15157c478bd9Sstevel@tonic-gate /* Skip leading whitespaces */ 15167c478bd9Sstevel@tonic-gate for (p = rdn; *p == ' ' || *p == '\t'; p++); 15177c478bd9Sstevel@tonic-gate if (*p == '\0') 15187c478bd9Sstevel@tonic-gate return (0); 15197c478bd9Sstevel@tonic-gate attrtype = p; 15207c478bd9Sstevel@tonic-gate 15217c478bd9Sstevel@tonic-gate /* Find '=' */ 15227c478bd9Sstevel@tonic-gate if ((p = strchr(attrtype, '=')) == 0 || p == attrtype || 15237c478bd9Sstevel@tonic-gate *(p - 1) == '\\') 15247c478bd9Sstevel@tonic-gate return (0); 15257c478bd9Sstevel@tonic-gate 15267c478bd9Sstevel@tonic-gate /* 15277c478bd9Sstevel@tonic-gate * Skip trailing whitespaces in attrtype 15287c478bd9Sstevel@tonic-gate * Don't worry, p won't decrease beyond attrtype 15297c478bd9Sstevel@tonic-gate */ 15307c478bd9Sstevel@tonic-gate for (--p; *p == ' ' || *p == '\t'; p--); 15317c478bd9Sstevel@tonic-gate len = p - attrtype + 1; 15327c478bd9Sstevel@tonic-gate 15337c478bd9Sstevel@tonic-gate for (i = 0; oc_lookup[i].attrType; i++) 15347c478bd9Sstevel@tonic-gate if (!strncasecmp(oc_lookup[i].attrType, attrtype, len)) 15357c478bd9Sstevel@tonic-gate /* Check length is right */ 15367c478bd9Sstevel@tonic-gate if (len == strlen(oc_lookup[i].attrType)) 15377c478bd9Sstevel@tonic-gate return (oc_lookup[i].objectClass); 15387c478bd9Sstevel@tonic-gate 15397c478bd9Sstevel@tonic-gate return (0); 15407c478bd9Sstevel@tonic-gate } 15417c478bd9Sstevel@tonic-gate 15427c478bd9Sstevel@tonic-gate /* 15437c478bd9Sstevel@tonic-gate * Split 'dn' into rdn and parentdn based on the first 15447c478bd9Sstevel@tonic-gate * occurrence of unescaped 'comma' or 'semicolon'. rdn 15457c478bd9Sstevel@tonic-gate * lies on the LHS while parentdn lies on the RHS of the 15467c478bd9Sstevel@tonic-gate * split. If none found, then an empty string ("") is 15477c478bd9Sstevel@tonic-gate * assigned to parentdn 15487c478bd9Sstevel@tonic-gate */ 15497c478bd9Sstevel@tonic-gate int 15507c478bd9Sstevel@tonic-gate splitDN(char *dn, char **rdn, char **parentdn) { 15517c478bd9Sstevel@tonic-gate char *value, *name; 15527c478bd9Sstevel@tonic-gate char *myself = "splitDN"; 15537c478bd9Sstevel@tonic-gate 15547c478bd9Sstevel@tonic-gate if ((name = sdup(myself, T, dn)) == 0) 15557c478bd9Sstevel@tonic-gate return (-1); 15567c478bd9Sstevel@tonic-gate 15577c478bd9Sstevel@tonic-gate for (value = name; *value != '\0'; value++) { 15587c478bd9Sstevel@tonic-gate if (*value == ',' || *value == ';') 15597c478bd9Sstevel@tonic-gate if (value == name || *(value - 1) != '\\') 15607c478bd9Sstevel@tonic-gate break; 15617c478bd9Sstevel@tonic-gate } 15627c478bd9Sstevel@tonic-gate 15637c478bd9Sstevel@tonic-gate if (*value != '\0') { 15647c478bd9Sstevel@tonic-gate *value = '\0'; 15657c478bd9Sstevel@tonic-gate value++; 15667c478bd9Sstevel@tonic-gate } else 15677c478bd9Sstevel@tonic-gate value = 0; 15687c478bd9Sstevel@tonic-gate 15697c478bd9Sstevel@tonic-gate if (parentdn) { 15707c478bd9Sstevel@tonic-gate if ((*parentdn = sdup(myself, T, value)) == 0) { 15717c478bd9Sstevel@tonic-gate sfree(name); 15727c478bd9Sstevel@tonic-gate return (-1); 15737c478bd9Sstevel@tonic-gate } 15747c478bd9Sstevel@tonic-gate } 15757c478bd9Sstevel@tonic-gate if (rdn) 15767c478bd9Sstevel@tonic-gate *rdn = name; 15777c478bd9Sstevel@tonic-gate else 15787c478bd9Sstevel@tonic-gate sfree(name); 15797c478bd9Sstevel@tonic-gate 15807c478bd9Sstevel@tonic-gate return (1); 15817c478bd9Sstevel@tonic-gate } 15827c478bd9Sstevel@tonic-gate 15837c478bd9Sstevel@tonic-gate /* 15847c478bd9Sstevel@tonic-gate * FUNCTION : makeNISObject() 15857c478bd9Sstevel@tonic-gate * 15867c478bd9Sstevel@tonic-gate * DESCRIPTION: Sets up a nis Object in the DIT. 15877c478bd9Sstevel@tonic-gate * 15887c478bd9Sstevel@tonic-gate * GIVEN : 15897c478bd9Sstevel@tonic-gate * Case 1: Both 'domain' and 'dn' are non-NULL 15907c478bd9Sstevel@tonic-gate * Create nisDomainObject with the given information 15917c478bd9Sstevel@tonic-gate * Case 2: Only 'domain' is non-NULL 15927c478bd9Sstevel@tonic-gate * Obtain the 'dn' from the nisLDAPdomainContext list 15937c478bd9Sstevel@tonic-gate * Create nisDomainObject with the above information 15947c478bd9Sstevel@tonic-gate * Case 3: Only 'dn' is non-NULL 15957c478bd9Sstevel@tonic-gate * Create an object with the 'dn' 15967c478bd9Sstevel@tonic-gate * Here we guess the objectclass attribute, based on 15977c478bd9Sstevel@tonic-gate * oc_lookup table 15987c478bd9Sstevel@tonic-gate * Case 4: Both 'domain' and 'dn' are NULL 15997c478bd9Sstevel@tonic-gate * Error 16007c478bd9Sstevel@tonic-gate * 16017c478bd9Sstevel@tonic-gate * RETURNS : SUCCESS = It worked 16027c478bd9Sstevel@tonic-gate * FAILURE = There was a problem. 16037c478bd9Sstevel@tonic-gate */ 16047c478bd9Sstevel@tonic-gate suc_code 16057c478bd9Sstevel@tonic-gate makeNISObject(char *domain, char *dn) { 16067c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv; 16077c478bd9Sstevel@tonic-gate __nis_ldap_search_t *ls; 16087c478bd9Sstevel@tonic-gate int i, rc, nr, add_rc; 16097c478bd9Sstevel@tonic-gate char *val; 16107c478bd9Sstevel@tonic-gate char *myself = "makeNISObject"; 16117c478bd9Sstevel@tonic-gate 16127c478bd9Sstevel@tonic-gate if (!dn && !domain) 16137c478bd9Sstevel@tonic-gate return (FAILURE); 16147c478bd9Sstevel@tonic-gate 16157c478bd9Sstevel@tonic-gate /* 16167c478bd9Sstevel@tonic-gate * If only 'domain' name is provided, then 16177c478bd9Sstevel@tonic-gate * try to find dn from the nisLDAPdomainContext 16187c478bd9Sstevel@tonic-gate * list generated by the parser 16197c478bd9Sstevel@tonic-gate */ 16207c478bd9Sstevel@tonic-gate if (!dn) { 16217c478bd9Sstevel@tonic-gate for (i = 0; i < ypDomains.numDomains; i++) { 16227c478bd9Sstevel@tonic-gate if (ypDomains.domainLabels[i] == 0) 16237c478bd9Sstevel@tonic-gate continue; 16247c478bd9Sstevel@tonic-gate if (strcasecmp(domain, ypDomains.domainLabels[i]) 16257c478bd9Sstevel@tonic-gate == 0) { 16267c478bd9Sstevel@tonic-gate dn = ypDomains.domains[i]; 16277c478bd9Sstevel@tonic-gate break; 16287c478bd9Sstevel@tonic-gate } 16297c478bd9Sstevel@tonic-gate } 16307c478bd9Sstevel@tonic-gate if (!dn) 16317c478bd9Sstevel@tonic-gate return (FAILURE); 16327c478bd9Sstevel@tonic-gate } 16337c478bd9Sstevel@tonic-gate 16347c478bd9Sstevel@tonic-gate /* 16357c478bd9Sstevel@tonic-gate * If only 'dn' is given, then it means that the 16367c478bd9Sstevel@tonic-gate * caller simply wants to a create an entry for 16377c478bd9Sstevel@tonic-gate * that 'dn'. 16387c478bd9Sstevel@tonic-gate * 16397c478bd9Sstevel@tonic-gate * If 'domain' is given, then check if the 'dn' 16407c478bd9Sstevel@tonic-gate * has already been set up as a nis domain object. 16417c478bd9Sstevel@tonic-gate * If not, see if we can make it become one. 16427c478bd9Sstevel@tonic-gate */ 16437c478bd9Sstevel@tonic-gate if (domain) { 16447c478bd9Sstevel@tonic-gate /* 16457c478bd9Sstevel@tonic-gate * Check to see if the nis domain object has 16467c478bd9Sstevel@tonic-gate * already been set up 16477c478bd9Sstevel@tonic-gate */ 16487c478bd9Sstevel@tonic-gate ls = buildLdapSearch(dn, LDAP_SCOPE_BASE, 0, 0, 16497c478bd9Sstevel@tonic-gate "objectclass=*", 0, 0, 0); 16507c478bd9Sstevel@tonic-gate if (ls == 0) { 16517c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 16527c478bd9Sstevel@tonic-gate "%s: Unable to create ldapSearch " 16537c478bd9Sstevel@tonic-gate "request for dn: %s", myself, dn); 16547c478bd9Sstevel@tonic-gate return (FAILURE); 16557c478bd9Sstevel@tonic-gate } 16567c478bd9Sstevel@tonic-gate nr = -1; 16577c478bd9Sstevel@tonic-gate rv = ldapSearch(ls, &nr, 0, &rc); 16587c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 16597c478bd9Sstevel@tonic-gate if (rc == LDAP_SUCCESS) { 16607c478bd9Sstevel@tonic-gate val = findVal("nisDomain", rv, mit_ldap); 16617c478bd9Sstevel@tonic-gate if (val != NULL) { 16627c478bd9Sstevel@tonic-gate /* 16637c478bd9Sstevel@tonic-gate * Yes, nis domain object found. Check 16647c478bd9Sstevel@tonic-gate * to see if the domain names match. 16657c478bd9Sstevel@tonic-gate * If so, we are done. If not, log 16667c478bd9Sstevel@tonic-gate * a warning message, and return SUCCESS. 16677c478bd9Sstevel@tonic-gate */ 16687c478bd9Sstevel@tonic-gate if (strcasecmp(val, domain) == 0) { 16697c478bd9Sstevel@tonic-gate freeRuleValue(rv, nr); 16707c478bd9Sstevel@tonic-gate return (SUCCESS); 16717c478bd9Sstevel@tonic-gate } else { 16727c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 16737c478bd9Sstevel@tonic-gate LOG_WARNING, 16747c478bd9Sstevel@tonic-gate "%s: Entry (dn: %s) already " 16757c478bd9Sstevel@tonic-gate "contains a nis domain name " 16767c478bd9Sstevel@tonic-gate "(%s). The domain name (%s) " 16777c478bd9Sstevel@tonic-gate "is not added.", 16787c478bd9Sstevel@tonic-gate myself, dn, val, domain); 16797c478bd9Sstevel@tonic-gate freeRuleValue(rv, nr); 16807c478bd9Sstevel@tonic-gate return (SUCCESS); 16817c478bd9Sstevel@tonic-gate } 16827c478bd9Sstevel@tonic-gate } else { 16837c478bd9Sstevel@tonic-gate freeRuleValue(rv, nr); 16847c478bd9Sstevel@tonic-gate /* 16857c478bd9Sstevel@tonic-gate * Entry for the 'dn' exists, but it 16867c478bd9Sstevel@tonic-gate * is not a nis domain object yet. 16877c478bd9Sstevel@tonic-gate * Add the nisDoamin attribute and 16887c478bd9Sstevel@tonic-gate * the nisDomainObject objectclass to 16897c478bd9Sstevel@tonic-gate * the entry. 16907c478bd9Sstevel@tonic-gate */ 16917c478bd9Sstevel@tonic-gate if ((rv = initRuleValue(1, 0)) == 0) 16927c478bd9Sstevel@tonic-gate return (FAILURE); 16937c478bd9Sstevel@tonic-gate 16947c478bd9Sstevel@tonic-gate if (addSAttr2RuleValue("nisDomain", 16957c478bd9Sstevel@tonic-gate domain, rv) == -1) { 16967c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 16977c478bd9Sstevel@tonic-gate return (FAILURE); 16987c478bd9Sstevel@tonic-gate } 16997c478bd9Sstevel@tonic-gate rc = ldapModify(dn, rv, 17007c478bd9Sstevel@tonic-gate "objectclass=nisDomainObject", 17017c478bd9Sstevel@tonic-gate 0); 17027c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 17037c478bd9Sstevel@tonic-gate if (rc == LDAP_SUCCESS) { 17047c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 17057c478bd9Sstevel@tonic-gate LOG_INFO, 17067c478bd9Sstevel@tonic-gate "%s: entry (dn: %s) " 17077c478bd9Sstevel@tonic-gate "modified to be an " 17087c478bd9Sstevel@tonic-gate "nis domain object", 17097c478bd9Sstevel@tonic-gate myself, dn); 17107c478bd9Sstevel@tonic-gate return (SUCCESS); 17117c478bd9Sstevel@tonic-gate } else { 17127c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 17137c478bd9Sstevel@tonic-gate LOG_ERR, 17147c478bd9Sstevel@tonic-gate "%s: unable to modify " 17157c478bd9Sstevel@tonic-gate "entry (dn: %s) to be " 17167c478bd9Sstevel@tonic-gate "a nis domain object: " 17177c478bd9Sstevel@tonic-gate "ldapModify error %d (%s)", 17187c478bd9Sstevel@tonic-gate myself, dn, rc, 17197c478bd9Sstevel@tonic-gate ldap_err2string(rc)); 17207c478bd9Sstevel@tonic-gate return (FAILURE); 17217c478bd9Sstevel@tonic-gate } 17227c478bd9Sstevel@tonic-gate } 17237c478bd9Sstevel@tonic-gate } else { /* search for 'dn' failed */ 17247c478bd9Sstevel@tonic-gate freeRuleValue(rv, nr); 17257c478bd9Sstevel@tonic-gate 17267c478bd9Sstevel@tonic-gate /* 17277c478bd9Sstevel@tonic-gate * It is OK if no such object, otherwise 17287c478bd9Sstevel@tonic-gate * log an error. 17297c478bd9Sstevel@tonic-gate */ 17307c478bd9Sstevel@tonic-gate if (rc != LDAP_NO_SUCH_OBJECT) { 17317c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 17327c478bd9Sstevel@tonic-gate "%s: unable to retrieve " 17337c478bd9Sstevel@tonic-gate "entry (dn: %s): " 17347c478bd9Sstevel@tonic-gate "ldapSearch error %d (%s)", 17357c478bd9Sstevel@tonic-gate myself, dn, rc, 17367c478bd9Sstevel@tonic-gate ldap_err2string(rc)); 17377c478bd9Sstevel@tonic-gate return (FAILURE); 17387c478bd9Sstevel@tonic-gate } 17397c478bd9Sstevel@tonic-gate } 17407c478bd9Sstevel@tonic-gate 17417c478bd9Sstevel@tonic-gate /* 17427c478bd9Sstevel@tonic-gate * If the 'dn' is actually the naming context of 17437c478bd9Sstevel@tonic-gate * the DIT, we should be able to make it a nis domain 17447c478bd9Sstevel@tonic-gate * object without worrying about missing parent 17457c478bd9Sstevel@tonic-gate * entries. If unable to add the entry for the 'dn' 17467c478bd9Sstevel@tonic-gate * due to missing parent entries, fall through 17477c478bd9Sstevel@tonic-gate * to create them and then add the nis domain object. 17487c478bd9Sstevel@tonic-gate */ 17497c478bd9Sstevel@tonic-gate if (addNISObject(domain, dn, &add_rc) == SUCCESS) 17507c478bd9Sstevel@tonic-gate return (SUCCESS); 17517c478bd9Sstevel@tonic-gate else if (add_rc != LDAP_NO_SUCH_OBJECT) 17527c478bd9Sstevel@tonic-gate return (FAILURE); 17537c478bd9Sstevel@tonic-gate } 17547c478bd9Sstevel@tonic-gate 17557c478bd9Sstevel@tonic-gate /* Create parent */ 17567c478bd9Sstevel@tonic-gate if (addParent(dn, NULL) == FAILURE) 17577c478bd9Sstevel@tonic-gate return (FAILURE); 17587c478bd9Sstevel@tonic-gate 17597c478bd9Sstevel@tonic-gate if (addNISObject(domain, dn, NULL) == FAILURE) 17607c478bd9Sstevel@tonic-gate return (FAILURE); 17617c478bd9Sstevel@tonic-gate 17627c478bd9Sstevel@tonic-gate return (SUCCESS); 17637c478bd9Sstevel@tonic-gate } 17647c478bd9Sstevel@tonic-gate 17657c478bd9Sstevel@tonic-gate suc_code 17667c478bd9Sstevel@tonic-gate addParent(char *dn, char **attr) { 17677c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv; 17687c478bd9Sstevel@tonic-gate __nis_ldap_search_t *ls; 17697c478bd9Sstevel@tonic-gate int rc, nr; 17707c478bd9Sstevel@tonic-gate char *parentdn = 0, *rdn = 0; 17717c478bd9Sstevel@tonic-gate char *myself = "addParent"; 17727c478bd9Sstevel@tonic-gate 17737c478bd9Sstevel@tonic-gate /* Obtain parentdn */ 17747c478bd9Sstevel@tonic-gate if (splitDN(dn, &rdn, &parentdn) == -1) 17757c478bd9Sstevel@tonic-gate return (FAILURE); 17767c478bd9Sstevel@tonic-gate if (!parentdn) { 17777c478bd9Sstevel@tonic-gate sfree(rdn); 17787c478bd9Sstevel@tonic-gate return (FAILURE); 17797c478bd9Sstevel@tonic-gate } 17807c478bd9Sstevel@tonic-gate 17817c478bd9Sstevel@tonic-gate /* Check if parentdn exists */ 17827c478bd9Sstevel@tonic-gate ls = buildLdapSearch(parentdn, LDAP_SCOPE_BASE, 0, 0, 17837c478bd9Sstevel@tonic-gate "objectclass=*", 0, 0, 0); 17847c478bd9Sstevel@tonic-gate if (ls == 0) { 17857c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 17867c478bd9Sstevel@tonic-gate "%s: Unable to create ldapSearch request for " 17877c478bd9Sstevel@tonic-gate "parent (dn: %s) of (dn: %s)", 17887c478bd9Sstevel@tonic-gate myself, parentdn, dn); 17897c478bd9Sstevel@tonic-gate sfree(parentdn); 17907c478bd9Sstevel@tonic-gate sfree(rdn); 17917c478bd9Sstevel@tonic-gate return (FAILURE); 17927c478bd9Sstevel@tonic-gate } 17937c478bd9Sstevel@tonic-gate nr = -1; 17947c478bd9Sstevel@tonic-gate rv = ldapSearch(ls, &nr, 0, &rc); 17957c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 17967c478bd9Sstevel@tonic-gate freeRuleValue(rv, nr); 17977c478bd9Sstevel@tonic-gate 17987c478bd9Sstevel@tonic-gate /* Create parent if it doesn't exists */ 17997c478bd9Sstevel@tonic-gate if (rc == LDAP_NO_SUCH_OBJECT) { 18007c478bd9Sstevel@tonic-gate if (makeNISObject(0, parentdn) == FAILURE) { 18017c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 18027c478bd9Sstevel@tonic-gate "%s: Unable to create parent (dn: %s) of " 18037c478bd9Sstevel@tonic-gate "(dn: %s) in the DIT", myself, parentdn, dn); 18047c478bd9Sstevel@tonic-gate sfree(parentdn); 18057c478bd9Sstevel@tonic-gate sfree(rdn); 18067c478bd9Sstevel@tonic-gate return (FAILURE); 18077c478bd9Sstevel@tonic-gate } 18087c478bd9Sstevel@tonic-gate } 18097c478bd9Sstevel@tonic-gate sfree(parentdn); 18107c478bd9Sstevel@tonic-gate 18117c478bd9Sstevel@tonic-gate if (attr && rdn) 18127c478bd9Sstevel@tonic-gate *attr = (char *)getObjectClass(rdn); 18137c478bd9Sstevel@tonic-gate sfree(rdn); 18147c478bd9Sstevel@tonic-gate 18157c478bd9Sstevel@tonic-gate return (SUCCESS); 18167c478bd9Sstevel@tonic-gate } 18177c478bd9Sstevel@tonic-gate 18187c478bd9Sstevel@tonic-gate 18197c478bd9Sstevel@tonic-gate 18207c478bd9Sstevel@tonic-gate /* 18217c478bd9Sstevel@tonic-gate * FUNCTION : is_fatal_error() 18227c478bd9Sstevel@tonic-gate * 18237c478bd9Sstevel@tonic-gate * DESCRIPTION: Works out if a failed mapping operation should be retried. 18247c478bd9Sstevel@tonic-gate * 18257c478bd9Sstevel@tonic-gate * INPUTS : Result code from operation 18267c478bd9Sstevel@tonic-gate * 18277c478bd9Sstevel@tonic-gate * OUTPUTS : TRUE = Fatal error, don't retry. 18287c478bd9Sstevel@tonic-gate * FALSE = Temporary error, retry. 18297c478bd9Sstevel@tonic-gate */ 18307c478bd9Sstevel@tonic-gate bool_t 18317c478bd9Sstevel@tonic-gate is_fatal_error(int res) 18327c478bd9Sstevel@tonic-gate { 18337c478bd9Sstevel@tonic-gate 18347c478bd9Sstevel@tonic-gate if (0 > res) 18357c478bd9Sstevel@tonic-gate /* An internal mapping error. Not going to go away. */ 18367c478bd9Sstevel@tonic-gate return (TRUE); 18377c478bd9Sstevel@tonic-gate 18387c478bd9Sstevel@tonic-gate switch (res) { 18397c478bd9Sstevel@tonic-gate case (LDAP_PROTOCOL_ERROR): 18407c478bd9Sstevel@tonic-gate case (LDAP_TIMELIMIT_EXCEEDED): 18417c478bd9Sstevel@tonic-gate case (LDAP_PARTIAL_RESULTS): 18427c478bd9Sstevel@tonic-gate case (LDAP_BUSY): 18437c478bd9Sstevel@tonic-gate case (LDAP_UNAVAILABLE): 18447c478bd9Sstevel@tonic-gate case (LDAP_UNWILLING_TO_PERFORM): 18457c478bd9Sstevel@tonic-gate case (LDAP_OTHER): 18467c478bd9Sstevel@tonic-gate case (LDAP_SERVER_DOWN): 18477c478bd9Sstevel@tonic-gate case (LDAP_LOCAL_ERROR): 18487c478bd9Sstevel@tonic-gate case (LDAP_TIMEOUT): 18497c478bd9Sstevel@tonic-gate case (LDAP_NO_MEMORY): 18507c478bd9Sstevel@tonic-gate /* Probably worth a retry */ 18517c478bd9Sstevel@tonic-gate return (FALSE); 18527c478bd9Sstevel@tonic-gate 18537c478bd9Sstevel@tonic-gate default: 18547c478bd9Sstevel@tonic-gate return (TRUE); 18557c478bd9Sstevel@tonic-gate } 18567c478bd9Sstevel@tonic-gate } 18577c478bd9Sstevel@tonic-gate 18587c478bd9Sstevel@tonic-gate /* 18597c478bd9Sstevel@tonic-gate * FUNCTION : addNISObject() 18607c478bd9Sstevel@tonic-gate * 18617c478bd9Sstevel@tonic-gate * DESCRIPTION: Add a nis Object in the DIT. 18627c478bd9Sstevel@tonic-gate * 18637c478bd9Sstevel@tonic-gate * GIVEN : 18647c478bd9Sstevel@tonic-gate * Case 1: 'dn' is NULL 18657c478bd9Sstevel@tonic-gate * Error 18667c478bd9Sstevel@tonic-gate * Case 2: 'domain' is non-NULL 18677c478bd9Sstevel@tonic-gate * Create nisDomainObject with the given information 18687c478bd9Sstevel@tonic-gate * Case 3: 'domain' is NULL 18697c478bd9Sstevel@tonic-gate * Create an object with the 'dn' 18707c478bd9Sstevel@tonic-gate * Here we guess the objectclass attribute, based on 18717c478bd9Sstevel@tonic-gate * oc_lookup table 18727c478bd9Sstevel@tonic-gate * 18737c478bd9Sstevel@tonic-gate * RETURNS : SUCCESS = It worked 18747c478bd9Sstevel@tonic-gate * FAILURE = There was a problem. If the ldap add 18757c478bd9Sstevel@tonic-gate * operation failed, ldap_rc will be set 18767c478bd9Sstevel@tonic-gate * to the ldap error code. 18777c478bd9Sstevel@tonic-gate */ 18787c478bd9Sstevel@tonic-gate suc_code 18797c478bd9Sstevel@tonic-gate addNISObject(char *domain, char *dn, int *ldap_rc) { 18807c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv; 18817c478bd9Sstevel@tonic-gate int rc; 18827c478bd9Sstevel@tonic-gate char *objClassAttrs = NULL, *attrs; 18837c478bd9Sstevel@tonic-gate char *value, *svalue, *rdn = NULL; 18847c478bd9Sstevel@tonic-gate char *myself = "addNISObject"; 18857c478bd9Sstevel@tonic-gate 18867c478bd9Sstevel@tonic-gate if (!dn) 18877c478bd9Sstevel@tonic-gate return (FAILURE); 18887c478bd9Sstevel@tonic-gate 18897c478bd9Sstevel@tonic-gate if ((rv = initRuleValue(1, 0)) == 0) 18907c478bd9Sstevel@tonic-gate return (FAILURE); 18917c478bd9Sstevel@tonic-gate 18927c478bd9Sstevel@tonic-gate if (ldap_rc) 18937c478bd9Sstevel@tonic-gate *ldap_rc = -1; 18947c478bd9Sstevel@tonic-gate 18957c478bd9Sstevel@tonic-gate /* 18967c478bd9Sstevel@tonic-gate * Add name=value pairs from RDN. Although this is not required 18977c478bd9Sstevel@tonic-gate * for SunOne Directory Server, during openldap interoperabilty 18987c478bd9Sstevel@tonic-gate * tests, it was found out that openldap server returned object 18997c478bd9Sstevel@tonic-gate * class violation errors if MUST attributes were not specified 19007c478bd9Sstevel@tonic-gate * explicitly. 19017c478bd9Sstevel@tonic-gate */ 19027c478bd9Sstevel@tonic-gate if (splitDN(dn, &rdn, 0) == -1) 19037c478bd9Sstevel@tonic-gate return (FAILURE); 19047c478bd9Sstevel@tonic-gate if (rdn != NULL) { 19057c478bd9Sstevel@tonic-gate objClassAttrs = (char *)getObjectClass(rdn); 19067c478bd9Sstevel@tonic-gate if (objClassAttrs == NULL) { 19077c478bd9Sstevel@tonic-gate sfree(rdn); 19087c478bd9Sstevel@tonic-gate return (FAILURE); 19097c478bd9Sstevel@tonic-gate } 19107c478bd9Sstevel@tonic-gate 19117c478bd9Sstevel@tonic-gate /* 19127c478bd9Sstevel@tonic-gate * RDN can be composed of multiple name=value pairs 19137c478bd9Sstevel@tonic-gate * concatenated by '+'. Hence, we need to determine each 19147c478bd9Sstevel@tonic-gate * pair and add it to 'rv' 19157c478bd9Sstevel@tonic-gate */ 19167c478bd9Sstevel@tonic-gate for (value = rdn, svalue = NULL; *value != '\0'; value++) { 19177c478bd9Sstevel@tonic-gate if (*value == '+') { 19187c478bd9Sstevel@tonic-gate /* Make sure it's not escaped */ 19197c478bd9Sstevel@tonic-gate if (value == rdn || *(value - 1) != '\\') { 19207c478bd9Sstevel@tonic-gate /* 19217c478bd9Sstevel@tonic-gate * We are at the start of the new 19227c478bd9Sstevel@tonic-gate * pair. 'svalue' now contains the 19237c478bd9Sstevel@tonic-gate * value for the previous pair. Add 19247c478bd9Sstevel@tonic-gate * the previous pair to 'rv' 19257c478bd9Sstevel@tonic-gate */ 19267c478bd9Sstevel@tonic-gate *value = '\0'; 19277c478bd9Sstevel@tonic-gate if (svalue && 19287c478bd9Sstevel@tonic-gate addSAttr2RuleValue(rdn, svalue, rv) 19297c478bd9Sstevel@tonic-gate == -1) { 19307c478bd9Sstevel@tonic-gate sfree(rdn); 19317c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 19327c478bd9Sstevel@tonic-gate return (FAILURE); 19337c478bd9Sstevel@tonic-gate } 19347c478bd9Sstevel@tonic-gate svalue = NULL; 19357c478bd9Sstevel@tonic-gate rdn = value + 1; 19367c478bd9Sstevel@tonic-gate continue; 19377c478bd9Sstevel@tonic-gate } 19387c478bd9Sstevel@tonic-gate } 19397c478bd9Sstevel@tonic-gate 19407c478bd9Sstevel@tonic-gate if (*value == '=') { 19417c478bd9Sstevel@tonic-gate if (value == rdn || *(value - 1) != '\\') { 19427c478bd9Sstevel@tonic-gate /* 19437c478bd9Sstevel@tonic-gate * 'rdn' now contains the name. 19447c478bd9Sstevel@tonic-gate * Whatever follows till the next 19457c478bd9Sstevel@tonic-gate * unescaped '+' or '\0' is the 19467c478bd9Sstevel@tonic-gate * value for this pair. 19477c478bd9Sstevel@tonic-gate */ 19487c478bd9Sstevel@tonic-gate *value = '\0'; 19497c478bd9Sstevel@tonic-gate svalue = value + 1; 19507c478bd9Sstevel@tonic-gate continue; 19517c478bd9Sstevel@tonic-gate } 19527c478bd9Sstevel@tonic-gate } 19537c478bd9Sstevel@tonic-gate } 19547c478bd9Sstevel@tonic-gate 19557c478bd9Sstevel@tonic-gate /* 19567c478bd9Sstevel@tonic-gate * End of String. Add the previous name=value pair to 'rv' 19577c478bd9Sstevel@tonic-gate */ 19587c478bd9Sstevel@tonic-gate if (svalue && addSAttr2RuleValue(rdn, svalue, rv) == -1) { 19597c478bd9Sstevel@tonic-gate sfree(rdn); 19607c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 19617c478bd9Sstevel@tonic-gate return (FAILURE); 19627c478bd9Sstevel@tonic-gate } 19637c478bd9Sstevel@tonic-gate sfree(rdn); 19647c478bd9Sstevel@tonic-gate } else /* rdn == NULL */ 19657c478bd9Sstevel@tonic-gate return (FAILURE); 19667c478bd9Sstevel@tonic-gate 19677c478bd9Sstevel@tonic-gate /* Create the entry */ 19687c478bd9Sstevel@tonic-gate if (domain) { 19697c478bd9Sstevel@tonic-gate if (addSAttr2RuleValue("nisDomain", domain, rv) == -1) { 19707c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 19717c478bd9Sstevel@tonic-gate return (FAILURE); 19727c478bd9Sstevel@tonic-gate } 19737c478bd9Sstevel@tonic-gate attrs = scat(myself, F, "objectclass=nisdomainobject,", 19747c478bd9Sstevel@tonic-gate objClassAttrs); 19757c478bd9Sstevel@tonic-gate if (!attrs) { 19767c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 19777c478bd9Sstevel@tonic-gate return (FAILURE); 19787c478bd9Sstevel@tonic-gate } 19797c478bd9Sstevel@tonic-gate rc = ldapAdd(dn, rv, attrs, 0); 19807c478bd9Sstevel@tonic-gate sfree(attrs); 19817c478bd9Sstevel@tonic-gate } else { 19827c478bd9Sstevel@tonic-gate rc = ldapAdd(dn, rv, objClassAttrs, 0); 19837c478bd9Sstevel@tonic-gate } 19847c478bd9Sstevel@tonic-gate 19857c478bd9Sstevel@tonic-gate if (rc == LDAP_SUCCESS) 19867c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_INFO, 19877c478bd9Sstevel@tonic-gate "%s: Entry (dn: %s) added to DIT", 19887c478bd9Sstevel@tonic-gate myself, dn); 19897c478bd9Sstevel@tonic-gate else if (rc == LDAP_ALREADY_EXISTS) 19907c478bd9Sstevel@tonic-gate /* Treat this as success */ 19917c478bd9Sstevel@tonic-gate rc = LDAP_SUCCESS; 19927c478bd9Sstevel@tonic-gate else 19937c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 19947c478bd9Sstevel@tonic-gate "%s: ldapAdd error %d (%s) for (dn: %s)", 19957c478bd9Sstevel@tonic-gate myself, rc, ldap_err2string(rc), dn); 19967c478bd9Sstevel@tonic-gate 19977c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 19987c478bd9Sstevel@tonic-gate if (ldap_rc) 19997c478bd9Sstevel@tonic-gate *ldap_rc = rc; 20007c478bd9Sstevel@tonic-gate return ((rc == LDAP_SUCCESS)?SUCCESS:FAILURE); 20017c478bd9Sstevel@tonic-gate } 2002