diff --git a/CHANGELOG b/CHANGELOG
index b0bec85..818b294 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -26,6 +26,10 @@
 - fix master map lexer to admit "." in macro values (Mike Matera).
 - make ldap attribute match case insensitive.
 - add missed man page update for APPEND_OPTIONS config option.
+- add ldaps protocol support.
+  - note: it's no longer possible to multiple hosts in an ldap map spec.
+  - note: if this is needed use only the map name and configure the URI
+    entry in the ldap client configuration.
 
 20/2/2007 autofs-5.0.1
 ----------------------
diff --git a/daemon/lookup.c b/daemon/lookup.c
index acf2e98..06fcecc 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -169,20 +169,30 @@ int lookup_nss_read_master(struct master *master, time_t age)
 			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;
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
index d33bda9..e1c5b4e 100644
--- a/include/lookup_ldap.h
+++ b/include/lookup_ldap.h
@@ -13,6 +13,7 @@ struct lookup_context {
 	char *mapname;
 
 	char *server;
+	int port;
 	char *base;
 	char *qdn;
 
diff --git a/lib/master_parse.y b/lib/master_parse.y
index 7e98a4e..8d2be02 100644
--- a/lib/master_parse.y
+++ b/lib/master_parse.y
@@ -288,6 +288,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;
+		}
 	}
 	;
 
@@ -341,12 +354,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;
diff --git a/lib/master_tok.l b/lib/master_tok.l
index 28d7d0d..e872245 100644
--- a/lib/master_tok.l
+++ b/lib/master_tok.l
@@ -110,7 +110,7 @@ DNATTRSTR	{AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}
 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})
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
index 382507b..0e36a6f 100644
--- a/man/auto.master.5.in
+++ b/man/auto.master.5.in
@@ -100,8 +100,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
diff --git a/modules/Makefile b/modules/Makefile
index d8f53d1..0d12f01 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -63,6 +63,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)
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 29ba0c8..ac3a272 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -100,14 +100,8 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
 	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");
@@ -348,7 +342,7 @@ int parse_ldap_config(struct lookup_context *ctxt)
 		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 *ctxt)
  */
 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;
 
+	*proto = '\0';
 	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 char *url, struct lookup_context *ctxt)
 		/* 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 char *url, struct lookup_context *ctxt)
 				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,
@@ -613,8 +633,14 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
 		}
 
 		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 char *url, struct lookup_context *ctxt)
 			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 char *url, struct lookup_context *ctxt)
 	 * 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 char *url, struct lookup_context *ctxt)
 		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);