static int _is_OU (const char* attr) { auto struct _attr_getter_pair* descAttr; for (descAttr = _attr_getter_table; descAttr->name1; ++descAttr) { if (descAttr->getter == NULL) { /* OU attribute */ if (!ldapu_strcasecmp (attr, descAttr->name1) || (descAttr->name2 && !ldapu_strcasecmp (attr, descAttr->name2))) { return 1; } break; } } return 0; }
static int certmap_name_to_secoid (const char *str) { if (!ldapu_strcasecmp(str, "c")) return SEC_OID_AVA_COUNTRY_NAME; if (!ldapu_strcasecmp(str, "o")) return SEC_OID_AVA_ORGANIZATION_NAME; if (!ldapu_strcasecmp(str, "cn")) return SEC_OID_AVA_COMMON_NAME; if (!ldapu_strcasecmp(str, "l")) return SEC_OID_AVA_LOCALITY; if (!ldapu_strcasecmp(str, "st")) return SEC_OID_AVA_STATE_OR_PROVINCE; if (!ldapu_strcasecmp(str, "ou")) return SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME; if (!ldapu_strcasecmp(str, "uid")) return SEC_OID_RFC1274_UID; if (!ldapu_strcasecmp(str, "e")) return SEC_OID_PKCS9_EMAIL_ADDRESS; if (!ldapu_strcasecmp(str, "mail")) return SEC_OID_RFC1274_MAIL; if (!ldapu_strcasecmp(str, "dc")) return SEC_OID_AVA_DC; return SEC_OID_AVA_UNKNOWN; /* return invalid OID */ }
NSAPI_PUBLIC int ldapu_dbinfo_attrval (DBConfDBInfo_t *db_info, const char *attr, char **val) { /* Look for given attr in the db_info and return its value */ int rv = LDAPU_ATTR_NOT_FOUND; DBPropVal_t *next; *val = 0; if (db_info) { next = db_info->firstprop; while (next) { rv = ldapu_strcasecmp(attr, next->prop); if (!rv) { /* Found the property */ *val = next->val ? strdup(next->val) : 0; if (next->val && !*val) { rv = LDAPU_ERR_OUT_OF_MEMORY; } else { rv = LDAPU_SUCCESS; } break; } next = next->next; } } return rv; }
static int _value_match (char* value, char* desc) { auto const int result = !ldapu_strcasecmp (_value_normalize(value), desc); return result; }
static int _replaceAVA (char* attr, char** avas) { if (attr && avas) { for (; *avas; ++avas) { if (!ldapu_strcasecmp (*avas, attr)) { *avas = attr; return 1; } } } return 0; }
int ldapu_member_certificate_match (void* cert, const char* desc) /* * Return Values: (same as ldapu_find) * LDAPU_SUCCESS cert matches desc * LDAPU_FAILED cert doesn't match desc * <rv> Something went wrong. */ { auto int err = LDAPU_FAILED; auto char*** descRDNs; if (!cert || !desc || desc[0] != '{') return LDAPU_FAILED; if (desc[1] == '\0') return LDAPU_SUCCESS; /* no AVAs */ descRDNs = _explode_dn (desc+1); if (descRDNs) { auto char** descAVAs = (char**)ldapu_malloc(sizeof(char*) * (_rdns_count(descRDNs)+1)); if (!descAVAs) { err = LDAPU_ERR_OUT_OF_MEMORY; } else { auto CERTName* subject = &(((CERTCertificate*)cert)->subject); auto char** descAVA; err = LDAPU_SUCCESS; { /* extract all the AVAs, but not duplicate types, except OU */ auto size_t descAVAsLen = 0; auto char*** descRDN; descAVAs[0] = NULL; for (descRDN = descRDNs; err == LDAPU_SUCCESS && *descRDN; ++descRDN) { for (descAVA = *descRDN; err == LDAPU_SUCCESS && *descAVA; ++descAVA) { err = _explode_AVA (*descAVA); if (err == LDAPU_SUCCESS) { if (_is_OU (*descAVA) || !_replaceAVA (*descAVA, descAVAs)) { descAVAs[descAVAsLen++] = *descAVA; descAVAs[descAVAsLen] = NULL; } } } } } /* match all the attributes except OU */ for (descAVA = descAVAs; err == LDAPU_SUCCESS && *descAVA; ++descAVA) { auto struct _attr_getter_pair* descAttr; err = LDAPU_FAILED; /* if no match */ for (descAttr = _attr_getter_table; descAttr->name1; ++descAttr) { if (!ldapu_strcasecmp (*descAVA, descAttr->name1) || (descAttr->name2 && !ldapu_strcasecmp (*descAVA, descAttr->name2))) { if (descAttr->getter == NULL) { /* OU attribute */ err = LDAPU_SUCCESS; /* for now */ } else { auto char* certVal = (*(descAttr->getter))(subject); if (certVal && _value_match (certVal, _AVA_value (*descAVA))) { err = LDAPU_SUCCESS; } PR_Free (certVal); } break; } } } /* match the OU attributes */ if (err == LDAPU_SUCCESS && descAVA != descAVAs) { /* Iterate over the OUs in the certificate subject */ auto CERTRDN** certRDN = subject->rdns; descAVA = _previous_OU (descAVA, descAVAs); for (; descAVA && *certRDN; ++certRDN) { auto CERTAVA** certAVA = (*certRDN)->avas; for (; descAVA && *certAVA; ++certAVA) { auto const int tag = CERT_GetAVATag (*certAVA); if (tag == SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME) { auto const size_t certValLen =(*certAVA)->value.len; auto const size_t lenLen = (certValLen < 128) ? 2 : 3; auto const size_t buflen = certValLen - lenLen; auto char* buf = (char*)ldapu_malloc(buflen+1); if (!buf) { err = LDAPU_ERR_OUT_OF_MEMORY; descAVA = NULL; } else { memcpy (buf, (*certAVA)->value.data+lenLen, buflen); buf[buflen] = 0; if (_value_match (buf, _AVA_value (*descAVA))) { descAVA = _previous_OU (descAVA, descAVAs); } free (buf); } } } } if (descAVA) { err = LDAPU_FAILED; /* no match for descAVA in subject */ } } free (descAVAs); } _rdns_free (descRDNs); } return err; }