-/* $OpenBSD: aldap.c,v 1.48 2022/03/31 09:06:55 martijn Exp $ */
+/* $OpenBSD: aldap.c,v 1.49 2022/10/13 04:55:33 jmatthew Exp $ */
/*
* Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org>
return (-1);
}
+int
+aldap_bind_sasl_external(struct aldap *ldap, char *bindid)
+{
+ struct ber_element *root = NULL, *elm;
+
+ if ((root = ober_add_sequence(NULL)) == NULL)
+ goto fail;
+
+ elm = ober_printf_elements(root, "d{tds{ts", ++ldap->msgid,
+ BER_CLASS_APP, LDAP_REQ_BIND, VERSION, "",
+ BER_CLASS_CONTEXT, LDAP_AUTH_SASL, LDAP_SASL_MECH_EXTERNAL);
+ if (elm == NULL)
+ goto fail;
+
+ if (bindid == NULL)
+ elm = ober_add_null(elm);
+ else
+ elm = ober_add_string(elm, bindid);
+
+ if (elm == NULL)
+ goto fail;
+
+ LDAP_DEBUG("aldap_bind_sasl_external", root);
+
+ if (aldap_send(ldap, root) == -1) {
+ root = NULL;
+ goto fail;
+ }
+ return (ldap->msgid);
+fail:
+ ober_free_elements(root);
+
+ ldap->err = ALDAP_ERR_OPERATION_FAILED;
+ return (-1);
+}
+
int
aldap_unbind(struct aldap *ldap)
{
-/* $OpenBSD: aldap.h,v 1.14 2019/05/11 17:46:02 rob Exp $ */
+/* $OpenBSD: aldap.h,v 1.15 2022/10/13 04:55:33 jmatthew Exp $ */
/*
* Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org>
#define LDAP_PAGED_OID "1.2.840.113556.1.4.319"
#define LDAP_STARTTLS_OID "1.3.6.1.4.1.1466.20037"
+#define LDAP_SASL_MECH_EXTERNAL "EXTERNAL"
+
struct aldap {
#define ALDAP_ERR_SUCCESS 0
#define ALDAP_ERR_PARSER_ERROR 1
enum authentication_choice {
LDAP_AUTH_SIMPLE = 0,
+ LDAP_AUTH_SASL = 3,
};
enum scope {
int aldap_req_starttls(struct aldap *);
int aldap_bind(struct aldap *, char *, char *);
+int aldap_bind_sasl_external(struct aldap *, char *);
int aldap_unbind(struct aldap *);
int aldap_search(struct aldap *, char *, enum scope, char *, char **, int, int, int, struct aldap_page_control *);
int aldap_get_errno(struct aldap *, const char **);
-/* $OpenBSD: ldapclient.c,v 1.45 2022/08/22 10:10:59 jmatthew Exp $ */
+/* $OpenBSD: ldapclient.c,v 1.46 2022/10/13 04:55:33 jmatthew Exp $ */
/*
* Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org>
int rc;
where = "binding";
- if (aldap_bind(al, idm->idm_binddn, idm->idm_bindcred) == -1)
+ if (idm->idm_bindext != 0)
+ rc = aldap_bind_sasl_external(al, idm->idm_bindextid);
+ else
+ rc = aldap_bind(al, idm->idm_binddn, idm->idm_bindcred);
+ if (rc == -1)
goto bad;
where = "parsing";
-/* $OpenBSD: parse.y,v 1.35 2022/08/19 03:50:32 jmatthew Exp $ */
+/* $OpenBSD: parse.y,v 1.36 2022/10/13 04:55:33 jmatthew Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
%token USER GROUP TO EXPIRE HOME SHELL GECOS UID GID INTERVAL
%token PASSWD NAME FIXED LIST GROUPNAME GROUPPASSWD GROUPGID MAP
%token INCLUDE DIRECTORY CLASS PORT ERROR GROUPMEMBERS LDAPS TLS CAFILE
-%token BIND LOCAL PORTMAP
+%token BIND LOCAL PORTMAP BINDEXT CERTFILE KEYFILE
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.number> opcode attribute
;
diropt : BINDDN STRING {
+ if (idm->idm_bindext != 0) {
+ yyerror("can't specify multiple bind types");
+ free($2);
+ YYERROR;
+ }
idm->idm_flags |= F_NEEDAUTH;
if (strlcpy(idm->idm_binddn, $2,
sizeof(idm->idm_binddn)) >=
free($2);
}
| BINDCRED STRING {
+ if (idm->idm_bindext != 0) {
+ yyerror("can't specify multiple bind types");
+ free($2);
+ YYERROR;
+ }
idm->idm_flags |= F_NEEDAUTH;
if (strlcpy(idm->idm_bindcred, $2,
sizeof(idm->idm_bindcred)) >=
}
free($2);
}
+ | BINDEXT STRING {
+ if (idm->idm_flags & F_NEEDAUTH) {
+ yyerror("can't specify multiple bind types");
+ free($2);
+ YYERROR;
+ }
+ idm->idm_flags |= F_NEEDAUTH;
+ idm->idm_bindext = 1;
+ if (strlcpy(idm->idm_bindextid, $2,
+ sizeof(idm->idm_bindextid)) >=
+ sizeof(idm->idm_bindextid)) {
+ yyerror("directory bindext truncated");
+ free($2);
+ YYERROR;
+ }
+ free($2);
+ }
+ | BINDEXT {
+ if (idm->idm_flags & F_NEEDAUTH) {
+ yyerror("can't specify multiple bind types");
+ YYERROR;
+ }
+ idm->idm_flags |= F_NEEDAUTH;
+ idm->idm_bindext = 1;
+ idm->idm_bindextid[0] = '\0';
+ }
+ | CERTFILE STRING {
+ if (idm->idm_tls_config == NULL) {
+ yyerror("can't set cert file without tls"
+ " enabled");
+ free($2);
+ YYERROR;
+ }
+ if (tls_config_set_cert_file(idm->idm_tls_config, $2)
+ == -1) {
+ yyerror("tls set cert file failed: %s",
+ tls_config_error(
+ idm->idm_tls_config));
+ free($2);
+ YYERROR;
+ }
+ }
+ | KEYFILE STRING {
+ if (idm->idm_tls_config == NULL) {
+ yyerror("can't set key file without tls"
+ " enabled");
+ free($2);
+ YYERROR;
+ }
+ if (tls_config_set_key_file(idm->idm_tls_config, $2)
+ == -1) {
+ yyerror("tls set key file failed: %s",
+ tls_config_error(
+ idm->idm_tls_config));
+ free($2);
+ YYERROR;
+ }
+ }
| BASEDN STRING {
if (strlcpy(idm->idm_basedn, $2,
sizeof(idm->idm_basedn)) >=
{ "bind", BIND },
{ "bindcred", BINDCRED },
{ "binddn", BINDDN },
+ { "bindext", BINDEXT },
{ "cafile", CAFILE },
+ { "certfile", CERTFILE },
{ "change", CHANGE },
{ "class", CLASS },
{ "directory", DIRECTORY },
{ "home", HOME },
{ "include", INCLUDE },
{ "interval", INTERVAL },
+ { "keyfile", KEYFILE },
{ "ldaps", LDAPS },
{ "list", LIST },
{ "local", LOCAL },
-.\" $OpenBSD: ypldap.conf.5,v 1.27 2022/08/22 07:07:45 jmatthew Exp $
+.\" $OpenBSD: ypldap.conf.5,v 1.28 2022/10/13 04:55:33 jmatthew Exp $
.\"
.\" Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
.\"
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: August 22 2022 $
+.Dd $Mdocdate: October 13 2022 $
.Dt YPLDAP.CONF 5
.Os
.Sh NAME
attribute to the LDAP attribute name supplied.
.It Ic basedn Ar string
Use the supplied search base as starting point for the directory search.
+.It Ic certfile Ar string
+Use the specified client certificate when connecting to the directory.
+The file must contain a PEM encoded certificate.
.It Ic groupdn Ar string
Use the supplied search base as starting point for the directory search for
groups.
Use the supplied credentials for simple authentication against the directory.
.It Ic binddn Ar string
Use the supplied Distinguished Name to bind to the directory.
+.It Ic bindext Oo Ar string Oc
+Bind to the directory using SASL EXTERNAL, optionally using a supplied identity
+string.
+When using a TLS client certificate, this allows the client to bind as the
+subject of the certificate.
+If an identity string is supplied, usually in the form of a distinguished name
+prefixed with "dn:", the directory will only allow the bind to succeed if it
+matches the subject of the certificate.
.It Ic fixed attribute Ar attribute string
Do not retrieve the specified attribute from LDAP but
instead set it unconditionally to the supplied value for
every entry.
.It Ic group filter Ar string
Use the supplied LDAP filter to retrieve group entries.
+.It Ic keyfile Ar string
+Use the specified private key when connecting to the directory.
+The file must contain a PEM encoded key.
.It Xo
.Ic list Ar name Ic maps to Ar string
.Xc
-/* $OpenBSD: ypldap.h,v 1.22 2022/08/19 03:50:32 jmatthew Exp $ */
+/* $OpenBSD: ypldap.h,v 1.23 2022/10/13 04:55:33 jmatthew Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
u_int32_t idm_list;
struct ypldap_addr_list idm_addr;
in_port_t idm_port;
+ int idm_bindext;
char idm_binddn[LINE_WIDTH];
+ char idm_bindextid[LINE_WIDTH];
char idm_bindcred[LINE_WIDTH];
char idm_basedn[LINE_WIDTH];
char idm_groupdn[LINE_WIDTH];