]> granicus.if.org Git - sudo/commitdiff
Add support for multiple URI lines by joining the contents and passing
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 24 Jun 2010 11:39:34 +0000 (07:39 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 24 Jun 2010 11:39:34 +0000 (07:39 -0400)
the result to ldap_initialize.

--HG--
branch : 1.7

ldap.c

diff --git a/ldap.c b/ldap.c
index 7aa4f6851ecab0701ef8fdfb7edc68b4d1be9efa..7d35ca6e62102c948cde9eda2920aa44309e0a82 100644 (file)
--- a/ldap.c
+++ b/ldap.c
@@ -143,7 +143,7 @@ static struct ldap_config {
     int rootuse_sasl;
     int ssl_mode;
     char *host;
-    char *uri;
+    struct ldap_config_list_str *uri;
     char *binddn;
     char *bindpw;
     char *rootbinddn;
@@ -167,7 +167,7 @@ static struct ldap_config_table ldap_conf_table[] = {
     { "port", CONF_INT, FALSE, -1, &ldap_conf.port },
     { "ssl", CONF_STR, FALSE, -1, &ldap_conf.ssl },
     { "sslpath", CONF_STR, FALSE, -1, &ldap_conf.tls_certfile },
-    { "uri", CONF_STR, FALSE, -1, &ldap_conf.uri },
+    { "uri", CONF_LIST_STR, FALSE, -1, &ldap_conf.uri },
 #ifdef LDAP_OPT_DEBUG_LEVEL
     { "debug", CONF_INT, FALSE, LDAP_OPT_DEBUG_LEVEL, &ldap_conf.ldap_debug },
 #endif
@@ -314,70 +314,75 @@ toobig:
  */
 static int
 sudo_ldap_parse_uri(uri_list)
-    const char *uri_list;
+    const struct ldap_config_list_str *uri_list;
 {
     char *buf, *uri, *host, *cp, *port;
     char hostbuf[LINE_MAX];
     int nldap = 0, nldaps = 0;
     int rc = -1;
 
-    buf = estrdup(uri_list);
-    hostbuf[0] = '\0';
-    for ((uri = strtok(buf, " \t")); uri != NULL; (uri = strtok(NULL, " \t"))) {
-       if (strncasecmp(uri, "ldap://", 7) == 0) {
-           nldap++;
-           host = uri + 7;
-       } else if (strncasecmp(uri, "ldaps://", 8) == 0) {
-           nldaps++;
-           host = uri + 8;
-       } else {
-           warningx("unsupported LDAP uri type: %s", uri);
-           goto done;
-       }
+    do {
+       buf = estrdup(uri_list->val);
+       hostbuf[0] = '\0';
+       for ((uri = strtok(buf, " \t")); uri != NULL; (uri = strtok(NULL, " \t"))) {
+           if (strncasecmp(uri, "ldap://", 7) == 0) {
+               nldap++;
+               host = uri + 7;
+           } else if (strncasecmp(uri, "ldaps://", 8) == 0) {
+               nldaps++;
+               host = uri + 8;
+           } else {
+               warningx("unsupported LDAP uri type: %s", uri);
+               goto done;
+           }
 
-       /* trim optional trailing slash */
-       if ((cp = strrchr(host, '/')) != NULL && cp[1] == '\0') {
-           *cp = '\0';
-       }
+           /* trim optional trailing slash */
+           if ((cp = strrchr(host, '/')) != NULL && cp[1] == '\0') {
+               *cp = '\0';
+           }
 
-       if (hostbuf[0] != '\0') {
-           if (strlcat(hostbuf, " ", sizeof(hostbuf)) >= sizeof(hostbuf))
-               goto toobig;
-       }
+           if (hostbuf[0] != '\0') {
+               if (strlcat(hostbuf, " ", sizeof(hostbuf)) >= sizeof(hostbuf))
+                   goto toobig;
+           }
 
-       if (*host == '\0')
-           host = "localhost";         /* no host specified, use localhost */
+           if (*host == '\0')
+               host = "localhost";             /* no host specified, use localhost */
 
-       if (strlcat(hostbuf, host, sizeof(hostbuf)) >= sizeof(hostbuf))
-           goto toobig;
+           if (strlcat(hostbuf, host, sizeof(hostbuf)) >= sizeof(hostbuf))
+               goto toobig;
 
-       /* If using SSL and no port specified, add port 636 */
-       if (nldaps) {
-           if ((port = strrchr(host, ':')) == NULL ||
-               !isdigit((unsigned char)port[1]))
-               if (strlcat(hostbuf, ":636", sizeof(hostbuf)) >= sizeof(hostbuf))
-                   goto toobig;
+           /* If using SSL and no port specified, add port 636 */
+           if (nldaps) {
+               if ((port = strrchr(host, ':')) == NULL ||
+                   !isdigit((unsigned char)port[1]))
+                   if (strlcat(hostbuf, ":636", sizeof(hostbuf)) >= sizeof(hostbuf))
+                       goto toobig;
+           }
        }
-    }
-    if (hostbuf[0] == '\0') {
-       warningx("invalid uri: %s", uri_list);
-       goto done;
-    }
-
-    if (nldaps != 0) {
-       if (nldap != 0) {
-           warningx("cannot mix ldap and ldaps URIs");
+       if (hostbuf[0] == '\0') {
+           warningx("invalid uri: %s", uri_list);
            goto done;
        }
-       if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) {
-           warningx("cannot mix ldaps and starttls");
-           goto done;
+
+       if (nldaps != 0) {
+           if (nldap != 0) {
+               warningx("cannot mix ldap and ldaps URIs");
+               goto done;
+           }
+           if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) {
+               warningx("cannot mix ldaps and starttls");
+               goto done;
+           }
+           ldap_conf.ssl_mode = SUDO_LDAP_SSL;
        }
-       ldap_conf.ssl_mode = SUDO_LDAP_SSL;
-    }
 
-    free(ldap_conf.host);
-    ldap_conf.host = estrdup(hostbuf);
+       free(ldap_conf.host);
+       ldap_conf.host = estrdup(hostbuf);
+       efree(buf);
+    } while ((uri_list = uri_list->next));
+
+    buf = NULL;
     rc = 0;
 
 done:
@@ -387,6 +392,31 @@ done:
 toobig:
     errorx(1, "sudo_ldap_parse_uri: out of space building hostbuf");
 }
+#else
+static char *
+sudo_ldap_join_uri(uri_list)
+    struct ldap_config_list_str *uri_list;
+{
+    struct ldap_config_list_str *uri;
+    size_t len = 0;
+    char *buf, *cp;
+
+    /* Usually just a single entry. */
+    if (uri_list->next == NULL)
+       return(estrdup(uri_list->val));
+
+    for (uri = uri_list; uri != NULL; uri = uri->next) {
+       len += strlen(uri->val) + 1;
+    }
+    buf = cp = emalloc(len);
+    buf[0] = '\0';
+    for (uri = uri_list; uri != NULL; uri = uri->next) {
+       cp += strlcpy(cp, uri->val, len - (cp - buf));
+       *cp++ = ' ';
+    }
+    cp[-1] = '\0';
+    return(buf);
+}
 #endif /* HAVE_LDAP_INITIALIZE */
 
 static int
@@ -1007,7 +1037,11 @@ sudo_ldap_read_config()
        fprintf(stderr, "LDAP Config Summary\n");
        fprintf(stderr, "===================\n");
        if (ldap_conf.uri) {
-           fprintf(stderr, "uri              %s\n", ldap_conf.uri);
+           struct ldap_config_list_str *uri = ldap_conf.uri;
+
+           do {
+               fprintf(stderr, "uri              %s\n", uri->val);
+           } while ((uri = uri->next) != NULL);
        } else {
            fprintf(stderr, "host             %s\n", ldap_conf.host ?
                ldap_conf.host : "(NONE)");
@@ -1089,10 +1123,13 @@ sudo_ldap_read_config()
 #ifndef HAVE_LDAP_INITIALIZE
     /* Convert uri list to host list if no ldap_initialize(). */
     if (ldap_conf.uri) {
-       if (sudo_ldap_parse_uri(ldap_conf.uri) != 0)
+       struct ldap_config_list_str *uri = ldap_conf.uri;
+       if (sudo_ldap_parse_uri(uri) != 0)
            return(FALSE);
-       free(ldap_conf.uri);
-       ldap_conf.uri = NULL;
+       do {
+           ldap_conf.uri = uri->next;
+           efree(uri);
+       } while ((uri = ldap_conf.uri));
        ldap_conf.port = LDAP_PORT;
     }
 #endif
@@ -1605,7 +1642,7 @@ sudo_ldap_set_options(ld)
                (long)tv.tv_sec, ldap_err2string(rc));
            return(-1);
        }
-       DPRINTF(("ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT, %ld)\n",
+       DPRINTF(("ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT, %ld)",
            (long)tv.tv_sec), 1);
     }
 #endif
@@ -1619,7 +1656,7 @@ sudo_ldap_set_options(ld)
                ldap_err2string(rc));
            return(-1);
        }
-       DPRINTF(("ldap_set_option(LDAP_OPT_X_TLS, LDAP_OPT_X_TLS_HARD)\n"), 1);
+       DPRINTF(("ldap_set_option(LDAP_OPT_X_TLS, LDAP_OPT_X_TLS_HARD)"), 1);
     }
 #endif
     return(0);
@@ -1728,8 +1765,10 @@ sudo_ldap_open(nss)
     /* Connect to LDAP server */
 #ifdef HAVE_LDAP_INITIALIZE
     if (ldap_conf.uri != NULL) {
-       DPRINTF(("ldap_initialize(ld, %s)", ldap_conf.uri), 2);
-       rc = ldap_initialize(&ld, ldap_conf.uri);
+       char *buf = sudo_ldap_join_uri(ldap_conf.uri);
+       DPRINTF(("ldap_initialize(ld, %s)", buf), 2);
+       rc = ldap_initialize(&ld, buf);
+       efree(buf);
     } else
 #endif
        rc = sudo_ldap_init(&ld, ldap_conf.host, ldap_conf.port);