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*36e852a1SRaja Andra * Common Development and Distribution License (the "License"). 6*36e852a1SRaja Andra * 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*36e852a1SRaja Andra * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <strings.h> 277c478bd9Sstevel@tonic-gate #include <sys/types.h> 287c478bd9Sstevel@tonic-gate #include <sys/stat.h> 297c478bd9Sstevel@tonic-gate #include <errno.h> 307c478bd9Sstevel@tonic-gate #include <stdio.h> 317c478bd9Sstevel@tonic-gate #include <rpcsvc/nis.h> 327c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include "ldap_util.h" 357c478bd9Sstevel@tonic-gate #include "ldap_attr.h" 367c478bd9Sstevel@tonic-gate #include "ldap_ruleval.h" 377c478bd9Sstevel@tonic-gate #include "ldap_op.h" 387c478bd9Sstevel@tonic-gate #include "ldap_map.h" 397c478bd9Sstevel@tonic-gate #include "ldap_glob.h" 407c478bd9Sstevel@tonic-gate #include "ldap_xdr.h" 417c478bd9Sstevel@tonic-gate #include "ldap_val.h" 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate /* From yptol/dit_access_utils.h */ 447c478bd9Sstevel@tonic-gate #define N2LKEY "rf_key" 457c478bd9Sstevel@tonic-gate #define N2LIPKEY "rf_ipkey" 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate __nis_hash_table_mt ldapMappingList = NIS_HASH_TABLE_MT_INIT; 487c478bd9Sstevel@tonic-gate extern int yp2ldap; 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate int 527c478bd9Sstevel@tonic-gate setColumnNames(__nis_table_mapping_t *t) { 53*36e852a1SRaja Andra int i, j, nic, noc; 547c478bd9Sstevel@tonic-gate char **col; 557c478bd9Sstevel@tonic-gate zotypes type; 567c478bd9Sstevel@tonic-gate char *myself = "setColumnNames"; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate if (t == 0) 597c478bd9Sstevel@tonic-gate return (0); 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate type = t->objType; 627c478bd9Sstevel@tonic-gate col = t->column; 637c478bd9Sstevel@tonic-gate nic = (col != 0) ? t->numColumns : -1; 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate t->objType = NIS_BOGUS_OBJ; 667c478bd9Sstevel@tonic-gate t->obj = 0; 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* 697c478bd9Sstevel@tonic-gate * If it's a table object, but there are no translation rules, 707c478bd9Sstevel@tonic-gate * this mapping is for the table object itself. In that case, 717c478bd9Sstevel@tonic-gate * we throw away the column names (if any). 727c478bd9Sstevel@tonic-gate */ 737c478bd9Sstevel@tonic-gate if (t->objType == NIS_TABLE_OBJ && t->numRulesFromLDAP == 0 && 747c478bd9Sstevel@tonic-gate t->numRulesToLDAP == 0) { 757c478bd9Sstevel@tonic-gate for (i = 0; i < t->numColumns; i++) 767c478bd9Sstevel@tonic-gate sfree(t->column[i]); 777c478bd9Sstevel@tonic-gate sfree(t->column); 787c478bd9Sstevel@tonic-gate t->column = 0; 797c478bd9Sstevel@tonic-gate t->numColumns = 0; 807c478bd9Sstevel@tonic-gate noc = 0; 817c478bd9Sstevel@tonic-gate } 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate /* 847c478bd9Sstevel@tonic-gate * Verify that all column names found by the parser 857c478bd9Sstevel@tonic-gate * are present in the actual column list. 867c478bd9Sstevel@tonic-gate */ 877c478bd9Sstevel@tonic-gate if (verbose) { 887c478bd9Sstevel@tonic-gate for (i = 0, noc = 0; i < nic; i++) { 897c478bd9Sstevel@tonic-gate int found = 0; 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate if (col[i] == 0) 927c478bd9Sstevel@tonic-gate continue; 937c478bd9Sstevel@tonic-gate /* Skip the 'zo_*' special column names */ 947c478bd9Sstevel@tonic-gate if (isObjAttrString(col[i])) 957c478bd9Sstevel@tonic-gate continue; 967c478bd9Sstevel@tonic-gate for (j = 0; j < t->numColumns; j++) { 977c478bd9Sstevel@tonic-gate if (strcmp(col[i], t->column[j]) == 0) { 987c478bd9Sstevel@tonic-gate noc++; 997c478bd9Sstevel@tonic-gate found = 1; 1007c478bd9Sstevel@tonic-gate break; 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate if (!found) { 1047c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 1057c478bd9Sstevel@tonic-gate "%s: No column \"%s\" in \"%s\"", 1067c478bd9Sstevel@tonic-gate myself, NIL(col[i]), NIL(t->objName)); 1077c478bd9Sstevel@tonic-gate } 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate /* Remove any setup by the parser */ 1127c478bd9Sstevel@tonic-gate for (i = 0; i < nic; i++) { 1137c478bd9Sstevel@tonic-gate sfree(col[i]); 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate sfree(col); 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate return (0); 1187c478bd9Sstevel@tonic-gate } 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate void 1217c478bd9Sstevel@tonic-gate freeSingleObjAttr(__nis_obj_attr_t *attr) { 1227c478bd9Sstevel@tonic-gate if (attr == 0) 1237c478bd9Sstevel@tonic-gate return; 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate sfree(attr->zo_owner); 1267c478bd9Sstevel@tonic-gate sfree(attr->zo_group); 1277c478bd9Sstevel@tonic-gate sfree(attr->zo_domain); 1287c478bd9Sstevel@tonic-gate sfree(attr); 1297c478bd9Sstevel@tonic-gate } 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate void 1327c478bd9Sstevel@tonic-gate freeObjAttr(__nis_obj_attr_t **attr, int numAttr) { 1337c478bd9Sstevel@tonic-gate int i; 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate if (attr == 0) 1367c478bd9Sstevel@tonic-gate return; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate for (i = 0; i < numAttr; i++) { 1397c478bd9Sstevel@tonic-gate freeSingleObjAttr(attr[i]); 1407c478bd9Sstevel@tonic-gate } 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate sfree(attr); 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate __nis_obj_attr_t * 1467c478bd9Sstevel@tonic-gate cloneObjAttr(__nis_obj_attr_t *old) { 1477c478bd9Sstevel@tonic-gate __nis_obj_attr_t *new; 1487c478bd9Sstevel@tonic-gate char *myself = "cloneObjAttr"; 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate if (old == 0) 1517c478bd9Sstevel@tonic-gate return (0); 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate new = am(myself, sizeof (*new)); 1547c478bd9Sstevel@tonic-gate if (new == 0) 1557c478bd9Sstevel@tonic-gate return (0); 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate new->zo_owner = sdup(myself, T, old->zo_owner); 1587c478bd9Sstevel@tonic-gate if (new->zo_owner == 0 && old->zo_owner != 0) 1597c478bd9Sstevel@tonic-gate goto cleanup; 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate new->zo_group = sdup(myself, T, old->zo_group); 1627c478bd9Sstevel@tonic-gate if (new->zo_group == 0 && old->zo_group != 0) 1637c478bd9Sstevel@tonic-gate goto cleanup; 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate new->zo_domain = sdup(myself, T, old->zo_domain); 1667c478bd9Sstevel@tonic-gate if (new->zo_domain == 0 && old->zo_domain != 0) 1677c478bd9Sstevel@tonic-gate goto cleanup; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate new->zo_access = old->zo_access; 1707c478bd9Sstevel@tonic-gate new->zo_ttl = old->zo_ttl; 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate return (new); 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate cleanup: 1757c478bd9Sstevel@tonic-gate freeSingleObjAttr(new); 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate return (0); 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate /* 1827c478bd9Sstevel@tonic-gate * Obtain NIS+ entries (in the form of db_query's) from the supplied table 1837c478bd9Sstevel@tonic-gate * mapping and db_query. 1847c478bd9Sstevel@tonic-gate * 1857c478bd9Sstevel@tonic-gate * If 'qin' is NULL, enumeration is desired. 1867c478bd9Sstevel@tonic-gate * 1877c478bd9Sstevel@tonic-gate * On exit, '*numQueries' contains the number of (db_query *)'s in the 1887c478bd9Sstevel@tonic-gate * return array, '*ldapStat' the LDAP operation status, and '*objAttr' 1897c478bd9Sstevel@tonic-gate * a pointer to an array (of '*numQueries elements) of object attributes 1907c478bd9Sstevel@tonic-gate * (zo_owner, etc.). If no object attributes were retrieved, '*objAttr' 1917c478bd9Sstevel@tonic-gate * is NULL; any and all of the (*objAttr)[i]'s may be NULL. 1927c478bd9Sstevel@tonic-gate */ 1937c478bd9Sstevel@tonic-gate db_query ** 1947c478bd9Sstevel@tonic-gate mapFromLDAP(__nis_table_mapping_t *t, db_query *qin, int *numQueries, 1957c478bd9Sstevel@tonic-gate char *dbId, int *ldapStat, __nis_obj_attr_t ***objAttr) { 1967c478bd9Sstevel@tonic-gate __nis_table_mapping_t **tp; 1977c478bd9Sstevel@tonic-gate db_query **q; 1987c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv; 1997c478bd9Sstevel@tonic-gate __nis_ldap_search_t *ls; 2007c478bd9Sstevel@tonic-gate int n, numVals, numMatches = 0; 2017c478bd9Sstevel@tonic-gate int stat; 2027c478bd9Sstevel@tonic-gate __nis_obj_attr_t **attr; 2037c478bd9Sstevel@tonic-gate char *myself = "mapFromLDAP"; 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate if (ldapStat == 0) 2067c478bd9Sstevel@tonic-gate ldapStat = &stat; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate if (t == 0 || numQueries == 0) { 2097c478bd9Sstevel@tonic-gate *ldapStat = LDAP_PARAM_ERROR; 2107c478bd9Sstevel@tonic-gate return (0); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate /* Select the correct table mapping(s) */ 2147c478bd9Sstevel@tonic-gate tp = selectTableMapping(t, qin, 0, 0, dbId, &numMatches); 2157c478bd9Sstevel@tonic-gate if (tp == 0 || numMatches <= 0) { 2167c478bd9Sstevel@tonic-gate /* 2177c478bd9Sstevel@tonic-gate * Not really an error; just no matching mapping 2187c478bd9Sstevel@tonic-gate * for the query. 2197c478bd9Sstevel@tonic-gate */ 2207c478bd9Sstevel@tonic-gate *ldapStat = LDAP_SUCCESS; 2217c478bd9Sstevel@tonic-gate return (0); 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate q = 0; 2257c478bd9Sstevel@tonic-gate attr = 0; 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate /* For each mapping */ 2287c478bd9Sstevel@tonic-gate for (numVals = 0, n = 0; n < numMatches; n++) { 2297c478bd9Sstevel@tonic-gate db_query **qt; 2307c478bd9Sstevel@tonic-gate int i, nqt = 0, filterOnQin, res = 0; 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate t = tp[n]; 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate if (qin != 0) { 2357c478bd9Sstevel@tonic-gate rv = buildNisPlusRuleValue(t, qin, 0); 2367c478bd9Sstevel@tonic-gate if (rv != 0) { 2377c478bd9Sstevel@tonic-gate /* 2387c478bd9Sstevel@tonic-gate * Depending on the value of res, we shall 2397c478bd9Sstevel@tonic-gate * proceed to next table mapping. 2407c478bd9Sstevel@tonic-gate */ 2417c478bd9Sstevel@tonic-gate ls = createLdapRequest(t, rv, 0, 1, &res, NULL); 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate else 2447c478bd9Sstevel@tonic-gate ls = 0; 2457c478bd9Sstevel@tonic-gate } else { 2467c478bd9Sstevel@tonic-gate /* Build enumeration request */ 2477c478bd9Sstevel@tonic-gate rv = 0; 2487c478bd9Sstevel@tonic-gate ls = createLdapRequest(t, 0, 0, 1, NULL, NULL); 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate if (ls == 0) { 2547c478bd9Sstevel@tonic-gate /* 2557c478bd9Sstevel@tonic-gate * if the res is NP_LDAP_RULES_NO_VALUE, that means we 2567c478bd9Sstevel@tonic-gate * have enough NIS+ columns for the rules to produce 2577c478bd9Sstevel@tonic-gate * values, but none of them did, so continue to the 2587c478bd9Sstevel@tonic-gate * next table mapping. Otherwise do cleanup and return 2597c478bd9Sstevel@tonic-gate * error. 2607c478bd9Sstevel@tonic-gate */ 2617c478bd9Sstevel@tonic-gate if (res == NP_LDAP_RULES_NO_VALUE) 2627c478bd9Sstevel@tonic-gate continue; 2637c478bd9Sstevel@tonic-gate for (i = 0; i < numVals; i++) 2647c478bd9Sstevel@tonic-gate freeQuery(q[i]); 2657c478bd9Sstevel@tonic-gate sfree(q); 2667c478bd9Sstevel@tonic-gate free(tp); 2677c478bd9Sstevel@tonic-gate *ldapStat = LDAP_OPERATIONS_ERROR; 2687c478bd9Sstevel@tonic-gate return (0); 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate /* Query LDAP */ 2727c478bd9Sstevel@tonic-gate nqt = (ls->isDN || qin != 0) ? 0 : -1; 2737c478bd9Sstevel@tonic-gate rv = ldapSearch(ls, &nqt, 0, ldapStat); 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate /* 2767c478bd9Sstevel@tonic-gate * If qin != 0, then we need to make sure that the 2777c478bd9Sstevel@tonic-gate * LDAP search is filtered so that only entries that 2787c478bd9Sstevel@tonic-gate * are compatible with 'qin' are retained. This will 2797c478bd9Sstevel@tonic-gate * happen automatically if we do a DN search (in which 2807c478bd9Sstevel@tonic-gate * case, no need to filter on 'qin'). 2817c478bd9Sstevel@tonic-gate */ 2827c478bd9Sstevel@tonic-gate if (ls->isDN || qin == 0) 2837c478bd9Sstevel@tonic-gate filterOnQin = 0; 2847c478bd9Sstevel@tonic-gate else 2857c478bd9Sstevel@tonic-gate filterOnQin = 1; 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate /* Convert rule-values to db_query's */ 2907c478bd9Sstevel@tonic-gate if (rv != 0 && nqt > 0) { 2917c478bd9Sstevel@tonic-gate int nrv = nqt; 2927c478bd9Sstevel@tonic-gate __nis_obj_attr_t **at = 0; 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate qt = ruleValue2Query(t, rv, 2957c478bd9Sstevel@tonic-gate (filterOnQin) ? qin : 0, &at, &nqt); 2967c478bd9Sstevel@tonic-gate freeRuleValue(rv, nrv); 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate if (qt != 0 && q == 0) { 2997c478bd9Sstevel@tonic-gate q = qt; 3007c478bd9Sstevel@tonic-gate attr = at; 3017c478bd9Sstevel@tonic-gate numVals = nqt; 3027c478bd9Sstevel@tonic-gate } else if (qt != 0) { 3037c478bd9Sstevel@tonic-gate db_query **tmp; 3047c478bd9Sstevel@tonic-gate __nis_obj_attr_t **atmp; 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate /* Extend the 'q' array */ 3077c478bd9Sstevel@tonic-gate tmp = realloc(q, 3087c478bd9Sstevel@tonic-gate (numVals+nqt) * sizeof (q[0])); 3097c478bd9Sstevel@tonic-gate /* ... and the 'attr' array */ 3107c478bd9Sstevel@tonic-gate atmp = realloc(attr, 3117c478bd9Sstevel@tonic-gate (numVals+nqt) * sizeof (attr[0])); 3127c478bd9Sstevel@tonic-gate if (tmp == 0 || atmp == 0) { 3137c478bd9Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 3147c478bd9Sstevel@tonic-gate "%s: realloc(%d) => NULL", 3157c478bd9Sstevel@tonic-gate myself, 3167c478bd9Sstevel@tonic-gate (numVals+nqt) * sizeof (q[0])); 3177c478bd9Sstevel@tonic-gate for (i = 0; i < numVals; i++) 3187c478bd9Sstevel@tonic-gate freeQuery(q[i]); 3197c478bd9Sstevel@tonic-gate for (i = 0; i < nqt; i++) 3207c478bd9Sstevel@tonic-gate freeQuery(qt[i]); 3217c478bd9Sstevel@tonic-gate sfree(tmp); 3227c478bd9Sstevel@tonic-gate sfree(atmp); 3237c478bd9Sstevel@tonic-gate sfree(q); 3247c478bd9Sstevel@tonic-gate sfree(qt); 3257c478bd9Sstevel@tonic-gate sfree(tp); 3267c478bd9Sstevel@tonic-gate freeObjAttr(at, nqt); 3277c478bd9Sstevel@tonic-gate freeObjAttr(attr, numVals); 3287c478bd9Sstevel@tonic-gate *ldapStat = LDAP_NO_MEMORY; 3297c478bd9Sstevel@tonic-gate return (0); 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate q = tmp; 3327c478bd9Sstevel@tonic-gate attr = atmp; 3337c478bd9Sstevel@tonic-gate /* Add the results for this 't' */ 3347c478bd9Sstevel@tonic-gate (void) memcpy(&q[numVals], qt, 3357c478bd9Sstevel@tonic-gate nqt * sizeof (qt[0])); 3367c478bd9Sstevel@tonic-gate (void) memcpy(&attr[numVals], at, 3377c478bd9Sstevel@tonic-gate nqt * sizeof (at[0])); 3387c478bd9Sstevel@tonic-gate numVals += nqt; 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate sfree(qt); 3417c478bd9Sstevel@tonic-gate sfree(at); 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate *numQueries = numVals; 3477c478bd9Sstevel@tonic-gate if (objAttr != 0) 3487c478bd9Sstevel@tonic-gate *objAttr = attr; 3497c478bd9Sstevel@tonic-gate else 3507c478bd9Sstevel@tonic-gate freeObjAttr(attr, numVals); 3517c478bd9Sstevel@tonic-gate sfree(tp); 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate return (q); 3547c478bd9Sstevel@tonic-gate } 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate /* 3577c478bd9Sstevel@tonic-gate * Add the object attributes (zo_owner, etc.) to the rule-value 'rv'. 3587c478bd9Sstevel@tonic-gate * Returns a pointer to the (possibly newly allocated) rule-value, 3597c478bd9Sstevel@tonic-gate * or NULL in case of failure. If not returning 'rvIn', the latter 3607c478bd9Sstevel@tonic-gate * will have been freed. 3617c478bd9Sstevel@tonic-gate */ 3627c478bd9Sstevel@tonic-gate __nis_rule_value_t * 3637c478bd9Sstevel@tonic-gate addObjAttr2RuleValue(nis_object *obj, __nis_rule_value_t *rvIn) { 3647c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv; 3657c478bd9Sstevel@tonic-gate char abuf[2 * sizeof (obj->zo_access) + 1]; 3667c478bd9Sstevel@tonic-gate char tbuf[2 * sizeof (obj->zo_ttl) + 1]; 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate if (obj == 0) 3697c478bd9Sstevel@tonic-gate return (0); 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate if (rvIn != 0) { 3727c478bd9Sstevel@tonic-gate rv = rvIn; 3737c478bd9Sstevel@tonic-gate } else { 3747c478bd9Sstevel@tonic-gate rv = initRuleValue(1, 0); 3757c478bd9Sstevel@tonic-gate if (rv == 0) 3767c478bd9Sstevel@tonic-gate return (0); 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate if (obj->zo_owner != 0) { 3807c478bd9Sstevel@tonic-gate if (addSCol2RuleValue("zo_owner", obj->zo_owner, rv) != 0) { 3817c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 3827c478bd9Sstevel@tonic-gate return (0); 3837c478bd9Sstevel@tonic-gate } 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate if (obj->zo_group != 0) { 3877c478bd9Sstevel@tonic-gate if (addSCol2RuleValue("zo_group", obj->zo_group, rv) != 0) { 3887c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 3897c478bd9Sstevel@tonic-gate return (0); 3907c478bd9Sstevel@tonic-gate } 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate if (obj->zo_domain != 0) { 3947c478bd9Sstevel@tonic-gate if (addSCol2RuleValue("zo_domain", obj->zo_domain, rv) != 0) { 3957c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 3967c478bd9Sstevel@tonic-gate return (0); 3977c478bd9Sstevel@tonic-gate } 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate (void) memset(abuf, 0, sizeof (abuf)); 4017c478bd9Sstevel@tonic-gate (void) memset(tbuf, 0, sizeof (tbuf)); 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate sprintf(abuf, "%x", obj->zo_access); 4047c478bd9Sstevel@tonic-gate sprintf(tbuf, "%x", obj->zo_ttl); 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate if (addSCol2RuleValue("zo_access", abuf, rv) != 0) { 4077c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 4087c478bd9Sstevel@tonic-gate return (0); 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate if (addSCol2RuleValue("zo_ttl", tbuf, rv) != 0) { 4117c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 4127c478bd9Sstevel@tonic-gate return (0); 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate return (rv); 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate /* 4197c478bd9Sstevel@tonic-gate * Returns a pointer to (NOT a copy of) the value for the specified 4207c478bd9Sstevel@tonic-gate * column 'col' in the rule-value 'rv'. 4217c478bd9Sstevel@tonic-gate */ 4227c478bd9Sstevel@tonic-gate __nis_value_t * 4237c478bd9Sstevel@tonic-gate findColValue(char *col, __nis_rule_value_t *rv) { 4247c478bd9Sstevel@tonic-gate int i; 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate if (col == 0 || rv == 0 || rv->numColumns <= 0) 4277c478bd9Sstevel@tonic-gate return (0); 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate for (i = 0; i < rv->numColumns; i++) { 4307c478bd9Sstevel@tonic-gate if (strcmp(col, rv->colName[i]) == 0) 4317c478bd9Sstevel@tonic-gate return (&rv->colVal[i]); 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate return (0); 4357c478bd9Sstevel@tonic-gate } 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate /* 4387c478bd9Sstevel@tonic-gate * Return the NIS+ object attributes (if any) in the rule-value 'rv'. 4397c478bd9Sstevel@tonic-gate */ 4407c478bd9Sstevel@tonic-gate __nis_obj_attr_t * 4417c478bd9Sstevel@tonic-gate ruleValue2ObjAttr(__nis_rule_value_t *rv) { 4427c478bd9Sstevel@tonic-gate __nis_obj_attr_t *attr; 4437c478bd9Sstevel@tonic-gate __nis_value_t *val; 4447c478bd9Sstevel@tonic-gate char *myself = "ruleValue2ObjAttr"; 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate if (rv == 0 || rv->numColumns <= 0) 4477c478bd9Sstevel@tonic-gate return (0); 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate attr = am(myself, sizeof (*attr)); 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate if ((val = findColValue("zo_owner", rv)) != 0 && 4527c478bd9Sstevel@tonic-gate val->type == vt_string && val->numVals == 1 && 4537c478bd9Sstevel@tonic-gate val->val[0].value != 0) { 4547c478bd9Sstevel@tonic-gate attr->zo_owner = sdup(myself, T, val->val[0].value); 4557c478bd9Sstevel@tonic-gate if (attr->zo_owner == 0) { 4567c478bd9Sstevel@tonic-gate freeSingleObjAttr(attr); 4577c478bd9Sstevel@tonic-gate return (0); 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate if ((val = findColValue("zo_group", rv)) != 0 && 4627c478bd9Sstevel@tonic-gate val->type == vt_string && val->numVals == 1 && 4637c478bd9Sstevel@tonic-gate val->val[0].value != 0) { 4647c478bd9Sstevel@tonic-gate attr->zo_group = sdup(myself, T, val->val[0].value); 4657c478bd9Sstevel@tonic-gate if (attr->zo_group == 0) { 4667c478bd9Sstevel@tonic-gate freeSingleObjAttr(attr); 4677c478bd9Sstevel@tonic-gate return (0); 4687c478bd9Sstevel@tonic-gate } 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate if ((val = findColValue("zo_domain", rv)) != 0 && 4727c478bd9Sstevel@tonic-gate val->type == vt_string && val->numVals == 1 && 4737c478bd9Sstevel@tonic-gate val->val[0].value != 0) { 4747c478bd9Sstevel@tonic-gate attr->zo_domain = sdup(myself, T, val->val[0].value); 4757c478bd9Sstevel@tonic-gate if (attr->zo_domain == 0) { 4767c478bd9Sstevel@tonic-gate freeSingleObjAttr(attr); 4777c478bd9Sstevel@tonic-gate return (0); 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate if ((val = findColValue("zo_access", rv)) != 0 && 4827c478bd9Sstevel@tonic-gate val->type == vt_string && val->numVals == 1 && 4837c478bd9Sstevel@tonic-gate val->val[0].value != 0) { 4847c478bd9Sstevel@tonic-gate if (sscanf(val->val[0].value, "%x", &attr->zo_access) != 1) { 4857c478bd9Sstevel@tonic-gate freeSingleObjAttr(attr); 4867c478bd9Sstevel@tonic-gate return (0); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate } 4897c478bd9Sstevel@tonic-gate 4907c478bd9Sstevel@tonic-gate if ((val = findColValue("zo_ttl", rv)) != 0 && 4917c478bd9Sstevel@tonic-gate val->type == vt_string && val->numVals == 1 && 4927c478bd9Sstevel@tonic-gate val->val[0].value != 0) { 4937c478bd9Sstevel@tonic-gate if (sscanf(val->val[0].value, "%x", &attr->zo_ttl) != 1) { 4947c478bd9Sstevel@tonic-gate freeSingleObjAttr(attr); 4957c478bd9Sstevel@tonic-gate return (0); 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate return (attr); 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate /* 5037c478bd9Sstevel@tonic-gate * If the supplied string is one of the object attributes, return one. 5047c478bd9Sstevel@tonic-gate * Otherwise, return zero. 5057c478bd9Sstevel@tonic-gate */ 5067c478bd9Sstevel@tonic-gate int 5077c478bd9Sstevel@tonic-gate isObjAttrString(char *str) { 5087c478bd9Sstevel@tonic-gate if (str == 0) 5097c478bd9Sstevel@tonic-gate return (0); 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate if (strcmp("zo_owner", str) == 0 || 5127c478bd9Sstevel@tonic-gate strcmp("zo_group", str) == 0 || 5137c478bd9Sstevel@tonic-gate strcmp("zo_domain", str) == 0 || 5147c478bd9Sstevel@tonic-gate strcmp("zo_access", str) == 0 || 5157c478bd9Sstevel@tonic-gate strcmp("zo_ttl", str) == 0) 5167c478bd9Sstevel@tonic-gate return (1); 5177c478bd9Sstevel@tonic-gate else 5187c478bd9Sstevel@tonic-gate return (0); 5197c478bd9Sstevel@tonic-gate } 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate /* 5237c478bd9Sstevel@tonic-gate * If the supplied value is one of the object attribute strings, return 5247c478bd9Sstevel@tonic-gate * a pointer to the string. Otherwise, return NULL. 5257c478bd9Sstevel@tonic-gate */ 5267c478bd9Sstevel@tonic-gate char * 5277c478bd9Sstevel@tonic-gate isObjAttr(__nis_single_value_t *val) { 5287c478bd9Sstevel@tonic-gate if (val == 0 || val->length <= 0 || val->value == 0) 5297c478bd9Sstevel@tonic-gate return (0); 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate if (isObjAttrString(val->value)) 5327c478bd9Sstevel@tonic-gate return (val->value); 5337c478bd9Sstevel@tonic-gate else 5347c478bd9Sstevel@tonic-gate return (0); 5357c478bd9Sstevel@tonic-gate } 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate int 5387c478bd9Sstevel@tonic-gate setObjAttrField(char *attrName, __nis_single_value_t *val, 5397c478bd9Sstevel@tonic-gate __nis_obj_attr_t **objAttr) { 5407c478bd9Sstevel@tonic-gate __nis_obj_attr_t *attr; 5417c478bd9Sstevel@tonic-gate char *myself = "setObjAttrField"; 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate if (attrName == 0 || val == 0 || objAttr == 0 || 5447c478bd9Sstevel@tonic-gate val->value == 0 || val->length <= 0) 5457c478bd9Sstevel@tonic-gate return (-1); 5467c478bd9Sstevel@tonic-gate 5477c478bd9Sstevel@tonic-gate if (*objAttr != 0) { 5487c478bd9Sstevel@tonic-gate attr = *objAttr; 5497c478bd9Sstevel@tonic-gate } else { 5507c478bd9Sstevel@tonic-gate attr = am(myself, sizeof (*attr)); 5517c478bd9Sstevel@tonic-gate if (attr == 0) 5527c478bd9Sstevel@tonic-gate return (-2); 5537c478bd9Sstevel@tonic-gate *objAttr = attr; 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate if (strcmp("zo_owner", attrName) == 0) { 5577c478bd9Sstevel@tonic-gate if (attr->zo_owner == 0) { 5587c478bd9Sstevel@tonic-gate attr->zo_owner = sdup(myself, T, val->value); 5597c478bd9Sstevel@tonic-gate if (attr->zo_owner == 0) 5607c478bd9Sstevel@tonic-gate return (-11); 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate } else if (strcmp("zo_group", attrName) == 0) { 5637c478bd9Sstevel@tonic-gate if (attr->zo_group == 0) { 5647c478bd9Sstevel@tonic-gate attr->zo_group = sdup(myself, T, val->value); 5657c478bd9Sstevel@tonic-gate if (attr->zo_group == 0) 5667c478bd9Sstevel@tonic-gate return (-12); 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate } else if (strcmp("zo_domain", attrName) == 0) { 5697c478bd9Sstevel@tonic-gate if (attr->zo_domain == 0) { 5707c478bd9Sstevel@tonic-gate attr->zo_domain = sdup(myself, T, val->value); 5717c478bd9Sstevel@tonic-gate if (attr->zo_domain == 0) 5727c478bd9Sstevel@tonic-gate return (-13); 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate } else if (strcmp("zo_access", attrName) == 0) { 5757c478bd9Sstevel@tonic-gate if (attr->zo_access == 0) { 5767c478bd9Sstevel@tonic-gate if (sscanf(val->value, "%x", &attr->zo_access) != 1) 5777c478bd9Sstevel@tonic-gate return (-14); 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate } else if (strcmp("zo_ttl", attrName) == 0) { 5807c478bd9Sstevel@tonic-gate if (attr->zo_ttl == 0) { 5817c478bd9Sstevel@tonic-gate if (sscanf(val->value, "%x", &attr->zo_ttl) != 1) 5827c478bd9Sstevel@tonic-gate return (-15); 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate return (0); 5877c478bd9Sstevel@tonic-gate } 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate /* 5907c478bd9Sstevel@tonic-gate * Return a DN and rule-value for the supplied mapping, db_query's, and 5917c478bd9Sstevel@tonic-gate * input rule-value. This function only works on a single mapping. See 5927c478bd9Sstevel@tonic-gate * mapToLDAP() below for a description of the action depending on the 5937c478bd9Sstevel@tonic-gate * values of 'old' and 'new'. 5947c478bd9Sstevel@tonic-gate * 5957c478bd9Sstevel@tonic-gate * If both 'old' and 'new' are supplied, and the modify would result 5967c478bd9Sstevel@tonic-gate * in a change to the DN, '*oldDN' will contain the old DN. Otherwise 5977c478bd9Sstevel@tonic-gate * (and normally), '*oldDN' will be NULL. 5987c478bd9Sstevel@tonic-gate */ 5997c478bd9Sstevel@tonic-gate char * 6007c478bd9Sstevel@tonic-gate map1qToLDAP(__nis_table_mapping_t *t, db_query *old, db_query *new, 6017c478bd9Sstevel@tonic-gate __nis_rule_value_t *rvIn, __nis_rule_value_t **rvOutP, 6027c478bd9Sstevel@tonic-gate char **oldDnP) { 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv, *rvt; 6057c478bd9Sstevel@tonic-gate __nis_ldap_search_t *ls; 6067c478bd9Sstevel@tonic-gate char *dn = 0, *oldDn = 0; 6077c478bd9Sstevel@tonic-gate __nis_table_mapping_t del; 6087c478bd9Sstevel@tonic-gate char *myself = "map1qToLDAP"; 6097c478bd9Sstevel@tonic-gate 6107c478bd9Sstevel@tonic-gate if (t == 0 || (old == 0 && new == 0) || rvOutP == 0) 6117c478bd9Sstevel@tonic-gate return (0); 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate /* 6147c478bd9Sstevel@tonic-gate * If entry should be deleted, we look at the delete 6157c478bd9Sstevel@tonic-gate * policy in the table mapping. Should it specify a 6167c478bd9Sstevel@tonic-gate * rule set, we use that rule set to build a rule- 6177c478bd9Sstevel@tonic-gate * value, and the delete actually becomes a modify 6187c478bd9Sstevel@tonic-gate * operation. 6197c478bd9Sstevel@tonic-gate */ 6207c478bd9Sstevel@tonic-gate if (old != 0 && new == 0) { 6217c478bd9Sstevel@tonic-gate if (t->objectDN->delDisp == dd_perDbId) { 6227c478bd9Sstevel@tonic-gate /* 6237c478bd9Sstevel@tonic-gate * The functions that build a rule-value from a 6247c478bd9Sstevel@tonic-gate * rule set expect a __nis_table_mapping_t, but the 6257c478bd9Sstevel@tonic-gate * rule set in the __nis_object_dn_t isn't of that 6267c478bd9Sstevel@tonic-gate * form. So, build a pseudo-__nis_table_mapping_t that 6277c478bd9Sstevel@tonic-gate * borrows heavily from 't'. 6287c478bd9Sstevel@tonic-gate */ 6297c478bd9Sstevel@tonic-gate del = *t; 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate del.numRulesToLDAP = del.objectDN->numDbIds; 6327c478bd9Sstevel@tonic-gate del.ruleToLDAP = del.objectDN->dbId; 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate /* 6357c478bd9Sstevel@tonic-gate * Do a modify with the pseudo-table 6367c478bd9Sstevel@tonic-gate * mapping, and the 'old' db_query 6377c478bd9Sstevel@tonic-gate * supplying input to the delete rule 6387c478bd9Sstevel@tonic-gate * set. 6397c478bd9Sstevel@tonic-gate */ 6407c478bd9Sstevel@tonic-gate t = &del; 6417c478bd9Sstevel@tonic-gate new = old; 6427c478bd9Sstevel@tonic-gate } else if (t->objectDN->delDisp == dd_always) { 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate /* Nothing to do here; all handled below */ 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate } else if (t->objectDN->delDisp == dd_never) { 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate return (0); 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate } else { 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate logmsg(MSG_INVALIDDELDISP, LOG_WARNING, 6537c478bd9Sstevel@tonic-gate "%s: Invalid delete disposition %d for \"%s\"", 6547c478bd9Sstevel@tonic-gate myself, t->objectDN->delDisp, 6557c478bd9Sstevel@tonic-gate NIL(t->dbId)); 6567c478bd9Sstevel@tonic-gate return (0); 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate } 6597c478bd9Sstevel@tonic-gate } 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate /* Make a copy of the input rule-value */ 6627c478bd9Sstevel@tonic-gate if (rvIn != 0) { 6637c478bd9Sstevel@tonic-gate rv = initRuleValue(1, rvIn); 6647c478bd9Sstevel@tonic-gate if (rv == 0) 6657c478bd9Sstevel@tonic-gate return (0); 6667c478bd9Sstevel@tonic-gate } else { 6677c478bd9Sstevel@tonic-gate rv = 0; 6687c478bd9Sstevel@tonic-gate } 6697c478bd9Sstevel@tonic-gate 6707c478bd9Sstevel@tonic-gate /* First get a rule-value from the supplied NIS+ entry. */ 6717c478bd9Sstevel@tonic-gate rvt = rv; 6727c478bd9Sstevel@tonic-gate rv = buildNisPlusRuleValue(t, ((old != 0) ? old : new), rvt); 6737c478bd9Sstevel@tonic-gate freeRuleValue(rvt, 1); 6747c478bd9Sstevel@tonic-gate if (rv == 0) { 6757c478bd9Sstevel@tonic-gate logmsg(MSG_NORULEVALUE, LOG_WARNING, 6767c478bd9Sstevel@tonic-gate "%s: No in-query rule-value derived for \"%s\"", 6777c478bd9Sstevel@tonic-gate myself, NIL(t->dbId)); 6787c478bd9Sstevel@tonic-gate return (0); 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate /* 6827c478bd9Sstevel@tonic-gate * Create a request (really only care about the DN) from the 6837c478bd9Sstevel@tonic-gate * supplied NIS+ entry data. 6847c478bd9Sstevel@tonic-gate */ 6857c478bd9Sstevel@tonic-gate ls = createLdapRequest(t, rv, &dn, 0, NULL, NULL); 6867c478bd9Sstevel@tonic-gate if (ls == 0 || dn == 0) { 6877c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 6887c478bd9Sstevel@tonic-gate "%s: Unable to create LDAP request for %s: %s", 6897c478bd9Sstevel@tonic-gate myself, NIL(t->dbId), 6907c478bd9Sstevel@tonic-gate (dn != 0) ? dn : rvId(rv, mit_nisplus)); 6917c478bd9Sstevel@tonic-gate sfree(dn); 6927c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 6937c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 6947c478bd9Sstevel@tonic-gate return (0); 6957c478bd9Sstevel@tonic-gate } 6967c478bd9Sstevel@tonic-gate 6977c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate if (new != 0) { 7007c478bd9Sstevel@tonic-gate /* 7017c478bd9Sstevel@tonic-gate * Create a rule-value from the new NIS+ entry. 7027c478bd9Sstevel@tonic-gate * Don't want to mix in the rule-value derived 7037c478bd9Sstevel@tonic-gate * from 'old', so delete it. However, we still 7047c478bd9Sstevel@tonic-gate * want the owner, group, etc., from 'rvIn'. 7057c478bd9Sstevel@tonic-gate */ 7067c478bd9Sstevel@tonic-gate if (old != 0) { 7077c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 7087c478bd9Sstevel@tonic-gate if (rvIn != 0) { 7097c478bd9Sstevel@tonic-gate rv = initRuleValue(1, rvIn); 7107c478bd9Sstevel@tonic-gate if (rv == 0) { 7117c478bd9Sstevel@tonic-gate sfree(dn); 7127c478bd9Sstevel@tonic-gate return (0); 7137c478bd9Sstevel@tonic-gate } 7147c478bd9Sstevel@tonic-gate } else { 7157c478bd9Sstevel@tonic-gate rv = 0; 7167c478bd9Sstevel@tonic-gate } 7177c478bd9Sstevel@tonic-gate } 7187c478bd9Sstevel@tonic-gate rvt = rv; 7197c478bd9Sstevel@tonic-gate rv = buildNisPlusRuleValue(t, new, rvt); 7207c478bd9Sstevel@tonic-gate freeRuleValue(rvt, 1); 7217c478bd9Sstevel@tonic-gate if (rv == 0) { 7227c478bd9Sstevel@tonic-gate logmsg(MSG_NORULEVALUE, LOG_WARNING, 7237c478bd9Sstevel@tonic-gate "%s: No new rule-value derived for \"%s: %s\"", 7247c478bd9Sstevel@tonic-gate myself, NIL(t->dbId), dn); 7257c478bd9Sstevel@tonic-gate sfree(dn); 7267c478bd9Sstevel@tonic-gate return (0); 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate /* 7297c478bd9Sstevel@tonic-gate * Check if the proposed modification would result in a 7307c478bd9Sstevel@tonic-gate * a change to the DN. 7317c478bd9Sstevel@tonic-gate */ 7327c478bd9Sstevel@tonic-gate if (old != 0) { 7337c478bd9Sstevel@tonic-gate oldDn = dn; 7347c478bd9Sstevel@tonic-gate dn = 0; 7357c478bd9Sstevel@tonic-gate ls = createLdapRequest(t, rv, &dn, 0, NULL, NULL); 7367c478bd9Sstevel@tonic-gate if (ls == 0 || dn == 0) { 7377c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 7387c478bd9Sstevel@tonic-gate "%s: Unable to create new DN for \"%s: %s\"", 7397c478bd9Sstevel@tonic-gate myself, NIL(t->dbId), oldDn); 7407c478bd9Sstevel@tonic-gate sfree(oldDn); 7417c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 7427c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 7437c478bd9Sstevel@tonic-gate return (0); 7447c478bd9Sstevel@tonic-gate } 7457c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 7467c478bd9Sstevel@tonic-gate if (strcasecmp(oldDn, dn) == 0) { 7477c478bd9Sstevel@tonic-gate sfree(oldDn); 7487c478bd9Sstevel@tonic-gate oldDn = 0; 7497c478bd9Sstevel@tonic-gate } 7507c478bd9Sstevel@tonic-gate } 7517c478bd9Sstevel@tonic-gate } 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate 7547c478bd9Sstevel@tonic-gate *rvOutP = rv; 7557c478bd9Sstevel@tonic-gate if (oldDnP != 0) 7567c478bd9Sstevel@tonic-gate *oldDnP = oldDn; 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate return (dn); 7597c478bd9Sstevel@tonic-gate } 7607c478bd9Sstevel@tonic-gate 7617c478bd9Sstevel@tonic-gate /* 7627c478bd9Sstevel@tonic-gate * Since the DN hash list is an automatic variable, there's no need for 7637c478bd9Sstevel@tonic-gate * locking, and we remove the locking overhead by using the libnsl 7647c478bd9Sstevel@tonic-gate * hash functions. 7657c478bd9Sstevel@tonic-gate */ 7667c478bd9Sstevel@tonic-gate #undef NIS_HASH_ITEM 7677c478bd9Sstevel@tonic-gate #undef NIS_HASH_TABLE 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate typedef struct { 7707c478bd9Sstevel@tonic-gate NIS_HASH_ITEM item; 7717c478bd9Sstevel@tonic-gate int index; 7727c478bd9Sstevel@tonic-gate char *oldDn; 7737c478bd9Sstevel@tonic-gate } __dn_item_t; 7747c478bd9Sstevel@tonic-gate 7757c478bd9Sstevel@tonic-gate /* 7767c478bd9Sstevel@tonic-gate * Update LDAP per the supplied table mapping and db_query's. 7777c478bd9Sstevel@tonic-gate * 7787c478bd9Sstevel@tonic-gate * 'nq' is the number of elements in the 'old', 'new', and 'rvIn' 7797c478bd9Sstevel@tonic-gate * arrays. mapToLDAP() generally performs one update for each 7807c478bd9Sstevel@tonic-gate * element; however, if one or more of the individual queries 7817c478bd9Sstevel@tonic-gate * produce the same DN, they're merged into a single update. 7827c478bd9Sstevel@tonic-gate * 7837c478bd9Sstevel@tonic-gate * There are four cases, depending on the values of 'old[iq]' and 7847c478bd9Sstevel@tonic-gate * 'new[iq]': 7857c478bd9Sstevel@tonic-gate * 7867c478bd9Sstevel@tonic-gate * (1) old[iq] == 0 && new[iq] == 0 7877c478bd9Sstevel@tonic-gate * No action; skip to next query 7887c478bd9Sstevel@tonic-gate * 7897c478bd9Sstevel@tonic-gate * (2) old[iq] == 0 && new[iq] != 0 7907c478bd9Sstevel@tonic-gate * Attempt to use the 'new' db_query to get a DN, and try to create 7917c478bd9Sstevel@tonic-gate * the corresponding LDAP entry. 7927c478bd9Sstevel@tonic-gate * 7937c478bd9Sstevel@tonic-gate * (3) old[iq] != 0 && new[iq] == 0 7947c478bd9Sstevel@tonic-gate * Use the 'old' db_query to get a DN, and try to delete the LDAP 7957c478bd9Sstevel@tonic-gate * entry per the table mapping. 7967c478bd9Sstevel@tonic-gate * 7977c478bd9Sstevel@tonic-gate * (4) old[iq] != 0 && new[iq] != 0 7987c478bd9Sstevel@tonic-gate * Use the 'old' db_query to get a DN, and update (possibly create) 7997c478bd9Sstevel@tonic-gate * the corresponding LDAP entry per the 'new' db_query. 8007c478bd9Sstevel@tonic-gate * 8017c478bd9Sstevel@tonic-gate * If 'rvIn' is non-NULL, it is expected to contain the object attributes 8027c478bd9Sstevel@tonic-gate * (zo_owner, etc.) to be written to LDAP. 'rvIn' is an array with 'nq' 8037c478bd9Sstevel@tonic-gate * elements. 8047c478bd9Sstevel@tonic-gate * 8057c478bd9Sstevel@tonic-gate * If 'firstOnly' is set, only the first old[iq]/new[iq] pair is used 8067c478bd9Sstevel@tonic-gate * to perform the actual update. Any additional queries specified will 8077c478bd9Sstevel@tonic-gate * have their values folded in, but are not used to derive update targets. 8087c478bd9Sstevel@tonic-gate * This mode is inteded to support the case where multiple NIS+ entries 8097c478bd9Sstevel@tonic-gate * map to one and the same LDAP entry. Note that 'rvIn' must still be 8107c478bd9Sstevel@tonic-gate * an array of 'nq' elements, though if 'firstOnly' is set, it should be 8117c478bd9Sstevel@tonic-gate * OK to leave all but 'rvIn[0]' empty. 8127c478bd9Sstevel@tonic-gate * 8137c478bd9Sstevel@tonic-gate * 'dbId' is used to further narow down the selection of mapping candidates 8147c478bd9Sstevel@tonic-gate * to those matching the 'dbId' value. 8157c478bd9Sstevel@tonic-gate */ 8167c478bd9Sstevel@tonic-gate int 8177c478bd9Sstevel@tonic-gate mapToLDAP(__nis_table_mapping_t *tm, int nq, db_query **old, db_query **new, 8187c478bd9Sstevel@tonic-gate __nis_rule_value_t *rvIn, int firstOnly, char *dbId) { 8197c478bd9Sstevel@tonic-gate __nis_table_mapping_t **tp, **tpa; 8207c478bd9Sstevel@tonic-gate int i, n, rnq, iq, r, ret = LDAP_SUCCESS; 8217c478bd9Sstevel@tonic-gate int maxMatches, numMatches = 0; 8227c478bd9Sstevel@tonic-gate __nis_ldap_search_t *ls; 8237c478bd9Sstevel@tonic-gate char **dn = 0, **odn = 0; 8247c478bd9Sstevel@tonic-gate __nis_rule_value_t **rv; 8257c478bd9Sstevel@tonic-gate __dn_item_t *dni; 8267c478bd9Sstevel@tonic-gate char *myself = "mapToLDAP"; 8277c478bd9Sstevel@tonic-gate 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate if (tm == 0 || (old == 0 && new == 0) || nq <= 0) 8307c478bd9Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 8317c478bd9Sstevel@tonic-gate 8327c478bd9Sstevel@tonic-gate /* Determine maximum number of table mapping matches */ 8337c478bd9Sstevel@tonic-gate if (nq == 1) { 8347c478bd9Sstevel@tonic-gate tp = selectTableMapping(tm, 8357c478bd9Sstevel@tonic-gate (old != 0 && old[0] != 0) ? old[0] : new[0], 1, 0, 8367c478bd9Sstevel@tonic-gate dbId, &maxMatches); 8377c478bd9Sstevel@tonic-gate numMatches = maxMatches; 8387c478bd9Sstevel@tonic-gate } else { 8397c478bd9Sstevel@tonic-gate tp = selectTableMapping(tm, 0, 1, 0, dbId, &maxMatches); 8407c478bd9Sstevel@tonic-gate } 8417c478bd9Sstevel@tonic-gate 8427c478bd9Sstevel@tonic-gate /* 8437c478bd9Sstevel@tonic-gate * If no matching mapping, we're not mapping to LDAP in this 8447c478bd9Sstevel@tonic-gate * particular case. 8457c478bd9Sstevel@tonic-gate */ 8467c478bd9Sstevel@tonic-gate if (tp == 0 || maxMatches == 0) { 8477c478bd9Sstevel@tonic-gate sfree(tp); 8487c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 8497c478bd9Sstevel@tonic-gate } 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gate /* 8527c478bd9Sstevel@tonic-gate * Allocate the 'rv', 'dn', and 'tpa' arrays. Worst case is that 8537c478bd9Sstevel@tonic-gate * we need nq * maxMatches elements in each array. However, if 8547c478bd9Sstevel@tonic-gate * 'firstOnly' is set, we only need one element per matching 8557c478bd9Sstevel@tonic-gate * mapping in each. 8567c478bd9Sstevel@tonic-gate */ 8577c478bd9Sstevel@tonic-gate dn = am(myself, (firstOnly ? 1 : nq) * maxMatches * sizeof (dn[0])); 8587c478bd9Sstevel@tonic-gate odn = am(myself, (firstOnly ? 1 : nq) * maxMatches * sizeof (odn[0])); 8597c478bd9Sstevel@tonic-gate rv = am(myself, (firstOnly ? 1 : nq) * maxMatches * sizeof (rv[0])); 8607c478bd9Sstevel@tonic-gate tpa = am(myself, (firstOnly ? 1 : nq) * maxMatches * sizeof (tpa[0])); 8617c478bd9Sstevel@tonic-gate if (dn == 0 || odn == 0 || rv == 0 || tpa == 0) { 8627c478bd9Sstevel@tonic-gate sfree(tp); 8637c478bd9Sstevel@tonic-gate sfree(dn); 8647c478bd9Sstevel@tonic-gate sfree(odn); 8657c478bd9Sstevel@tonic-gate sfree(rv); 8667c478bd9Sstevel@tonic-gate sfree(tpa); 8677c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 8687c478bd9Sstevel@tonic-gate } 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate /* Unless nq == 1, we don't need the 'tp' value */ 8717c478bd9Sstevel@tonic-gate if (nq != 1) 8727c478bd9Sstevel@tonic-gate sfree(tp); 8737c478bd9Sstevel@tonic-gate 8747c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 8757c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 8767c478bd9Sstevel@tonic-gate LOG_WARNING, 8777c478bd9Sstevel@tonic-gate #else 8787c478bd9Sstevel@tonic-gate LOG_INFO, 8797c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 8807c478bd9Sstevel@tonic-gate "%s: %s: %d * %d potential updates", 8817c478bd9Sstevel@tonic-gate myself, NIL(tm->objName), nq, maxMatches); 8827c478bd9Sstevel@tonic-gate 8837c478bd9Sstevel@tonic-gate /* 8847c478bd9Sstevel@tonic-gate * Create DNs, column and attribute values, and merge duplicate DNs. 8857c478bd9Sstevel@tonic-gate */ 8867c478bd9Sstevel@tonic-gate for (iq = 0, rnq = 0; iq < nq; iq++) { 8877c478bd9Sstevel@tonic-gate int idx; 8887c478bd9Sstevel@tonic-gate 8897c478bd9Sstevel@tonic-gate if ((old == 0 || old[iq] == 0) && 8907c478bd9Sstevel@tonic-gate (new == 0 || new[iq] == 0)) 8917c478bd9Sstevel@tonic-gate continue; 8927c478bd9Sstevel@tonic-gate 8937c478bd9Sstevel@tonic-gate /* 8947c478bd9Sstevel@tonic-gate * Select matching table mappings; if nq == 1, we've already 8957c478bd9Sstevel@tonic-gate * got the 'tp' array from above. We expect this to be the 8967c478bd9Sstevel@tonic-gate * most common case, so it's worth special treatment. 8977c478bd9Sstevel@tonic-gate */ 8987c478bd9Sstevel@tonic-gate if (nq != 1) 8997c478bd9Sstevel@tonic-gate tp = selectTableMapping(tm, 9007c478bd9Sstevel@tonic-gate (old != 0 && old[iq] != 0) ? old[iq] : new[iq], 1, 0, 9017c478bd9Sstevel@tonic-gate dbId, &numMatches); 9027c478bd9Sstevel@tonic-gate if (tp == 0) 9037c478bd9Sstevel@tonic-gate continue; 9047c478bd9Sstevel@tonic-gate else if (numMatches <= 0) { 9057c478bd9Sstevel@tonic-gate sfree(tp); 9067c478bd9Sstevel@tonic-gate continue; 9077c478bd9Sstevel@tonic-gate } 9087c478bd9Sstevel@tonic-gate 9097c478bd9Sstevel@tonic-gate idx = iq * maxMatches; 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate if (idx == 0 || !firstOnly) 9127c478bd9Sstevel@tonic-gate (void) memcpy(&tpa[idx], tp, 9137c478bd9Sstevel@tonic-gate numMatches * sizeof (tpa[idx])); 9147c478bd9Sstevel@tonic-gate 9157c478bd9Sstevel@tonic-gate for (n = 0; n < numMatches; n++) { 9167c478bd9Sstevel@tonic-gate char *dnt, *odnt; 9177c478bd9Sstevel@tonic-gate __nis_rule_value_t *rvt = 0; 9187c478bd9Sstevel@tonic-gate 9197c478bd9Sstevel@tonic-gate if (tp[n] == 0) 9207c478bd9Sstevel@tonic-gate continue; 9217c478bd9Sstevel@tonic-gate 9227c478bd9Sstevel@tonic-gate dnt = map1qToLDAP(tp[n], 9237c478bd9Sstevel@tonic-gate (old != 0) ? old[iq] : 0, 9247c478bd9Sstevel@tonic-gate (new != 0) ? new[iq] : 0, 9257c478bd9Sstevel@tonic-gate (rvIn != 0) ? &rvIn[iq] : 0, 9267c478bd9Sstevel@tonic-gate &rvt, &odnt); 9277c478bd9Sstevel@tonic-gate 9287c478bd9Sstevel@tonic-gate if (dnt == 0) 9297c478bd9Sstevel@tonic-gate continue; 9307c478bd9Sstevel@tonic-gate if (rvt == 0) { 9317c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 9327c478bd9Sstevel@tonic-gate abort(); 9337c478bd9Sstevel@tonic-gate #else 9347c478bd9Sstevel@tonic-gate sfree(dnt); 9357c478bd9Sstevel@tonic-gate sfree(odnt); 9367c478bd9Sstevel@tonic-gate continue; 9377c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 9387c478bd9Sstevel@tonic-gate } 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate /* 9417c478bd9Sstevel@tonic-gate * Create a request to get a rule-value with 9427c478bd9Sstevel@tonic-gate * NIS+ data translated to LDAP equivalents. 9437c478bd9Sstevel@tonic-gate */ 9447c478bd9Sstevel@tonic-gate ls = createLdapRequest(tp[n], rvt, 0, 0, NULL, NULL); 9457c478bd9Sstevel@tonic-gate if (ls == 0) { 9467c478bd9Sstevel@tonic-gate if (ret == LDAP_SUCCESS) 9477c478bd9Sstevel@tonic-gate ret = LDAP_OPERATIONS_ERROR; 9487c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 9497c478bd9Sstevel@tonic-gate "%s: Unable to map to LDAP attrs for %s:dn=%s", 9507c478bd9Sstevel@tonic-gate myself, NIL(tp[n]->dbId), dnt); 9517c478bd9Sstevel@tonic-gate sfree(dnt); 9527c478bd9Sstevel@tonic-gate freeRuleValue(rvt, 1); 9537c478bd9Sstevel@tonic-gate continue; 9547c478bd9Sstevel@tonic-gate } 9557c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate /* 9587c478bd9Sstevel@tonic-gate * If the DN is the same as one we already know 9597c478bd9Sstevel@tonic-gate * about, merge the rule-values. 9607c478bd9Sstevel@tonic-gate */ 9617c478bd9Sstevel@tonic-gate 962*36e852a1SRaja Andra if ((iq == 0 || !firstOnly) && dnt != 0) { 9637c478bd9Sstevel@tonic-gate dni = am(myself, sizeof (*dni)); 9647c478bd9Sstevel@tonic-gate if (dni != 0) { 9657c478bd9Sstevel@tonic-gate dni->item.name = dnt; 9667c478bd9Sstevel@tonic-gate dni->index = idx + n; 9677c478bd9Sstevel@tonic-gate dni->oldDn = odnt; 9687c478bd9Sstevel@tonic-gate } else { 9697c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 9707c478bd9Sstevel@tonic-gate "%s: Skipping update for dn=\"%s\"", 9717c478bd9Sstevel@tonic-gate myself, dnt); 9727c478bd9Sstevel@tonic-gate sfree(dnt); 9737c478bd9Sstevel@tonic-gate dnt = 0; 9747c478bd9Sstevel@tonic-gate } 9757c478bd9Sstevel@tonic-gate if (dnt != 0) { 9767c478bd9Sstevel@tonic-gate dn[idx+n] = dnt; 9777c478bd9Sstevel@tonic-gate odn[idx+n] = odnt; 9787c478bd9Sstevel@tonic-gate rv[idx+n] = rvt; 9797c478bd9Sstevel@tonic-gate rnq++; 9807c478bd9Sstevel@tonic-gate } else { 9817c478bd9Sstevel@tonic-gate freeRuleValue(rvt, 1); 9827c478bd9Sstevel@tonic-gate rvt = 0; 9837c478bd9Sstevel@tonic-gate } 9847c478bd9Sstevel@tonic-gate } else if (dnt != 0) { 9857c478bd9Sstevel@tonic-gate sfree(dnt); 9867c478bd9Sstevel@tonic-gate sfree(odnt); 9877c478bd9Sstevel@tonic-gate freeRuleValue(rvt, 1); 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate } 9907c478bd9Sstevel@tonic-gate sfree(tp); 9917c478bd9Sstevel@tonic-gate } 9927c478bd9Sstevel@tonic-gate 9937c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 9947c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 9957c478bd9Sstevel@tonic-gate LOG_WARNING, 9967c478bd9Sstevel@tonic-gate #else 9977c478bd9Sstevel@tonic-gate LOG_INFO, 9987c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 9997c478bd9Sstevel@tonic-gate "%s: %s: %d update%s requested", 10007c478bd9Sstevel@tonic-gate myself, NIL(tm->objName), rnq, rnq != 1 ? "s" : ""); 10017c478bd9Sstevel@tonic-gate 10027c478bd9Sstevel@tonic-gate /* Perform the updates */ 10037c478bd9Sstevel@tonic-gate for (i = rnq = 0; i < (firstOnly ? maxMatches : nq*maxMatches); i++) { 10047c478bd9Sstevel@tonic-gate int delPerDbId; 10057c478bd9Sstevel@tonic-gate 10067c478bd9Sstevel@tonic-gate if (dn[i] == 0) 10077c478bd9Sstevel@tonic-gate continue; 10087c478bd9Sstevel@tonic-gate 10097c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 10107c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_INFO, 10117c478bd9Sstevel@tonic-gate "%s: %s %s:dn=%s", 10127c478bd9Sstevel@tonic-gate myself, 10137c478bd9Sstevel@tonic-gate (new != 0 && new[i/maxMatches] != 0) ? 10147c478bd9Sstevel@tonic-gate "modify" : "delete", 10157c478bd9Sstevel@tonic-gate NIL(tpa[i]->dbId), dn[i]); 10167c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate delPerDbId = (tpa[i]->objectDN->delDisp == dd_perDbId); 10197c478bd9Sstevel@tonic-gate if ((new != 0 && new[i/maxMatches] != 0) || delPerDbId) { 10207c478bd9Sstevel@tonic-gate /* 10217c478bd9Sstevel@tonic-gate * Try to modify/create the specified DN. First, 10227c478bd9Sstevel@tonic-gate * however, if the update changes the DN, make 10237c478bd9Sstevel@tonic-gate * that change. 10247c478bd9Sstevel@tonic-gate */ 10257c478bd9Sstevel@tonic-gate if (odn[i] == 0 || (r = ldapChangeDN(odn[i], dn[i])) == 10267c478bd9Sstevel@tonic-gate LDAP_SUCCESS) { 10277c478bd9Sstevel@tonic-gate int addFirst; 10287c478bd9Sstevel@tonic-gate 10297c478bd9Sstevel@tonic-gate addFirst = (new != 0 && 10307c478bd9Sstevel@tonic-gate new[i/maxMatches] != 0 && 10317c478bd9Sstevel@tonic-gate !delPerDbId); 10327c478bd9Sstevel@tonic-gate r = ldapModify(dn[i], rv[i], 10337c478bd9Sstevel@tonic-gate tpa[i]->objectDN->write.attrs, 10347c478bd9Sstevel@tonic-gate addFirst); 10357c478bd9Sstevel@tonic-gate } 10367c478bd9Sstevel@tonic-gate } else { 10377c478bd9Sstevel@tonic-gate /* Try to delete the specified DN */ 10387c478bd9Sstevel@tonic-gate r = ldapModify(dn[i], 0, 10397c478bd9Sstevel@tonic-gate tpa[i]->objectDN->write.attrs, 0); 10407c478bd9Sstevel@tonic-gate } 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate if (r == LDAP_SUCCESS) { 10437c478bd9Sstevel@tonic-gate rnq++; 10447c478bd9Sstevel@tonic-gate } else { 10457c478bd9Sstevel@tonic-gate if (ret == LDAP_SUCCESS) 10467c478bd9Sstevel@tonic-gate ret = r; 10477c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 10487c478bd9Sstevel@tonic-gate "%s: LDAP %s request error %d for %s:dn=%s", 10497c478bd9Sstevel@tonic-gate myself, 10507c478bd9Sstevel@tonic-gate (new != 0 && new[i/maxMatches] != 0) ? 10517c478bd9Sstevel@tonic-gate "modify" : "delete", 10527c478bd9Sstevel@tonic-gate r, NIL(tpa[i]->dbId), dn[i]); 10537c478bd9Sstevel@tonic-gate } 10547c478bd9Sstevel@tonic-gate 10557c478bd9Sstevel@tonic-gate sfree(dn[i]); 10567c478bd9Sstevel@tonic-gate dn[i] = 0; 10577c478bd9Sstevel@tonic-gate freeRuleValue(rv[i], 1); 10587c478bd9Sstevel@tonic-gate rv[i] = 0; 10597c478bd9Sstevel@tonic-gate } 10607c478bd9Sstevel@tonic-gate 10617c478bd9Sstevel@tonic-gate sfree(dn); 10627c478bd9Sstevel@tonic-gate sfree(odn); 10637c478bd9Sstevel@tonic-gate sfree(rv); 10647c478bd9Sstevel@tonic-gate sfree(tpa); 10657c478bd9Sstevel@tonic-gate 10667c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 10677c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 10687c478bd9Sstevel@tonic-gate LOG_WARNING, 10697c478bd9Sstevel@tonic-gate #else 10707c478bd9Sstevel@tonic-gate LOG_INFO, 10717c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 10727c478bd9Sstevel@tonic-gate "%s: %s: %d update%s performed", 10737c478bd9Sstevel@tonic-gate myself, NIL(tm->objName), rnq, rnq != 1 ? "s" : ""); 10747c478bd9Sstevel@tonic-gate 10757c478bd9Sstevel@tonic-gate return (ret); 10767c478bd9Sstevel@tonic-gate } 10777c478bd9Sstevel@tonic-gate 10787c478bd9Sstevel@tonic-gate /* 10797c478bd9Sstevel@tonic-gate * In nis+2ldap, check if the query 'q' matches the selector index 'x->index'. 10807c478bd9Sstevel@tonic-gate * 10817c478bd9Sstevel@tonic-gate * In nis2ldap, if 'name' is provided then check if its value in 'val' 10827c478bd9Sstevel@tonic-gate * matches the selector index. If 'name' is NULL, then check if rule-value 'rv' 10837c478bd9Sstevel@tonic-gate * matches the index. 10847c478bd9Sstevel@tonic-gate * To match the selector index, all fieldspecs in the indexlist should match 10857c478bd9Sstevel@tonic-gate * (AND). In nis2ldap, an exception is, if there are multiple fieldspecs with 10867c478bd9Sstevel@tonic-gate * the same fieldname then only one of them needs to match (OR). 10877c478bd9Sstevel@tonic-gate * Example: 10887c478bd9Sstevel@tonic-gate * Indexlist = [host="H*", host="I*", user="U*", domain="D*"] 10897c478bd9Sstevel@tonic-gate * Then, 10907c478bd9Sstevel@tonic-gate * host = "H1", user="U1", domain="D1" ==> pass 10917c478bd9Sstevel@tonic-gate * host = "I1", user="U1", domain="D1" ==> pass 10927c478bd9Sstevel@tonic-gate * host = "X1", user="U1", domain="D1" ==> fail 10937c478bd9Sstevel@tonic-gate * host = "H1", user="X1", domain="D1" ==> fail 10947c478bd9Sstevel@tonic-gate * host = "H1", user="U1" ==> fail 10957c478bd9Sstevel@tonic-gate * 10967c478bd9Sstevel@tonic-gate * Return 1 in case of a match, 0 otherwise. 10977c478bd9Sstevel@tonic-gate */ 10987c478bd9Sstevel@tonic-gate int 10997c478bd9Sstevel@tonic-gate verifyIndexMatch(__nis_table_mapping_t *x, db_query *q, 11007c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv, char *name, char *val) { 11017c478bd9Sstevel@tonic-gate int i, j, k, match = 1; 11027c478bd9Sstevel@tonic-gate char *myself = "verifyIndexMatch"; 11037c478bd9Sstevel@tonic-gate 11047c478bd9Sstevel@tonic-gate /* 11057c478bd9Sstevel@tonic-gate * The pass and fail arrays are used by N2L to keep track of 11067c478bd9Sstevel@tonic-gate * index matches. This saves us from having matches in a 11077c478bd9Sstevel@tonic-gate * nested loop to decide OR or AND. 11087c478bd9Sstevel@tonic-gate */ 11097c478bd9Sstevel@tonic-gate int ppos, fpos; 11107c478bd9Sstevel@tonic-gate char **pass, **fail; 11117c478bd9Sstevel@tonic-gate 11127c478bd9Sstevel@tonic-gate if (x == 0) 11137c478bd9Sstevel@tonic-gate return (0); 11147c478bd9Sstevel@tonic-gate 11157c478bd9Sstevel@tonic-gate /* Trivial match */ 11167c478bd9Sstevel@tonic-gate if (x->index.numIndexes <= 0 || (!yp2ldap && q == 0)) 11177c478bd9Sstevel@tonic-gate return (1); 11187c478bd9Sstevel@tonic-gate 11197c478bd9Sstevel@tonic-gate if (yp2ldap) { 11207c478bd9Sstevel@tonic-gate if (!(pass = am(myself, x->index.numIndexes * sizeof (char *)))) 11217c478bd9Sstevel@tonic-gate return (0); 11227c478bd9Sstevel@tonic-gate if (!(fail = am(myself, 11237c478bd9Sstevel@tonic-gate x->index.numIndexes * sizeof (char *)))) { 11247c478bd9Sstevel@tonic-gate sfree(pass); 11257c478bd9Sstevel@tonic-gate return (0); 11267c478bd9Sstevel@tonic-gate } 11277c478bd9Sstevel@tonic-gate ppos = fpos = 0; 11287c478bd9Sstevel@tonic-gate } 11297c478bd9Sstevel@tonic-gate 11307c478bd9Sstevel@tonic-gate /* Check each index */ 11317c478bd9Sstevel@tonic-gate for (i = 0; i < x->index.numIndexes; i++) { 11327c478bd9Sstevel@tonic-gate int len = 0; 11337c478bd9Sstevel@tonic-gate char *value = 0; 11347c478bd9Sstevel@tonic-gate 11357c478bd9Sstevel@tonic-gate /* Skip NULL index names */ 11367c478bd9Sstevel@tonic-gate if (x->index.name[i] == 0) 11377c478bd9Sstevel@tonic-gate continue; 11387c478bd9Sstevel@tonic-gate 11397c478bd9Sstevel@tonic-gate /* Check N2L values */ 11407c478bd9Sstevel@tonic-gate if (yp2ldap) { 11417c478bd9Sstevel@tonic-gate if (name) { 11427c478bd9Sstevel@tonic-gate if (strcasecmp(x->index.name[i], name) == 0) 11437c478bd9Sstevel@tonic-gate value = val; 11447c478bd9Sstevel@tonic-gate else 11457c478bd9Sstevel@tonic-gate continue; 11467c478bd9Sstevel@tonic-gate } else if (rv) { 11477c478bd9Sstevel@tonic-gate if (strcasecmp(x->index.name[i], N2LKEY) == 0 || 11487c478bd9Sstevel@tonic-gate strcasecmp(x->index.name[i], N2LIPKEY) 11497c478bd9Sstevel@tonic-gate == 0) 11507c478bd9Sstevel@tonic-gate continue; 11517c478bd9Sstevel@tonic-gate value = findVal(x->index.name[i], rv, 11527c478bd9Sstevel@tonic-gate mit_nisplus); 11537c478bd9Sstevel@tonic-gate } 11547c478bd9Sstevel@tonic-gate 11557c478bd9Sstevel@tonic-gate if (value && verifyMappingMatch(x->index.value[i], 11567c478bd9Sstevel@tonic-gate value)) 11577c478bd9Sstevel@tonic-gate pass[ppos++] = x->index.name[i]; 11587c478bd9Sstevel@tonic-gate else 11597c478bd9Sstevel@tonic-gate fail[fpos++] = x->index.name[i]; 11607c478bd9Sstevel@tonic-gate continue; 11617c478bd9Sstevel@tonic-gate } 11627c478bd9Sstevel@tonic-gate 11637c478bd9Sstevel@tonic-gate /* If here, means nis+2ldap */ 11647c478bd9Sstevel@tonic-gate 11657c478bd9Sstevel@tonic-gate /* Is the index name a known column ? */ 11667c478bd9Sstevel@tonic-gate for (j = 0; j < x->numColumns; j++) { 11677c478bd9Sstevel@tonic-gate if (strcmp(x->index.name[i], x->column[j]) == 0) { 11687c478bd9Sstevel@tonic-gate /* 11697c478bd9Sstevel@tonic-gate * Do we have a value for the column ? 11707c478bd9Sstevel@tonic-gate */ 11717c478bd9Sstevel@tonic-gate for (k = 0; k < q->components.components_len; 11727c478bd9Sstevel@tonic-gate k++) { 11737c478bd9Sstevel@tonic-gate if (q->components.components_val[k]. 11747c478bd9Sstevel@tonic-gate which_index == j) { 11757c478bd9Sstevel@tonic-gate value = q->components. 11767c478bd9Sstevel@tonic-gate components_val[k]. 11777c478bd9Sstevel@tonic-gate index_value-> 11787c478bd9Sstevel@tonic-gate itemvalue. 11797c478bd9Sstevel@tonic-gate itemvalue_val; 11807c478bd9Sstevel@tonic-gate len = q->components. 11817c478bd9Sstevel@tonic-gate components_val[k]. 11827c478bd9Sstevel@tonic-gate index_value-> 11837c478bd9Sstevel@tonic-gate itemvalue. 11847c478bd9Sstevel@tonic-gate itemvalue_len; 11857c478bd9Sstevel@tonic-gate break; 11867c478bd9Sstevel@tonic-gate } 11877c478bd9Sstevel@tonic-gate } 11887c478bd9Sstevel@tonic-gate if (value != 0) 11897c478bd9Sstevel@tonic-gate break; 11907c478bd9Sstevel@tonic-gate } 11917c478bd9Sstevel@tonic-gate } 11927c478bd9Sstevel@tonic-gate 11937c478bd9Sstevel@tonic-gate /* 11947c478bd9Sstevel@tonic-gate * If we found a value, check if it matches the 11957c478bd9Sstevel@tonic-gate * format. If no value found or no match, this 11967c478bd9Sstevel@tonic-gate * mapping is _not_ an alternative. Otherwise, 11977c478bd9Sstevel@tonic-gate * we continue checking any other indexes. 11987c478bd9Sstevel@tonic-gate */ 11997c478bd9Sstevel@tonic-gate if (value == 0 || 12007c478bd9Sstevel@tonic-gate !verifyMappingMatch(x->index.value[i], 12017c478bd9Sstevel@tonic-gate value)) { 12027c478bd9Sstevel@tonic-gate match = 0; 12037c478bd9Sstevel@tonic-gate break; 12047c478bd9Sstevel@tonic-gate } 12057c478bd9Sstevel@tonic-gate } 12067c478bd9Sstevel@tonic-gate 12077c478bd9Sstevel@tonic-gate if (yp2ldap) { 12087c478bd9Sstevel@tonic-gate for (--fpos; fpos >= 0; fpos--) { 12097c478bd9Sstevel@tonic-gate for (i = 0; i < ppos; i++) { 12107c478bd9Sstevel@tonic-gate if (strcmp(pass[i], fail[fpos]) == 0) 12117c478bd9Sstevel@tonic-gate break; 12127c478bd9Sstevel@tonic-gate } 12137c478bd9Sstevel@tonic-gate if (i == ppos) { 12147c478bd9Sstevel@tonic-gate match = 0; 12157c478bd9Sstevel@tonic-gate break; 12167c478bd9Sstevel@tonic-gate } 12177c478bd9Sstevel@tonic-gate } 12187c478bd9Sstevel@tonic-gate sfree(pass); 12197c478bd9Sstevel@tonic-gate sfree(fail); 12207c478bd9Sstevel@tonic-gate } 12217c478bd9Sstevel@tonic-gate 12227c478bd9Sstevel@tonic-gate return (match); 12237c478bd9Sstevel@tonic-gate } 12247c478bd9Sstevel@tonic-gate 12257c478bd9Sstevel@tonic-gate /* 12267c478bd9Sstevel@tonic-gate * Return all table mappings that match the column values in 'q'. 12277c478bd9Sstevel@tonic-gate * If there's no match, return those alternative mappings that don't 12287c478bd9Sstevel@tonic-gate * have an index; if no such mapping exists, return NULL. 12297c478bd9Sstevel@tonic-gate * 12307c478bd9Sstevel@tonic-gate * If 'wantWrite' is set, we want mappings for writing (i.e., data 12317c478bd9Sstevel@tonic-gate * to LDAP); otherwise, we want mappings for reading. 12327c478bd9Sstevel@tonic-gate * 12337c478bd9Sstevel@tonic-gate * If 'wantObj' is set, we want object mappings only (i.e., _not_ 12347c478bd9Sstevel@tonic-gate * those used to map entries in tables). 12357c478bd9Sstevel@tonic-gate * 12367c478bd9Sstevel@tonic-gate * If 'dbId' is non-NULL, we select mappings with a matching dbId field. 12377c478bd9Sstevel@tonic-gate */ 12387c478bd9Sstevel@tonic-gate __nis_table_mapping_t ** 12397c478bd9Sstevel@tonic-gate selectTableMapping(__nis_table_mapping_t *t, db_query *q, 12407c478bd9Sstevel@tonic-gate int wantWrite, int wantObj, char *dbId, 12417c478bd9Sstevel@tonic-gate int *numMatches) { 12427c478bd9Sstevel@tonic-gate __nis_table_mapping_t *r, *x, **tp; 12437c478bd9Sstevel@tonic-gate int i, j, k, nm, numap; 12447c478bd9Sstevel@tonic-gate char *myself = "selectTableMapping"; 12457c478bd9Sstevel@tonic-gate 12467c478bd9Sstevel@tonic-gate if (numMatches == 0) 12477c478bd9Sstevel@tonic-gate numMatches = &nm; 12487c478bd9Sstevel@tonic-gate 12497c478bd9Sstevel@tonic-gate /* 12507c478bd9Sstevel@tonic-gate * Count the number of possible mappings, so that we can 12517c478bd9Sstevel@tonic-gate * allocate the 'tp' array up front. 12527c478bd9Sstevel@tonic-gate */ 12537c478bd9Sstevel@tonic-gate for (numap = 0, x = t; x != 0; numap++, x = x->next); 12547c478bd9Sstevel@tonic-gate 12557c478bd9Sstevel@tonic-gate if (numap == 0) { 12567c478bd9Sstevel@tonic-gate *numMatches = 0; 12577c478bd9Sstevel@tonic-gate return (0); 12587c478bd9Sstevel@tonic-gate } 12597c478bd9Sstevel@tonic-gate 12607c478bd9Sstevel@tonic-gate tp = am(myself, numap * sizeof (tp[0])); 12617c478bd9Sstevel@tonic-gate if (tp == 0) { 12627c478bd9Sstevel@tonic-gate *numMatches = -1; 12637c478bd9Sstevel@tonic-gate return (0); 12647c478bd9Sstevel@tonic-gate } 12657c478bd9Sstevel@tonic-gate 12667c478bd9Sstevel@tonic-gate /* 12677c478bd9Sstevel@tonic-gate * Special cases: 12687c478bd9Sstevel@tonic-gate * 12697c478bd9Sstevel@tonic-gate * q == 0 trivially matches any 't' of the correct object type 12707c478bd9Sstevel@tonic-gate * 12717c478bd9Sstevel@tonic-gate * wantObj != 0 means we ignore 'q' 12727c478bd9Sstevel@tonic-gate */ 12737c478bd9Sstevel@tonic-gate if (q == 0 || wantObj) { 12747c478bd9Sstevel@tonic-gate for (i = 0, x = t, nm = 0; i < numap; i++, x = x->next) { 12757c478bd9Sstevel@tonic-gate if (x->objectDN == 0) 12767c478bd9Sstevel@tonic-gate continue; 12777c478bd9Sstevel@tonic-gate if (wantWrite) { 12787c478bd9Sstevel@tonic-gate if (x->objectDN->write.scope == 12797c478bd9Sstevel@tonic-gate LDAP_SCOPE_UNKNOWN) 12807c478bd9Sstevel@tonic-gate continue; 12817c478bd9Sstevel@tonic-gate } else { 12827c478bd9Sstevel@tonic-gate if (x->objectDN->read.scope == 12837c478bd9Sstevel@tonic-gate LDAP_SCOPE_UNKNOWN) 12847c478bd9Sstevel@tonic-gate continue; 12857c478bd9Sstevel@tonic-gate } 12867c478bd9Sstevel@tonic-gate if (wantObj) { 12877c478bd9Sstevel@tonic-gate if (x->numColumns > 0) 12887c478bd9Sstevel@tonic-gate continue; 12897c478bd9Sstevel@tonic-gate } else { 12907c478bd9Sstevel@tonic-gate if (x->numColumns <= 0) 12917c478bd9Sstevel@tonic-gate continue; 12927c478bd9Sstevel@tonic-gate } 12937c478bd9Sstevel@tonic-gate if (dbId != 0 && x->dbId != 0 && 12947c478bd9Sstevel@tonic-gate strcmp(dbId, x->dbId) != 0) 12957c478bd9Sstevel@tonic-gate continue; 12967c478bd9Sstevel@tonic-gate tp[nm] = x; 12977c478bd9Sstevel@tonic-gate nm++; 12987c478bd9Sstevel@tonic-gate } 12997c478bd9Sstevel@tonic-gate *numMatches = nm; 13007c478bd9Sstevel@tonic-gate if (nm == 0) { 13017c478bd9Sstevel@tonic-gate sfree(tp); 13027c478bd9Sstevel@tonic-gate tp = 0; 13037c478bd9Sstevel@tonic-gate } 13047c478bd9Sstevel@tonic-gate return (tp); 13057c478bd9Sstevel@tonic-gate } 13067c478bd9Sstevel@tonic-gate 13077c478bd9Sstevel@tonic-gate /* Scan all mappings, and collect candidates */ 13087c478bd9Sstevel@tonic-gate for (nm = 0, r = 0, x = t; x != 0; x = x->next) { 13097c478bd9Sstevel@tonic-gate if (x->objectDN == 0) 13107c478bd9Sstevel@tonic-gate continue; 13117c478bd9Sstevel@tonic-gate if (wantWrite) { 13127c478bd9Sstevel@tonic-gate if (x->objectDN->write.scope == LDAP_SCOPE_UNKNOWN) 13137c478bd9Sstevel@tonic-gate continue; 13147c478bd9Sstevel@tonic-gate } else { 13157c478bd9Sstevel@tonic-gate if (x->objectDN->read.scope == LDAP_SCOPE_UNKNOWN) 13167c478bd9Sstevel@tonic-gate continue; 13177c478bd9Sstevel@tonic-gate } 13187c478bd9Sstevel@tonic-gate /* Only want table/entry mappings */ 13197c478bd9Sstevel@tonic-gate if (x->numColumns <= 0) 13207c478bd9Sstevel@tonic-gate continue; 13217c478bd9Sstevel@tonic-gate if (dbId != 0 && x->dbId != 0 && 13227c478bd9Sstevel@tonic-gate strcmp(dbId, x->dbId) != 0) 13237c478bd9Sstevel@tonic-gate continue; 13247c478bd9Sstevel@tonic-gate /* 13257c478bd9Sstevel@tonic-gate * It's a match if: there are no indexes, or we actually 13267c478bd9Sstevel@tonic-gate * match the query with the indexes. 13277c478bd9Sstevel@tonic-gate */ 13287c478bd9Sstevel@tonic-gate if (x->index.numIndexes <= 0 || 13297c478bd9Sstevel@tonic-gate verifyIndexMatch(x, q, 0, 0, 0)) { 13307c478bd9Sstevel@tonic-gate tp[nm] = x; 13317c478bd9Sstevel@tonic-gate nm++; 13327c478bd9Sstevel@tonic-gate } 13337c478bd9Sstevel@tonic-gate } 13347c478bd9Sstevel@tonic-gate 13357c478bd9Sstevel@tonic-gate if (nm == 0) { 13367c478bd9Sstevel@tonic-gate free(tp); 13377c478bd9Sstevel@tonic-gate tp = 0; 13387c478bd9Sstevel@tonic-gate } 13397c478bd9Sstevel@tonic-gate 13407c478bd9Sstevel@tonic-gate *numMatches = nm; 13417c478bd9Sstevel@tonic-gate 13427c478bd9Sstevel@tonic-gate return (tp); 13437c478bd9Sstevel@tonic-gate } 13447c478bd9Sstevel@tonic-gate 13457c478bd9Sstevel@tonic-gate /* 13467c478bd9Sstevel@tonic-gate * Return 1 if there's an indexed mapping, 0 otherwise. 13477c478bd9Sstevel@tonic-gate */ 13487c478bd9Sstevel@tonic-gate int 13497c478bd9Sstevel@tonic-gate haveIndexedMapping(__nis_table_mapping_t *t) { 13507c478bd9Sstevel@tonic-gate __nis_table_mapping_t *x; 13517c478bd9Sstevel@tonic-gate 13527c478bd9Sstevel@tonic-gate for (x = t; x != 0; x = x->next) { 13537c478bd9Sstevel@tonic-gate if (x->index.numIndexes > 0) 13547c478bd9Sstevel@tonic-gate return (1); 13557c478bd9Sstevel@tonic-gate } 13567c478bd9Sstevel@tonic-gate 13577c478bd9Sstevel@tonic-gate return (0); 13587c478bd9Sstevel@tonic-gate } 13597c478bd9Sstevel@tonic-gate 13607c478bd9Sstevel@tonic-gate /* 13617c478bd9Sstevel@tonic-gate * Given an input string 'attrs' of the form "attr1=val1,attr2=val2,...", 13627c478bd9Sstevel@tonic-gate * or a filter, return the value associated with the attribute 'attrName'. 13637c478bd9Sstevel@tonic-gate * If no instance of 'attrName' is found, return 'default'. In all cases, 13647c478bd9Sstevel@tonic-gate * the return value is a copy, and must be freed by the caller. 13657c478bd9Sstevel@tonic-gate * 13667c478bd9Sstevel@tonic-gate * Of course, return NULL in case of failure. 13677c478bd9Sstevel@tonic-gate */ 13687c478bd9Sstevel@tonic-gate static char * 13697c478bd9Sstevel@tonic-gate attrVal(char *msg, char *attrName, char *def, char *attrs) { 13707c478bd9Sstevel@tonic-gate char *val, *filter, **fc = 0; 13717c478bd9Sstevel@tonic-gate int i, nfc; 13727c478bd9Sstevel@tonic-gate char *myself = "attrVal"; 13737c478bd9Sstevel@tonic-gate 13747c478bd9Sstevel@tonic-gate if (attrName == 0 || attrs == 0) 13757c478bd9Sstevel@tonic-gate return (0); 13767c478bd9Sstevel@tonic-gate 13777c478bd9Sstevel@tonic-gate if (msg == 0) 13787c478bd9Sstevel@tonic-gate msg = myself; 13797c478bd9Sstevel@tonic-gate 13807c478bd9Sstevel@tonic-gate val = def; 13817c478bd9Sstevel@tonic-gate 13827c478bd9Sstevel@tonic-gate filter = makeFilter(attrs); 13837c478bd9Sstevel@tonic-gate if (filter != 0 && (fc = makeFilterComp(filter, &nfc)) != 0 && 13847c478bd9Sstevel@tonic-gate nfc > 0) { 13857c478bd9Sstevel@tonic-gate for (i = 0; i < nfc; i++) { 13867c478bd9Sstevel@tonic-gate char *name, *value; 13877c478bd9Sstevel@tonic-gate 13887c478bd9Sstevel@tonic-gate name = fc[i]; 13897c478bd9Sstevel@tonic-gate /* Skip if not of attr=value form */ 13907c478bd9Sstevel@tonic-gate if ((value = strchr(name, '=')) == 0) 13917c478bd9Sstevel@tonic-gate continue; 13927c478bd9Sstevel@tonic-gate 13937c478bd9Sstevel@tonic-gate *value = '\0'; 13947c478bd9Sstevel@tonic-gate value++; 13957c478bd9Sstevel@tonic-gate 13967c478bd9Sstevel@tonic-gate if (strcasecmp(attrName, name) == 0) { 13977c478bd9Sstevel@tonic-gate val = value; 13987c478bd9Sstevel@tonic-gate break; 13997c478bd9Sstevel@tonic-gate } 14007c478bd9Sstevel@tonic-gate } 14017c478bd9Sstevel@tonic-gate } 14027c478bd9Sstevel@tonic-gate 14037c478bd9Sstevel@tonic-gate if (val != 0) 14047c478bd9Sstevel@tonic-gate val = sdup(msg, T, val); 14057c478bd9Sstevel@tonic-gate 14067c478bd9Sstevel@tonic-gate sfree(filter); 14077c478bd9Sstevel@tonic-gate freeFilterComp(fc, nfc); 14087c478bd9Sstevel@tonic-gate 14097c478bd9Sstevel@tonic-gate return (val); 14107c478bd9Sstevel@tonic-gate } 14117c478bd9Sstevel@tonic-gate 14127c478bd9Sstevel@tonic-gate extern bool_t xdr_nis_object(register XDR *xdrs, nis_object *objp); 14137c478bd9Sstevel@tonic-gate 14147c478bd9Sstevel@tonic-gate /* 14157c478bd9Sstevel@tonic-gate * Copy an XDR:ed version of the NIS+ object 'o' (or the one indicated 14167c478bd9Sstevel@tonic-gate * by 't->objName' if 'o' is NULL) to the place indicated by 14177c478bd9Sstevel@tonic-gate * 't->objectDN->write'. Return an appropriate LDAP status code. 14187c478bd9Sstevel@tonic-gate */ 14197c478bd9Sstevel@tonic-gate int 14207c478bd9Sstevel@tonic-gate objToLDAP(__nis_table_mapping_t *t, nis_object *o, entry_obj **ea, int numEa) { 14217c478bd9Sstevel@tonic-gate __nis_table_mapping_t **tp; 14227c478bd9Sstevel@tonic-gate XDR xdr; 14237c478bd9Sstevel@tonic-gate char *objName; 14247c478bd9Sstevel@tonic-gate int stat, osize, n, numMatches = 0; 14257c478bd9Sstevel@tonic-gate void *buf; 14267c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv; 14277c478bd9Sstevel@tonic-gate __nis_value_t *val; 14287c478bd9Sstevel@tonic-gate __nis_single_value_t *sv; 14297c478bd9Sstevel@tonic-gate char **attrName, *dn; 14307c478bd9Sstevel@tonic-gate char *myself = "objToLDAP"; 14317c478bd9Sstevel@tonic-gate 14327c478bd9Sstevel@tonic-gate if (t == 0) 14337c478bd9Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 14347c478bd9Sstevel@tonic-gate 14357c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 14367c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 14377c478bd9Sstevel@tonic-gate LOG_WARNING, 14387c478bd9Sstevel@tonic-gate #else 14397c478bd9Sstevel@tonic-gate LOG_INFO, 14407c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 14417c478bd9Sstevel@tonic-gate "%s: %s", myself, NIL(t->objName)); 14427c478bd9Sstevel@tonic-gate 14437c478bd9Sstevel@tonic-gate tp = selectTableMapping(t, 0, 1, 1, 0, &numMatches); 14447c478bd9Sstevel@tonic-gate if (tp == 0 || numMatches <= 0) { 14457c478bd9Sstevel@tonic-gate sfree(tp); 14467c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 14477c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 14487c478bd9Sstevel@tonic-gate LOG_WARNING, 14497c478bd9Sstevel@tonic-gate #else 14507c478bd9Sstevel@tonic-gate LOG_INFO, 14517c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 14527c478bd9Sstevel@tonic-gate "%s: %s (no mapping)", myself, NIL(t->objName)); 14537c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 14547c478bd9Sstevel@tonic-gate } 14557c478bd9Sstevel@tonic-gate 14567c478bd9Sstevel@tonic-gate for (n = 0; n < numMatches; n++) { 14577c478bd9Sstevel@tonic-gate 14587c478bd9Sstevel@tonic-gate t = tp[n]; 14597c478bd9Sstevel@tonic-gate 14607c478bd9Sstevel@tonic-gate if (o == 0) { 14617c478bd9Sstevel@tonic-gate sfree(tp); 14627c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 14637c478bd9Sstevel@tonic-gate } 14647c478bd9Sstevel@tonic-gate 14657c478bd9Sstevel@tonic-gate buf = (char *)xdrNisObject(o, ea, numEa, &osize); 14667c478bd9Sstevel@tonic-gate if (buf == 0) { 14677c478bd9Sstevel@tonic-gate sfree(tp); 14687c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 14697c478bd9Sstevel@tonic-gate } 14707c478bd9Sstevel@tonic-gate 14717c478bd9Sstevel@tonic-gate /* 14727c478bd9Sstevel@tonic-gate * Prepare to build a rule-value containing the XDR:ed 14737c478bd9Sstevel@tonic-gate * object 14747c478bd9Sstevel@tonic-gate */ 14757c478bd9Sstevel@tonic-gate rv = am(myself, sizeof (*rv)); 14767c478bd9Sstevel@tonic-gate sv = am(myself, sizeof (*sv)); 14777c478bd9Sstevel@tonic-gate val = am(myself, sizeof (*val)); 14787c478bd9Sstevel@tonic-gate attrName = am(myself, sizeof (attrName[0])); 14797c478bd9Sstevel@tonic-gate if (attrName != 0) 14807c478bd9Sstevel@tonic-gate attrName[0] = attrVal(myself, "nisplusObject", 14817c478bd9Sstevel@tonic-gate "nisplusObject", 14827c478bd9Sstevel@tonic-gate t->objectDN->write.attrs); 14837c478bd9Sstevel@tonic-gate if (rv == 0 || sv == 0 || val == 0 || attrName == 0 || 14847c478bd9Sstevel@tonic-gate attrName[0] == 0) { 14857c478bd9Sstevel@tonic-gate sfree(tp); 14867c478bd9Sstevel@tonic-gate sfree(buf); 14877c478bd9Sstevel@tonic-gate sfree(rv); 14887c478bd9Sstevel@tonic-gate sfree(sv); 14897c478bd9Sstevel@tonic-gate sfree(val); 14907c478bd9Sstevel@tonic-gate sfree(attrName); 14917c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 14927c478bd9Sstevel@tonic-gate } 14937c478bd9Sstevel@tonic-gate 14947c478bd9Sstevel@tonic-gate sv->length = osize; 14957c478bd9Sstevel@tonic-gate sv->value = buf; 14967c478bd9Sstevel@tonic-gate 14977c478bd9Sstevel@tonic-gate /* 'vt_ber' just means "not a NUL-terminated string" */ 14987c478bd9Sstevel@tonic-gate val->type = vt_ber; 14997c478bd9Sstevel@tonic-gate val->repeat = 0; 15007c478bd9Sstevel@tonic-gate val->numVals = 1; 15017c478bd9Sstevel@tonic-gate val->val = sv; 15027c478bd9Sstevel@tonic-gate 15037c478bd9Sstevel@tonic-gate rv->numAttrs = 1; 15047c478bd9Sstevel@tonic-gate rv->attrName = attrName; 15057c478bd9Sstevel@tonic-gate rv->attrVal = val; 15067c478bd9Sstevel@tonic-gate 15077c478bd9Sstevel@tonic-gate /* 15087c478bd9Sstevel@tonic-gate * The 'write.base' is the actual DN of the entry (and the 15097c478bd9Sstevel@tonic-gate * scope had better be 'base', but we don't check that). 15107c478bd9Sstevel@tonic-gate */ 15117c478bd9Sstevel@tonic-gate dn = t->objectDN->write.base; 15127c478bd9Sstevel@tonic-gate 15137c478bd9Sstevel@tonic-gate stat = ldapModify(dn, rv, t->objectDN->write.attrs, 1); 15147c478bd9Sstevel@tonic-gate 15157c478bd9Sstevel@tonic-gate freeRuleValue(rv, 1); 15167c478bd9Sstevel@tonic-gate 15177c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 15187c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 15197c478bd9Sstevel@tonic-gate LOG_WARNING, 15207c478bd9Sstevel@tonic-gate #else 15217c478bd9Sstevel@tonic-gate LOG_INFO, 15227c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 15237c478bd9Sstevel@tonic-gate "%s: %s (%s)", myself, NIL(t->objName), ldap_err2string(stat)); 15247c478bd9Sstevel@tonic-gate 15257c478bd9Sstevel@tonic-gate if (stat != LDAP_SUCCESS) 15267c478bd9Sstevel@tonic-gate break; 15277c478bd9Sstevel@tonic-gate 15287c478bd9Sstevel@tonic-gate } 15297c478bd9Sstevel@tonic-gate 15307c478bd9Sstevel@tonic-gate sfree(tp); 15317c478bd9Sstevel@tonic-gate 15327c478bd9Sstevel@tonic-gate return (stat); 15337c478bd9Sstevel@tonic-gate } 15347c478bd9Sstevel@tonic-gate 15357c478bd9Sstevel@tonic-gate /* 15367c478bd9Sstevel@tonic-gate * Retrieve a copy of the 't->objName' object from LDAP, where it's 15377c478bd9Sstevel@tonic-gate * stored in XDR:ed form in the place indicated by 't->objectDN->read'. 15387c478bd9Sstevel@tonic-gate * Un-XDR the object, and return a pointer to it in '*obj'; it's the 15397c478bd9Sstevel@tonic-gate * responsibility of the caller to free the object when it's no 15407c478bd9Sstevel@tonic-gate * longer needed. 15417c478bd9Sstevel@tonic-gate * 15427c478bd9Sstevel@tonic-gate * Returns an appropriate LDAP status. 15437c478bd9Sstevel@tonic-gate */ 15447c478bd9Sstevel@tonic-gate int 15457c478bd9Sstevel@tonic-gate objFromLDAP(__nis_table_mapping_t *t, nis_object **obj, 15467c478bd9Sstevel@tonic-gate entry_obj ***eaP, int *numEaP) { 15477c478bd9Sstevel@tonic-gate __nis_table_mapping_t **tp; 15487c478bd9Sstevel@tonic-gate XDR xdr; 15497c478bd9Sstevel@tonic-gate nis_object *o; 15507c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv; 15517c478bd9Sstevel@tonic-gate __nis_ldap_search_t *ls; 15527c478bd9Sstevel@tonic-gate char *attrs[2], *filter, **fc = 0; 15537c478bd9Sstevel@tonic-gate void *buf; 15547c478bd9Sstevel@tonic-gate int i, j, nfc, nrv, blen, stat = LDAP_SUCCESS; 15557c478bd9Sstevel@tonic-gate int n, numMatches; 15567c478bd9Sstevel@tonic-gate char *myself = "objFromLDAP"; 15577c478bd9Sstevel@tonic-gate 15587c478bd9Sstevel@tonic-gate if (t == 0) 15597c478bd9Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 15607c478bd9Sstevel@tonic-gate 15617c478bd9Sstevel@tonic-gate /* 15627c478bd9Sstevel@tonic-gate * If there's nowhere to store the result, we might as 15637c478bd9Sstevel@tonic-gate * well pretend all went well, and return right away. 15647c478bd9Sstevel@tonic-gate */ 15657c478bd9Sstevel@tonic-gate if (obj == 0) 15667c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 15677c478bd9Sstevel@tonic-gate 15687c478bd9Sstevel@tonic-gate /* Prepare for the worst */ 15697c478bd9Sstevel@tonic-gate *obj = 0; 15707c478bd9Sstevel@tonic-gate 15717c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 15727c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 15737c478bd9Sstevel@tonic-gate LOG_WARNING, 15747c478bd9Sstevel@tonic-gate #else 15757c478bd9Sstevel@tonic-gate LOG_INFO, 15767c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 15777c478bd9Sstevel@tonic-gate "%s: %s", myself, NIL(t->objName)); 15787c478bd9Sstevel@tonic-gate 15797c478bd9Sstevel@tonic-gate tp = selectTableMapping(t, 0, 0, 1, 0, &numMatches); 15807c478bd9Sstevel@tonic-gate if (tp == 0 || numMatches <= 0) { 15817c478bd9Sstevel@tonic-gate sfree(tp); 15827c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 15837c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 15847c478bd9Sstevel@tonic-gate LOG_WARNING, 15857c478bd9Sstevel@tonic-gate #else 15867c478bd9Sstevel@tonic-gate LOG_INFO, 15877c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 15887c478bd9Sstevel@tonic-gate "%s: %s (no mapping)", myself, NIL(t->objName)); 15897c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 15907c478bd9Sstevel@tonic-gate } 15917c478bd9Sstevel@tonic-gate 15927c478bd9Sstevel@tonic-gate for (n = 0; n < numMatches; n++) { 15937c478bd9Sstevel@tonic-gate 15947c478bd9Sstevel@tonic-gate t = tp[n]; 15957c478bd9Sstevel@tonic-gate 15967c478bd9Sstevel@tonic-gate filter = makeFilter(t->objectDN->read.attrs); 15977c478bd9Sstevel@tonic-gate if (filter == 0 || (fc = makeFilterComp(filter, &nfc)) == 0 || 15987c478bd9Sstevel@tonic-gate nfc <= 0) { 15997c478bd9Sstevel@tonic-gate sfree(tp); 16007c478bd9Sstevel@tonic-gate sfree(filter); 16017c478bd9Sstevel@tonic-gate freeFilterComp(fc, nfc); 16027c478bd9Sstevel@tonic-gate return ((t->objectDN->read.attrs != 0) ? 16037c478bd9Sstevel@tonic-gate LDAP_NO_MEMORY : LDAP_PARAM_ERROR); 16047c478bd9Sstevel@tonic-gate } 16057c478bd9Sstevel@tonic-gate /* Don't need the filter, just the components */ 16067c478bd9Sstevel@tonic-gate sfree(filter); 16077c478bd9Sstevel@tonic-gate 16087c478bd9Sstevel@tonic-gate /* 16097c478bd9Sstevel@tonic-gate * Look for a "nisplusObject" attribute, and (if found) copy 16107c478bd9Sstevel@tonic-gate * the value to attrs[0]. Also remove the "nisplusObject" 16117c478bd9Sstevel@tonic-gate * attribute and value from the filter components. 16127c478bd9Sstevel@tonic-gate */ 16137c478bd9Sstevel@tonic-gate attrs[0] = sdup(myself, T, "nisplusObject"); 16147c478bd9Sstevel@tonic-gate if (attrs[0] == 0) { 16157c478bd9Sstevel@tonic-gate sfree(tp); 16167c478bd9Sstevel@tonic-gate freeFilterComp(fc, nfc); 16177c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 16187c478bd9Sstevel@tonic-gate } 16197c478bd9Sstevel@tonic-gate attrs[1] = 0; 16207c478bd9Sstevel@tonic-gate for (i = 0; i < nfc; i++) { 16217c478bd9Sstevel@tonic-gate char *name, *value; 16227c478bd9Sstevel@tonic-gate int compare; 16237c478bd9Sstevel@tonic-gate 16247c478bd9Sstevel@tonic-gate name = fc[i]; 16257c478bd9Sstevel@tonic-gate /* Skip if not of attr=value form */ 16267c478bd9Sstevel@tonic-gate if ((value = strchr(name, '=')) == 0) 16277c478bd9Sstevel@tonic-gate continue; 16287c478bd9Sstevel@tonic-gate 16297c478bd9Sstevel@tonic-gate /* Temporarily overWrite the '=' with a '\0' */ 16307c478bd9Sstevel@tonic-gate *value = '\0'; 16317c478bd9Sstevel@tonic-gate 16327c478bd9Sstevel@tonic-gate /* Compare with our target attribute name */ 16337c478bd9Sstevel@tonic-gate compare = strcasecmp("nisplusObject", name); 16347c478bd9Sstevel@tonic-gate 16357c478bd9Sstevel@tonic-gate /* Put back the '=' */ 16367c478bd9Sstevel@tonic-gate *value = '='; 16377c478bd9Sstevel@tonic-gate 16387c478bd9Sstevel@tonic-gate /* Is it the name we're looking for ? */ 16397c478bd9Sstevel@tonic-gate if (compare == 0) { 16407c478bd9Sstevel@tonic-gate sfree(attrs[0]); 16417c478bd9Sstevel@tonic-gate attrs[0] = sdup(myself, T, value+1); 16427c478bd9Sstevel@tonic-gate if (attrs[0] == 0) { 16437c478bd9Sstevel@tonic-gate sfree(tp); 16447c478bd9Sstevel@tonic-gate freeFilterComp(fc, nfc); 16457c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 16467c478bd9Sstevel@tonic-gate } 16477c478bd9Sstevel@tonic-gate sfree(fc[i]); 16487c478bd9Sstevel@tonic-gate if (i < nfc-1) 16497c478bd9Sstevel@tonic-gate (void) memmove(&fc[i], &fc[i+1], 16507c478bd9Sstevel@tonic-gate (nfc-1-i) * sizeof (fc[i])); 16517c478bd9Sstevel@tonic-gate nfc--; 16527c478bd9Sstevel@tonic-gate break; 16537c478bd9Sstevel@tonic-gate } 16547c478bd9Sstevel@tonic-gate } 16557c478bd9Sstevel@tonic-gate 16567c478bd9Sstevel@tonic-gate ls = buildLdapSearch(t->objectDN->read.base, 16577c478bd9Sstevel@tonic-gate t->objectDN->read.scope, 16587c478bd9Sstevel@tonic-gate nfc, fc, 0, attrs, 0, 1); 16597c478bd9Sstevel@tonic-gate sfree(attrs[0]); 16607c478bd9Sstevel@tonic-gate freeFilterComp(fc, nfc); 16617c478bd9Sstevel@tonic-gate if (ls == 0) { 16627c478bd9Sstevel@tonic-gate sfree(tp); 16637c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 16647c478bd9Sstevel@tonic-gate } 16657c478bd9Sstevel@tonic-gate 16667c478bd9Sstevel@tonic-gate nrv = 0; 16677c478bd9Sstevel@tonic-gate rv = ldapSearch(ls, &nrv, 0, &stat); 16687c478bd9Sstevel@tonic-gate if (rv == 0) { 16697c478bd9Sstevel@tonic-gate sfree(tp); 16707c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 16717c478bd9Sstevel@tonic-gate return (stat); 16727c478bd9Sstevel@tonic-gate } 16737c478bd9Sstevel@tonic-gate 16747c478bd9Sstevel@tonic-gate for (i = 0, buf = 0; i < nrv && buf == 0; i++) { 16757c478bd9Sstevel@tonic-gate for (j = 0; j < rv[i].numAttrs; j++) { 16767c478bd9Sstevel@tonic-gate if (strcasecmp(ls->attrs[0], 16777c478bd9Sstevel@tonic-gate rv[i].attrName[j]) == 0) { 16787c478bd9Sstevel@tonic-gate if (rv[i].attrVal[j].numVals <= 0) 16797c478bd9Sstevel@tonic-gate continue; 16807c478bd9Sstevel@tonic-gate buf = rv[i].attrVal[j].val[0].value; 16817c478bd9Sstevel@tonic-gate blen = rv[i].attrVal[j].val[0].length; 16827c478bd9Sstevel@tonic-gate break; 16837c478bd9Sstevel@tonic-gate } 16847c478bd9Sstevel@tonic-gate } 16857c478bd9Sstevel@tonic-gate } 16867c478bd9Sstevel@tonic-gate 16877c478bd9Sstevel@tonic-gate if (buf != 0) { 16887c478bd9Sstevel@tonic-gate o = unXdrNisObject(buf, blen, eaP, numEaP); 16897c478bd9Sstevel@tonic-gate if (o == 0) { 16907c478bd9Sstevel@tonic-gate sfree(tp); 16917c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 16927c478bd9Sstevel@tonic-gate freeRuleValue(rv, nrv); 16937c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 16947c478bd9Sstevel@tonic-gate } 16957c478bd9Sstevel@tonic-gate stat = LDAP_SUCCESS; 16967c478bd9Sstevel@tonic-gate *obj = o; 16977c478bd9Sstevel@tonic-gate } else { 16987c478bd9Sstevel@tonic-gate stat = LDAP_NO_SUCH_OBJECT; 16997c478bd9Sstevel@tonic-gate } 17007c478bd9Sstevel@tonic-gate 17017c478bd9Sstevel@tonic-gate freeLdapSearch(ls); 17027c478bd9Sstevel@tonic-gate freeRuleValue(rv, nrv); 17037c478bd9Sstevel@tonic-gate 17047c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 17057c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 17067c478bd9Sstevel@tonic-gate LOG_WARNING, 17077c478bd9Sstevel@tonic-gate #else 17087c478bd9Sstevel@tonic-gate LOG_INFO, 17097c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 17107c478bd9Sstevel@tonic-gate "%s: %s (%s)", myself, NIL(t->objName), ldap_err2string(stat)); 17117c478bd9Sstevel@tonic-gate 17127c478bd9Sstevel@tonic-gate if (stat != LDAP_SUCCESS) 17137c478bd9Sstevel@tonic-gate break; 17147c478bd9Sstevel@tonic-gate 17157c478bd9Sstevel@tonic-gate } 17167c478bd9Sstevel@tonic-gate 17177c478bd9Sstevel@tonic-gate sfree(tp); 17187c478bd9Sstevel@tonic-gate 17197c478bd9Sstevel@tonic-gate return (stat); 17207c478bd9Sstevel@tonic-gate } 17217c478bd9Sstevel@tonic-gate 17227c478bd9Sstevel@tonic-gate int 17237c478bd9Sstevel@tonic-gate deleteLDAPobj(__nis_table_mapping_t *t) { 17247c478bd9Sstevel@tonic-gate __nis_table_mapping_t **tp; 17257c478bd9Sstevel@tonic-gate int n, stat, numMatches = 0; 17267c478bd9Sstevel@tonic-gate char *myself = "deleteLDAPobj"; 17277c478bd9Sstevel@tonic-gate 17287c478bd9Sstevel@tonic-gate if (t == 0) 17297c478bd9Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 17307c478bd9Sstevel@tonic-gate 17317c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 17327c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 17337c478bd9Sstevel@tonic-gate LOG_WARNING, 17347c478bd9Sstevel@tonic-gate #else 17357c478bd9Sstevel@tonic-gate LOG_INFO, 17367c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 17377c478bd9Sstevel@tonic-gate "%s: %s", myself, NIL(t->objName)); 17387c478bd9Sstevel@tonic-gate 17397c478bd9Sstevel@tonic-gate tp = selectTableMapping(t, 0, 1, 1, 0, &numMatches); 17407c478bd9Sstevel@tonic-gate if (tp == 0 || numMatches <= 0) { 17417c478bd9Sstevel@tonic-gate sfree(tp); 17427c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 17437c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 17447c478bd9Sstevel@tonic-gate LOG_WARNING, 17457c478bd9Sstevel@tonic-gate #else 17467c478bd9Sstevel@tonic-gate LOG_INFO, 17477c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 17487c478bd9Sstevel@tonic-gate "%s: %s (no mapping)", myself, NIL(t->objName)); 17497c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 17507c478bd9Sstevel@tonic-gate } 17517c478bd9Sstevel@tonic-gate 17527c478bd9Sstevel@tonic-gate for (n = 0; n < numMatches; n++) { 17537c478bd9Sstevel@tonic-gate 17547c478bd9Sstevel@tonic-gate t = tp[n]; 17557c478bd9Sstevel@tonic-gate 17567c478bd9Sstevel@tonic-gate if (t->objectDN->delDisp == dd_always) { 17577c478bd9Sstevel@tonic-gate /* Delete entire entry */ 17587c478bd9Sstevel@tonic-gate stat = ldapModify(t->objectDN->write.base, 0, 17597c478bd9Sstevel@tonic-gate t->objectDN->write.attrs, 1); 17607c478bd9Sstevel@tonic-gate } else if (t->objectDN->delDisp == dd_perDbId) { 17617c478bd9Sstevel@tonic-gate /* 17627c478bd9Sstevel@tonic-gate * Delete the attribute holding the object. 17637c478bd9Sstevel@tonic-gate * First, determine what that attribute is called. 17647c478bd9Sstevel@tonic-gate */ 17657c478bd9Sstevel@tonic-gate char *attrName = 17667c478bd9Sstevel@tonic-gate attrVal(myself, 17677c478bd9Sstevel@tonic-gate "nisplusObject", 17687c478bd9Sstevel@tonic-gate "nisplusObject", 17697c478bd9Sstevel@tonic-gate t->objectDN->write.attrs); 17707c478bd9Sstevel@tonic-gate __nis_rule_value_t rv; 17717c478bd9Sstevel@tonic-gate __nis_value_t val; 17727c478bd9Sstevel@tonic-gate 17737c478bd9Sstevel@tonic-gate if (attrName == 0) { 17747c478bd9Sstevel@tonic-gate sfree(tp); 17757c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 17767c478bd9Sstevel@tonic-gate } 17777c478bd9Sstevel@tonic-gate 17787c478bd9Sstevel@tonic-gate /* 17797c478bd9Sstevel@tonic-gate * Build a __nis_value_t with 'numVals' < 0 to 17807c478bd9Sstevel@tonic-gate * indicate deletion. 17817c478bd9Sstevel@tonic-gate */ 17827c478bd9Sstevel@tonic-gate val.type = vt_ber; 17837c478bd9Sstevel@tonic-gate val.numVals = -1; 17847c478bd9Sstevel@tonic-gate val.val = 0; 17857c478bd9Sstevel@tonic-gate 17867c478bd9Sstevel@tonic-gate /* 17877c478bd9Sstevel@tonic-gate * Build a rule-value with the name we determined 17887c478bd9Sstevel@tonic-gate * above, and the deletion value. 17897c478bd9Sstevel@tonic-gate */ 17907c478bd9Sstevel@tonic-gate (void) memset(&rv, 0, sizeof (rv)); 17917c478bd9Sstevel@tonic-gate rv.numAttrs = 1; 17927c478bd9Sstevel@tonic-gate rv.attrName = &attrName; 17937c478bd9Sstevel@tonic-gate rv.attrVal = &val; 17947c478bd9Sstevel@tonic-gate 17957c478bd9Sstevel@tonic-gate stat = ldapModify(t->objectDN->write.base, &rv, 17967c478bd9Sstevel@tonic-gate t->objectDN->write.attrs, 0); 17977c478bd9Sstevel@tonic-gate 17987c478bd9Sstevel@tonic-gate sfree(attrName); 17997c478bd9Sstevel@tonic-gate } else if (t->objectDN->delDisp == dd_never) { 18007c478bd9Sstevel@tonic-gate /* Nothing to do, so we're trivially successful */ 18017c478bd9Sstevel@tonic-gate stat = LDAP_SUCCESS; 18027c478bd9Sstevel@tonic-gate } else { 18037c478bd9Sstevel@tonic-gate stat = LDAP_PARAM_ERROR; 18047c478bd9Sstevel@tonic-gate } 18057c478bd9Sstevel@tonic-gate 18067c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, 18077c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 18087c478bd9Sstevel@tonic-gate LOG_WARNING, 18097c478bd9Sstevel@tonic-gate #else 18107c478bd9Sstevel@tonic-gate LOG_INFO, 18117c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 18127c478bd9Sstevel@tonic-gate "%s: %s (%s)", myself, NIL(t->objName), ldap_err2string(stat)); 18137c478bd9Sstevel@tonic-gate 18147c478bd9Sstevel@tonic-gate /* If there were no such object, we've trivially succeeded */ 18157c478bd9Sstevel@tonic-gate if (stat == LDAP_NO_SUCH_OBJECT) 18167c478bd9Sstevel@tonic-gate stat = LDAP_SUCCESS; 18177c478bd9Sstevel@tonic-gate 18187c478bd9Sstevel@tonic-gate if (stat != LDAP_SUCCESS) 18197c478bd9Sstevel@tonic-gate break; 18207c478bd9Sstevel@tonic-gate 18217c478bd9Sstevel@tonic-gate } 18227c478bd9Sstevel@tonic-gate 18237c478bd9Sstevel@tonic-gate sfree(tp); 18247c478bd9Sstevel@tonic-gate 18257c478bd9Sstevel@tonic-gate return (stat); 18267c478bd9Sstevel@tonic-gate } 1827