diff mbox series

[nfs-utils:nfsidmap,v2] Add LDAP_tls_reqcert tunable to idmapd.conf.

Message ID 20190523161014.60182-1-srikrishanmalik@gmail.com (mailing list archive)
State New, archived
Headers show
Series [nfs-utils:nfsidmap,v2] Add LDAP_tls_reqcert tunable to idmapd.conf. | expand

Commit Message

Srikrishan Malik May 23, 2019, 4:10 p.m. UTC
This tunable will control the checks on server certs for a TLS session
similar to ldap.conf(5).
LDAP_ca_cert can be skipped if LDAP_tls_reqcert is set to "never"

Signed-off-by: Srikrishan Malik <srikrishanmalik@gmail.com>
---
 support/nfsidmap/idmapd.conf   |  8 ++++-
 support/nfsidmap/idmapd.conf.5 | 11 ++++++-
 support/nfsidmap/umich_ldap.c  | 57 ++++++++++++++++++++++++++++------
 3 files changed, 64 insertions(+), 12 deletions(-)

Comments

Steve Dickson May 23, 2019, 5:42 p.m. UTC | #1
On 5/23/19 12:10 PM, Srikrishan Malik wrote:
> This tunable will control the checks on server certs for a TLS session
> similar to ldap.conf(5).
> LDAP_ca_cert can be skipped if LDAP_tls_reqcert is set to "never"
> 
> Signed-off-by: Srikrishan Malik <srikrishanmalik@gmail.com>
> ---
>  support/nfsidmap/idmapd.conf   |  8 ++++-
>  support/nfsidmap/idmapd.conf.5 | 11 ++++++-
>  support/nfsidmap/umich_ldap.c  | 57 ++++++++++++++++++++++++++++------
>  3 files changed, 64 insertions(+), 12 deletions(-)
Thank you for the updates... Committed!!

steved.
> 
> diff --git a/support/nfsidmap/idmapd.conf b/support/nfsidmap/idmapd.conf
> index f07286c3..b673c7d7 100644
> --- a/support/nfsidmap/idmapd.conf
> +++ b/support/nfsidmap/idmapd.conf
> @@ -101,7 +101,13 @@ LDAP_base = dc=local,dc=domain,dc=edu
>  # Set to true to enable SSL - anything else is not enabled
>  #LDAP_use_ssl = false
>  
> -# You must specify a CA certificate location if you enable SSL
> +# Controls the LDAP server certificate validation behavior
> +# It can take the same values as ldap.conf(5)'s TLS_REQCERT
> +# tunable
> +#LDAP_tls_reqcert = "hard"
> +
> +# Location of CA certificate, mandatory if LDAP_tls_reqcert
> +# is not set to "never"
>  #LDAP_ca_cert = /etc/ldapca.cert
>  
>  # Objectclass mapping information
> diff --git a/support/nfsidmap/idmapd.conf.5 b/support/nfsidmap/idmapd.conf.5
> index 9a6457e2..61fbb613 100644
> --- a/support/nfsidmap/idmapd.conf.5
> +++ b/support/nfsidmap/idmapd.conf.5
> @@ -195,7 +195,16 @@ Set to "true" to enable SSL communication with the LDAP server.
>  Location of a trusted CA certificate used when SSL is enabled
>  (Required if
>  .B LDAP_use_ssl
> -is true)
> +is true and
> +.B LDAP_tls_reqcert
> +is not set to never)
> +.TP
> +.B LDAP_tls_reqcert
> +Controls the LDAP server certificate validation behavior.
> +It can take the same values as ldap.conf(5)'s
> +.B TLS_REQCERT
> +tunable.
> +(Default: "hard")
>  .TP
>  .B NFSv4_person_objectclass
>  The object class name for people accounts in your local LDAP schema
> diff --git a/support/nfsidmap/umich_ldap.c b/support/nfsidmap/umich_ldap.c
> index 10d1d979..b7445c37 100644
> --- a/support/nfsidmap/umich_ldap.c
> +++ b/support/nfsidmap/umich_ldap.c
> @@ -100,6 +100,7 @@ struct umich_ldap_info {
>  	char *passwd;		/* Password to use when binding to directory */
>  	int use_ssl;		/* SSL flag */
>  	char *ca_cert;		/* File location of the ca_cert */
> +	int tls_reqcert;	/* req and validate server cert */
>  	int memberof_for_groups;/* Use 'memberof' attribute when
>  				   looking up user groups */
>  	int ldap_timeout;	/* Timeout in seconds for searches
> @@ -118,6 +119,7 @@ static struct umich_ldap_info ldap_info = {
>  	.passwd = NULL,
>  	.use_ssl = 0,
>  	.ca_cert = NULL,
> +	.tls_reqcert = LDAP_OPT_X_TLS_HARD,
>  	.memberof_for_groups = 0,
>  	.ldap_timeout = DEFAULT_UMICH_SEARCH_TIMEOUT,
>  };
> @@ -153,7 +155,7 @@ ldap_init_and_bind(LDAP **pld,
>  	LDAPAPIInfo apiinfo = {.ldapai_info_version = LDAP_API_INFO_VERSION};
>  
>  	snprintf(server_url, sizeof(server_url), "%s://%s:%d",
> -		 (linfo->use_ssl && linfo->ca_cert) ? "ldaps" : "ldap",
> +		 (linfo->use_ssl) ? "ldaps" : "ldap",
>  		 linfo->server, linfo->port);
>  
>  	/*
> @@ -208,9 +210,8 @@ ldap_init_and_bind(LDAP **pld,
>  	}
>  
>  	/* Set option to to use SSL/TLS if requested */
> -	if (linfo->use_ssl && linfo->ca_cert) {
> +	if (linfo->use_ssl) {
>  		int tls_type = LDAP_OPT_X_TLS_HARD;
> -
>  		lerr = ldap_set_option(ld, LDAP_OPT_X_TLS, &tls_type);
>  		if (lerr != LDAP_SUCCESS) {
>  			IDMAP_LOG(2, ("ldap_init_and_bind: setting SSL "
> @@ -218,11 +219,23 @@ ldap_init_and_bind(LDAP **pld,
>  				  ldap_err2string(lerr), lerr));
>  			goto out;
>  		}
> -		lerr = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
> -				       linfo->ca_cert);
> +
> +		if (linfo->ca_cert != NULL) {
> +			lerr = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
> +					       linfo->ca_cert);
> +			if (lerr != LDAP_SUCCESS) {
> +				IDMAP_LOG(2, ("ldap_init_and_bind: setting CA "
> +					  "certificate file failed : %s (%d)",
> +					  ldap_err2string(lerr), lerr));
> +				goto out;
> +			}
> +		}
> +
> +		lerr = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
> +				       &linfo->tls_reqcert);
>  		if (lerr != LDAP_SUCCESS) {
> -			IDMAP_LOG(2, ("ldap_init_and_bind: setting CA "
> -				  "certificate file failed : %s (%d)",
> +			IDMAP_LOG(2, ("ldap_init_and_bind: setting "
> +				      "req CA cert failed : %s(%d)",
>  				  ldap_err2string(lerr), lerr));
>  			goto out;
>  		}
> @@ -1098,7 +1111,7 @@ out_err:
>  static int
>  umichldap_init(void)
>  {
> -	char *tssl, *canonicalize, *memberof;
> +	char *tssl, *canonicalize, *memberof, *cert_req;
>  	char missing_msg[128] = "";
>  	char *server_in, *canon_name;
>  
> @@ -1119,6 +1132,24 @@ umichldap_init(void)
>  	else
>  		ldap_info.use_ssl = 0;
>  	ldap_info.ca_cert = conf_get_str(LDAP_SECTION, "LDAP_CA_CERT");
> +	cert_req = conf_get_str(LDAP_SECTION, "LDAP_tls_reqcert");
> +	if (cert_req != NULL) {
> +		if (strcasecmp(cert_req, "hard") == 0)
> +			ldap_info.tls_reqcert = LDAP_OPT_X_TLS_HARD;
> +		else if (strcasecmp(cert_req, "demand") == 0)
> +			ldap_info.tls_reqcert = LDAP_OPT_X_TLS_DEMAND;
> +		else if (strcasecmp(cert_req, "try") == 0)
> +			ldap_info.tls_reqcert = LDAP_OPT_X_TLS_TRY;
> +		else if (strcasecmp(cert_req, "allow") == 0)
> +			ldap_info.tls_reqcert = LDAP_OPT_X_TLS_ALLOW;
> +		else if (strcasecmp(cert_req, "never") == 0)
> +			ldap_info.tls_reqcert = LDAP_OPT_X_TLS_NEVER;
> +		else {
> +			IDMAP_LOG(0, ("umichldap_init: Invalid value(%s) for "
> +				      "LDAP_tls_reqcert."));
> +			goto fail;
> +		}
> +	}
>  	/* vary the default port depending on whether they use SSL or not */
>  	ldap_info.port = conf_get_num(LDAP_SECTION, "LDAP_port",
>  				      (ldap_info.use_ssl) ?
> @@ -1230,9 +1261,12 @@ umichldap_init(void)
>  	if (ldap_info.group_tree == NULL || strlen(ldap_info.group_tree) == 0)
>  		ldap_info.group_tree = ldap_info.base;
>  
> -	if (ldap_info.use_ssl && ldap_info.ca_cert == NULL) {
> +	if (ldap_info.use_ssl &&
> +	    ldap_info.tls_reqcert != LDAP_OPT_X_TLS_NEVER &&
> +	    ldap_info.ca_cert == NULL) {
>  		IDMAP_LOG(0, ("umichldap_init: You must specify LDAP_ca_cert "
> -			  "with LDAP_use_ssl=yes"));
> +			  "with LDAP_use_ssl=yes and "
> +			  "LDAP_tls_reqcert not set to \"never\""));
>  		goto fail;
>  	}
>  
> @@ -1257,6 +1291,9 @@ umichldap_init(void)
>  		  ldap_info.use_ssl ? "yes" : "no"));
>  	IDMAP_LOG(1, ("umichldap_init: ca_cert : %s",
>  		  ldap_info.ca_cert ? ldap_info.ca_cert : "<not-supplied>"));
> +	IDMAP_LOG(1, ("umichldap_init: tls_reqcert : %s(%d)",
> +		  cert_req ? cert_req : "<not-supplied>",
> +		  ldap_info.tls_reqcert));
>  	IDMAP_LOG(1, ("umichldap_init: use_memberof_for_groups : %s",
>  		  ldap_info.memberof_for_groups ? "yes" : "no"));
>  
>
diff mbox series

Patch

diff --git a/support/nfsidmap/idmapd.conf b/support/nfsidmap/idmapd.conf
index f07286c3..b673c7d7 100644
--- a/support/nfsidmap/idmapd.conf
+++ b/support/nfsidmap/idmapd.conf
@@ -101,7 +101,13 @@  LDAP_base = dc=local,dc=domain,dc=edu
 # Set to true to enable SSL - anything else is not enabled
 #LDAP_use_ssl = false
 
-# You must specify a CA certificate location if you enable SSL
+# Controls the LDAP server certificate validation behavior
+# It can take the same values as ldap.conf(5)'s TLS_REQCERT
+# tunable
+#LDAP_tls_reqcert = "hard"
+
+# Location of CA certificate, mandatory if LDAP_tls_reqcert
+# is not set to "never"
 #LDAP_ca_cert = /etc/ldapca.cert
 
 # Objectclass mapping information
diff --git a/support/nfsidmap/idmapd.conf.5 b/support/nfsidmap/idmapd.conf.5
index 9a6457e2..61fbb613 100644
--- a/support/nfsidmap/idmapd.conf.5
+++ b/support/nfsidmap/idmapd.conf.5
@@ -195,7 +195,16 @@  Set to "true" to enable SSL communication with the LDAP server.
 Location of a trusted CA certificate used when SSL is enabled
 (Required if
 .B LDAP_use_ssl
-is true)
+is true and
+.B LDAP_tls_reqcert
+is not set to never)
+.TP
+.B LDAP_tls_reqcert
+Controls the LDAP server certificate validation behavior.
+It can take the same values as ldap.conf(5)'s
+.B TLS_REQCERT
+tunable.
+(Default: "hard")
 .TP
 .B NFSv4_person_objectclass
 The object class name for people accounts in your local LDAP schema
diff --git a/support/nfsidmap/umich_ldap.c b/support/nfsidmap/umich_ldap.c
index 10d1d979..b7445c37 100644
--- a/support/nfsidmap/umich_ldap.c
+++ b/support/nfsidmap/umich_ldap.c
@@ -100,6 +100,7 @@  struct umich_ldap_info {
 	char *passwd;		/* Password to use when binding to directory */
 	int use_ssl;		/* SSL flag */
 	char *ca_cert;		/* File location of the ca_cert */
+	int tls_reqcert;	/* req and validate server cert */
 	int memberof_for_groups;/* Use 'memberof' attribute when
 				   looking up user groups */
 	int ldap_timeout;	/* Timeout in seconds for searches
@@ -118,6 +119,7 @@  static struct umich_ldap_info ldap_info = {
 	.passwd = NULL,
 	.use_ssl = 0,
 	.ca_cert = NULL,
+	.tls_reqcert = LDAP_OPT_X_TLS_HARD,
 	.memberof_for_groups = 0,
 	.ldap_timeout = DEFAULT_UMICH_SEARCH_TIMEOUT,
 };
@@ -153,7 +155,7 @@  ldap_init_and_bind(LDAP **pld,
 	LDAPAPIInfo apiinfo = {.ldapai_info_version = LDAP_API_INFO_VERSION};
 
 	snprintf(server_url, sizeof(server_url), "%s://%s:%d",
-		 (linfo->use_ssl && linfo->ca_cert) ? "ldaps" : "ldap",
+		 (linfo->use_ssl) ? "ldaps" : "ldap",
 		 linfo->server, linfo->port);
 
 	/*
@@ -208,9 +210,8 @@  ldap_init_and_bind(LDAP **pld,
 	}
 
 	/* Set option to to use SSL/TLS if requested */
-	if (linfo->use_ssl && linfo->ca_cert) {
+	if (linfo->use_ssl) {
 		int tls_type = LDAP_OPT_X_TLS_HARD;
-
 		lerr = ldap_set_option(ld, LDAP_OPT_X_TLS, &tls_type);
 		if (lerr != LDAP_SUCCESS) {
 			IDMAP_LOG(2, ("ldap_init_and_bind: setting SSL "
@@ -218,11 +219,23 @@  ldap_init_and_bind(LDAP **pld,
 				  ldap_err2string(lerr), lerr));
 			goto out;
 		}
-		lerr = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
-				       linfo->ca_cert);
+
+		if (linfo->ca_cert != NULL) {
+			lerr = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
+					       linfo->ca_cert);
+			if (lerr != LDAP_SUCCESS) {
+				IDMAP_LOG(2, ("ldap_init_and_bind: setting CA "
+					  "certificate file failed : %s (%d)",
+					  ldap_err2string(lerr), lerr));
+				goto out;
+			}
+		}
+
+		lerr = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
+				       &linfo->tls_reqcert);
 		if (lerr != LDAP_SUCCESS) {
-			IDMAP_LOG(2, ("ldap_init_and_bind: setting CA "
-				  "certificate file failed : %s (%d)",
+			IDMAP_LOG(2, ("ldap_init_and_bind: setting "
+				      "req CA cert failed : %s(%d)",
 				  ldap_err2string(lerr), lerr));
 			goto out;
 		}
@@ -1098,7 +1111,7 @@  out_err:
 static int
 umichldap_init(void)
 {
-	char *tssl, *canonicalize, *memberof;
+	char *tssl, *canonicalize, *memberof, *cert_req;
 	char missing_msg[128] = "";
 	char *server_in, *canon_name;
 
@@ -1119,6 +1132,24 @@  umichldap_init(void)
 	else
 		ldap_info.use_ssl = 0;
 	ldap_info.ca_cert = conf_get_str(LDAP_SECTION, "LDAP_CA_CERT");
+	cert_req = conf_get_str(LDAP_SECTION, "LDAP_tls_reqcert");
+	if (cert_req != NULL) {
+		if (strcasecmp(cert_req, "hard") == 0)
+			ldap_info.tls_reqcert = LDAP_OPT_X_TLS_HARD;
+		else if (strcasecmp(cert_req, "demand") == 0)
+			ldap_info.tls_reqcert = LDAP_OPT_X_TLS_DEMAND;
+		else if (strcasecmp(cert_req, "try") == 0)
+			ldap_info.tls_reqcert = LDAP_OPT_X_TLS_TRY;
+		else if (strcasecmp(cert_req, "allow") == 0)
+			ldap_info.tls_reqcert = LDAP_OPT_X_TLS_ALLOW;
+		else if (strcasecmp(cert_req, "never") == 0)
+			ldap_info.tls_reqcert = LDAP_OPT_X_TLS_NEVER;
+		else {
+			IDMAP_LOG(0, ("umichldap_init: Invalid value(%s) for "
+				      "LDAP_tls_reqcert."));
+			goto fail;
+		}
+	}
 	/* vary the default port depending on whether they use SSL or not */
 	ldap_info.port = conf_get_num(LDAP_SECTION, "LDAP_port",
 				      (ldap_info.use_ssl) ?
@@ -1230,9 +1261,12 @@  umichldap_init(void)
 	if (ldap_info.group_tree == NULL || strlen(ldap_info.group_tree) == 0)
 		ldap_info.group_tree = ldap_info.base;
 
-	if (ldap_info.use_ssl && ldap_info.ca_cert == NULL) {
+	if (ldap_info.use_ssl &&
+	    ldap_info.tls_reqcert != LDAP_OPT_X_TLS_NEVER &&
+	    ldap_info.ca_cert == NULL) {
 		IDMAP_LOG(0, ("umichldap_init: You must specify LDAP_ca_cert "
-			  "with LDAP_use_ssl=yes"));
+			  "with LDAP_use_ssl=yes and "
+			  "LDAP_tls_reqcert not set to \"never\""));
 		goto fail;
 	}
 
@@ -1257,6 +1291,9 @@  umichldap_init(void)
 		  ldap_info.use_ssl ? "yes" : "no"));
 	IDMAP_LOG(1, ("umichldap_init: ca_cert : %s",
 		  ldap_info.ca_cert ? ldap_info.ca_cert : "<not-supplied>"));
+	IDMAP_LOG(1, ("umichldap_init: tls_reqcert : %s(%d)",
+		  cert_req ? cert_req : "<not-supplied>",
+		  ldap_info.tls_reqcert));
 	IDMAP_LOG(1, ("umichldap_init: use_memberof_for_groups : %s",
 		  ldap_info.memberof_for_groups ? "yes" : "no"));