/* parses a message to construct a nice contact */ OPENLDAP::ContactPtr OPENLDAP::Book::parse_result (LDAPMessage* message) { ContactPtr result; BerElement *ber = NULL; struct berval bv, *bvals; std::string username; std::map<std::string, std::string> call_addresses; char **attributes = bookinfo.urld->lud_attrs; int i, rc; /* skip past entry DN */ rc = ldap_get_dn_ber (ldap_context, message, &ber, &bv); while (rc == LDAP_SUCCESS) { rc = ldap_get_attribute_ber (ldap_context, message, ber, &bv, &bvals); if (bv.bv_val == NULL) break; if (attributes[0] == NULL || !g_ascii_strcasecmp(bv.bv_val, attributes[0])) { username = std::string (bvals[0].bv_val, bvals[0].bv_len); } else { for (i=1; attributes[i]; i++) { if (!g_ascii_strcasecmp(bv.bv_val,attributes[i]) && bvals && bvals[0].bv_val ) { /* FIXME: this is annoying. Assume if a colon is present that * the value is already in URI form, otherwise add a sip: prefix. */ if (strchr(bvals[0].bv_val, ':')) call_addresses[attributes[i]] = std::string (bvals[0].bv_val, bvals[0].bv_len); else call_addresses[attributes[i]] = std::string ("sip:") + std::string (bvals[0].bv_val, bvals[0].bv_len); } } } if (bvals) ber_memfree(bvals); } ber_free (ber, 0); if (!username.empty () && !call_addresses.empty()) { result = OPENLDAP::Contact::create (core, fix_to_utf8 (username), call_addresses); } return result; }
extern "C" std::string getRecipient(void * vh, Source * source) { ldap_handle * h = (ldap_handle *) vh; int msgtype; int code; int rc; struct berval bv; std::string result; if (!h) return ""; for (;;) { if (h->value && h->value->bv_val) { result = std::string(h->value->bv_val, h->value->bv_len); h->value++; if (result.length() > 5 && !strncasecmp(result.c_str(), "smtp:", 5)) result = result.substr(5); if (result.find_first_not_of(mailchars) != std::string::npos) continue; return result; } if (h->ber) { rc = ldap_get_attribute_ber(h->ldap, h->msg, h->ber, &bv, &h->values); h->value = h->values; if (rc == LDAP_SUCCESS && bv.bv_val) continue; } h->release_message(); rc = ldap_result(h->ldap, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &h->msg); if (!h->msg) throw ldap_error(rc); msgtype = ldap_msgtype(h->msg); switch (msgtype) { case LDAP_RES_SEARCH_RESULT: rc = ldap_parse_result(h->ldap, h->msg, &code, NULL, NULL, NULL, NULL, 0); if (rc != LDAP_SUCCESS) throw ldap_error(rc); if (code != LDAP_SUCCESS) throw ldap_error(code); return ""; case LDAP_RES_SEARCH_ENTRY: break; default: continue; } rc = ldap_get_dn_ber(h->ldap, h->msg, &h->ber, &bv); if (rc != LDAP_SUCCESS) throw ldap_error(rc); } return ""; }
static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf, size_t len, CURLcode *err) { ldapconninfo *li = conn->proto.generic; struct SessionHandle *data = conn->data; ldapreqinfo *lr = data->req.protop; int rc, ret; LDAPMessage *msg = NULL; LDAPMessage *ent; BerElement *ber = NULL; struct timeval tv = {0, 1}; (void)len; (void)buf; (void)sockindex; rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg); if(rc < 0) { failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc)); *err = CURLE_RECV_ERROR; return -1; } *err = CURLE_AGAIN; ret = -1; /* timed out */ if(!msg) return ret; for(ent = ldap_first_message(li->ld, msg); ent; ent = ldap_next_message(li->ld, ent)) { struct berval bv, *bvals, **bvp = &bvals; int binary = 0, msgtype; msgtype = ldap_msgtype(ent); if(msgtype == LDAP_RES_SEARCH_RESULT) { int code; char *info = NULL; rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0); if(rc) { failf(data, "LDAP local: search ldap_parse_result %s", ldap_err2string(rc)); *err = CURLE_LDAP_SEARCH_FAILED; } else if(code && code != LDAP_SIZELIMIT_EXCEEDED) { failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc), info ? info : ""); *err = CURLE_LDAP_SEARCH_FAILED; } else { /* successful */ if(code == LDAP_SIZELIMIT_EXCEEDED) infof(data, "There are more than %d entries\n", lr->nument); data->req.size = data->req.bytecount; *err = CURLE_OK; ret = 0; } lr->msgid = 0; ldap_memfree(info); break; } else if(msgtype != LDAP_RES_SEARCH_ENTRY) continue; lr->nument++; rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv); if(rc < 0) { /* TODO: verify that this is really how this return code should be handled */ *err = CURLE_RECV_ERROR; return -1; } *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4); if(*err) return -1; *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, bv.bv_len); if(*err) return -1; *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); if(*err) return -1; data->req.bytecount += bv.bv_len + 5; for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp); rc == LDAP_SUCCESS; rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) { int i; if(bv.bv_val == NULL) break; if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7)) binary = 1; else binary = 0; for(i=0; bvals[i].bv_val != NULL; i++) { int binval = 0; *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); if(*err) return -1; *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, bv.bv_len); if(*err) return -1; *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1); if(*err) return -1; data->req.bytecount += bv.bv_len + 2; if(!binary) { /* check for leading or trailing whitespace */ if(ISSPACE(bvals[i].bv_val[0]) || ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1])) binval = 1; else { /* check for unprintable characters */ unsigned int j; for(j=0; j<bvals[i].bv_len; j++) if(!ISPRINT(bvals[i].bv_val[j])) { binval = 1; break; } } } if(binary || binval) { char *val_b64 = NULL; size_t val_b64_sz = 0; /* Binary value, encode to base64. */ CURLcode error = Curl_base64_encode(data, bvals[i].bv_val, bvals[i].bv_len, &val_b64, &val_b64_sz); if(error) { ber_memfree(bvals); ber_free(ber, 0); ldap_msgfree(msg); *err = error; return -1; } *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2); if(*err) return -1; data->req.bytecount += 2; if(val_b64_sz > 0) { *err = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz); if(*err) return -1; free(val_b64); data->req.bytecount += val_b64_sz; } } else { *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1); if(*err) return -1; *err = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val, bvals[i].bv_len); if(*err) return -1; data->req.bytecount += bvals[i].bv_len + 1; } *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); if(*err) return -1; data->req.bytecount++; } ber_memfree(bvals); *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); if(*err) return -1; data->req.bytecount++; } *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); if(*err) return -1; data->req.bytecount++; ber_free(ber, 0); } ldap_msgfree(msg); return ret; }