Changeset 268
- Timestamp:
- 05/09/07 08:48:00 (5 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
-
configure.in (modified) (1 diff)
-
doc/pam_pkcs11.xml (modified) (1 diff)
-
etc/pam_pkcs11.conf.example (modified) (1 diff)
-
src/mappers/ldap_mapper.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/configure.in
r242 r268 77 77 ]) 78 78 fi 79 if test "$with_ldap" \!= "no"; then 80 AC_CHECK_FUNCS(ldap_init ldap_initialize) 81 AC_CHECK_FUNCS(ldap_set_option ldap_get_option) 82 AC_CHECK_FUNCS(ldap_start_tls ldap_start_tls_s) 83 fi 79 84 AC_SUBST(LDAP_CFLAGS) 80 85 AC_SUBST(LDAP_LIBS) -
trunk/doc/pam_pkcs11.xml
r228 r268 1664 1664 This mapper is still under development. 1665 1665 </para> 1666 <para> 1667 ldap_mapper configuration file shows like: 1668 <screen> 1669 # Directory ( ldap style ) mapper 1670 mapper ldap { 1671 debug = false; 1672 module = /usr/lib/pam_pkcs11/ldap_mapper.so; 1673 ldaphost = ""; 1674 ldapport = ; 1675 URI = ""; 1676 scope = 2; 1677 binddn = "cn=pam,o=example,c=com"; 1678 passwd = ""; 1679 base = "ou=People,o=example,c=com"; 1680 attribute = "userCertificate"; 1681 filter = "<![CDATA[(&(objectClass=posixAccount)(uid=%s))]]>" 1682 # SSL/TLS-Settings 1683 ssl = tls 1684 # tls_randfile = ... 1685 tls_cacertfile = /etc/ssl/cacert.pem 1686 # tls_cacertdir = ... 1687 tls_checkpeer = 0 1688 #tls_ciphers = ... 1689 #tls_cert = ... 1690 #tls_key = ... 1691 } 1692 </screen> 1693 The following options are recognized by 1694 1695 <varlistentry> 1696 <term><token>ldaphost</token></term> 1697 <listitem>The FQDN (hostname) oder IP-address of the ldap server.</listitem> 1698 </varlistentry> 1699 1700 <varlistentry> 1701 <term><token>URI</token></term> 1702 <listitem>A space separated list of LDAP URIs. The URIs are used in the given order. 1703 If a ldaphost is also submitted, it will be appended to the URI list. 1704 </listitem> 1705 </varlistentry> 1706 1707 <varlistentry> 1708 <term><token>ldapport</token></term> 1709 <listitem>The LDAP Port on the server (default: 1710 389 for LDAP and LDAP-TLS and 636 for SSL) 1711 </listitem> 1712 </varlistentry> 1713 1714 <varlistentry> 1715 <term><token>scope</token></term> 1716 <listitem>Scope of search: 0-2 1717 <itemizedlist> 1718 <listitem><option> 0 </option> "base", search only the basedn 1719 </listitem> 1720 1721 <listitem><option> 1 </option> "one", only the set of records one 1722 level below the basedn is searched (default) 1723 </listitem> 1724 1725 <listitem><option> 2 </option> "sub" means the union of entries 1726 at the "base" level and all levels below are searched 1727 </listitem> 1728 </itemizedlist> 1729 </listitem> 1730 1731 </varlistentry> 1732 1733 <varlistentry> 1734 <term><token>binddn</token></term> 1735 <listitem>The bind-DN if needed. 1736 </listitem> 1737 </varlistentry> 1738 1739 <varlistentry> 1740 <term><token>passwd</token></term> 1741 <listitem>Password for bind-DN 1742 </listitem> 1743 </varlistentry> 1744 1745 <varlistentry> 1746 <term><token>base</token></term> 1747 <listitem>The DN of the searchbase (see scope) 1748 </listitem> 1749 </varlistentry> 1750 1751 <varlistentry> 1752 <term><token>attribute</token></term> 1753 <listitem>The user attribute in LDAP entry, which contains 1754 the certificate. This can be an multi-value attribute. That 1755 implies you can store more than one certificate under this 1756 attribute. All certificates are utilized. 1757 </listitem> 1758 </varlistentry> 1759 1760 1761 <varlistentry> 1762 <term><token>filter</token></term> 1763 <listitem>LDAP filter string. You can use ist to restrict 1764 the entries returned by the LDAP server, e.g. by checking 1765 other attributes of the user entry. 1766 %s is substituted by the user name. 1767 1768 <![CDATA[(&(objectClass=posixAccount)(uid=%s))]]> 1769 means, only that 1770 LDAP entry is returned which has an objectClass 1771 "posixAccount" and the uid with the user name. 1772 1773 <lineannotation>IMPORTANT NOTE:</lineannotation> The filter string 1774 must be choosen in such a way that only one entry for the user is 1775 returned. If an user has more certifactes than these should be 1776 collected under the attribute. 1777 </listitem> 1778 </varlistentry> 1779 1780 <varlistentry> 1781 <term><token>ssl</token></term> 1782 <listitem>Enable or disable the usage of TLS or SSL 1783 <itemizedlist> 1784 <listitem><option> off </option> TLS/SSL off(default) 1785 </listitem> 1786 1787 <listitem><option> tls </option> enable TLS 1788 </listitem> 1789 1790 <listitem><option> on|ssl </option> enable SSL 1791 </listitem> 1792 </itemizedlist> 1793 </listitem> 1794 </varlistentry> 1795 1796 <varlistentry> 1797 <term><token>tls_randfile</token></term> 1798 <listitem>Specifies the path to an entropy source. 1799 </listitem> 1800 </varlistentry> 1801 1802 <varlistentry> 1803 <term><token>tls_cacertfile</token></term> 1804 <listitem>Specifies the path to the X.509 certificate for peer authentication. 1805 </listitem> 1806 </varlistentry> 1807 1808 <varlistentry> 1809 <term><token>tls_cacertdir</token></term> 1810 <listitem>Specifies the directory containing X.509 certificates for peer authentication. 1811 </listitem> 1812 </varlistentry> 1813 1814 <varlistentry> 1815 <term><token>tls_checkpeer</token></term> 1816 <listitem>Specifies whether to require and verify the server certificate or not. 1817 <option> 1 </option> check the certificate 1818 <option> 0 </option> off (default) 1819 </listitem> 1820 </varlistentry> 1821 1822 <varlistentry> 1823 <term><token>tls_ciphers</token></term> 1824 <listitem>Specifies the ciphers to use. 1825 </listitem> 1826 </varlistentry> 1827 1828 <varlistentry> 1829 <term><token>tls_cert</token></term> 1830 <listitem>Specifies the path to the file containing the local certificate for client TLS authentication if required. 1831 </listitem> 1832 </varlistentry> 1833 1834 <varlistentry> 1835 <term><token>tls_key</token></term> 1836 <listitem>Specifies the path to the file containing the private key for client TLS authentication. 1837 </listitem> 1838 </varlistentry> 1839 1840 </para> 1841 1842 1843 1666 1844 </sect2> 1667 1845 -
trunk/etc/pam_pkcs11.conf.example
r225 r268 182 182 debug = false; 183 183 module = /usr/lib/pam_pkcs11/ldap_mapper.so; 184 # where base directory resides 185 basedir = /etc/pam_pkcs11/mapdir; 186 # hostname of ldap server 187 ldaphost = "localhost"; 188 # Port on ldap server to connect 189 ldapport = 389; 190 # Scope of search: 0 = x, 1 = y, 2 = z 191 scope = 2; 192 # DN to bind with. Must have read-access for user entries under "base" 193 binddn = "cn=pam,o=example,c=com"; 184 # hostname of ldap server (use LDAP-URI for more then one) 185 ldaphost = ""; 186 # Port on ldap server to connect, this is also the default 187 # if no port is given in URI below 188 # if empty, then 389 for TLS and 636 for SSL is used 189 ldapport = ; 190 # space separted list of LDAP URIs (URIs are used by given order) 191 URI = ""; 192 # Scope of search: 0-2 193 # Default is 1 = "one", meaning the set of records one 194 # level below the basedn. 195 # 0 = "base" means search only the basedn, and 196 # 2 = "sub" means the union of entries at the "base" level 197 # and ? all or "one" level below ??? FIXME 198 scope = 2; 199 # DN to bind with. Must have read-access for user entries 200 # under "base" 201 binddn = "cn=pam,o=example,c=com"; 194 202 # Password for above DN 195 passwd = "test";203 passwd = ""; 196 204 # Searchbase for user entries 197 base = "ou=People,o=example,c=com";205 base = "ou=People,o=example,c=com"; 198 206 # Attribute of user entry which contains the certificate 199 attribute = "userCertificate"; 200 # Searchfilter for user entry. Must only let pass user entry for the login user. 201 filter = "(&(objectClass=posixAccount)(uid=%s))" 207 attribute = "userCertificate"; 208 # Searchfilter for user entry. Must only let pass user entry 209 # for the login user. 210 filter = "(&(objectClass=posixAccount)(uid=%s))" 211 # SSL/TLS-Switch 212 # This is a global switch, you can't switch between 213 # SSL or TLS and non secured connections per URI! 214 # values: off (standard), tls or on (ssl) or ssl 215 ssl = tls 216 # SSL specific settings 217 # tls_randfile = ... 218 tls_cacertfile = /etc/ssl/cacert.pem 219 # tls_cacertdir = ... 220 tls_checkpeer = 0 221 #tls_ciphers = ... 222 #tls_cert = ... 223 #tls_key = ... 202 224 } 203 225 -
trunk/src/mappers/ldap_mapper.c
r238 r268 22 22 */ 23 23 24 /* 25 * Sandro Wefel (SaW) <sandro.wefel@informatik.uni-halle.de> added 26 * TLS/SSL support (see autofs-ldap and libnss-ldap) 27 * multiple LDAP-Server support 28 * multi-value certificate entries 29 */ 30 24 31 #define __LDAP_MAPPER_C_ 25 32 … … 49 56 */ 50 57 58 59 static const int LDAP_CONFIG_URI_MAX = 10; 60 61 51 62 /* 52 * TODO: Support for LDAPS Connection 53 */ 63 * TODO: 64 * - Support for SASL-AUTH not included yet, I can't test it 65 * 66 * - ldap_unbind (*ld) crash if you connect to a SSL port but have set TLS intead SSL 67 * - no idea why!? 68 * - you got no error-massage from your application 69 * - believe skip ldap_unbind (*ld) for a bind handle isn't a good solution 70 * 71 * - implement searchtimeout 72 * - implement ignorecase 73 */ 74 75 76 enum ldap_ssl_options 77 { 78 SSL_OFF, 79 SSL_LDAPS, 80 SSL_START_TLS 81 }; 82 83 typedef enum ldap_ssl_options ldap_ssl_options_t; 84 85 #ifndef LDAPS_PORT 86 #define LDAPS_PORT 636 87 #endif 88 54 89 55 90 /*** Internal vars *****************************************************/ 56 91 57 static const char *ldaphost="localhost"; 58 static int ldapport=389; 59 static int scope=0; /* 0: LDAP_SCOPE_BASE, 1: LDAP_SCOPE_ONE, 2: LDAP_SCOPE_SUB */ 92 /* Host and Port */ 93 static const char *ldaphost=""; 94 static int ldapport=0; 95 /* or URI (allow multiple hosts) */ 96 static const char *ldapURI=""; 97 static int scope=1; /* 0: LDAP_SCOPE_BASE, 1: LDAP_SCOPE_ONE, 2: LDAP_SCOPE_SUB */ 60 98 static const char *binddn=""; 61 99 static const char *passwd=""; … … 65 103 static int searchtimeout=20; 66 104 static int ignorecase=0; 67 static const X509 *ldap_x509; 105 static const X509 **ldap_x509; 106 static int certcnt=0; 107 108 static ldap_ssl_options_t ssl_on = SSL_OFF; 109 #if defined HAVE_LDAP_START_TLS_S || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) 110 /* TLS/SSL specific options */ 111 static const char *tls_randfile=""; 112 static const char *tls_cacertfile=""; 113 static const char *tls_cacertdir=""; 114 static int tls_checkpeer=-1; 115 static const char *tls_ciphers=""; 116 static const char *tls_cert=""; 117 static const char *tls_key=""; 118 #endif 119 120 static int ldapVersion = 3; 121 #ifdef HAVE_LDAP_SET_OPTION 122 static int timeout = 8; // 8 seconds 123 #endif 124 static int bind_timelimit = 2; // Timelimit for BIND 125 126 static const int sscope[] = { 127 LDAP_SCOPE_BASE, 128 LDAP_SCOPE_ONELEVEL, 129 LDAP_SCOPE_SUBTREE}; 68 130 69 131 /*** Internal funcs ****************************************************/ 132 133 134 static int do_init (LDAP ** ld, const char *uri, int ldapdefport) 135 { 136 int rc; 137 int ldaps; 138 char uribuf[512]; 139 char *p; 140 141 DBG("do_init():"); 142 143 ldaps = (strncasecmp (uri, "ldaps://", sizeof ("ldaps://") - 1) == 0); 144 p = strchr (uri, ':'); 145 /* we should be looking for the second instance to find the port number */ 146 if (p != NULL) 147 { 148 p = strchr (p, ':'); 149 } 150 151 #ifdef HAVE_LDAP_INITIALIZE 152 if (p == NULL && 153 ((ldaps && ldapdefport != LDAPS_PORT) || (!ldaps && ldapdefport != LDAP_PORT))) 154 { 155 /* No port specified in URI and non-default port specified */ 156 snprintf (uribuf, sizeof (uribuf), "%s:%d", uri, ldapdefport); 157 uri = uribuf; 158 } 159 rc = ldap_initialize (ld, uri); 160 #else 161 // TODO: !HAVE_LDAP_INITIALIZE => no ldaps:// possible? 162 if (strncasecmp (uri, "ldap://", sizeof ("ldap://") - 1) != 0) 163 { 164 return LDAP_UNAVAILABLE; 165 } 166 167 uri += sizeof ("ldap://") - 1; 168 p = strchr (uri, ':'); 169 170 if (p != NULL) 171 { 172 size_t urilen = (p - uri); 173 174 if (urilen >= sizeof (uribuf)) 175 { 176 return LDAP_UNAVAILABLE; 177 } 178 179 memcpy (uribuf, uri, urilen); 180 uribuf[urilen] = '\0'; 181 182 ldapdefport = atoi (p + 1); 183 uri = uribuf; 184 } 185 186 # ifdef HAVE_LDAP_INIT 187 *ld = ldap_init (uri, defport); 188 # else 189 *ld = ldap_open (uri, defport); 190 # endif 191 rc = (*ld == NULL) ? LDAP_SERVER_DOWN : LDAP_SUCCESS; 192 193 #endif /* HAVE_LDAP_INITIALIZE */ 194 195 if (rc == LDAP_SUCCESS && *ld == NULL) 196 { 197 rc = LDAP_UNAVAILABLE; 198 } 199 return rc; 200 } 201 202 203 #if defined HAVE_LDAP_START_TLS_S || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) 204 /* 205 * Set the ssl option 206 */ 207 static int do_ssl_options (LDAP *ldap_connection) 208 { 209 int rc; 210 211 DBG("do_ssl_options"); 212 213 #ifdef LDAP_OPT_X_TLS_RANDOM_FILE 214 if (strncmp(tls_randfile,"",1)) 215 { 216 217 /* rand file */ 218 rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE, 219 tls_randfile); 220 if (rc != LDAP_SUCCESS) 221 { 222 DBG("do_ssl_options: Setting of LDAP_OPT_X_TLS_RANDOM_FILE failed"); 223 return LDAP_OPERATIONS_ERROR; 224 } 225 } 226 #endif /* LDAP_OPT_X_TLS_RANDOM_FILE */ 227 228 if (strncmp(tls_cacertfile,"",1)) 229 { 230 /* ca cert file */ 231 rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE, 232 tls_cacertfile); 233 if (rc != LDAP_SUCCESS) 234 { 235 DBG("do_ssl_options: Setting of LDAP_OPT_X_TLS_CACERTFILE failed"); 236 return LDAP_OPERATIONS_ERROR; 237 } 238 } 239 240 if (strncmp(tls_cacertdir,"",1)) 241 { 242 /* ca cert directory */ 243 rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR, 244 tls_cacertdir); 245 if (rc != LDAP_SUCCESS) 246 { 247 DBG("do_ssl_options: Setting of LDAP_OPT_X_TLS_CACERTDIR failed"); 248 return LDAP_OPERATIONS_ERROR; 249 } 250 } 251 252 /* the cert have to be checked ? */ 253 if (tls_checkpeer > -1) 254 { 255 rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, 256 &tls_checkpeer); 257 if (rc != LDAP_SUCCESS) 258 { 259 DBG("do_ssl_options: Setting of LDAP_OPT_X_TLS_REQUIRE_CERT failed"); 260 return LDAP_OPERATIONS_ERROR; 261 } 262 } 263 264 if (strncmp(tls_ciphers,"",1)) 265 { 266 /* set cipher suite, certificate and private key: */ 267 rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, 268 tls_ciphers); 269 if (rc != LDAP_SUCCESS) 270 { 271 DBG("do_ssl_options: Setting of LDAP_OPT_X_TLS_CIPHER_SUITE failed"); 272 return LDAP_OPERATIONS_ERROR; 273 } 274 } 275 276 /* where is the requiered cert */ 277 if (strncmp(tls_cert,"",1)) 278 { 279 rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE, 280 tls_cert); 281 if (rc != LDAP_SUCCESS) 282 { 283 DBG("do_ssl_options: Setting of LDAP_OPT_X_TLS_CERTFILE failed"); 284 return LDAP_OPERATIONS_ERROR; 285 } 286 } 287 288 /* where is the key */ 289 if (strncmp(tls_key,"",1)) 290 { 291 rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE, 292 tls_key); 293 if (rc != LDAP_SUCCESS) 294 { 295 DBG("do_ssl_options: Setting of LDAP_OPT_X_TLS_KEYFILE failed"); 296 return LDAP_OPERATIONS_ERROR; 297 } 298 } 299 return LDAP_SUCCESS; 300 } 301 #endif 302 303 304 static int 305 do_bind (LDAP * ldap_connection, int timelimit) 306 { 307 int rc; 308 int rv; 309 struct timeval tv; 310 LDAPMessage *result; 311 312 /* 313 * set timelimit in ld for select() call in ldap_pvt_connect() 314 * function implemented in libldap2's os-ip.c 315 */ 316 tv.tv_sec = timelimit; 317 tv.tv_usec = 0; 318 319 DBG2("do_bind(): bind DN=\"%s\" pass=\"%s\"",binddn,passwd); 320 321 /* LDAPv3 doesn't need bind at all, 322 * nevertheless, if no binddn is given than bind anonymous */ 323 if ( ! strncmp(binddn,"",1) ) { 324 rv = ldap_simple_bind(ldap_connection, NULL, NULL); 325 } else { 326 rv = ldap_simple_bind(ldap_connection, binddn, passwd); 327 } 328 329 if (rv < 0) 330 { 331 DBG("do_bind: rv < 0"); 332 333 #if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) 334 if (ldap_get_option (ldap_connection, LDAP_OPT_ERROR_NUMBER, &rc) != 335 LDAP_SUCCESS) 336 { 337 rc = LDAP_UNAVAILABLE; 338 } 339 #else 340 rc = ldap_connection->ld_errno; 341 #endif /* LDAP_OPT_ERROR_NUMBER */ 342 /* Notify if we failed. */ 343 DBG3("could not connect to LDAP server as %s - %d - %s", 344 binddn, rc, ldap_err2string (rc)); 345 346 return rc; 347 } 348 349 rc = ldap_result (ldap_connection, rv, 0, &tv, &result); 350 if (rc > 0) 351 { 352 DBG1("do_bind rc=%d", rc); 353 //debug ("<== do_bind"); 354 return ldap_result2error (ldap_connection, result, 1); 355 } 356 357 /* took too long */ 358 if (rc == 0) 359 { 360 DBG("do_bind rc=0"); 361 362 ldap_abandon (ldap_connection, rv); 363 } 364 365 DBG("do_bind return -1"); 366 return -1; 367 } 368 369 /* 370 * Opes connection to an LDAP server 371 * uri must be one URI 372 */ 373 static int do_open (LDAP **ld, const char* uri, int defport, ldap_ssl_options_t ssl_on) 374 { 375 376 #if defined(LDAP_OPT_NETWORK_TIMEOUT) || defined(HAVE_LDAP_START_TLS) 377 struct timeval tv; 378 #endif 379 #ifdef HAVE_LDAP_START_TLS 380 struct timeval *tvp; 381 LDAPMessage *res = NULL; 382 int msgid; 383 #endif 384 int rc; 385 386 rc = do_init (ld, uri, defport); 387 388 if (rc != LDAP_SUCCESS) 389 { 390 DBG("do_open(): do_init failed"); 391 return rc; 392 } 393 394 if( ! *ld) 395 { 396 DBG("do_open(): internal error - assert (*ld != NULL)"); 397 return(-2); 398 } 399 400 #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_PROTOCOL_VERSION) 401 ldap_set_option (*ld, LDAP_OPT_PROTOCOL_VERSION, &ldapVersion); 402 #endif /* LDAP_OPT_PROTOCOL_VERSION */ 403 404 #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT) 405 // ldap_set_option (*ld, LDAP_OPT_NETWORK_TIMEOUT, &timeout); 406 407 rc = ldap_set_option(*ld, LDAP_OPT_NETWORK_TIMEOUT, &timeout); 408 if ( rc != LDAP_SUCCESS ) { 409 DBG2("Warning: failed to set connection timeout to %d: %s", timeout, ldap_err2string(rc)); 410 } else 411 DBG1("Set connection timeout to %d", timeout); 412 #endif /* LDAP_OPT_NETWORK_TIMEOUT */ 413 414 #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT) 415 tv.tv_sec = bind_timelimit; 416 tv.tv_usec = 0; 417 ldap_set_option (*ld, LDAP_OPT_NETWORK_TIMEOUT, &tv); 418 #endif /* LDAP_OPT_NETWORK_TIMEOUT */ 419 420 421 #if defined(HAVE_LDAP_START_TLS_S) || defined(HAVE_LDAP_START_TLS) 422 if (ssl_on == SSL_START_TLS) 423 { 424 int version; 425 426 // we need V3 at least 427 if (ldap_get_option(*ld, LDAP_OPT_PROTOCOL_VERSION, 428 &version) == LDAP_OPT_SUCCESS) 429 { 430 if (ldapVersion < LDAP_VERSION3) 431 { 432 ldapVersion = LDAP_VERSION3; 433 ldap_set_option (*ld, LDAP_OPT_PROTOCOL_VERSION, 434 &ldapVersion); 435 } 436 } 437 438 /* set up SSL context */ 439 if (do_ssl_options (*ld) != LDAP_SUCCESS) 440 { 441 ldap_unbind (*ld); 442 DBG("do_open(): SSL setup failed"); 443 return LDAP_UNAVAILABLE; 444 } 445 446 #ifdef HAVE_LDAP_START_TLS 447 448 DBG("do_open(): do_start_tls"); 449 rc = ldap_start_tls (*ld, NULL, NULL, &msgid); 450 if (rc != LDAP_SUCCESS) 451 { 452 DBG1("do_open(): ldap_start_tls failed: %s", ldap_err2string (rc)); 453 return rc; 454 } 455 456 if (bind_timelimit == LDAP_NO_LIMIT) 457 { 458 tvp = NULL; 459 } 460 else 461 { 462 tv.tv_sec = bind_timelimit; 463 tv.tv_usec = 0; 464 tvp = &tv; 465 } 466 467 rc = ldap_result (*ld, msgid, 1, tvp, &res); 468 if (rc == -1) 469 { 470 #if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) 471 if (ldap_get_option (*ld, LDAP_OPT_ERROR_NUMBER, &rc) != LDAP_SUCCESS) 472 { 473 rc = LDAP_UNAVAILABLE; 474 } 475 #else 476 rc = ld->ld_errno; 477 #endif /* LDAP_OPT_ERROR_NUMBER */ 478 479 DBG1("do_open(): ldap_start_tls failed: %s", ldap_err2string (rc)); 480 return rc; 481 } 482 483 rc = ldap_result2error (*ld, res, 1); 484 if (rc != LDAP_SUCCESS) 485 { 486 DBG1("do_open(): ldap_result2error failed: %s)", ldap_err2string (rc)); 487 return rc; 488 } 489 490 rc = ldap_install_tls (*ld); 491 #else 492 rc = ldap_start_tls_s (*ld, NULL, NULL); 493 #endif /* HAVE_LDAP_START_TLS */ 494 495 if (rc == LDAP_SUCCESS) 496 { 497 DBG("do_open(): TLS startup succeeded"); 498 } 499 else 500 { 501 ldap_unbind (*ld); 502 DBG2("do_open(): TLS startup failed for LDAP server %s: %s", 503 uri, ldap_err2string (rc)); 504 return rc; 505 } 506 } 507 else 508 #endif /* HAVE_LDAP_START_TLS_S || HAVE_LDAP_START_TLS */ 509 510 /* 511 * If SSL is desired, then enable it. 512 */ 513 if (ssl_on == SSL_LDAPS) 514 { 515 #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS) 516 int tls = LDAP_OPT_X_TLS_HARD; 517 if (ldap_set_option (*ld, LDAP_OPT_X_TLS, &tls) != 518 LDAP_SUCCESS) 519 { 520 ldap_unbind (*ld); 521 DBG("do_open(): TLS setup failed"); 522 return LDAP_UNAVAILABLE; 523 } 524 525 /* set up SSL context */ 526 if (do_ssl_options (*ld) != LDAP_SUCCESS) 527 { 528 ldap_unbind (*ld); 529 DBG("do_open(): SSL setup failed"); 530 return LDAP_UNAVAILABLE; 531 } 532 #endif 533 } 534 535 rc = do_bind (*ld, bind_timelimit); 536 if (rc != LDAP_SUCCESS) 537 { 538 DBG2("do_open(): failed to bind to LDAP server %s: %s", 539 uri, ldap_err2string (rc)); 540 ldap_unbind (*ld); 541 } 542 return rc; 543 } 544 545 /* 546 * add singe URI to array of uris 547 */ 548 int ldap_add_uri (char **uris, const char *a_uri, char **buffer, size_t *buflen) 549 { 550 int i; 551 size_t uri_len; 552 553 for (i = 0; uris[i] != NULL; i++) 554 ; 555 556 if (i == LDAP_CONFIG_URI_MAX) 557 { 558 DBG("maximum number of URIs exceeded"); 559 return -1; 560 } 561 562 uri_len = strlen (a_uri); 563 564 if (*buflen < uri_len + 1) 565 { 566 DBG("buffer to small for URI"); 567 return -1; 568 } 569 570 memcpy (*buffer, a_uri, uri_len + 1); 571 572 uris[i] = *buffer; 573 uris[i + 1] = NULL; 574 575 *buffer += uri_len + 1; 576 *buflen -= uri_len + 1; 577 578 DBG1("added URI %s", a_uri); 579 580 return 0; 581 } 582 583 70 584 71 585 /** 72 586 * Get certificate from LDAP-Server. 73 587 */ 588 // not global then 589 // static int ldap_get_certificate(const char *login, X509*** ldap_x509) { 74 590 static int ldap_get_certificate(const char *login) { 75 591 LDAP *ldap_connection; … … 82 598 char filter_str[100]; 83 599 char *attrs[2]; 600 int rv; 601 void *bv_val; 602 603 char uri[4096]; 604 char uribuf[4096]; 605 char *uris[LDAP_CONFIG_URI_MAX + 1]; 606 const char *p; 607 int current_uri = 0, start_uri = 0; 608 609 uris[0] = NULL; 84 610 85 611 attrs[0] = (char *)attribute; 86 612 attrs[1] = NULL; 87 88 613 89 614 DBG1("ldap_get_certificate(): begin login = %s", login); 90 615 616 // Put the login to the %s in Filterstring 91 617 snprintf(filter_str, sizeof(filter_str), filter, login); 92 618 93 619 DBG1("ldap_get_certificate(): filter_str = %s", filter_str); 94 620 95 ldap_connection = ldap_init(ldaphost, ldapport); 96 if ( NULL == ldap_connection) { 97 DBG("ldap_init() failed"); 621 // parse and split URI config entry 622 char *buffer = uribuf; 623 size_t buflen = sizeof (uribuf); 624 625 strncpy(uri, ldapURI, sizeof (uri)-1); 626 627 /* Add a space separated list of URIs */ 628 // TODO: no spaces in one URI allowed => URL-encoding? 629 if(strncmp(ldapURI,"",1)) 630 for (p = uri; p != NULL; ) 631 { 632 char *q = strchr (p, ' '); 633 if (q != NULL) 634 *q = '\0'; 635 636 if( strlen(p) > 1 ) // SAW: don't add spaces 637 rv = ldap_add_uri (uris, p, &buffer, &buflen); 638 639 p = (q != NULL) ? ++q : NULL; 640 641 if (rv) 642 break; 643 } 644 // set the default port if no port is given 645 if (ldapport == 0) 646 { 647 if (ssl_on == SSL_LDAPS) 648 { 649 ldapport = LDAPS_PORT; 650 } 651 else 652 { 653 ldapport = LDAP_PORT; 654 } 655 } 656 657 // add ldaphost to uris if set, nevermind "uri" is set in config 658 if( strlen(ldaphost) > 1 ) 659 { 660 /* No port specified in URI and non-default port specified */ 661 snprintf (uri, sizeof (uri), "%s%s:%d", 662 ssl_on == SSL_LDAPS ? "ldaps://" : "ldap://", 663 ldaphost, ldapport); 664 rv = ldap_add_uri (uris, uri, &buffer, &buflen); 665 } 666 667 if (uris[0] == NULL) 668 { 669 DBG("ldap_get_certificate(): Nor URI or useable Host entry found"); 98 670 return(-1); 99 } 100 101 if ( 0 != ldap_simple_bind_s(ldap_connection, binddn, passwd)) { 102 DBG("ldap_simple_bind_s() failed"); 671 } 672 673 /* Attempt to connect to specified URI in order until do_open succeed */ 674 start_uri = current_uri; 675 do 676 { 677 if(uris[current_uri] != NULL) 678 DBG1("ldap_get_certificate(): try do_open for %s", uris[current_uri]); 679 rv = do_open(&ldap_connection, uris[current_uri], ldapport, ssl_on); 680 // hot-fix, because in some circumstances an LDAP_SERVER_DOWN is returned 681 if (rv != LDAP_UNAVAILABLE && rv != LDAP_SERVER_DOWN) 682 break; 683 current_uri++; 684 685 if (uris[current_uri] == NULL) 686 current_uri = 0; 687 } 688 while (current_uri != start_uri); 689 690 if( rv != LDAP_SUCCESS ) 691 { 692 DBG("ldap_get_certificate(): do_open failed"); 103 693 return(-2); 104 694 } 105 695 106 if ( LDAP_SUCCESS != ldap_search_s(ldap_connection, base, LDAP_SCOPE_SUBTREE, filter_str, attrs, 0, &res)) { 107 DBG("ldap_search_s() failed"); 696 /* TODO: (1) The problem: if an working uri is found it is used 697 and if there is an (SSL-)error, no other one is tried 698 (2) There is no session, so we don't know which LDAP_Server 699 is the last with a successful connection. So we try the same 700 server again. Perhaps create a state file/smem/etc. ? 701 */ 702 703 rv = ldap_search_s( 704 ldap_connection, 705 base, 706 sscope[scope], 707 filter_str, 708 attrs, 709 0, 710 &res); 711 if ( rv != LDAP_SUCCESS ) { 712 DBG1("ldap_search_s() failed: %s", ldap_err2string(rv)); 108 713 ldap_unbind_s(ldap_connection); 109 714 return(-3); … … 112 717 DBG1("ldap_get_certificate(): entries = %d", entries); 113 718 719 if( entries > 1 ) { 720 DBG("! Warning, more than one entry found. Please choose \"filter\" and"); 721 DBG("! \"attribute\" in ldap mapper config section of your config,"); 722 DBG("! that only one entry with one attribute is matched"); 723 DBG("! Maybe there is an other problem in ldap with not unique user"); 724 DBG("! entries in your LDAP server."); 725 } 726 114 727 /* Only first entry is used. "filter" and "attribute" 115 728 * should be choosen, so that only one entry with 116 729 * one attribute is returned */ 117 730 if ( NULL == (entry = ldap_first_entry(ldap_connection, res))){ 118 DBG("ldap_first_entry() failed ");731 DBG("ldap_first_entry() failed: %s"); 119 732 ldap_unbind_s(ldap_connection); 120 733 return(-4); … … 129 742 DBG1("attribute name = %s", name); 130 743 131 /* TODO: Add support for multi-value attribute for usercertificate */132 744 bvals = ldap_get_values_len(ldap_connection, entry, name); 133 ldap_x509 = d2i_X509(NULL, (unsigned char **) &bvals[0]->bv_val, bvals[0]->bv_len); 134 if (NULL == ldap_x509) { 135 DBG("d2i_X509() failed"); 136 ldap_msgfree(res); 137 ldap_unbind_s(ldap_connection); 138 return(-6); 139 }else { 140 DBG("d2i_X509(): success"); 745 certcnt = ldap_count_values_len(bvals); 746 747 DBG1("number auf usercertificates = %d", certcnt); 748 749 //*ldap_x509 = malloc(sizeof(X509*) * certcnt ); 750 ldap_x509 = malloc(sizeof(X509*) * certcnt ); 751 752 rv = 0; 753 while(rv < certcnt ) 754 { 755 // SaW: not nifty, but otherwise gcc doesn't optimize 756 bv_val = &bvals[rv]->bv_val; 757 ldap_x509[rv] = d2i_X509(NULL, ((const unsigned char **) bv_val), bvals[rv]->bv_len); 758 if (NULL == ldap_x509) { 759 DBG1("d2i_X509() failed for certificate %d", rv); 760 free(ldap_x509); 761 certcnt=0; 762 ldap_msgfree(res); 763 ldap_unbind_s(ldap_connection); 764 return(-6); 765 }else { 766 DBG1("d2i_X509(): success for certificate %d", rv); 767 } 768 rv++; 141 769 } 142 770 ldap_msgfree(res); 771 // TODO: this leads to a segfault, but the doc said ... 772 // ldap_value_free_len(bvals); 143 773 } 144 774 if ( 0 != (ret = ldap_unbind_s(ldap_connection))) { … … 156 786 ldaphost = scconf_get_str(blk,"ldaphost",ldaphost); 157 787 ldapport = scconf_get_int(blk,"ldapport",ldapport); 788 ldapURI = scconf_get_str(blk,"uri",ldapURI); 158 789 scope = scconf_get_int(blk,"scope",scope); 159 790 binddn = scconf_get_str(blk,"binddn",binddn); … … 165 796 searchtimeout = scconf_get_int(blk,"searchtimeout",searchtimeout); 166 797 798 const char *ssltls = scconf_get_str(blk,"ssl","off"); 799 if (! strncasecmp (ssltls, "tls", 3)) 800 ssl_on = SSL_START_TLS; 801 else if( ! strncasecmp (ssltls, "on", 2)) 802 ssl_on = SSL_LDAPS; 803 else if( ! strncasecmp (ssltls, "ssl", 3)) 804 ssl_on = SSL_LDAPS; 805 806 #if defined HAVE_LDAP_START_TLS_S || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) 807 /* TLS specific options */ 808 tls_randfile = scconf_get_str(blk,"tls_randfile",tls_randfile); 809 tls_cacertfile = scconf_get_str(blk,"tls_cacertfile",tls_cacertfile); 810 tls_cacertdir = scconf_get_str(blk,"tls_cacertdir",tls_cacertdir); 811 tls_checkpeer=scconf_get_int(blk,"tls_checkpeer",tls_checkpeer); 812 tls_ciphers = scconf_get_str(blk,"tls_ciphers",tls_ciphers); 813 tls_cert = scconf_get_str(blk,"tls_cert",tls_cert); 814 tls_key = scconf_get_str(blk,"tls_key",tls_key); 815 #endif 816 817 167 818 set_debug_level(debug); 819 DBG1("test ssltls = %s", ssltls); 168 820 169 821 DBG("LDAP mapper started."); 170 DBG1("debug = %d", debug); 171 DBG1("ignorecase = %d", ignorecase); 172 DBG1("ldaphost = %s", ldaphost); 173 DBG1("ldapport = %d", ldapport); 174 DBG1("scope = %d", scope); 175 DBG1("binddn = %s", binddn); 176 DBG1("passwd = %s", passwd); 177 DBG1("base = %s", base); 178 DBG1("attribute = %s", attribute); 179 DBG1("filter = %s", filter); 822 DBG1("debug = %d", debug); 823 DBG1("ignorecase = %d", ignorecase); 824 DBG1("ldaphost = %s", ldaphost); 825 DBG1("ldapport = %d", ldapport); 826 DBG1("ldapURI = %s", ldapURI); 827 DBG1("scope = %d", scope); 828 DBG1("binddn = %s", binddn); 829 DBG1("passwd = %s", passwd); 830 DBG1("base = %s", base); 831 DBG1("attribute = %s", attribute); 832 DBG1("filter = %s", filter); 833 DBG1("searchtimeout = %d", searchtimeout); 834 DBG1("ssl_on = %d", ssl_on); 835 #if defined HAVE_LDAP_START_TLS_S || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) 836 DBG1("tls_randfile = %s", tls_randfile); 837 DBG1("tls_cacertfile= %s", tls_cacertfile); 838 DBG1("tls_cacertdir = %s", tls_cacertdir); 839 DBG1("tls_checkpeer = %d", tls_checkpeer); 840 DBG1("tls_ciphers = %s", tls_ciphers); 841 DBG1("tls_cert = %s", tls_cert); 842 DBG1("tls_key = %s", tls_key); 843 #endif 180 844 return 1; 181 845 … … 194 858 195 859 static int ldap_mapper_match_user(X509 *x509, const char *login, void *context) { 860 //X509 **ldap_x509 = 0; 196 861 int match_found = 0; 197 862 int i=0; 863 864 //if ( 1 != ldap_get_certificate(login, &ldap_x509)){ 198 865 if ( 1 != ldap_get_certificate(login)){ 199 866 DBG("ldap_get_certificate() failed"); … … 201 868 } else { 202 869 /* TODO: maybe compare public keys instead of hashes */ 203 if ( 0 == X509_cmp(x509, ldap_x509)) { 204 DBG("Certifcates matching"); 205 match_found = 1; 206 } else { 207 DBG("Certifcates NOT matching"); 208 match_found = 0; 209 } 870 while( i<certcnt && !match_found ) { 871 if ( 0 == X509_cmp(x509, ldap_x509[i])) { 872 DBG1("Certificate %d is matching", i); 873 match_found = 1; 874 } else { 875 DBG1("Certificate %d is NOT matching", i); 876 } 877 i++; 878 } 879 if (certcnt) 880 free(ldap_x509); 881 certcnt=0; 210 882 } 211 883 return match_found; … … 229 901 } 230 902 endpwent(); 903 904 #ifdef false 905 int res; 906 res= ldap_mapper_match_user(x509,"wefel",context); 907 if (res) { 908 DBG("Certificate maps to user wefel"); 909 found= clone_str("wefel"); 910 } else { 911 DBG("Certificate map to user wefel failed"); 912 } 913 #endif 914 231 915 return found; 232 916 } … … 253 937 mapper_module *pt; 254 938 255 pt = init_mapper_st(blk,mapper_name);939 pt = init_mapper_st(blk,mapper_name); 256 940 257 941 if (blk) { … … 261 945 DBG1("No configuration entry for mapper '%s'. Assume defaults", mapper_name); 262 946 } 263 264 return pt; 265 } 947 return pt; 948 }
Note: See TracChangeset
for help on using the changeset viewer.
