int sdap_get_msg_dn(TALLOC_CTX *memctx, struct sdap_handle *sh, struct sdap_msg *sm, char **_dn) { char *str; int lerrno; int ret; lerrno = 0; ret = ldap_set_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); if (ret != LDAP_OPT_SUCCESS) { DEBUG(1, ("ldap_set_option failed [%s], ignored.\n", sss_ldap_err2string(ret))); } str = ldap_get_dn(sh->ldap, sm->msg); if (!str) { ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); DEBUG(1, ("ldap_get_dn failed: %d(%s)\n", lerrno, sss_ldap_err2string(lerrno))); return EIO; } *_dn = talloc_strdup(memctx, str); ldap_memfree(str); if (!*_dn) return ENOMEM; return EOK; }
static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sss_ldap_init_state *state = tevent_req_data(req, struct sss_ldap_init_state); int ret; int lret; ret = sssd_async_socket_init_recv(subreq, &state->sd); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssd_async_socket_init request failed: [%d]: %s.\n", ret, sss_strerror(ret)); goto fail; } /* Initialize LDAP handler */ lret = ldap_init_fd(state->sd, LDAP_PROTO_TCP, state->uri, &state->ldap); if (lret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_init_fd failed: %s. [%d][%s]\n", sss_ldap_err2string(lret), state->sd, state->uri); ret = lret == LDAP_SERVER_DOWN ? ETIMEDOUT : EIO; goto fail; } if (ldap_is_ldaps_url(state->uri)) { lret = ldap_install_tls(state->ldap); if (lret != LDAP_SUCCESS) { if (lret == LDAP_LOCAL_ERROR) { DEBUG(SSSDBG_FUNC_DATA, "TLS/SSL already in place.\n"); } else { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_install_tls failed: %s\n", sss_ldap_err2string(lret)); ret = EIO; goto fail; } } } tevent_req_done(req); return; fail: tevent_req_error(req, ret); }
struct tevent_req *sss_ldap_init_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *uri, struct sockaddr_storage *addr, int addr_len, int timeout) { int ret = EOK; struct tevent_req *req; struct sss_ldap_init_state *state; req = tevent_req_create(mem_ctx, &state, struct sss_ldap_init_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n"); return NULL; } talloc_set_destructor((TALLOC_CTX *)state, sss_ldap_init_state_destructor); state->ldap = NULL; state->sd = -1; state->uri = uri; #ifdef HAVE_LDAP_INIT_FD struct tevent_req *subreq; subreq = sssd_async_socket_init_send(state, ev, addr, addr_len, timeout); if (subreq == NULL) { ret = ENOMEM; DEBUG(SSSDBG_CRIT_FAILURE, "sssd_async_socket_init_send failed.\n"); goto fail; } tevent_req_set_callback(subreq, sss_ldap_init_sys_connect_done, req); return req; fail: tevent_req_error(req, ret); #else DEBUG(SSSDBG_MINOR_FAILURE, "ldap_init_fd not available, " "will use ldap_initialize with uri [%s].\n", uri); ret = ldap_initialize(&state->ldap, uri); if (ret == LDAP_SUCCESS) { tevent_req_done(req); } else { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_initialize failed [%s].\n", sss_ldap_err2string(ret)); if (ret == LDAP_SERVER_DOWN) { tevent_req_error(req, ETIMEDOUT); } else { tevent_req_error(req, EIO); } } #endif tevent_req_post(req, ev); return req; }
int sdap_parse_entry(TALLOC_CTX *memctx, struct sdap_handle *sh, struct sdap_msg *sm, struct sdap_attr_map *map, int attrs_num, struct sysdb_attrs **_attrs, char **_dn, bool disable_range_retrieval) { struct sysdb_attrs *attrs; BerElement *ber = NULL; struct berval **vals; struct ldb_val v; char *str; int lerrno; int a, i, ret; const char *name; bool store; bool base64; char *base_attr; char *dn = NULL; uint32_t range_offset; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; lerrno = 0; ret = ldap_set_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); if (ret != LDAP_OPT_SUCCESS) { DEBUG(1, ("ldap_set_option failed [%s], ignored.\n", sss_ldap_err2string(ret))); } attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } str = ldap_get_dn(sh->ldap, sm->msg); if (!str) { ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); DEBUG(1, ("ldap_get_dn failed: %d(%s)\n", lerrno, sss_ldap_err2string(lerrno))); ret = EIO; goto done; } DEBUG(9, ("OriginalDN: [%s].\n", str)); ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_DN, str); if (ret) goto done; if (_dn) { dn = talloc_strdup(tmp_ctx, str); if (!dn) { ret = ENOMEM; ldap_memfree(str); goto done; } } ldap_memfree(str); if (map) { vals = ldap_get_values_len(sh->ldap, sm->msg, "objectClass"); if (!vals) { DEBUG(1, ("Unknown entry type, no objectClasses found!\n")); ret = EINVAL; goto done; } for (i = 0; vals[i]; i++) { /* the objectclass is always the first name in the map */ if (strncasecmp(map[0].name, vals[i]->bv_val, vals[i]->bv_len) == 0) { /* ok it's an entry of the right type */ break; } } if (!vals[i]) { DEBUG(1, ("objectClass not matching: %s\n", map[0].name)); ldap_value_free_len(vals); ret = EINVAL; goto done; } ldap_value_free_len(vals); } str = ldap_first_attribute(sh->ldap, sm->msg, &ber); if (!str) { ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); DEBUG(lerrno == LDAP_SUCCESS ? SSSDBG_TRACE_INTERNAL : SSSDBG_MINOR_FAILURE, ("Entry has no attributes [%d(%s)]!?\n", lerrno, sss_ldap_err2string(lerrno))); if (map) { ret = EINVAL; goto done; } } while (str) { base64 = false; ret = sdap_parse_range(tmp_ctx, str, &base_attr, &range_offset, disable_range_retrieval); switch(ret) { case EAGAIN: /* This attribute contained range values and needs more to * be retrieved */ /* TODO: return the set of attributes that need additional retrieval * For now, we'll continue below and treat it as regular values. */ /* FALLTHROUGH */ case ECANCELED: /* FALLTHROUGH */ case EOK: break; default: DEBUG(SSSDBG_MINOR_FAILURE, ("Could not determine if attribute [%s] was ranged\n", str)); goto done; } if (map) { for (a = 1; a < attrs_num; a++) { /* check if this attr is valid with the chosen schema */ if (!map[a].name) continue; /* check if it is an attr we are interested in */ if (strcasecmp(base_attr, map[a].name) == 0) break; } /* interesting attr */ if (a < attrs_num) { store = true; name = map[a].sys_name; if (strcmp(name, SYSDB_SSH_PUBKEY) == 0) { base64 = true; } } else { store = false; name = NULL; } } else { name = base_attr; store = true; } if (ret == ECANCELED) { ret = EOK; store = false; } if (store) { vals = ldap_get_values_len(sh->ldap, sm->msg, str); if (!vals) { ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); if (lerrno != LDAP_SUCCESS) { DEBUG(1, ("LDAP Library error: %d(%s)", lerrno, sss_ldap_err2string(lerrno))); ret = EIO; goto done; } DEBUG(5, ("Attribute [%s] has no values, skipping.\n", str)); } else { if (!vals[0]) { DEBUG(1, ("Missing value after ldap_get_values() ??\n")); ret = EINVAL; goto done; } for (i = 0; vals[i]; i++) { if (vals[i]->bv_len == 0) { DEBUG(SSSDBG_MINOR_FAILURE, ("Value of attribute [%s] is empty. " "Skipping this value.\n", str)); continue; } if (base64) { v.data = (uint8_t *)sss_base64_encode(attrs, (uint8_t *)vals[i]->bv_val, vals[i]->bv_len); if (!v.data) { ret = ENOMEM; goto done; } v.length = strlen((const char *)v.data); } else { v.data = (uint8_t *)vals[i]->bv_val; v.length = vals[i]->bv_len; } ret = sysdb_attrs_add_val(attrs, name, &v); if (ret) goto done; } ldap_value_free_len(vals); } } ldap_memfree(str); str = ldap_next_attribute(sh->ldap, sm->msg, ber); } ber_free(ber, 0); ber = NULL; ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); if (lerrno) { DEBUG(1, ("LDAP Library error: %d(%s)", lerrno, sss_ldap_err2string(lerrno))); ret = EIO; goto done; } *_attrs = talloc_steal(memctx, attrs); if (_dn) *_dn = talloc_steal(memctx, dn); ret = EOK; done: if (ber) ber_free(ber, 0); talloc_free(tmp_ctx); return ret; }
errno_t setup_tls_config(struct dp_option *basic_opts) { int ret; int ldap_opt_x_tls_require_cert; const char *tls_opt; tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_REQCERT); if (tls_opt) { if (strcasecmp(tls_opt, "never") == 0) { ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_NEVER; } else if (strcasecmp(tls_opt, "allow") == 0) { ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_ALLOW; } else if (strcasecmp(tls_opt, "try") == 0) { ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_TRY; } else if (strcasecmp(tls_opt, "demand") == 0) { ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_DEMAND; } else if (strcasecmp(tls_opt, "hard") == 0) { ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_HARD; } else { DEBUG(1, ("Unknown value for tls_reqcert.\n")); return EINVAL; } /* LDAP_OPT_X_TLS_REQUIRE_CERT has to be set as a global option, * because the SSL/TLS context is initialized from this value. */ ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_opt_x_tls_require_cert); if (ret != LDAP_OPT_SUCCESS) { DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret))); return EIO; } } tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CACERT); if (tls_opt) { ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, tls_opt); if (ret != LDAP_OPT_SUCCESS) { DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret))); return EIO; } } tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CACERTDIR); if (tls_opt) { ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR, tls_opt); if (ret != LDAP_OPT_SUCCESS) { DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret))); return EIO; } } tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CERT); if (tls_opt) { ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, tls_opt); if (ret != LDAP_OPT_SUCCESS) { DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret))); return EIO; } } tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_KEY); if (tls_opt) { ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, tls_opt); if (ret != LDAP_OPT_SUCCESS) { DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret))); return EIO; } } tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CIPHER_SUITE); if (tls_opt) { ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, tls_opt); if (ret != LDAP_OPT_SUCCESS) { DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret))); return EIO; } } return EOK; }