static void update_list (mu_list_t *plist, const char *arg) { size_t j; struct mu_wordsplit ws; mu_list_t list = *plist; if (!list) { MU_ASSERT (mu_list_create (&list)); *plist = list; } ws.ws_delim = ","; if (mu_wordsplit (arg, &ws, MU_WRDSF_DEFFLAGS | MU_WRDSF_DELIM)) { mu_error ("mu_wordsplit: %s", mu_wordsplit_strerror (&ws)); exit (1); } for (j = 0; j < ws.ws_wordc; j++) MU_ASSERT (mu_list_append (list, ws.ws_wordv[j])); ws.ws_wordc = 0; mu_wordsplit_free (&ws); }
static int _mu_conn_setup (LDAP **pld) { int rc; LDAPURLDesc *ludlist, **ludp; char **urls = NULL; int nurls = 0; char *ldapuri = NULL; LDAP *ld = NULL; int protocol = LDAP_VERSION3; /* FIXME: must be configurable */ if (ldap_param.debug) { if (ber_set_option (NULL, LBER_OPT_DEBUG_LEVEL, &ldap_param.debug) != LBER_OPT_SUCCESS ) mu_error (_("cannot set LBER_OPT_DEBUG_LEVEL %d"), ldap_param.debug); if (ldap_set_option (NULL, LDAP_OPT_DEBUG_LEVEL, &ldap_param.debug) != LDAP_OPT_SUCCESS ) mu_error (_("could not set LDAP_OPT_DEBUG_LEVEL %d"), ldap_param.debug); } if (ldap_param.url) { rc = ldap_url_parse (ldap_param.url, &ludlist); if (rc != LDAP_URL_SUCCESS) { mu_error (_("cannot parse LDAP URL(s)=%s (%d)"), ldap_param.url, rc); return 1; } for (ludp = &ludlist; *ludp; ) { LDAPURLDesc *lud = *ludp; char **tmp; if (lud->lud_dn && lud->lud_dn[0] && (lud->lud_host == NULL || lud->lud_host[0] == '\0')) { /* if no host but a DN is provided, try DNS SRV to gather the host list */ char *domain = NULL, *hostlist = NULL; size_t i; struct mu_wordsplit ws; if (ldap_dn2domain (lud->lud_dn, &domain) || !domain) { mu_error (_("DNS SRV: cannot convert DN=\"%s\" into a domain"), lud->lud_dn ); goto dnssrv_free; } rc = ldap_domain2hostlist (domain, &hostlist); if (rc) { mu_error (_("DNS SRV: cannot convert domain=%s into a hostlist"), domain); goto dnssrv_free; } if (mu_wordsplit (hostlist, &ws, MU_WRDSF_DEFFLAGS)) { mu_error (_("DNS SRV: could not parse hostlist=\"%s\": %s"), hostlist, mu_wordsplit_strerror (&ws)); goto dnssrv_free; } tmp = realloc (urls, sizeof(char *) * (nurls + ws.ws_wordc + 1)); if (!tmp) { mu_error ("DNS SRV %s", mu_strerror (errno)); goto dnssrv_free; } urls = tmp; urls[nurls] = NULL; for (i = 0; i < ws.ws_wordc; i++) { urls[nurls + i + 1] = NULL; rc = mu_asprintf (&urls[nurls + i], "%s://%s", lud->lud_scheme, ws.ws_wordv[i]); if (rc) { mu_error ("DNS SRV %s", mu_strerror (rc)); goto dnssrv_free; } } nurls += i; dnssrv_free: mu_wordsplit_free (&ws); ber_memfree (hostlist); ber_memfree (domain); } else { tmp = realloc (urls, sizeof(char *) * (nurls + 2)); if (!tmp) { mu_error ("DNS SRV %s", mu_strerror (errno)); break; } urls = tmp; urls[nurls + 1] = NULL; urls[nurls] = ldap_url_desc2str (lud); if (!urls[nurls]) { mu_error ("DNS SRV %s", mu_strerror (errno)); break; } nurls++; } *ludp = lud->lud_next; lud->lud_next = NULL; ldap_free_urldesc (lud); } if (ludlist) { ldap_free_urldesc (ludlist); return 1; } else if (!urls) return 1; rc = mu_argcv_string (nurls, urls, &ldapuri); if (rc) { mu_error ("%s", mu_strerror (rc)); return 1; } ber_memvfree ((void **)urls); } mu_diag_output (MU_DIAG_INFO, "constructed LDAP URI: %s", ldapuri ? ldapuri : "<DEFAULT>"); rc = ldap_initialize (&ld, ldapuri); if (rc != LDAP_SUCCESS) { mu_error (_("cannot create LDAP session handle for URI=%s (%d): %s"), ldapuri, rc, ldap_err2string (rc)); free (ldapuri); return 1; } free (ldapuri); ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &protocol); if (ldap_param.tls) { rc = ldap_start_tls_s (ld, NULL, NULL); if (rc != LDAP_SUCCESS) { char *msg = NULL; ldap_get_option (ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&msg); mu_error (_("ldap_start_tls failed: %s"), ldap_err2string (rc)); mu_error (_("TLS diagnostics: %s"), msg); ldap_memfree (msg); ldap_unbind_ext (ld, NULL, NULL); return 1; } } /* FIXME: Timeouts, SASL, etc. */ *pld = ld; return 0; }
static int _mu_ldap_search (LDAP *ld, const char *filter_pat, const char *key, struct mu_auth_data **return_data) { int rc; char **attrs; size_t nattrs; LDAPMessage *res, *msg; ber_int_t msgid; const char *env[3]; struct mu_wordsplit ws; rc = _construct_attr_array (&nattrs, &attrs); if (rc) return rc; env[0] = "user"; env[1] = key; env[2] = NULL; ws.ws_env = env; if (mu_wordsplit (filter_pat, &ws, MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | MU_WRDSF_ENV | MU_WRDSF_ENV_KV)) { mu_error (_("cannot expand line `%s': %s"), filter_pat, mu_wordsplit_strerror (&ws)); return MU_ERR_FAILURE; } else if (ws.ws_wordc == 0) { mu_error (_("expanding %s yields empty string"), filter_pat); mu_wordsplit_free (&ws); mu_argcv_free (nattrs, attrs); return MU_ERR_FAILURE; } rc = ldap_search_ext (ld, ldap_param.base, LDAP_SCOPE_SUBTREE, ws.ws_wordv[0], attrs, 0, NULL, NULL, NULL, -1, &msgid); mu_wordsplit_free (&ws); mu_argcv_free (nattrs, attrs); if (rc != LDAP_SUCCESS) { mu_error ("ldap_search_ext: %s", ldap_err2string (rc)); if (rc == LDAP_NO_SUCH_OBJECT) return MU_ERR_NOENT; else return MU_ERR_FAILURE; } rc = ldap_result (ld, msgid, LDAP_MSG_ALL, NULL, &res ); if (rc < 0) { mu_error ("ldap_result failed"); return MU_ERR_FAILURE; } rc = ldap_count_entries (ld, res); if (rc == 0) { mu_error ("not enough entires"); return MU_ERR_NOENT; } if (rc > 1) mu_error ("LDAP: too many entries for key %s", key); msg = ldap_first_entry (ld, res); rc = _mu_entry_to_auth_data (ld, msg, return_data); ldap_msgfree (res); return rc; }
oo\n\ "; int main (int argc, char **argv) { int i; char *p; mu_message_t msg; mu_stream_t stream = NULL; mu_header_t hdr; mu_body_t body; mu_set_program_name (argv[0]); mu_static_memory_stream_create (&stream, text, strlen (text)); assert (mu_stream_to_message (stream, &msg) == 0); mu_stream_unref (stream); assert (mu_message_get_header (msg, &hdr) == 0); assert (mu_message_get_body (msg, &body) == 0); assert (mu_body_get_streamref (body, &stream) == 0); assert (mu_stream_seek (stream, 0, MU_SEEK_END, NULL) == 0); for (i = 1; i < argc; i++) { if (strcmp (argv[i], "-h") == 0) { mu_printf ("usage: %s [-a HDR:VAL] [-t TEXT]\n", mu_program_name); return 0; } if (strcmp (argv[i], "-a") == 0) { i++; assert (argv[i] != NULL); p = strchr (argv[i], ':'); assert (p != NULL); *p++ = 0; while (*p && mu_isspace (*p)) p++; assert (mu_header_set_value (hdr, argv[i], p, 1) == 0); } else if (strcmp (argv[i], "-l") == 0) { mu_off_t off; int whence = MU_SEEK_SET; i++; assert (argv[i] != NULL); off = strtol (argv[i], &p, 10); assert (*p == 0); if (off < 0) whence = MU_SEEK_END; assert (mu_stream_seek (stream, off, whence, NULL) == 0); } else if (strcmp (argv[i], "-t") == 0) { mu_wordsplit_t ws; i++; assert (argv[i] != NULL); if (mu_wordsplit (argv[i], &ws, MU_WRDSF_NOSPLIT | MU_WRDSF_DEFFLAGS)) { mu_error ("mu_wordsplit: %s", mu_wordsplit_strerror (&ws)); exit (1); } else assert (mu_stream_write (stream, ws.ws_wordv[0], strlen (ws.ws_wordv[0]), NULL) == 0); mu_wordsplit_free (&ws); } else mu_error ("ignoring unknown argument %s", argv[i]); } mu_stream_unref (stream); assert (mu_message_get_streamref (msg, &stream) == 0); assert (mu_stream_copy (mu_strout, stream, 0, NULL) == 0); mu_stream_unref (stream); return 0; }