--- contrib/mod_ldap.c.orig 2013-11-24 04:45:28.000000000 +0400 +++ contrib/mod_ldap.c 2014-05-16 13:13:12.326617345 +0400 @@ -142,7 +142,14 @@ *ldap_attr_memberuid = "memberUid", *ldap_attr_ftpquota = "ftpQuota", *ldap_attr_ftpquota_profiledn = "ftpQuotaProfileDN", - *ldap_attr_ssh_pubkey = "sshPublicKey"; + *ldap_attr_ssh_pubkey = "sshPublicKey", + *ldap_tls_ca_cert_dir, + *ldap_tls_ca_cert_file, + *ldap_tls_cert_file, + *ldap_tls_cipher_suite, + *ldap_tls_crl_file, + *ldap_tls_dh_file, + *ldap_tls_key_file; #ifdef HAS_LDAP_INITIALIZE static char *ldap_server_url; #endif /* HAS_LDAP_INITIALIZE */ @@ -152,7 +159,9 @@ ldap_forcedefaultuid = FALSE, ldap_forcedefaultgid = FALSE, ldap_forcegenhdir = FALSE, ldap_protocol_version = 3, ldap_dereference = LDAP_DEREF_NEVER, - ldap_search_scope = LDAP_SCOPE_SUBTREE; + ldap_search_scope = LDAP_SCOPE_SUBTREE, + ldap_tls_crl_check = -1, + ldap_tls_require_cert = -1; static struct timeval ldap_querytimeout_tv; #define PR_LDAP_QUERY_TIMEOUT_DEFAULT 5 @@ -196,6 +205,86 @@ struct berval bindcred; #endif + if (ldap_tls_ca_cert_dir) { + res = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR, ldap_tls_ca_cert_dir); + if (res != LDAP_OPT_SUCCESS) { + pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CACERTDIR option failed: %s", ldap_err2string(res)); + pr_ldap_unbind(); + return -1; + } + pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CACERTDIR to %s", ldap_tls_ca_cert_dir); + } + + if (ldap_tls_ca_cert_file) { + res = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_tls_ca_cert_file); + if (res != LDAP_OPT_SUCCESS) { + pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CACERTFILE option failed: %s", ldap_err2string(res)); + pr_ldap_unbind(); + return -1; + } + pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CACERTFILE to %s", ldap_tls_ca_cert_file); + } + + if (ldap_tls_cert_file) { + res = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, ldap_tls_cert_file); + if (res != LDAP_OPT_SUCCESS) { + pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CERTFILE option failed: %s", ldap_err2string(res)); + pr_ldap_unbind(); + return -1; + } + pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CERTFILE to %s", ldap_tls_cert_file); + } + + if (ldap_tls_cipher_suite) { + res = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, ldap_tls_cipher_suite); + if (res != LDAP_OPT_SUCCESS) { + pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CIPHER_SUITE option failed: %s", ldap_err2string(res)); + pr_ldap_unbind(); + return -1; + } + pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CIPHER_SUITE to %s", ldap_tls_cipher_suite); + } + + if (ldap_tls_dh_file) { + res = ldap_set_option(NULL, LDAP_OPT_X_TLS_DHFILE, ldap_tls_dh_file); + if (res != LDAP_OPT_SUCCESS) { + pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_DHFILE option failed: %s", ldap_err2string(res)); + pr_ldap_unbind(); + return -1; + } + pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_DHFILE version to %s", ldap_tls_dh_file); + } + + if (ldap_tls_key_file) { + res = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, ldap_tls_key_file); + if (res != LDAP_OPT_SUCCESS) { + pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_KEYFILE option failed: %s", ldap_err2string(res)); + pr_ldap_unbind(); + return -1; + } + pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": pr_ldap_connect(): set LDAP_OPT_X_TLS_KEYFILE to %s", ldap_tls_key_file); + } + + if (ldap_tls_crl_check != -1) { + res = ldap_set_option(NULL, LDAP_OPT_X_TLS_CRLCHECK, (void *)&ldap_tls_crl_check); + if (res != LDAP_OPT_SUCCESS) { + pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CRLCHECK option failed: %s", ldap_err2string(res)); + pr_ldap_unbind(); + return -1; + } + pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CRLCHECK to %d", ldap_tls_crl_check); + } + + if (ldap_tls_require_cert != -1) { + res = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, (void *)&ldap_tls_require_cert); + if (res != LDAP_OPT_SUCCESS) { + pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_REQUIRE_CERT option failed: %s", ldap_err2string(res)); + pr_ldap_unbind(); + return -1; + } + pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_REQUIRE_CERT to %d", ldap_tls_require_cert); + } + #ifdef HAS_LDAP_INITIALIZE (void) pr_log_writefile(ldap_logfd, MOD_LDAP_VERSION, "attempting connection to URL %s", @@ -2029,6 +2118,130 @@ return PR_HANDLED(cmd); } +MODRET +set_ldap_tls_ca_cert_dir(cmd_rec *cmd) +{ + CHECK_ARGS(cmd, 1); + CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); + + add_config_param_str(cmd->argv[0], 1, cmd->argv[1]); + return PR_HANDLED(cmd); +} + +MODRET +set_ldap_tls_ca_cert_file(cmd_rec *cmd) +{ + CHECK_ARGS(cmd, 1); + CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); + + add_config_param_str(cmd->argv[0], 1, cmd->argv[1]); + return PR_HANDLED(cmd); +} + +MODRET +set_ldap_tls_cert_file(cmd_rec *cmd) +{ + CHECK_ARGS(cmd, 1); + CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); + + add_config_param_str(cmd->argv[0], 1, cmd->argv[1]); + return PR_HANDLED(cmd); +} + +MODRET +set_ldap_tls_cipher_suite(cmd_rec *cmd) +{ + CHECK_ARGS(cmd, 1); + CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); + + add_config_param_str(cmd->argv[0], 1, cmd->argv[1]); + return PR_HANDLED(cmd); +} + +MODRET +set_ldap_tls_crl_check(cmd_rec *cmd) +{ + int value; + config_rec *c; + + CHECK_ARGS(cmd, 1); + CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); + + if (strcasecmp(cmd->argv[1], "none") == 0) { + value = LDAP_OPT_X_TLS_CRL_NONE; + } else if (strcasecmp(cmd->argv[1], "peer") == 0) { + value = LDAP_OPT_X_TLS_CRL_PEER; + } else if (strcasecmp(cmd->argv[1], "all") == 0) { + value = LDAP_OPT_X_TLS_CRL_ALL; + } else { + CONF_ERROR(cmd, "LDAPTLSCrlCheck: expected a valid LDAP_OPT_X_TLS_CRLCHECK option (none, peer, all)."); + } + + c = add_config_param("LDAPTLSCrlCheck", 1, NULL); + c->argv[0] = pcalloc(c->pool, sizeof(int)); + *((int *) c->argv[0]) = value; + return PR_HANDLED(cmd); +} + +MODRET +set_ldap_tls_dh_file(cmd_rec *cmd) +{ + CHECK_ARGS(cmd, 1); + CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); + + add_config_param_str(cmd->argv[0], 1, cmd->argv[1]); + return PR_HANDLED(cmd); +} + +MODRET +set_ldap_tls_crl_file(cmd_rec *cmd) +{ + CHECK_ARGS(cmd, 1); + CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); + + add_config_param_str(cmd->argv[0], 1, cmd->argv[1]); + return PR_HANDLED(cmd); +} + +MODRET +set_ldap_tls_key_file(cmd_rec *cmd) +{ + CHECK_ARGS(cmd, 1); + CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); + + add_config_param_str(cmd->argv[0], 1, cmd->argv[1]); + return PR_HANDLED(cmd); +} + +MODRET +set_ldap_tls_require_cert(cmd_rec *cmd) +{ + int value; + config_rec *c; + + CHECK_ARGS(cmd, 1); + CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); + + if (strcasecmp(cmd->argv[1], "never") == 0) { + value = LDAP_OPT_X_TLS_NEVER; + } else if (strcasecmp(cmd->argv[1], "hard") == 0) { + value = LDAP_OPT_X_TLS_HARD; + } else if (strcasecmp(cmd->argv[1], "demand") == 0) { + value = LDAP_OPT_X_TLS_DEMAND; + } else if (strcasecmp(cmd->argv[1], "allow") == 0) { + value = LDAP_OPT_X_TLS_ALLOW; + } else if (strcasecmp(cmd->argv[1], "try") == 0) { + value = LDAP_OPT_X_TLS_TRY; + } else { + CONF_ERROR(cmd, "LDAPTLSRequireCert: expected a valid LDAP_OPT_X_TLS_REQUIRE_CERT option (never, hard, demand, allow, try)."); + } + + c = add_config_param("LDAPTLSRequireCert", 1, NULL); + c->argv[0] = pcalloc(c->pool, sizeof(int)); + *((int *) c->argv[0]) = value; + return PR_HANDLED(cmd); +} + /* Initialization routines */ @@ -2279,6 +2492,22 @@ } } + ldap_tls_ca_cert_dir = (char *)get_param_ptr(main_server->conf, "LDAPTLSCACertDir", FALSE); + ldap_tls_ca_cert_file = (char *)get_param_ptr(main_server->conf, "LDAPTLSCACertFile", FALSE); + ldap_tls_cert_file = (char *)get_param_ptr(main_server->conf, "LDAPTLSCertFile", FALSE); + ldap_tls_cipher_suite = (char *)get_param_ptr(main_server->conf, "LDAPTLSCipherSuite", FALSE); + ldap_tls_crl_file = (char *)get_param_ptr(main_server->conf, "LDAPTLSCrlFile", FALSE); + ldap_tls_dh_file = (char *)get_param_ptr(main_server->conf, "LDAPTLSDHFile", FALSE); + ldap_tls_key_file = (char *)get_param_ptr(main_server->conf, "LDAPTLSKeyFile", FALSE); + ptr = get_param_ptr(main_server->conf, "LDAPTLSCrlCheck", FALSE); + if (ptr) { + ldap_tls_crl_check = *((int *) ptr); + } + ptr = get_param_ptr(main_server->conf, "LDAPTLSRequireCert", FALSE); + if (ptr) { + ldap_tls_require_cert = *((int *) ptr); + } + return 0; } @@ -2309,7 +2538,15 @@ { "LDAPServer", set_ldapserver, NULL }, { "LDAPUsers", set_ldapuserlookups, NULL }, { "LDAPUseTLS", set_ldapusetls, NULL }, - + { "LDAPTLSCACertDir", set_ldap_tls_ca_cert_dir, NULL }, + { "LDAPTLSCACertFile", set_ldap_tls_ca_cert_file, NULL }, + { "LDAPTLSCertFile", set_ldap_tls_cert_file, NULL }, + { "LDAPTLSCipherSuite", set_ldap_tls_cipher_suite, NULL }, + { "LDAPTLSCrlCheck", set_ldap_tls_crl_check, NULL }, + { "LDAPTLSCrlFile", set_ldap_tls_crl_file, NULL }, + { "LDAPTLSDHFile", set_ldap_tls_dh_file, NULL }, + { "LDAPTLSKeyFile", set_ldap_tls_key_file, NULL }, + { "LDAPTLSRequireCert", set_ldap_tls_require_cert, NULL }, { NULL, NULL, NULL }, };