static struct aldap * ldap_connect(const char *addr) { struct aldap_url lu; struct addrinfo hints, *res0, *res; char *buf; int error, fd = -1; if ((buf = strdup(addr)) == NULL) return (NULL); /* XXX buf leak */ if (aldap_parse_url(buf, &lu) != 1) { log_warnx("warn: table-ldap: ldap_parse_url fail"); return (NULL); } bzero(&hints, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /* DUMMY */ error = getaddrinfo(lu.host, NULL, &hints, &res0); if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME) return (NULL); if (error) { log_warnx("warn: table-ldap: could not parse \"%s\": %s", lu.host, gai_strerror(error)); return (NULL); } for (res = res0; res; res = res->ai_next) { if (res->ai_family != AF_INET && res->ai_family != AF_INET6) continue; fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (fd == -1) continue; if (res->ai_family == AF_INET) { struct sockaddr_in sin4 = *(struct sockaddr_in *)res->ai_addr; sin4.sin_port = htons(lu.port); if (connect(fd, (struct sockaddr *)&sin4, res->ai_addrlen) == 0) return aldap_init(fd); } else if (res->ai_family == AF_INET6) { struct sockaddr_in6 sin6 = *(struct sockaddr_in6 *)res->ai_addr; sin6.sin6_port = htons(lu.port); if (connect(fd, (struct sockaddr *)&sin6, res->ai_addrlen) == 0) return aldap_init(fd); } close(fd); fd = -1; } return (NULL); }
int main(int argc, char **argv) { struct aldap_url url; char *hostname = NULL; const char *binddn = NULL, *passwd = NULL; const char *errmsg = NULL; struct aldap *ld; FILE *fp = NULL; int c, port = 0, starttls = 1, ret; bzero(&url, sizeof(url)); while ((c = getopt(argc, argv, "Cf:h:H:p:D:ZvWw:x")) != -1) { switch (c) { case 'f': if (fp != NULL) err(1, "-f already specified"); if (strcmp(optarg, "-") == 0) fp = stdin; else if ((fp = fopen(optarg, "r")) == NULL) err(1, optarg); break; 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; 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 'D': binddn = optarg; break; case 'C': starttls = 0; break; case 'Z': starttls = 2; break; case 'v': break; case 'w': passwd = optarg; break; case 'W': case 'x': break; default: usage(); return 1; } } argc -= optind; argv += optind; 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)); if (fp == NULL) fp = stdin; process_ldif(ld, fp); aldap_unbind_s(ld); if (fp != stdin) fclose(fp); return 0; }
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; }