Beispiel #1
0
datum *
getKeyFromRuleValue(__nis_table_mapping_t *t, __nis_rule_value_t *rv, int *nv,
					int *statP) {
	int	i, j;
	datum	*key = 0;
	char	*str;
	char	*myself = "getKeyFromRuleValue";

	/* No error yet */
	*statP = 0;

	if (rv == 0 || nv == 0)
		return (0);

	for (i = 0; i < rv->numColumns; i++) {
		if (rv->colName[i] == 0)
			continue;
		if (strcasecmp(N2LKEY, rv->colName[i]) == 0 ||
				strcasecmp(N2LIPKEY, rv->colName[i]) == 0) {
			if ((*nv = rv->colVal[i].numVals) == 0)
				return (0);
			if ((key = am(myself, sizeof (key[0]) * *nv)) == 0) {
				*statP = MAP_NO_MEMORY;
				return (0);
			}
			for (j = 0; j < *nv; j++) {
				if ((str = rv->colVal[i].val[j].value) == 0) {
					key[j].dsize = 0;
					key[j].dptr = 0;
				} else {
					if (verifyIndexMatch(t, 0, 0,
							rv->colName[i],
								str) == 0) {
						key[j].dsize = 0;
						key[j].dptr = 0;
						continue;
					}
					key[j].dsize = strlen(str);
					key[j].dptr = am(myself,
							key[j].dsize + 1);
					if (key[j].dptr == 0) {
						*statP = MAP_NO_MEMORY;
						for (--j; j >= 0; j--)
							sfree(key[j].dptr);
						sfree(key);
						return (0);
					}
					bcopy(str, key[j].dptr, key[j].dsize);
				}
			}
			return (key);
		}
	}
	return (0);
}
Beispiel #2
0
datum *
getKeyFromRuleValue(__nis_table_mapping_t *t, __nis_rule_value_t *rv, int *nv,
    int *statP, bool_t xlate_to_lcase)
{
	int	i, j, k;
	datum	*key = 0;
	char	*str;
	char	*myself = "getKeyFromRuleValue";

	/* No error yet */
	*statP = 0;

	if (rv == 0 || nv == 0)
		return (0);

	for (i = 0; i < rv->numColumns; i++) {
		if (rv->colName[i] == 0)
			continue;
		if (strcasecmp(N2LKEY, rv->colName[i]) == 0 ||
		    strcasecmp(N2LIPKEY, rv->colName[i]) == 0) {
			if ((*nv = rv->colVal[i].numVals) == 0)
				return (0);
			if ((key = am(myself, sizeof (key[0]) * *nv)) == 0) {
				*statP = MAP_NO_MEMORY;
				return (0);
			}
			for (j = 0; j < *nv; j++) {
				if ((str = rv->colVal[i].val[j].value) == 0) {
					key[j].dsize = 0;
					key[j].dptr = 0;
				} else {
					if (verifyIndexMatch(t, 0, 0,
					    rv->colName[i], str) == 0) {
						key[j].dsize = 0;
						key[j].dptr = 0;
						continue;
					}

					key[j].dsize = strlen(str);
					key[j].dptr = am(myself,
					    key[j].dsize + 1);
					if (key[j].dptr == 0) {
						*statP = MAP_NO_MEMORY;
						for (--j; j >= 0; j--)
							sfree(key[j].dptr);
						sfree(key);
						return (0);
					}

					/* transliterate key to lowercase */
					if (xlate_to_lcase == TRUE) {

						/*
						 * For multi-homed
						 * entries, skip over
						 * "YP_MULTI_" prefix.
						 */
						k = 0;
						if (strncmp(YPMULTI, str,
						    YPMULTISZ) == 0) {
							k = YPMULTISZ;
							bcopy(str, key[j].dptr,
							    YPMULTISZ);
						}
						while (k < key[j].dsize) {
							key[j].dptr[k] =
							    (char)tolower(
							    (int)(uchar_t)
							    str[k]);
							k++;
						}
					} else {
						bcopy(str, key[j].dptr,
						    key[j].dsize);
					}
				}
			}
			return (key);
		}
	}
	return (0);
}
Beispiel #3
0
/*
 * Updates 'rv' with NIS name=value pairs suitable to
 * construct datum from namefield information.
 * Some part based on createNisPlusEntry (from ldap_nisdbquery.c)
 * This code assumes that from a given LDAP entry, applying the
 * mapping rules, would give us one or more NIS entries, differing
 * only in key.
 */
suc_code
buildNISRuleValue(__nis_table_mapping_t *t, __nis_rule_value_t *rv,
					char *domain) {
	int			r, i, j, k, l, nrq, res, len;
	int			numItems, splitname, count, statP;
	__nis_value_t		*rval;
	__nis_mapping_item_t	*litem;
	__nis_mapping_rule_t	*rl;
	__nis_rule_value_t	*rvq;
	char			*value, *emptystr = "";

	statP = SUCCESS;

	/* Initialize default base */
	__nisdb_get_tsd()->searchBase = t->objectDN->read.base;

	/* Initialize rule-value rvq */
	rvq = 0;
	count = 0;

	/* Add domainname to rule-value */
	if (addCol2RuleValue(vt_string, N2LDOMAIN, domain, strlen(domain),
						rv)) {
		return (MAP_INTERNAL_ERROR);
	}

	for (r = 0; r < t->numRulesFromLDAP; r++) {
		rl = t->ruleFromLDAP[r];

		/* Set escapeFlag if RHS is "dn" to remove escape chars */
		if (rl->rhs.numElements == 1 &&
			rl->rhs.element->type == me_item &&
			rl->rhs.element->element.item.type == mit_ldap &&
			strcasecmp(rl->rhs.element->element.item.name, "dn")
									== 0) {
				__nisdb_get_tsd()->escapeFlag = '2';
		}

		rval = buildRvalue(&rl->rhs, mit_ldap, rv, NULL);

		/* Reset escapeFlag */
		__nisdb_get_tsd()->escapeFlag = '\0';

		if (rval == 0) {
			continue;
		}

		if (rval->numVals <= 0) {
			/* Treat as invalid */
			freeValue(rval, 1);
			continue;
		}

		litem = buildLvalue(&rl->lhs, &rval, &numItems);
		if (litem == 0) {
			/* This will take care of numItems == 0 */
			freeValue(rval, 1);
			continue;
		}

		if (rval->numVals > 1) {
			if (numItems == 1 && litem->repeat)
				nrq = rval->numVals;
			else if (numItems > 1 && rval->repeat)
				nrq = 1 + ((rval->numVals-1)/numItems);
			else
				nrq = 1;
		} else
			nrq = 1;

		/* Set splitname if splitfield names are specified */
		for (i = 0; i < numItems; i++) {
			if (strcasecmp(litem[i].name, N2LKEY) == 0 ||
				strcasecmp(litem[i].name, N2LIPKEY) == 0 ||
				strcasecmp(litem[i].name, N2LCOMMENT) == 0)
				continue;
			for (j = 0; j < t->numColumns; j++) {
				if (strcmp(litem[i].name, t->column[j]) == 0)
					break;
			}
			if (j == t->numColumns)
				break;
		}

		splitname = (i < numItems)?1:0;

		for (j = 0; j < nrq; j++) {
			if (splitname == 1) {
				/*
				 * Put every value of splitfieldname in a new
				 * rule-value. Helps generating splitfields.
				 */
				rvq = growRuleValue(count, count + 1, rvq, 0);
				if (rvq == 0) {
					freeRuleValue(rvq, count);
					freeValue(rval, 1);
					freeMappingItem(litem, numItems);
					return (MAP_INTERNAL_ERROR);
				}
				count++;
			}

			for (k = j % nrq, l = 0; l < numItems; k += nrq, l++) {
				/* If we run out of values, use empty strings */
				if (k >= rval->numVals) {
					value = emptystr;
					len = 0;
				} else {
					value = rval->val[k].value;
					len = rval->val[k].length;
				}
				res = (splitname == 1)?addCol2RuleValue(
					vt_string, litem[l].name, value,
					len, &rvq[count - 1]):0;
				if (res != -1)
					res = addCol2RuleValue(vt_string,
						litem[l].name, value, len, rv);
				if (res == -1) {
					freeRuleValue(rvq, count);
					freeValue(rval, 1);
					freeMappingItem(litem, numItems);
					return (MAP_INTERNAL_ERROR);
				}
			}
		}
		freeValue(rval, 1);
		rval = 0;
		freeMappingItem(litem, numItems);
		litem = 0;
		numItems = 0;
	} /* for r < t->numRulesFromLDAP */

	statP = addSplitFieldValues(t, rvq, rv, count, domain);

	if (rvq)
		freeRuleValue(rvq, count);

	if (verifyIndexMatch(t, 0, rv, 0, 0) == 0)
		return (MAP_INDEXLIST_ERROR);
	return (statP);

} /* end of buildNISRuleValue */
Beispiel #4
0
/*
 * Maps and writes a single NIS entry to the LDAP DIT
 */
int
singleWriteToDIT(char *map, char *domain, datum *key, datum *value,
						bool_t replace) {
	__nis_table_mapping_t	*t;
	__nis_rule_value_t	*rv, *frv;
	__nis_ldap_search_t	*ls;
	int			statP = SUCCESS, flag;
	int			nv, nr, i, rc, collapse;
	char			*dn = 0, *skey, *svalue, *str;
	char			*myself = "singleWriteToDIT";

	if (!map || !domain || !key || !value) {
		return (MAP_PARAM_ERROR);
	}

	/* Return SUCCESS for empty or whitespace key */
	for (i = 0; i < key->dsize && (key->dptr[i] == 0 ||
		key->dptr[i] == ' ' || key->dptr[i] == '\t'); i++);
	if (i >= key->dsize)
		return (SUCCESS);

	/* Get the mapping information for the map */
	if ((t = mappingFromMap(map, domain, &statP)) == 0) {
		/*
		 * No problem. We don't handle this map and domain. Maybe it's
		 * handled by a service other than NIS.
		 */
		return (statP);
	}

	/* NULL-terminated version of key and value for logging */
	if ((skey = am(myself, key->dsize + 1)) == 0)
		return (MAP_NO_MEMORY);
	(void) memcpy(skey, key->dptr, key->dsize);

	if ((svalue = am(myself, value->dsize + 1)) == 0) {
		sfree(skey);
		return (MAP_NO_MEMORY);
	}
	(void) memcpy(svalue, value->dptr, value->dsize);

	if ((str = getFullMapName(map, domain)) == 0) {
		sfree(skey);
		sfree(svalue);
		return (MAP_NO_MEMORY);
	}

	/* For each alternate mapping */
	for (flag = 0; t != 0; t = t->next) {
		/* Verify objName */
		if (strcmp(str, t->objName) != 0) {
			continue;
		}

		/* Verify if key matches the index */
		if (verifyIndexMatch(t, 0, 0, N2LKEY, skey) == 0 ||
			verifyIndexMatch(t, 0, 0, N2LIPKEY, skey) == 0)
			continue;

		/* Check the writespecs */
		if (t->objectDN->write.base == 0) {
			logmsg(MSG_NOTIMECHECK, LOG_INFO,
				"%s: No baseDN in writespec. Write disabled "
				"for %s (%s)", myself, t->dbId, map);
			continue;
		}

		/* Check if rulesToLDAP are provided */
		if (t->numRulesToLDAP == 0) {
			logmsg(MSG_NOTIMECHECK, LOG_INFO,
				"%s: No rulesToLDAP. Write disabled for "
				"%s (%s)", myself, t->dbId, map);
			continue;
		}

		/* Set flag to indicate write is enabled */
		flag = 1;

		/* Convert key  and value into an array of rule-values */
		if ((rv = datumToRuleValue(key, value, t, &nv, domain, FALSE,
								&statP)) == 0) {
			logmsg(MSG_NOTIMECHECK, LOG_ERR,
				"%s: Conversion error %d (NIS to name=value "
				"pairs) for NIS data (key=%s, value=%s) "
				"for %s (%s)",
				myself, statP, skey, svalue, t->dbId, map);
			sfree(skey);
			sfree(svalue);

			/* Free full map name */
			sfree(str);

			return (statP);
		}

		/* Convert NIS data to LDAP equivalents for each rule-value */
		for (i = 0; i < nv; i++) {
			/* Verify indexlist with name=value pairs */
			if (verifyIndexMatch(t, 0, &rv[i], 0, 0) == 0)
				break;

			/* Create LDAP request and LDAP name=value pairs */
			if ((ls = createLdapRequest(t, &rv[i],
			    0, 0, NULL, NULL)) == 0) {
				logmsg(MSG_NOTIMECHECK, LOG_ERR,
					"%s: Conversion error (name=value pairs"
					" to LDAP) for NIS data "
					"(key=%s, value=%s) for %s (%s)",
					myself, skey, svalue, t->dbId, map);
				freeRuleValue(rv, nv);
				sfree(skey);
				sfree(svalue);

				/* Free full map name */
				sfree(str);

				return (MAP_CREATE_LDAP_REQUEST_ERROR);
			}
			freeLdapSearch(ls);
			/* printRuleValue(&rv[i]); */
		}

		/* If i < nv then this alternate mapping isn't the one */
		if (i < nv)
			continue;

		/*
		 * Merge rule-values with the same DN so that we have
		 * one ldap write request for each DN
		 */
		nr = nv;
		frv = mergeRuleValueWithSameDN(rv, &nr);
		freeRuleValue(rv, nv);
		if (frv == 0) {
			if (nr == -1) {
				logmsg(MSG_NOTIMECHECK, LOG_ERR,
					"%s: Unable to merge LDAP write "
					"requests to same DN for NIS data "
					"(key=%s, value=%s) for %s (%s)",
					myself, skey, svalue, t->dbId, map);
				statP = MAP_INTERNAL_ERROR;
			} else if (nr == 0) {
				logmsg(MSG_NOTIMECHECK, LOG_WARNING,
					"%s: Cannot generate write DN due to "
					"missing information for NIS data "
					"(key=%s, value=%s) for %s (%s)",
					myself, skey, svalue, t->dbId, map);
				statP = MAP_NO_DN;
			}
			sfree(skey);
			sfree(svalue);

			/* Free full map name */
			sfree(str);

			return (statP);
		}

		/* Write to the LDAP server */
		for (collapse = 0, i = 0; i < nr; i++) {
			if ((dn = findVal("dn", &frv[i], mit_ldap)) != 0) {
				if (replace == FALSE) {
					/* ldap add */
					rc = ldapAdd(dn, &frv[i],
						t->objectDN->write.attrs, 0);
				} else {
					/* ldap modify with addFirst set */
					rc = ldapModify(dn, &frv[i],
						t->objectDN->write.attrs, 1);
				}

				/* if we get err=20, collapse and try again */
				if (!collapse &&
					(rc == LDAP_TYPE_OR_VALUE_EXISTS) &&
					(collapseRuleValue(&frv[i]) == 1)) {
					logmsg(MSG_NOTIMECHECK, LOG_WARNING,
						"%s: Ignoring values differing "
						"in case from NIS data (key=%s,"
						" value=%s) for (dn: %s) for "
						"%s (%s)", myself, skey,
						svalue, dn, t->dbId, map);
					collapse = 1;
					i--;
					continue;
				}

				collapse = 0;
				if (rc != LDAP_SUCCESS) {
					/* Log error */
					logmsg(MSG_NOTIMECHECK, LOG_ERR,
						"%s: %s error %d (%s) for "
						"(dn: %s) for NIS data "
						"(key=%s, value=%s) "
						"for %s (%s)",
						myself, (replace == TRUE) ?
						"ldapModify" : "ldapAdd", rc,
						ldap_err2string(rc), dn, skey,
						svalue, t->dbId, map);

					/* Dumping failed call may be useful */
					/* printRuleValue(&frv[i]); */

					/*
					 * Return the error code and let wrapper
					 * sort out if mapping should continue
					 * or abort.
					 */
					statP = rc;
					sfree(skey);
					sfree(svalue);
					freeRuleValue(frv, nr);

					/* Free full map name */
					sfree(str);

					return (statP);
				}
			}
		}

		freeRuleValue(frv, nr);
	}

	sfree(skey);
	sfree(svalue);

	/* Free full map name */
	sfree(str);

	return ((flag)?SUCCESS:MAP_WRITE_DISABLED);
}
Beispiel #5
0
/*
 * Read (i.e get and map) a single NIS entry from the LDAP DIT
 */
bool_t
singleReadFromDIT(char *map, char *domain, datum *key, datum *value,
							int *statP) {
	__nis_table_mapping_t	*t;
	__nis_rule_value_t	*rv_request = 0, *rv_result = 0;
	__nis_ldap_search_t	*ls;
	__nis_object_dn_t	*objectDN = NULL;
	int			i, rc, nr = 0;
	datum			*datval = 0;
	char			*skey, *str;
	char			*myself = "singleReadFromDIT";

	*statP = SUCCESS;

	if (!map || !domain || !key || !value) {
		*statP = MAP_PARAM_ERROR;
		return (FALSE);
	}


	/* Get the mapping information for the map */
	if ((t = mappingFromMap(map, domain, statP)) == 0) {
		/*
		 * No problem. We don't handle this map and domain. Maybe it's
		 * handled by a service other than NIS.
		 */
		return (FALSE);
	}

	/* NULL-terminated version of datum key for logging */
	if ((skey = am(myself, key->dsize + 1)) == 0) {
		*statP = MAP_NO_MEMORY;
		return (FALSE);
	}
	(void) memcpy(skey, key->dptr, key->dsize);

	if ((str = getFullMapName(map, domain)) == 0) {
		*statP = MAP_NO_MEMORY;
		return (FALSE);
	}

	/* For each alternate mapping */
	for (; t != 0; t = t->next) {
		/* Verify objName */
		if (strcmp(str, t->objName) != 0) {
			continue;
		}

		/* Verify if key matches the index */
		if (verifyIndexMatch(t, 0, 0, N2LKEY, skey) == 0 ||
			verifyIndexMatch(t, 0, 0, N2LIPKEY, skey) == 0)
			continue;

		/* Check if rulesFromLDAP are provided */
		if (t->numRulesFromLDAP == 0) {
			logmsg(MSG_NOTIMECHECK, LOG_INFO,
				"%s: No rulesFromLDAP information available "
				"for %s (%s)", myself, t->dbId, map);
			continue;
		}

		/* Convert key into rule-value */
		if ((rv_request = datumToRuleValue(key, 0, t, 0, domain, TRUE,
								statP)) == 0) {
			logmsg(MSG_NOTIMECHECK, LOG_ERR,
				"%s: Conversion error %d (NIS to name=value "
				"pairs) for NIS key (%s) for %s (%s)",
				myself, *statP, skey, t->dbId, map);
			continue;
		}
		/* Convert rule-value into ldap request */
		for (objectDN = t->objectDN; objectDN &&
				objectDN->read.base;
				objectDN = objectDN->next) {
			ls = createLdapRequest(t, rv_request, 0, 1, NULL,
								objectDN);
			if (ls == 0) {
				*statP = MAP_CREATE_LDAP_REQUEST_ERROR;
				logmsg(MSG_NOTIMECHECK, LOG_ERR,
					"%s: Failed to create ldapSearch "
					"request for "
					"NIS key (%s) for %s (%s) "
					"for base %s",
					myself, skey, t->dbId, map,
					objectDN->read.base);
				continue;
			}
			ls->timeout.tv_sec = SINGLE_ACCESS_TIMEOUT_SEC;
			ls->timeout.tv_usec = SINGLE_ACCESS_TIMEOUT_USEC;
			/* Query LDAP */
			nr = (ls->isDN)?0:-1;
			rv_result = ldapSearch(ls, &nr, 0, statP);
			freeLdapSearch(ls);
			if (rv_result == 0) {
				if (*statP == LDAP_NO_SUCH_OBJECT) {
					/* Entry does not exist in */
					/* the ldap server */
				}
				continue;
			}
			freeRuleValue(rv_request, 1);
			rv_request = 0;

			/* if result > 1, first match will be returned */
			if (nr > 1) {
				logmsg(MSG_NOTIMECHECK, LOG_INFO,
					"%s: %d ldapSearch results "
					"for NIS key (%s) "
					"for %s (%s) for base %s. "
					"First match will be returned ",
					myself, nr, skey, t->dbId, map,
					objectDN->read.base);
			}

			for (i = 0; i < nr; i++) {
				/* Convert LDAP data to NIS equivalents */
				*statP = buildNISRuleValue(t, &rv_result[i],
								domain);
				if (*statP == MAP_INDEXLIST_ERROR)
					continue;

				if (*statP != SUCCESS) {
					logmsg(MSG_NOTIMECHECK, LOG_WARNING,
					"%s: Conversion error %d (LDAP to "
					"name=value pairs) for NIS key (%s) "
					"for %s (%s) for base %s", myself,
					*statP, skey,
					t->dbId, map, objectDN->read.base);
					continue;
				}

			/*
			 * Check if 'key' from the ldap result matches the key
			 * provided by our caller
			 */
				if ((rc = verifyKey(skey, &rv_result[i]))
						== -1) {
					logmsg(MSG_NOTIMECHECK, LOG_INFO,
					"%s: Cannot verify key from ldap "
					"result for NIS key (%s) for %s (%s) "
					"for base %s",
					myself, skey, t->dbId, map,
					objectDN->read.base);
					continue;
				}

				if (rc == 1) {
					datval = ruleValueToDatum(t,
							&rv_result[i], statP);
					if (datval == 0) {
						logmsg(MSG_NOTIMECHECK,
						LOG_WARNING,
						"%s: Conversion error %d "
						"(name=value pairs to NIS) "
						"for NIS key (%s) for %s (%s)"
						" for base %s",
						myself,
						*statP, skey, t->dbId, map,
						objectDN->read.base);
						continue;
					}
					if (value) {
						value->dptr = datval->dptr;
						value->dsize = datval->dsize;
					}
					sfree(datval);
					sfree(skey);
					freeRuleValue(rv_result, nr);
					rv_result = 0;
					*statP = SUCCESS;

					/* Free full map name */
					sfree(str);

					return (TRUE);
				}
			}
			freeRuleValue(rv_result, nr);
			rv_result = 0;
		}   /* end of for over objectDN */

		if (rv_request != 0) {
			freeRuleValue(rv_request, 1);
			rv_request = 0;
		}
		if (rv_result != 0) {
			freeRuleValue(rv_result, nr);
			rv_result = 0;
		}
	}
	sfree(skey);
	*statP = MAP_NO_MATCHING_KEY;

	/* Free full map name */
	sfree(str);

	return (FALSE);
}