summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authoraschrijver <aschrijver@cvs.openbsd.org>2008-10-14 21:41:04 +0000
committeraschrijver <aschrijver@cvs.openbsd.org>2008-10-14 21:41:04 +0000
commitfd1fc729039aaaba1069b6040004a7239cd79976 (patch)
tree6c9841bc003970f92794def093c1c9ad1716eeba /usr.sbin
parentec0e78b6596661dd1918b16a1f8b8594bdb5b036 (diff)
Add support for referrals and lists of attributes.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/ypldap/aldap.c21
-rw-r--r--usr.sbin/ypldap/aldap.h6
-rw-r--r--usr.sbin/ypldap/ldapclient.c407
-rw-r--r--usr.sbin/ypldap/parse.y19
-rw-r--r--usr.sbin/ypldap/ypldap.h3
5 files changed, 348 insertions, 108 deletions
diff --git a/usr.sbin/ypldap/aldap.c b/usr.sbin/ypldap/aldap.c
index b8cb3ec0e6a..c2b69a7c5c1 100644
--- a/usr.sbin/ypldap/aldap.c
+++ b/usr.sbin/ypldap/aldap.c
@@ -1,5 +1,5 @@
-/* $Id: aldap.c,v 1.4 2008/10/06 08:01:28 aschrijver Exp $ */
-/* $OpenBSD: aldap.c,v 1.4 2008/10/06 08:01:28 aschrijver Exp $ */
+/* $Id: aldap.c,v 1.5 2008/10/14 21:41:03 aschrijver Exp $ */
+/* $OpenBSD: aldap.c,v 1.5 2008/10/14 21:41:03 aschrijver Exp $ */
/*
* Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org>
@@ -156,7 +156,7 @@ aldap_parse(struct aldap *ldap)
&m->body.res.rescode, &m->dn, &m->body.res.diagmsg, &a) != 0)
goto parsefail;
if(m->body.res.rescode == LDAP_REFERRAL)
- if(ber_scanf_elements(a, "{e", &m->body.references) != 0)
+ if(ber_scanf_elements(a, "{e", &m->references) != 0)
goto parsefail;
break;
case LDAP_RES_SEARCH_ENTRY:
@@ -165,7 +165,7 @@ aldap_parse(struct aldap *ldap)
goto parsefail;
break;
case LDAP_RES_SEARCH_REFERENCE:
- if(ber_scanf_elements(m->protocol_op, "{e", &m->body.references) != 0)
+ if(ber_scanf_elements(m->protocol_op, "{e", &m->references) != 0)
goto parsefail;
break;
}
@@ -205,7 +205,9 @@ aldap_get_dn(struct aldap_message *msg)
char **
aldap_get_references(struct aldap_message *msg)
{
- return aldap_get_stringset(msg->body.references);
+ if(msg->references == NULL)
+ return NULL;
+ return aldap_get_stringset(msg->references);
}
void
@@ -387,7 +389,8 @@ aldap_parse_url(char *url, struct aldap_url *lu)
*forward2 = '\0';
/* if a port is given */
if(*(forward2+1) != '\0') {
- lu->port = strtonum(++forward2, 0, sizeof(lu->port), &errstr);
+#define PORT_MAX UINT16_MAX
+ lu->port = strtonum(++forward2, 0, PORT_MAX, &errstr);
if(errstr)
goto fail;
}
@@ -478,9 +481,11 @@ aldap_get_stringset(struct ber_element *elm)
if(elm->be_type != BER_TYPE_OCTETSTRING)
return NULL;
- for(a = elm, i = 1; i > 0 && a->be_type == BER_TYPE_OCTETSTRING;
- a = a->be_next, i++)
+ for(a = elm, i = 1; i > 0 && a != NULL && a->be_type ==
+ BER_TYPE_OCTETSTRING; a = a->be_next, i++)
;
+ if(i == 1)
+ return NULL;
if((ret = calloc(i + 1, sizeof(char *))) == NULL)
return NULL;
diff --git a/usr.sbin/ypldap/aldap.h b/usr.sbin/ypldap/aldap.h
index d27feb76c5e..5619d7dfec7 100644
--- a/usr.sbin/ypldap/aldap.h
+++ b/usr.sbin/ypldap/aldap.h
@@ -1,5 +1,5 @@
-/* $Id: aldap.h,v 1.3 2008/10/06 11:20:20 aschrijver Exp $ */
-/* $OpenBSD: aldap.h,v 1.3 2008/10/06 11:20:20 aschrijver Exp $ */
+/* $Id: aldap.h,v 1.4 2008/10/14 21:41:03 aschrijver Exp $ */
+/* $OpenBSD: aldap.h,v 1.4 2008/10/14 21:41:03 aschrijver Exp $ */
/*
* Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org>
@@ -49,8 +49,8 @@ struct aldap_message {
struct ber_element *iter;
struct ber_element *entries;
} search;
- struct ber_element *references;
} body;
+ struct ber_element *references;
};
enum aldap_protocol {
diff --git a/usr.sbin/ypldap/ldapclient.c b/usr.sbin/ypldap/ldapclient.c
index 1f812bc59ac..ac366464e28 100644
--- a/usr.sbin/ypldap/ldapclient.c
+++ b/usr.sbin/ypldap/ldapclient.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldapclient.c,v 1.4 2008/10/06 11:20:20 aschrijver Exp $ */
+/* $OpenBSD: ldapclient.c,v 1.5 2008/10/14 21:41:03 aschrijver Exp $ */
/*
* Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org>
@@ -37,9 +37,7 @@
#include <stdlib.h>
#include <string.h>
-#define LDAP_DEPRECATED 1
#include "aldap.h"
-
#include "ypldap.h"
void client_sig_handler(int, short, void *);
@@ -52,35 +50,69 @@ int client_try_idm(struct env *, struct idm *);
void client_try_idm_wrapper(int, short, void *);
void client_try_server_wrapper(int, short, void *);
-static int remote_connect(const char *, const char *, struct addrinfo);
+int do_build_group(struct env *, struct idm *, struct aldap *, char *, enum
+ scope, char *);
+int do_build_passwd(struct env *, struct idm *, struct aldap *, char *, enum
+ scope, char *);
+
+struct aldap *aldap_open(char *, char *);
+int aldap_close(struct aldap *);
+struct aldap *connect_to_referral(struct aldap_message *, struct aldap_url *);
-static int
-remote_connect(const char *host, const char *port, struct addrinfo hints)
+int
+aldap_close(struct aldap *al)
{
+ if(close(al->ber.fd) == -1)
+ return (-1);
+
+ free(al);
+
+ return (0);
+}
+
+struct aldap *
+aldap_open(char *host, char *port)
+{
+ struct addrinfo hints;
+ struct aldap *al;
+ int fd;
+
struct addrinfo *res, *res0;
- int s, error;
+ int error;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ log_debug("trying directory: %s", host);
if ((error = getaddrinfo(host, port, &hints, &res)))
errx(1, "getaddrinfo: %s", gai_strerror(error));
res0 = res;
do {
- if ((s = socket(res0->ai_family, res0->ai_socktype,
+ if ((fd = socket(res0->ai_family, res0->ai_socktype,
res0->ai_protocol)) < 0)
continue;
- if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
+ if (connect(fd, res0->ai_addr, res0->ai_addrlen) == 0)
break;
- else
+ else {
warn("connect to %s port %s (%s) failed", host, port, "tcp");
+ return NULL;
+ }
- close(s);
- s = -1;
+ close(fd);
+ fd = -1;
} while ((res0 = res0->ai_next) != NULL);
freeaddrinfo(res);
- return (s);
+ if((al = aldap_init(fd)) == NULL)
+ return NULL;
+
+ return al;
}
void
@@ -263,160 +295,351 @@ client_configure_wrapper(int fd, short event, void *p)
client_configure(env);
}
-int
-client_try_idm(struct env *env, struct idm *idm)
+struct aldap *
+connect_to_referral(struct aldap_message *m, struct aldap_url *lu)
{
- int i, j, fd;
- char *attrs[ATTR_MAX+1];
- char **ldap_attrs;
- const char *where;
- struct idm_req ir;
- struct addrinfo hints;
- struct aldap_message *m;
- struct aldap *al;
+ int i;
+ char **refs, *port;
+ struct aldap *al = NULL;
- log_debug("trying directory: %s", idm->idm_name);
+ if((refs = aldap_get_references(m)) == NULL)
+ return NULL;
- bzero(&ir, sizeof(ir));
- imsg_compose(env->sc_ibuf, IMSG_START_UPDATE, 0, 0, &ir, sizeof(ir));
+ for(i = 0; i >= 0 && refs[i] != NULL; i++) {
+ aldap_parse_url(refs[i], lu);
+ asprintf(&port, "%d", lu->port ? lu->port : 389);
- /* connect to LDAP server */
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
+ if((al = aldap_open(lu->host, port)) != NULL) {
+ free(port);
+ break;
+ }
- where = "connect";
- fd = remote_connect(idm->idm_name, "389", hints);
- if(fd == -1)
- goto bad;
+ free(port);
+ }
- al = aldap_init(fd);
- if(al == NULL)
- goto bad;
+ aldap_free_references(refs);
- /* do a bind request */
- if(aldap_bind(al, idm->idm_binddn, idm->idm_bindcred) == -1)
- goto bad;
- where = "parsing";
- if((m = aldap_parse(al)) == NULL)
- goto bad;
- if(al->msgid != m->msgid)
- goto bad; /* XXX: error reporting */
- aldap_freemsg(m);
+ return al;
+}
+
+#define MAX_REFERRALS 10
+int
+do_build_group(struct env *env, struct idm *idm, struct aldap *al, char
+ *basedn, enum scope scope, char *filter)
+{
+ char *attrs[ATTR_MAX+1];
+ char **ldap_attrs;
+ struct idm_req ir;
+ struct aldap_message *m;
+ struct aldap_url lu;
+ struct aldap *al_ref;
+ int i, j, k;
+ const char *where;
+ static int refcnt = 0;
bzero(attrs, sizeof(attrs));
- for (i = 0, j = 0; i < ATTR_MAX; i++) {
+ for (i = ATTR_GR_MIN, j = 0; i < ATTR_GR_MAX; i++) {
if (idm->idm_flags & F_FIXED_ATTR(i))
continue;
attrs[j++] = idm->idm_attrs[i];
}
attrs[j] = NULL;
- /* do a search request */
- aldap_search(al, idm->idm_basedn, LDAP_SCOPE_SUBTREE,
- idm->idm_filters[FILTER_USER], attrs, 0, 0, 0);
+ where = "search";
+ if(aldap_search(al, basedn, scope, filter, attrs, 0, 0, 0) == -1)
+ goto bad;
/*
- * build password line.
+ * build group line.
*/
while((m = aldap_parse(al)) != NULL) {
- if(al->msgid != m->msgid)
- goto bad; /* XXX: error reporting */
- if (m->message_type == LDAP_RES_SEARCH_RESULT)
+ where = "verifying msgid";
+ if(al->msgid != m->msgid) {
+ aldap_freemsg(m);
+ goto bad;
+ }
+ /* continuation referral */
+ if (m->message_type == LDAP_RES_SEARCH_REFERENCE) {
+ if(refcnt++ >= MAX_REFERRALS)
+ goto next_entry;
+
+ if((al_ref = connect_to_referral(m, &lu)) == NULL)
+ goto next_entry;
+ do_build_group(env, idm, al_ref, lu.dn,
+ lu.scope, idm->idm_filters[FILTER_GROUP]);
+ aldap_close(al_ref);
+ goto next_entry;
+ }
+ /* normal referral */
+ if(m->message_type == LDAP_RES_SEARCH_RESULT &&
+ aldap_get_resultcode(m) == LDAP_REFERRAL) {
+ if(refcnt++ == MAX_REFERRALS) {
+ aldap_freemsg(m);
+ break;
+ }
+
+ if((al_ref = connect_to_referral(m, &lu)) == NULL) {
+ aldap_freemsg(m);
+ break;
+ }
+ do_build_group(env, idm, al_ref, lu.dn,
+ lu.scope, idm->idm_filters[FILTER_GROUP]);
+ aldap_close(al_ref);
+ }
+ /* end of the search result chain */
+ if (m->message_type == LDAP_RES_SEARCH_RESULT) {
+ aldap_freemsg(m);
break;
+ }
+ /* search entry; the rest we won't handle */
+ if(m->message_type != LDAP_RES_SEARCH_ENTRY) {
+ aldap_freemsg(m);
+ goto bad;
+ }
+ /* search entry */
bzero(&ir, sizeof(ir));
- for (i = 0, j = 0; i < ATTR_MAX; i++) {
+ for (i = ATTR_GR_MIN, j = 0; i < ATTR_GR_MAX; i++) {
if (idm->idm_flags & F_FIXED_ATTR(i)) {
if (strlcat(ir.ir_line, idm->idm_attrs[i],
sizeof(ir.ir_line)) >= sizeof(ir.ir_line))
/*
* entry yields a line > 1024, trash it.
*/
- continue;
- if (i == ATTR_UID) {
- ir.ir_key.ik_uid = strtonum(
+ goto next_entry;
+ if (i == ATTR_GR_GID) {
+ ir.ir_key.ik_gid = strtonum(
idm->idm_attrs[i], 0,
- UID_MAX, NULL);
+ GID_MAX, NULL);
}
+ } else if (idm->idm_list & F_LIST(i)) {
+ if (aldap_match_entry(m, attrs[j++], &ldap_attrs) == -1)
+ goto next_entry;
+ if (ldap_attrs == NULL || ldap_attrs[0] == NULL)
+ goto next_entry;
+ for(k = 0; k >= 0 && ldap_attrs[k] != NULL; k++) {
+ if (strlcat(ir.ir_line, ldap_attrs[k],
+ sizeof(ir.ir_line)) >= sizeof(ir.ir_line))
+ continue;
+ if(ldap_attrs[k+1] != NULL)
+ if (strlcat(ir.ir_line, ",",
+ sizeof(ir.ir_line))
+ >= sizeof(ir.ir_line)) {
+ aldap_free_entry(ldap_attrs);
+ goto next_entry;
+ }
+ }
+ aldap_free_entry(ldap_attrs);
} else {
- aldap_match_entry(m, attrs[j++], &ldap_attrs);
+ if(aldap_match_entry(m, attrs[j++], &ldap_attrs) == -1)
+ goto next_entry;
if (ldap_attrs == NULL || ldap_attrs[0] == NULL)
- continue;
+ goto next_entry;
if (strlcat(ir.ir_line, ldap_attrs[0],
- sizeof(ir.ir_line)) >= sizeof(ir.ir_line))
- continue;
- if (i == ATTR_UID) {
+ sizeof(ir.ir_line)) >= sizeof(ir.ir_line)) {
+ aldap_free_entry(ldap_attrs);
+ goto next_entry;
+ }
+ if (i == ATTR_GR_GID) {
ir.ir_key.ik_uid = strtonum(
- ldap_attrs[0], 0, UID_MAX, NULL);
+ ldap_attrs[0], 0, GID_MAX, NULL);
}
aldap_free_entry(ldap_attrs);
}
- if (i != ATTR_SHELL)
+ if (i != ATTR_GR_MEMBERS)
if (strlcat(ir.ir_line, ":",
sizeof(ir.ir_line)) >= sizeof(ir.ir_line))
- continue;
+ goto next_entry;
}
- imsg_compose(env->sc_ibuf, IMSG_PW_ENTRY, 0, 0,
+ imsg_compose(env->sc_ibuf, IMSG_GRP_ENTRY, 0, 0,
&ir, sizeof(ir));
+next_entry:
+ aldap_freemsg(m);
}
- /*
- * exact same code but for groups.
- */
+ return (0);
+bad:
+ log_debug("directory %s errored out in %s", idm->idm_name, where);
+ return (-1);
+}
+
+int
+do_build_passwd(struct env *env, struct idm *idm, struct aldap *al, char
+ *basedn, enum scope scope, char *filter)
+{
+ char *attrs[ATTR_MAX+1];
+ char **ldap_attrs;
+ struct idm_req ir;
+ struct aldap_message *m;
+ struct aldap_url lu;
+ struct aldap *al_ref;
+ int i, j, k;
+ const char *where;
+ static int refcnt = 0;
bzero(attrs, sizeof(attrs));
- for (i = ATTR_GR_MIN, j = 0; i < ATTR_GR_MAX; i++) {
+ for (i = 0, j = 0; i < ATTR_MAX; i++) {
if (idm->idm_flags & F_FIXED_ATTR(i))
continue;
attrs[j++] = idm->idm_attrs[i];
}
attrs[j] = NULL;
- aldap_search(al, idm->idm_basedn, LDAP_SCOPE_SUBTREE,
- idm->idm_filters[FILTER_GROUP], attrs, 0, 0, 0);
+ where = "search";
+ if(aldap_search(al, basedn, scope, filter, attrs, 0, 0, 0) == -1)
+ goto bad;
+ /*
+ * build password line.
+ */
while((m = aldap_parse(al)) != NULL) {
- if(al->msgid != m->msgid)
- goto bad; /* XXX: error reporting */
- if (m->message_type == LDAP_RES_SEARCH_RESULT)
+ where = "verifying msgid";
+ if(al->msgid != m->msgid) {
+ aldap_freemsg(m);
+ goto bad;
+ }
+ /* continuation referral */
+ if (m->message_type == LDAP_RES_SEARCH_REFERENCE) {
+ if(refcnt++ >= MAX_REFERRALS)
+ goto next_entry;
+
+ if((al_ref = connect_to_referral(m, &lu)) == NULL)
+ goto next_entry;
+ do_build_passwd(env, idm, al_ref, lu.dn,
+ lu.scope, idm->idm_filters[FILTER_USER]);
+ aldap_close(al_ref);
+ goto next_entry;
+ }
+ /* normal referral */
+ if(m->message_type == LDAP_RES_SEARCH_RESULT &&
+ aldap_get_resultcode(m) == LDAP_REFERRAL) {
+ if(refcnt++ == MAX_REFERRALS) {
+ aldap_freemsg(m);
+ break;
+ }
+
+ if((al_ref = connect_to_referral(m, &lu)) == NULL) {
+ aldap_freemsg(m);
+ break;
+ }
+ do_build_passwd(env, idm, al_ref, lu.dn,
+ lu.scope, idm->idm_filters[FILTER_USER]);
+ aldap_close(al_ref);
+ }
+ /* end of the search result chain */
+ if (m->message_type == LDAP_RES_SEARCH_RESULT) {
+ aldap_freemsg(m);
break;
+ }
+ /* search entry; the rest we won't handle */
+ if(m->message_type != LDAP_RES_SEARCH_ENTRY) {
+ aldap_freemsg(m);
+ goto bad;
+ }
+ /* search entry */
bzero(&ir, sizeof(ir));
- for (i = ATTR_GR_MIN, j = 0; i < ATTR_GR_MAX; i++) {
+ for (i = 0, j = 0; i < ATTR_MAX; i++) {
if (idm->idm_flags & F_FIXED_ATTR(i)) {
if (strlcat(ir.ir_line, idm->idm_attrs[i],
sizeof(ir.ir_line)) >= sizeof(ir.ir_line))
/*
* entry yields a line > 1024, trash it.
*/
- continue;
- if (i == ATTR_GR_GID) {
- ir.ir_key.ik_gid = strtonum(
+ goto next_entry;
+ if (i == ATTR_UID) {
+ ir.ir_key.ik_uid = strtonum(
idm->idm_attrs[i], 0,
- GID_MAX, NULL);
+ UID_MAX, NULL);
+ }
+ } else if (idm->idm_list & F_LIST(i)) {
+ if (aldap_match_entry(m, attrs[j++], &ldap_attrs) == -1)
+ goto next_entry;
+ if (ldap_attrs == NULL || ldap_attrs[0] == NULL)
+ goto next_entry;
+ for(k = 0; k >= 0 && ldap_attrs[k] != NULL; k++) {
+ if (strlcat(ir.ir_line, ldap_attrs[k],
+ sizeof(ir.ir_line)) >= sizeof(ir.ir_line))
+ continue;
+ if(ldap_attrs[k+1] != NULL)
+ if (strlcat(ir.ir_line, ",",
+ sizeof(ir.ir_line))
+ >= sizeof(ir.ir_line)) {
+ aldap_free_entry(ldap_attrs);
+ goto next_entry;
+ }
}
+ aldap_free_entry(ldap_attrs);
} else {
- aldap_match_entry(m, attrs[j++], &ldap_attrs);
+ if (aldap_match_entry(m, attrs[j++], &ldap_attrs) == -1)
+ goto next_entry;
if (ldap_attrs == NULL || ldap_attrs[0] == NULL)
- continue;
+ goto next_entry;
if (strlcat(ir.ir_line, ldap_attrs[0],
- sizeof(ir.ir_line)) >= sizeof(ir.ir_line))
- continue;
- if (i == ATTR_GR_GID) {
+ sizeof(ir.ir_line)) >= sizeof(ir.ir_line)) {
+ aldap_free_entry(ldap_attrs);
+ goto next_entry;
+ }
+ if (i == ATTR_UID) {
ir.ir_key.ik_uid = strtonum(
- ldap_attrs[0], 0, GID_MAX, NULL);
+ ldap_attrs[0], 0, UID_MAX, NULL);
}
aldap_free_entry(ldap_attrs);
}
- if (i != ATTR_GR_MEMBERS)
+ if (i != ATTR_SHELL)
if (strlcat(ir.ir_line, ":",
sizeof(ir.ir_line)) >= sizeof(ir.ir_line))
- continue;
+ goto next_entry;
}
- imsg_compose(env->sc_ibuf, IMSG_GRP_ENTRY, 0, 0,
+ imsg_compose(env->sc_ibuf, IMSG_PW_ENTRY, 0, 0,
&ir, sizeof(ir));
+next_entry:
+ aldap_freemsg(m);
+ }
+
+ return (0);
+bad:
+ log_debug("directory %s errored out in %s", idm->idm_name, where);
+ return (-1);
+}
+
+
+int
+client_try_idm(struct env *env, struct idm *idm)
+{
+ const char *where;
+ struct idm_req ir;
+ struct aldap_message *m;
+ struct aldap *al;
+
+ bzero(&ir, sizeof(ir));
+ imsg_compose(env->sc_ibuf, IMSG_START_UPDATE, 0, 0, &ir, sizeof(ir));
+
+ where = "connect";
+ if((al = aldap_open(idm->idm_name, "389")) == NULL)
+ goto bad;
+
+ if (idm->idm_flags & F_NEEDAUTH) {
+ where = "binding";
+ if(aldap_bind(al, idm->idm_binddn, idm->idm_bindcred) == -1)
+ goto bad;
+
+ where = "parsing";
+ if((m = aldap_parse(al)) == NULL)
+ goto bad;
+ where = "verifying msgid";
+ if(al->msgid != m->msgid) {
+ aldap_freemsg(m);
+ goto bad;
+ }
+ aldap_freemsg(m);
}
+ do_build_passwd(env, idm, al, idm->idm_basedn, LDAP_SCOPE_SUBTREE,
+ idm->idm_filters[FILTER_USER]);
+ do_build_group(env, idm, al, idm->idm_basedn, LDAP_SCOPE_SUBTREE,
+ idm->idm_filters[FILTER_GROUP]);
+
+ aldap_close(al);
+
return (0);
bad:
log_debug("directory %s errored out in %s", idm->idm_name, where);
diff --git a/usr.sbin/ypldap/parse.y b/usr.sbin/ypldap/parse.y
index 8ee475028a6..dfab48c3c11 100644
--- a/usr.sbin/ypldap/parse.y
+++ b/usr.sbin/ypldap/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.2 2008/09/30 16:24:16 aschrijver Exp $ */
+/* $OpenBSD: parse.y,v 1.3 2008/10/14 21:41:03 aschrijver Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -98,7 +98,7 @@ typedef struct {
%token SERVER FILTER ATTRIBUTE BASEDN BINDDN BINDCRED MAPS CHANGE DOMAIN PROVIDE
%token USER GROUP TO EXPIRE HOME SHELL GECOS UID GID INTERVAL
-%token PASSWD NAME FIXED GROUPNAME GROUPPASSWD GROUPGID MAP
+%token PASSWD NAME FIXED LIST GROUPNAME GROUPPASSWD GROUPGID MAP
%token INCLUDE DIRECTORY CLASS PORT SSL ERROR GROUPMEMBERS
%token <v.string> STRING
%token <v.number> NUMBER
@@ -196,11 +196,10 @@ diropt : BINDDN STRING {
free($2);
}
| BASEDN STRING {
- idm->idm_flags |= F_NEEDAUTH;
if (strlcpy(idm->idm_basedn, $2,
sizeof(idm->idm_basedn)) >=
sizeof(idm->idm_basedn)) {
- yyerror("directory bindcred truncated");
+ yyerror("directory basedn truncated");
free($2);
YYERROR;
}
@@ -237,6 +236,17 @@ diropt : BINDDN STRING {
idm->idm_flags |= F_FIXED_ATTR($3);
free($4);
}
+ | LIST attribute MAPS TO STRING {
+ if (strlcpy(idm->idm_attrs[$2], $5,
+ sizeof(idm->idm_attrs[$2])) >=
+ sizeof(idm->idm_attrs[$2])) {
+ yyerror("attribute truncated");
+ free($5);
+ YYERROR;
+ }
+ idm->idm_list |= F_LIST($2);
+ free($5);
+ }
;
directory : DIRECTORY STRING port ssl {
@@ -368,6 +378,7 @@ lookup(char *s)
{ "home", HOME },
{ "include", INCLUDE },
{ "interval", INTERVAL },
+ { "list", LIST },
{ "map", MAP },
{ "maps", MAPS },
{ "name", NAME },
diff --git a/usr.sbin/ypldap/ypldap.h b/usr.sbin/ypldap/ypldap.h
index cc31bd31869..e8d4ac5e060 100644
--- a/usr.sbin/ypldap/ypldap.h
+++ b/usr.sbin/ypldap/ypldap.h
@@ -117,7 +117,9 @@ struct idm {
#define F_CONFIGURING 0x00200000
#define F_NEEDAUTH 0x00400000
#define F_FIXED_ATTR(n) (1<<n)
+#define F_LIST(n) (1<<n)
u_int32_t idm_flags; /* lower 20 reserved */
+ u_int32_t idm_list;
in_port_t idm_port;
char idm_binddn[LINE_WIDTH];
char idm_bindcred[LINE_WIDTH];
@@ -148,7 +150,6 @@ struct idm {
#ifdef SSL
struct ssl *idm_ssl;
#endif
-
};
struct idm_req {