diff options
Diffstat (limited to 'usr.sbin/ypldap')
-rw-r--r-- | usr.sbin/ypldap/ldapclient.c | 110 | ||||
-rw-r--r-- | usr.sbin/ypldap/parse.y | 84 | ||||
-rw-r--r-- | usr.sbin/ypldap/ypldap.h | 1 |
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]; |