#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
+#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef HAVE_LBER_H
* For each uri, convert to host:port pairs. For ldaps:// enable SSL
* Accepts: uris of the form ldap:/// or ldap://hostname:portnum/
* where the trailing slash is optional.
+ * Returns LDAP_SUCCESS on success, else non-zero.
*/
static int
sudo_ldap_parse_uri(const struct ldap_config_str_list *uri_list)
efree(ldap_conf.host);
ldap_conf.host = estrdup(hostbuf);
- rc = 0;
+ rc = LDAP_SUCCESS;
done:
efree(buf);
}
#endif /* HAVE_LDAP_INITIALIZE */
+/*
+ * Wrapper for ldap_create() or ldap_init() that handles
+ * SSL/TLS initialization as well.
+ * Returns LDAP_SUCCESS on success, else non-zero.
+ */
static int
sudo_ldap_init(LDAP **ldp, const char *host, int port)
{
- LDAP *ld = NULL;
+ LDAP *ld;
int rc = LDAP_CONNECT_ERROR;
debug_decl(sudo_ldap_init, SUDO_DEBUG_LDAP)
if (rc != LDAP_SUCCESS) {
warningx("ldap_ssl_client_init(): %s (SSL reason code %d)",
ldap_err2string(rc), sslrc);
- debug_return_int(-1);
+ goto done;
}
DPRINTF2("ldap_ssl_init(%s, %d, NULL)", host, port);
if ((ld = ldap_ssl_init((char *)host, port, NULL)) != NULL)
#endif
}
-done:
*ldp = ld;
+done:
debug_return_int(rc);
}
if (!STAILQ_EMPTY(&ldap_conf.uri)) {
struct ldap_config_str *uri;
- if (sudo_ldap_parse_uri(&ldap_conf.uri) != 0)
+ if (sudo_ldap_parse_uri(&ldap_conf.uri) != LDAP_SUCCESS)
debug_return_bool(false);
while ((uri = STAILQ_FIRST(&ldap_conf.uri)) != NULL) {
STAILQ_REMOVE_HEAD(&ldap_conf.uri, entries);
/*
* Set LDAP options from the specified options table
+ * Returns LDAP_SUCCESS on success, else non-zero.
*/
static int
sudo_ldap_set_options_table(LDAP *ld, struct ldap_config_table *table)
break;
}
}
- debug_return_int(errors ? -1 : 0);
+ debug_return_int(errors ? -1 : LDAP_SUCCESS);
}
/*
* Set LDAP options based on the global config table.
+ * Returns LDAP_SUCCESS on success, else non-zero.
*/
static int
sudo_ldap_set_options_global(void)
/* Parse global LDAP options table. */
rc = sudo_ldap_set_options_table(NULL, ldap_conf_global);
- if (rc == -1)
- debug_return_int(-1);
- debug_return_int(0);
+ debug_return_int(rc);
}
/*
* Set LDAP options based on the per-connection config table.
+ * Returns LDAP_SUCCESS on success, else non-zero.
*/
static int
sudo_ldap_set_options_conn(LDAP *ld)
}
}
#endif
- debug_return_int(0);
+ debug_return_int(LDAP_SUCCESS);
}
/*
}
/*
- * Connect to the LDAP server specified by ld
+ * Connect to the LDAP server specified by ld.
+ * Returns LDAP_SUCCESS on success, else non-zero.
*/
static int
sudo_ldap_bind_s(LDAP *ld)
if (rc != LDAP_SUCCESS) {
warningx("ldap_sasl_interactive_bind_s(): %s",
ldap_err2string(rc));
- debug_return_int(-1);
+ goto done;
}
DPRINTF1("ldap_sasl_interactive_bind_s() ok");
} else
NULL, NULL, NULL);
if (rc != LDAP_SUCCESS) {
warningx("ldap_sasl_bind_s(): %s", ldap_err2string(rc));
- debug_return_int(-1);
+ goto done;
}
DPRINTF1("ldap_sasl_bind_s() ok");
}
rc = ldap_simple_bind_s(ld, ldap_conf.binddn, ldap_conf.bindpw);
if (rc != LDAP_SUCCESS) {
warningx("ldap_simple_bind_s(): %s", ldap_err2string(rc));
- debug_return_int(-1);
+ goto done;
}
DPRINTF1("ldap_simple_bind_s() ok");
}
#endif
- debug_return_int(0);
+done:
+ debug_return_int(rc);
}
/*
sudo_ldap_open(struct sudo_nss *nss)
{
LDAP *ld;
- int rc;
+ int rc = -1;
+ sigaction_t sa, saved_sa_pipe;
bool ldapnoinit = false;
struct sudo_ldap_handle *handle;
debug_decl(sudo_ldap_open, SUDO_DEBUG_LDAP)
+ /* Ignore SIGPIPE if we cannot bind to the server. */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = SIG_IGN;
+ (void) sigaction(SIGPIPE, &sa, &saved_sa_pipe);
+
if (!sudo_ldap_read_config())
- debug_return_int(-1);
+ goto done;
/* Prevent reading of user ldaprc and system defaults. */
if (sudo_getenv("LDAPNOINIT") == NULL) {
}
/* Set global LDAP options */
- if (sudo_ldap_set_options_global() < 0)
- debug_return_int(-1);
+ if (sudo_ldap_set_options_global() != LDAP_SUCCESS)
+ goto done;
/* Connect to LDAP server */
#ifdef HAVE_LDAP_INITIALIZE
#endif
rc = sudo_ldap_init(&ld, ldap_conf.host, ldap_conf.port);
if (rc != LDAP_SUCCESS)
- debug_return_int(-1);
+ goto done;
/* Set LDAP per-connection options */
- if (sudo_ldap_set_options_conn(ld) < 0)
- debug_return_int(-1);
+ rc = sudo_ldap_set_options_conn(ld);
+ if (rc != LDAP_SUCCESS)
+ goto done;
if (ldapnoinit)
sudo_unsetenv("LDAPNOINIT");
rc = ldap_start_tls_s(ld, NULL, NULL);
if (rc != LDAP_SUCCESS) {
warningx("ldap_start_tls_s(): %s", ldap_err2string(rc));
- debug_return_int(-1);
+ goto done;
}
DPRINTF1("ldap_start_tls_s() ok");
#elif defined(HAVE_LDAP_SSL_CLIENT_INIT) && defined(HAVE_LDAP_START_TLS_S_NP)
if (rc != LDAP_SUCCESS) {
warningx("ldap_ssl_client_init(): %s (SSL reason code %d)",
ldap_err2string(rc), sslrc);
- debug_return_int(-1);
+ goto done;
}
rc = ldap_start_tls_s_np(ld, NULL);
if (rc != LDAP_SUCCESS) {
warningx("ldap_start_tls_s_np(): %s", ldap_err2string(rc));
- debug_return_int(-1);
+ goto done;
}
DPRINTF1("ldap_start_tls_s_np() ok");
#else
}
/* Actually connect */
- if (sudo_ldap_bind_s(ld) != 0)
- debug_return_int(-1);
+ rc = sudo_ldap_bind_s(ld);
+ if (rc != LDAP_SUCCESS)
+ goto done;
/* Create a handle container. */
handle = ecalloc(1, sizeof(struct sudo_ldap_handle));
/* handle->grlist = NULL; */
nss->handle = handle;
- debug_return_int(0);
+done:
+ (void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
+ debug_return_int(rc == LDAP_SUCCESS ? 0 : -1);
}
static int