--- autofs-5.0.1/include/lookup_ldap.h.add-ldaps-support 2006-09-01 13:29:50.000000000 +0800 +++ autofs-5.0.1/include/lookup_ldap.h 2007-06-20 11:41:02.000000000 +0800 @@ -13,6 +13,7 @@ struct lookup_context { char *mapname; char *server; + int port; char *base; char *qdn; --- autofs-5.0.1/modules/Makefile.add-ldaps-support 2007-06-20 11:41:02.000000000 +0800 +++ autofs-5.0.1/modules/Makefile 2007-06-20 11:41:02.000000000 +0800 @@ -64,6 +64,7 @@ install: all -rm -f $(INSTALLROOT)$(autofslibdir)/mount_smbfs.so ln -fs lookup_file.so $(INSTALLROOT)$(autofslibdir)/lookup_files.so ln -fs lookup_yp.so $(INSTALLROOT)$(autofslibdir)/lookup_nis.so + ln -fs lookup_ldap.so $(INSTALLROOT)$(autofslibdir)/lookup_ldaps.so ln -fs mount_nfs.so $(INSTALLROOT)$(autofslibdir)/mount_nfs4.so ifeq ($(EXT2FS), 1) ifeq ($(EXT3FS), 1) --- autofs-5.0.1/modules/lookup_ldap.c.add-ldaps-support 2007-06-20 11:41:02.000000000 +0800 +++ autofs-5.0.1/modules/lookup_ldap.c 2007-06-20 11:41:52.000000000 +0800 @@ -100,14 +100,8 @@ LDAP *init_ldap_connection(struct lookup ctxt->version = 3; /* Initialize the LDAP context. */ - /* LDAP_PORT should not be hard-coded, here. If we are going to - * parse ldap strings ourselves, then we can put the port specified - * in the host:port format here. Otherwise, we can just pass the - * host:port string to the ldap_init call and let the library handle - * it. -JM - */ - ldap = ldap_init(ctxt->server, LDAP_PORT); - if (!ldap) { + rv = ldap_initialize(&ldap, ctxt->server); + if (rv != LDAP_OPT_SUCCESS) { crit(LOGOPT_ANY, MODPREFIX "couldn't initialize LDAP connection to %s", ctxt->server ? ctxt->server : "default server"); @@ -119,8 +113,8 @@ LDAP *init_ldap_connection(struct lookup if (rv != LDAP_OPT_SUCCESS) { /* fall back to LDAPv2 */ ldap_unbind_ext(ldap, NULL, NULL); - ldap = ldap_init(ctxt->server, LDAP_PORT); - if (!ldap) { + rv = ldap_initialize(&ldap, ctxt->server); + if (rv != LDAP_OPT_SUCCESS) { crit(LOGOPT_ANY, MODPREFIX "couldn't initialize LDAP"); return NULL; } @@ -348,7 +342,7 @@ int parse_ldap_config(struct lookup_cont goto out; } - if (!usetls) + if (!usetls || ctxt->port == LDAPS_PORT) use_tls = LDAP_TLS_DONT_USE; else { if (!strcasecmp(usetls, "yes")) @@ -551,16 +545,31 @@ int auth_init(struct lookup_context *ctx */ static int parse_server_string(const char *url, struct lookup_context *ctxt) { - char buf[MAX_ERR_BUF], *tmp = NULL; - const char *ptr; - int l; + char buf[MAX_ERR_BUF], *tmp = NULL, proto[9]; + const char *ptr, *name; + int l, al_len; + memset(proto, 0, 9); ptr = url; debug(LOGOPT_NONE, MODPREFIX "Attempting to parse LDAP information from string \"%s\".", ptr); + ctxt->port = LDAP_PORT; + if (!strncmp(ptr, "ldap:", 5) || !strncmp(ptr, "ldaps:", 6)) { + if (*(ptr + 4) == 's') { + ctxt->port = LDAPS_PORT; + memcpy(proto, ptr, 6); + strcat(proto, "//"); + ptr += 6; + } else { + memcpy(proto, ptr, 5); + strcat(proto, "//"); + ptr += 5; + } + } + if (!strncmp(ptr, "//", 2)) { const char *s = ptr + 2; const char *q = NULL; @@ -568,7 +577,13 @@ static int parse_server_string(const cha /* Isolate the server(s). */ if ((q = strchr(s, '/'))) { l = q - s; - tmp = malloc(l + 1); + if (*proto) { + al_len = l + strlen(proto) + 2; + tmp = malloc(al_len); + } else { + al_len = l + 1; + tmp = malloc(al_len); + } if (!tmp) { char *estr; estr = strerror_r(errno, buf, MAX_ERR_BUF); @@ -576,8 +591,13 @@ static int parse_server_string(const cha return 0; } ctxt->server = tmp; - memset(ctxt->server, 0, l + 1); - memcpy(ctxt->server, s, l); + memset(ctxt->server, 0, al_len); + if (*proto) { + strcpy(ctxt->server, proto); + memcpy(ctxt->server + strlen(proto), s, l); + strcat(ctxt->server, "/"); + } else + memcpy(ctxt->server, s, l); ptr = q + 1; } else { crit(LOGOPT_ANY, @@ -600,7 +620,7 @@ static int parse_server_string(const cha } else if (strchr(ptr, ':') != NULL) { char *q = NULL; - /* Isolate the server(s). Include the port spec */ + /* Isolate the server. Include the port spec */ q = strchr(ptr, ':'); if (isdigit(*q)) while (isdigit(*q)) @@ -613,8 +633,14 @@ static int parse_server_string(const cha } l = q - ptr; + if (*proto) { + al_len = l + strlen(proto) + 2; + tmp = malloc(al_len); + } else { + al_len = l + 1; + tmp = malloc(al_len); + } /* Isolate the server's name. */ - tmp = malloc(l + 1); if (!tmp) { char *estr; estr = strerror_r(errno, buf, MAX_ERR_BUF); @@ -622,8 +648,13 @@ static int parse_server_string(const cha return 0; } ctxt->server = tmp; - memset(ctxt->server, 0, l + 1); - memcpy(ctxt->server, ptr, l); + memset(ctxt->server, 0, al_len); + if (*proto) { + strcpy(ctxt->server, proto); + memcpy(ctxt->server + strlen(proto), ptr, l); + strcat(ctxt->server, "/"); + } else + memcpy(ctxt->server, ptr, l); ptr += l + 1; } @@ -639,29 +670,41 @@ static int parse_server_string(const cha * the later LDAP calls will fail. */ l = strlen(ptr); - if (strchr(ptr, '=')) { + if ((name = strchr(ptr, '='))) { char *base; + /* + * An '=' with no ',' means a mapname has been given so just + * grab it alone to keep it independent of schema otherwize + * we expect a full dn. + */ if (!strchr(ptr, ',')) { - debug(LOGOPT_NONE, - MODPREFIX "LDAP dn not fuly specified"); - if (ctxt->server) - free(ctxt->server); - return 0; - } - - base = malloc(l + 1); - if (!base) { - char *estr; - estr = strerror_r(errno, buf, MAX_ERR_BUF); - crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr); - if (ctxt->server) - free(ctxt->server); - return 0; + char *map = strdup(name + 1); + if (map) + ctxt->mapname = map; + else { + char *estr; + estr = strerror_r(errno, buf, MAX_ERR_BUF); + crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr); + if (ctxt->server) + free(ctxt->server); + return 0; + } + + } else { + base = malloc(l + 1); + if (!base) { + char *estr; + estr = strerror_r(errno, buf, MAX_ERR_BUF); + crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr); + if (ctxt->server) + free(ctxt->server); + return 0; + } + ctxt->base = base; + memset(ctxt->base, 0, l + 1); + memcpy(ctxt->base, ptr, l); } - ctxt->base = base; - memset(ctxt->base, 0, l + 1); - memcpy(ctxt->base, ptr, l); } else { char *map = malloc(l + 1); if (!map) { @@ -676,6 +719,14 @@ static int parse_server_string(const cha memset(ctxt->mapname, 0, l + 1); memcpy(map, ptr, l); } + + if (!ctxt->server && *proto) { + if (!strncmp(proto, "ldaps", 5)) { + warn(LOGOPT_ANY, MODPREFIX + "server must be given to force ldaps, connection " + "will use LDAP client configured protocol"); + } + } done: if (ctxt->mapname) debug(LOGOPT_NONE, MODPREFIX "mapname %s", ctxt->mapname); --- autofs-5.0.1/daemon/lookup.c.add-ldaps-support 2007-06-20 11:41:02.000000000 +0800 +++ autofs-5.0.1/daemon/lookup.c 2007-06-20 11:41:02.000000000 +0800 @@ -169,20 +169,30 @@ int lookup_nss_read_master(struct master char source[10]; memset(source, 0, 10); - /* TODO: ldaps is not yet handled by ldap module */ - /* TODO: must tighten up this test */ - if (!strncmp(name, "file", 4) || - !strncmp(name, "yp", 2) || - !strncmp(name, "nis", 3) || - !strncmp(name, "nisplus", 7) || - !strncmp(name, "ldap", 4)) { + if (!strncmp(name, "file:", 5) || + !strncmp(name, "yp:", 3) || + !strncmp(name, "nis:", 4) || + !strncmp(name, "nisplus:", 8) || + !strncmp(name, "ldap:", 5) || + !strncmp(name, "ldaps:", 6)) { strncpy(source, name, tmp - name); - master->name = tmp + 1; - - debug(LOGOPT_NONE, - "reading master %s %s", - source, master->name); + /* + * If it's an ldap map leave the source in the + * name so the lookup module can work out if + * ldaps has been requested. + */ + if (strncmp(name, "ldap", 4)) { + master->name = tmp + 1; + debug(LOGOPT_NONE, + "reading master %s %s", + source, master->name); + } else { + master->name = name; + debug(LOGOPT_NONE, + "reading master %s %s", + source, tmp + 1); + } result = do_read_master(master, source, age); master->name = name; --- autofs-5.0.1/lib/master_parse.y.add-ldaps-support 2007-06-20 11:41:02.000000000 +0800 +++ autofs-5.0.1/lib/master_parse.y 2007-06-20 11:41:02.000000000 +0800 @@ -290,6 +290,19 @@ map: PATH local_free_vars(); YYABORT; } + /* Add back the type for lookup_ldap.c to handle ldaps */ + if (*local_argv[0]) { + tmp = malloc(strlen(type) + strlen(local_argv[0]) + 2); + if (!tmp) { + local_free_vars(); + YYABORT; + } + strcpy(tmp, type); + strcat(tmp, ":"); + strcat(tmp, local_argv[0]); + free(local_argv[0]); + local_argv[0] = tmp; + } } ; @@ -343,12 +356,12 @@ dnattrs: DNATTR EQUAL DNNAME strcat($$, ","); strcat($$, $5); } - | DNATTR + | DNNAME { - master_notify($1); - YYABORT; + /* Matches map in old style syntax ldap:server:map */ + strcpy($$, $1); } - | DNNAME + | DNATTR { master_notify($1); YYABORT; --- autofs-5.0.1/lib/master_tok.l.add-ldaps-support 2007-06-20 11:41:02.000000000 +0800 +++ autofs-5.0.1/lib/master_tok.l 2007-06-20 11:41:02.000000000 +0800 @@ -104,7 +104,7 @@ DNATTRSTR (cn|nisMapName|automountMapNam DNNAMESTR ([[:alnum:]_.\-]+) INTMAP (-hosts|-null) -MTYPE ((file|program|yp|nis|nisplus|ldap|hesiod|userdir)(,(sun|hesiod))?) +MTYPE ((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?) OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) --- autofs-5.0.1/man/auto.master.5.in.add-ldaps-support 2006-09-01 13:29:50.000000000 +0800 +++ autofs-5.0.1/man/auto.master.5.in 2007-06-20 11:41:02.000000000 +0800 @@ -101,8 +101,9 @@ The map is a hesiod database whose .B filsys entries are used for maps. .TP -.B ldap -The map is stored in an LDAP directory. +.B ldap \fPor\fB ldaps +The map is stored in an LDAP directory. If \fBldaps\fP is used the +appropriate certificate must be configured in the LDAP client. .RE .TP \fBformat\fP