#include <lber.h>
#include <ldap.h>
#include <string.h>
#include "ldap_util.h"
#include "ldap_op.h"
#include "ldap_attr.h"
#include "ldap_ldap.h"
static __nis_value_t *
evalMappingElement(__nis_mapping_element_t *e, __nis_rule_value_t *rvIn) {
__nis_rule_value_t *rv = rvIn;
int freeRv = 0;
__nis_value_t *val;
if (rv == 0) {
rv = initRuleValue(1, 0);
if (rv == 0)
return (0);
freeRv = 1;
}
val = getMappingElement(e, mit_any, rv, NULL);
if (freeRv)
freeRuleValue(rv, 1);
return (val);
}
__nis_value_t *
lookupLDAP(__nis_search_triple_t *t, char *attrName, __nis_rule_value_t *rv,
__nis_object_dn_t *def, int *np_ldap_stat) {
__nis_value_t *val, *eVal = 0;
char *base, *filter;
__nis_ldap_search_t *ls;
char *attrs[2];
int scope, i, stat, nrv = 0, freeBase = 0;
char *myself = "lookupLDAP";
if (t == 0 || slen(attrName) <= 0)
return (0);
if (t->element != 0) {
eVal = evalMappingElement(t->element, rv);
if (eVal == 0)
return (0);
if (eVal->type != vt_string || eVal->numVals <= 0) {
freeValue(eVal, 1);
{
char *ename = "<unknown>";
eVal = evalMappingElement(t->element, 0);
if (eVal != 0 && eVal->type == vt_string &&
eVal->numVals == 1 &&
eVal->val[0].length > 0 &&
eVal->val[0].value != 0)
ename = eVal->val[0].value;
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"%s: %s: unable to evaluate filter expression \"%s\"",
myself, attrName, ename);
freeValue(eVal, 1);
}
return (0);
}
filter = eVal->val[0].value;
} else {
filter = t->attrs;
}
if (slen(t->base) > 0) {
base = appendBase(t->base, (def != 0) ? def->read.base : 0,
&stat, 0);
if (stat != 0) {
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"%s: %s: error appending \"%s\" to \"%s\"",
myself, attrName, NIL(def->read.base),
NIL(t->base));
return (0);
}
freeBase = 1;
} else {
if (def == 0 || def->read.scope == LDAP_SCOPE_UNKNOWN ||
slen(def->read.base) <= 0) {
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"%s: %s: no supplied or default search base",
myself, attrName);
freeValue(eVal, 1);
return (0);
}
base = def->read.base;
}
if (slen(filter) > 0)
scope = t->scope;
else
scope = LDAP_SCOPE_BASE;
attrs[0] = attrName;
attrs[1] = 0;
ls = buildLdapSearch(base, scope, 0, 0, filter, attrs, 0, 0);
if (ls == 0) {
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"%s: %s: error building LDAP search information for \"%s?%s?%s\"",
myself, attrName, NIL(base), getScope(scope),
NIL(filter));
freeValue(eVal, 1);
if (freeBase)
sfree(base);
return (0);
}
rv = ldapSearch(ls, &nrv, 0, &stat);
freeLdapSearch(ls);
if (np_ldap_stat != NULL && stat == LDAP_NO_SUCH_OBJECT)
*np_ldap_stat = NP_LDAP_NO_VALUE;
if (rv == 0) {
logmsg(MSG_NOTIMECHECK,
(stat == LDAP_NO_SUCH_OBJECT)?LOG_DEBUG:LOG_ERR,
"%s: %s: LDAP error %d (%s) for \"%s?%s?%s\"",
myself, attrName, stat, ldap_err2string(stat),
NIL(base), getScope(scope), NIL(filter));
if (freeBase)
sfree(base);
freeValue(eVal, 1);
return (0);
}
if (freeBase)
sfree(base);
freeValue(eVal, 1);
eVal = 0;
for (i = 0, val = 0; i < nrv; i++) {
int j;
for (j = 0; j < rv[i].numAttrs; j++) {
if (strcasecmp(attrName, rv[i].attrName[j]) == 0) {
eVal = concatenateValues(val,
&rv[i].attrVal[j]);
freeValue(val, 1);
if (eVal == 0) {
freeRuleValue(rv, nrv);
return (0);
}
val = eVal;
break;
}
}
}
freeRuleValue(rv, nrv);
return (val);
}
int
storeLDAP(__nis_mapping_item_t *item, int index, int numIndexes,
__nis_value_t *val, __nis_object_dn_t *defDN,
char **dn, int numDN) {
__nis_ldap_search_t ls;
int stat, i, ix, six, nix;
int freeDN = 0;
char *locDN[1];
__nis_rule_value_t *rv;
char *defBase = 0;
char *myself = "storeLDAP";
if (item == 0 || item->type != mit_ldap || item->name == 0 ||
index < 0 || index >= numIndexes ||
val == 0 || val->numVals < -1 || val->numVals == 0)
return (LDAP_PARAM_ERROR);
if (defDN != 0 && slen(defDN->write.base) > 0)
defBase = defDN->write.base;
ls.numFilterComps = 0;
ls.filterComp = 0;
ls.numAttrs = 0;
ls.attrs = 0;
ls.isDN = 0;
if (item->searchSpec.triple.scope == LDAP_SCOPE_UNKNOWN) {
if (defDN == 0)
return (LDAP_PARAM_ERROR);
if (defDN != 0 && defDN->write.scope == LDAP_SCOPE_UNKNOWN) {
logmsg(MSG_NOTIMECHECK, LOG_INFO,
"%s: write not enabled for \"%s\"",
myself, NIL(item->name));
return (LDAP_SUCCESS);
}
} else {
if (slen(item->searchSpec.triple.base) > 0)
ls.base = item->searchSpec.triple.base;
else
ls.base = defBase;
ls.base = appendBase(ls.base, defBase, &stat, 0);
if (stat != 0)
return (0);
ls.scope = item->searchSpec.triple.scope;
if (slen(item->searchSpec.triple.attrs) > 0 ||
item->searchSpec.triple.element != 0) {
__nis_value_t *eVal = 0;
__nis_rule_value_t *rvDN;
int nv = 0;
if (item->searchSpec.triple.element != 0) {
eVal = evalMappingElement(
item->searchSpec.triple.element, 0);
if (eVal == 0) {
sfree(ls.base);
return (0);
}
if (eVal->type != vt_string ||
eVal->numVals <= 0) {
sfree(ls.base);
freeValue(eVal, 1);
return (0);
}
ls.filter = eVal->val[0].value;
} else {
ls.filter = item->searchSpec.triple.attrs;
}
rvDN = ldapSearch(&ls, &nv, 0, &stat);
sfree(ls.base);
freeValue(eVal, 1);
if (rvDN == 0 || nv <= 0)
return (stat);
dn = findDNs(myself, rvDN, nv, 0, &numDN);
freeRuleValue(rvDN, nv);
if (dn == 0 || numDN <= 0) {
freeDNs(dn, numDN);
return (LDAP_NO_MEMORY);
}
freeDN = 1;
} else if (slen(item->searchSpec.triple.base) > 0) {
locDN[0] = item->searchSpec.triple.base;
dn = locDN;
numDN = 1;
}
}
if (dn == 0 || numDN < 1) {
if (freeDN)
freeDNs(dn, numDN);
return (LDAP_PARAM_ERROR);
}
if (val->numVals > 0) {
rv = am(myself, sizeof (*rv));
if (rv == 0)
return (LDAP_NO_MEMORY);
rv->attrName = am(myself, sizeof (rv->attrName[0]));
rv->attrVal = am(myself, sizeof (rv->attrVal[0]));
if (rv->attrName == 0 || rv->attrVal == 0) {
if (freeDN)
freeDNs(dn, numDN);
freeRuleValue(rv, 1);
return (LDAP_NO_MEMORY);
}
if (index < val->numVals)
six = index;
else
six = val->numVals - 1;
if (item->repeat && index == (numIndexes - 1))
nix = 1 + (six - (val->numVals - 1));
else
nix = 1;
rv->attrName[0] = sdup(myself, T, item->name);
rv->attrVal[0].val = am(myself,
nix * sizeof (rv->attrVal[0].val[0]));
if (rv->attrName[0] == 0 || rv->attrVal[0].val == 0) {
if (freeDN)
freeDNs(dn, numDN);
freeRuleValue(rv, 1);
return (LDAP_NO_MEMORY);
}
rv->numAttrs = 1;
for (ix = six; ix < nix; ix++) {
rv->attrVal[0].numVals++;
rv->attrVal[0].val[ix-six].value =
am(myself, val->val[ix].length);
if (rv->attrVal[0].val[ix-six].value == 0 &&
val->val[ix].value != 0) {
if (freeDN)
freeDNs(dn, numDN);
freeRuleValue(rv, 1);
return (LDAP_NO_MEMORY);
}
rv->attrVal[0].val[ix-six].length =
val->val[ix].length;
if (rv->attrVal[0].val[ix-six].length > 0) {
(void) memcpy(rv->attrVal[0].val[ix-six].value,
val->val[ix].value,
rv->attrVal[0].val[ix-six].length);
}
}
rv->attrVal[0].type = val->type;
} else {
rv = 0;
}
for (i = 0; i < numDN; i++) {
stat = ldapModify(dn[i], rv, item->searchSpec.triple.attrs, 0);
if (stat != LDAP_SUCCESS)
break;
}
if (freeDN)
freeDNs(dn, numDN);
freeRuleValue(rv, 1);
return (stat);
}