summaryrefslogtreecommitdiff
path: root/usr.sbin/ypldap
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ypldap')
-rw-r--r--usr.sbin/ypldap/ldapclient.c110
-rw-r--r--usr.sbin/ypldap/parse.y84
-rw-r--r--usr.sbin/ypldap/ypldap.h1
3 files changed, 129 insertions, 66 deletions
diff --git a/usr.sbin/ypldap/ldapclient.c b/usr.sbin/ypldap/ldapclient.c
index ac366464e28..759beec3120 100644
--- a/usr.sbin/ypldap/ldapclient.c
+++ b/usr.sbin/ypldap/ldapclient.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldapclient.c,v 1.5 2008/10/14 21:41:03 aschrijver Exp $ */
+/* $OpenBSD: ldapclient.c,v 1.6 2008/10/19 12:00:54 aschrijver Exp $ */
/*
* Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org>
@@ -55,9 +55,12 @@ int do_build_group(struct env *, struct idm *, struct aldap *, char *, enum
int do_build_passwd(struct env *, struct idm *, struct aldap *, char *, enum
scope, char *);
-struct aldap *aldap_open(char *, char *);
+struct aldap *aldap_openidm(struct idm *idm);
int aldap_close(struct aldap *);
+#ifdef REFERRALS
struct aldap *connect_to_referral(struct aldap_message *, struct aldap_url *);
+struct aldap *aldap_openhost(char *, char *);
+#endif
int
aldap_close(struct aldap *al)
@@ -71,27 +74,19 @@ aldap_close(struct aldap *al)
}
struct aldap *
-aldap_open(char *host, char *port)
+aldap_openidm(struct idm *idm)
{
- struct addrinfo hints;
- struct aldap *al;
int fd;
+ struct addrinfo *res0;
- struct addrinfo *res, *res0;
- 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);
+ res0 = idm->idm_addrinfo;
+ do {
+ char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
- if ((error = getaddrinfo(host, port, &hints, &res)))
- errx(1, "getaddrinfo: %s", gai_strerror(error));
+ if (getnameinfo(res0->ai_addr, res0->ai_addrlen, hbuf, sizeof(hbuf), sbuf,
+ sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV))
+ errx(1, "could not get numeric hostname");
- res0 = res;
- do {
if ((fd = socket(res0->ai_family, res0->ai_socktype,
res0->ai_protocol)) < 0)
continue;
@@ -99,7 +94,7 @@ aldap_open(char *host, char *port)
if (connect(fd, res0->ai_addr, res0->ai_addrlen) == 0)
break;
else {
- warn("connect to %s port %s (%s) failed", host, port, "tcp");
+ warn("connect to %s port %s (%s) failed", hbuf, sbuf, "tcp");
return NULL;
}
@@ -107,14 +102,10 @@ aldap_open(char *host, char *port)
fd = -1;
} while ((res0 = res0->ai_next) != NULL);
- freeaddrinfo(res);
-
- if((al = aldap_init(fd)) == NULL)
- return NULL;
-
- return al;
+ return aldap_init(fd);
}
+
void
client_sig_handler(int sig, short event, void *p)
{
@@ -295,6 +286,52 @@ client_configure_wrapper(int fd, short event, void *p)
client_configure(env);
}
+#ifdef REFERRALS
+struct aldap *
+aldap_openhost(char *host, char *port)
+{
+ struct addrinfo hints;
+ struct aldap *al;
+ int fd;
+
+ struct addrinfo *res, *res0;
+ 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 ((fd = socket(res0->ai_family, res0->ai_socktype,
+ res0->ai_protocol)) < 0)
+ continue;
+
+ if (connect(fd, res0->ai_addr, res0->ai_addrlen) == 0)
+ break;
+ else {
+ warn("connect to %s port %s (%s) failed", host, port, "tcp");
+ return NULL;
+ }
+
+ close(fd);
+ fd = -1;
+ } while ((res0 = res0->ai_next) != NULL);
+
+ freeaddrinfo(res);
+
+ if((al = aldap_init(fd)) == NULL)
+ return NULL;
+
+ return al;
+}
+
struct aldap *
connect_to_referral(struct aldap_message *m, struct aldap_url *lu)
{
@@ -309,7 +346,7 @@ connect_to_referral(struct aldap_message *m, struct aldap_url *lu)
aldap_parse_url(refs[i], lu);
asprintf(&port, "%d", lu->port ? lu->port : 389);
- if((al = aldap_open(lu->host, port)) != NULL) {
+ if((al = aldap_openhost(lu->host, port)) != NULL) {
free(port);
break;
}
@@ -321,6 +358,7 @@ connect_to_referral(struct aldap_message *m, struct aldap_url *lu)
return al;
}
+#endif
#define MAX_REFERRALS 10
int
@@ -331,11 +369,13 @@ do_build_group(struct env *env, struct idm *idm, struct aldap *al, char
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;
+#ifdef REFERRALS
static int refcnt = 0;
+ struct aldap_url lu;
+ struct aldap *al_ref;
+#endif
bzero(attrs, sizeof(attrs));
for (i = ATTR_GR_MIN, j = 0; i < ATTR_GR_MAX; i++) {
@@ -358,6 +398,7 @@ do_build_group(struct env *env, struct idm *idm, struct aldap *al, char
aldap_freemsg(m);
goto bad;
}
+#ifdef REFERRALS
/* continuation referral */
if (m->message_type == LDAP_RES_SEARCH_REFERENCE) {
if(refcnt++ >= MAX_REFERRALS)
@@ -386,12 +427,14 @@ do_build_group(struct env *env, struct idm *idm, struct aldap *al, char
lu.scope, idm->idm_filters[FILTER_GROUP]);
aldap_close(al_ref);
}
+#endif
/* 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 */
+ where = "verifying message_type";
if(m->message_type != LDAP_RES_SEARCH_ENTRY) {
aldap_freemsg(m);
goto bad;
@@ -470,11 +513,13 @@ do_build_passwd(struct env *env, struct idm *idm, struct aldap *al, char
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;
+#ifdef REFERRALS
static int refcnt = 0;
+ struct aldap_url lu;
+ struct aldap *al_ref;
+#endif
bzero(attrs, sizeof(attrs));
for (i = 0, j = 0; i < ATTR_MAX; i++) {
@@ -497,6 +542,7 @@ do_build_passwd(struct env *env, struct idm *idm, struct aldap *al, char
aldap_freemsg(m);
goto bad;
}
+#ifdef REFERRALS
/* continuation referral */
if (m->message_type == LDAP_RES_SEARCH_REFERENCE) {
if(refcnt++ >= MAX_REFERRALS)
@@ -525,12 +571,14 @@ do_build_passwd(struct env *env, struct idm *idm, struct aldap *al, char
lu.scope, idm->idm_filters[FILTER_USER]);
aldap_close(al_ref);
}
+#endif
/* 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 */
+ where = "verifying message_type";
if(m->message_type != LDAP_RES_SEARCH_ENTRY) {
aldap_freemsg(m);
goto bad;
@@ -614,7 +662,7 @@ client_try_idm(struct env *env, struct idm *idm)
imsg_compose(env->sc_ibuf, IMSG_START_UPDATE, 0, 0, &ir, sizeof(ir));
where = "connect";
- if((al = aldap_open(idm->idm_name, "389")) == NULL)
+ if((al = aldap_openidm(idm)) == NULL)
goto bad;
if (idm->idm_flags & F_NEEDAUTH) {
diff --git a/usr.sbin/ypldap/parse.y b/usr.sbin/ypldap/parse.y
index f7c386b7ad4..a74da98f077 100644
--- a/usr.sbin/ypldap/parse.y
+++ b/usr.sbin/ypldap/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.4 2008/10/17 13:02:55 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.5 2008/10/19 12:00:54 aschrijver Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -71,6 +71,8 @@ int lgetc(int);
int lungetc(int);
int findeol(void);
+struct addrinfo *host(const char *, const char *);
+
TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
struct sym {
TAILQ_ENTRY(sym) entry;
@@ -99,10 +101,11 @@ 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 LIST GROUPNAME GROUPPASSWD GROUPGID MAP
-%token INCLUDE DIRECTORY CLASS PORT SSL ERROR GROUPMEMBERS
+%token INCLUDE DIRECTORY CLASS PORT ERROR GROUPMEMBERS
%token <v.string> STRING
%token <v.number> NUMBER
-%type <v.number> opcode attribute port ssl
+%type <v.number> opcode attribute
+%type <v.string> port
%%
@@ -122,6 +125,7 @@ optnl : '\n' optnl
| /* empty */
;
+
include : INCLUDE STRING {
struct file *nfile;
@@ -145,18 +149,15 @@ varset : STRING '=' STRING {
}
;
-ssl : SSL { $$ = 1; }
- | /*empty*/ { $$ = 0; }
- ;
-
-port : PORT NUMBER { $$ = $2; }
- | /*empty*/ { $$ = 0; }
+port : /* empty */ { $$ = NULL; }
+ | PORT STRING { $$ = $2; }
;
opcode : GROUP { $$ = 0; }
| PASSWD { $$ = 1; }
;
+
attribute : NAME { $$ = 0; }
| PASSWD { $$ = 1; }
| UID { $$ = 2; }
@@ -249,36 +250,24 @@ diropt : BINDDN STRING {
}
;
-directory : DIRECTORY STRING port ssl {
- const char *service;
- struct servent *srv;
-
+directory : DIRECTORY STRING port {
if ((idm = calloc(1, sizeof(*idm))) == NULL)
fatal(NULL);
- if (strlcpy(idm->idm_name, $2, sizeof(idm->idm_name)) >=
- sizeof(idm->idm_name)) {
- yyerror("directory name truncated");
- free(idm);
- free($2);
- YYERROR;
+ if($3 != NULL) {
+ if((idm->idm_addrinfo = host($2, $3)) == NULL) {
+ yyerror("domain not found");
+ free($2);
+ YYERROR;
+ }
+ } else {
+ if((idm->idm_addrinfo = host($2, "389")) == NULL) {
+ yyerror("domain not found");
+ free($2);
+ YYERROR;
+ }
}
- if ($4) {
- service = "ldaps";
- } else
- service = "ldap";
- srv = getservbyname(service, "tcp");
-
- if ($3)
- idm->idm_port = $3;
- else if (srv == NULL) {
- if ($4)
- idm->idm_port = 389;
- else
- idm->idm_port = 686;
- } else
- idm->idm_port = ntohs(srv->s_port);
free($2);
} '{' optnl diropts '}' {
TAILQ_INSERT_TAIL(&conf->sc_idms, idm, idm_entry);
@@ -325,6 +314,7 @@ main : INTERVAL NUMBER {
diropts : diropts diropt nl
| diropt optnl
;
+
%%
struct keywords {
@@ -387,7 +377,6 @@ lookup(char *s)
{ "provide", PROVIDE },
{ "server", SERVER },
{ "shell", SHELL },
- { "ssl", SSL },
{ "to", TO },
{ "uid", UID },
{ "user", USER },
@@ -827,3 +816,28 @@ symget(const char *nam)
}
return (NULL);
}
+
+struct addrinfo *
+host(const char *s, const char *port)
+{
+ int error;
+ struct addrinfo *res, hints;
+
+ if (s == NULL)
+ return NULL;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ if ((error = getaddrinfo(s, port, &hints, &res)) != 0) {
+ errx(1, "getaddrinfo: %s", gai_strerror(error));
+
+ freeaddrinfo(res);
+
+ return NULL;
+ }
+
+ return res;
+}
diff --git a/usr.sbin/ypldap/ypldap.h b/usr.sbin/ypldap/ypldap.h
index e8d4ac5e060..63fc567b19e 100644
--- a/usr.sbin/ypldap/ypldap.h
+++ b/usr.sbin/ypldap/ypldap.h
@@ -120,6 +120,7 @@ struct idm {
#define F_LIST(n) (1<<n)
u_int32_t idm_flags; /* lower 20 reserved */
u_int32_t idm_list;
+ struct addrinfo *idm_addrinfo;
in_port_t idm_port;
char idm_binddn[LINE_WIDTH];
char idm_bindcred[LINE_WIDTH];