static int ldap_query(const char *filter, char **attributes, char ***outp, size_t n) { struct aldap_message *m = NULL; struct aldap_page_control *pg = NULL; int ret, found; size_t i; char basedn__[MAX_LDAP_BASELEN]; char filter__[MAX_LDAP_FILTERLEN]; if (strlcpy(basedn__, basedn, sizeof basedn__) >= sizeof basedn__) return -1; if (strlcpy(filter__, filter, sizeof filter__) >= sizeof filter__) return -1; found = 0; do { if ((ret = aldap_search(aldap, basedn__, LDAP_SCOPE_SUBTREE, filter__, NULL, 0, 0, 0, pg)) == -1) { return -1; } if (pg != NULL) { aldap_freepage(pg); pg = NULL; } while ((m = aldap_parse(aldap)) != NULL) { if (aldap->msgid != m->msgid) goto error; if (m->message_type == LDAP_RES_SEARCH_RESULT) { if (m->page != NULL && m->page->cookie_len) pg = m->page; aldap_freemsg(m); m = NULL; break; } if (m->message_type != LDAP_RES_SEARCH_ENTRY) goto error; found = 1; for (i = 0; i < n; ++i) if (aldap_match_attr(m, attributes[i], &outp[i]) != 1) goto error; aldap_freemsg(m); m = NULL; } } while (pg != NULL); ret = found ? 1 : 0; goto end; error: ret = -1; end: if (m) aldap_freemsg(m); log_debug("debug: table_ldap_internal_query: filter=%s, ret=%d", filter, ret); return ret; }
int main(int argc, char **argv) { struct aldap_url url; struct aldap_search params; char *hostname = NULL; const char *binddn = NULL, *passwd = NULL; struct aldap *ld; struct aldap_message *res; struct ber_val *cookie = NULL; const char *errmsg; char **values, **val; int c, port = 0, starttls = 1, ret, i; int msgid, code, pagesize = 1000; bzero(&url, sizeof(url)); bzero(¶ms, sizeof(params)); params.scope = 42; /* auto-detect: base for root DSE, subtree otherwise */ while ((c = getopt(argc, argv, "h:CH:p:P:D:WZvw:b:s:l:z:x")) != -1) { switch (c) { case 'h': hostname = optarg; break; case 'H': aldap_free_url(&url); bzero(&url, sizeof(url)); if (aldap_parse_url(optarg, &url) == -1) errx(2, "invalid LDAP URL: %s", optarg); hostname = url.host; port = url.port; params.basedn = url.params.basedn; params.filter = url.params.filter; params.scope = url.params.scope; bcopy(&url.params.attributes, ¶ms.attributes, sizeof(params.attributes)); if (port == 0 && url.protocol == LDAPS) port = 636; break; case 'p': port = strtonum(optarg, 1, 65535, &errmsg); if (errmsg != NULL) errx(1, "port is %s", errmsg); break; case 'P': pagesize = strtonum(optarg, 0, INT_MAX, &errmsg); if (errmsg != NULL) errx(1, "page size is %s", errmsg); break; case 'D': binddn = optarg; break; case 'C': starttls = 0; break; case 'Z': starttls = 2; break; case 'w': passwd = optarg; break; case 'l': if (strcasecmp(optarg, "none") == 0) params.timelimit = 0; else if (strcasecmp(optarg, "max") == 0) params.timelimit = INT_MAX; else { params.timelimit = strtonum(optarg, 0, INT_MAX, &errmsg); if (errmsg != NULL) errx(1, "time limit is %s", errmsg); } break; case 'z': if (strcasecmp(optarg, "none") == 0) params.sizelimit = 0; else if (strcasecmp(optarg, "max") == 0) params.sizelimit = INT_MAX; else { params.sizelimit = strtonum(optarg, 0, INT_MAX, &errmsg); if (errmsg != NULL) errx(1, "size limit is %s", errmsg); } break; case 'W': case 'x': break; case 'b': params.basedn = optarg; break; case 's': if (strcmp(optarg, "base") == 0) params.scope = LDAP_SCOPE_BASE; else if (strcmp(optarg, "one") == 0) params.scope = LDAP_SCOPE_ONELEVEL; else if (strcmp(optarg, "sub") == 0) params.scope = LDAP_SCOPE_SUBTREE; break; default: usage(); return 1; } } argc -= optind; argv += optind; if (argc > 0) { if (strchr(argv[0], '=') != NULL) { /* looks like a search filter */ params.filter = argv[0]; argc -= 1; argv += 1; } } if (params.basedn == NULL) params.basedn = ""; if (params.scope == 42) { if (*params.basedn == '\0') params.scope = LDAP_SCOPE_BASE; else params.scope = LDAP_SCOPE_SUBTREE; } if (argc > 0) { for (i = 0; i < argc && i < ALDAP_MAXATTR; i++) params.attributes[i] = argv[i]; } if (hostname == NULL) { /* default to unix socket /var/run/ldapi */ url.protocol = LDAPI; hostname = "/var/run/ldapi"; /* errx(1, "missing hostname"); */ } if (binddn != NULL && passwd == NULL) { char *prompt; if (asprintf(&prompt, "password for %s: ", binddn) == -1) err(2, "asprintf"); if ((passwd = getpass(prompt)) == NULL) return 3; free(prompt); } if (url.protocol == LDAPI) ld = aldap_open_local(hostname); else ld = aldap_open(hostname, port); if (ld == NULL) err(2, "%s", hostname); if (url.protocol == LDAPS) { if (aldap_ssl_init_s(ld) == -1) err(3, "ssl"); } else if (((url.protocol == LDAPI && starttls == 2) || (url.protocol == LDAP && starttls)) && (ret = aldap_start_tls_s(ld)) != 0) { if (starttls == 2) /* starttls required */ err(2, "%s: %s", hostname, aldap_strerror(ret)); } if (binddn && (ret = aldap_bind_s(ld, binddn, passwd)) != 0) errx(2, "failed to bind: %s", aldap_strerror(ret)); printf("version: 1\n\n"); for (;;) { if (pagesize > 0) { params.controls[0] = aldap_page_control(0, pagesize, cookie); if (params.controls[0] == NULL) err(2, "failed to create paged results control"); aldap_berfree(cookie); } if ((msgid = aldap_search(ld, ¶ms)) == -1) { aldap_get_errno(ld, &errmsg); errx(1, "search failed: %s", errmsg); } for (;;) { code = aldap_result(ld, msgid, NULL, &res); if (code == -1) { aldap_get_errno(ld, &errmsg); errx(1, "search failed: %s", errmsg); } if (aldap_msgtype(res) == LDAP_RES_SEARCH_RESULT) break; if (aldap_msgtype(res) == LDAP_RES_SEARCH_REFERENCE) { aldap_freemsg(res); continue; } ldif_print(res, stdout); aldap_freemsg(res); } if (code == LDAP_REFERRAL) { values = aldap_get_references(res); for (val = values; val != NULL && *val != NULL; val++) printf("referral: %s\n", *val); aldap_free_values(values); break; } if (aldap_get_page_control(res, NULL, &cookie) == -1) break; aldap_freemsg(res); if (cookie->size == 0) { /* last page */ aldap_berfree(cookie); break; } #if 0 fprintf(stderr, "press enter for next page\n"); getchar(); #endif } aldap_unbind_s(ld); return 0; }