mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-08 16:04:47 -05:00
This could cause problems on odd systems. The generic headers should be extended as needed to include necessary system headers or, if necessary, make explicit declarations. Extended ac/string.h header to look for string.h/strings.h if STDC_HEADERS is not defined. Also provide basic declarations for str*() functions. This could cause problems on odd systems. Extended ac/unistd.h header to define basic declaration for misc functions that might be missing from headers. This includes externs for getenv(), getopt(), mktemp(), tempname(). Protect fax500.h from multiple inclusion. Moved includes of system/generic headers back to source files. Made mail500 helper functions static. Fixed includes of ctype.h, signal.h, etc. to use generics. lutil/tempname.c: was including stdlib.h twice, one should stdio.h. Wrapped <sys/resource.h> with HAVE_SYS_RESOURCE_H. lber/io.c/ber_get_next(): Changed noctets back to signed. Used with BerRead which expects signed int as second arg and returns signed int.
265 lines
6.2 KiB
C
265 lines
6.2 KiB
C
/* bind.c - ldbm backend bind and unbind routines */
|
|
|
|
#include "portable.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <ac/krb.h>
|
|
#include <ac/socket.h>
|
|
#include <ac/string.h>
|
|
#include <ac/unistd.h>
|
|
|
|
#include "slap.h"
|
|
#include "back-ldbm.h"
|
|
#include "proto-back-ldbm.h"
|
|
|
|
#ifdef SLAPD_SHA1
|
|
#include <lutil_sha1.h>
|
|
#endif /* SLAPD_SHA1 */
|
|
|
|
#ifdef SLAPD_MD5
|
|
#include <lutil_md5.h>
|
|
#endif /* SLAPD_MD5 */
|
|
|
|
#include <lutil.h>
|
|
|
|
#ifdef HAVE_KERBEROS
|
|
extern int krbv4_ldap_auth();
|
|
#endif
|
|
|
|
#ifdef SLAPD_CRYPT
|
|
pthread_mutex_t crypt_mutex;
|
|
|
|
static int
|
|
crypted_value_find(
|
|
struct berval **vals,
|
|
struct berval *v,
|
|
int syntax,
|
|
int normalize,
|
|
struct berval *cred
|
|
)
|
|
{
|
|
int i;
|
|
for ( i = 0; vals[i] != NULL; i++ ) {
|
|
if ( syntax != SYNTAX_BIN && strncasecmp( "{CRYPT}",
|
|
vals[i]->bv_val, (sizeof("{CRYPT}") - 1 ) ) == 0 ) {
|
|
char *userpassword = vals[i]->bv_val + sizeof("{CRYPT}") - 1;
|
|
pthread_mutex_lock( &crypt_mutex );
|
|
if (strcmp(userpassword, crypt(cred->bv_val,
|
|
userpassword)) == 0) {
|
|
pthread_mutex_unlock( &crypt_mutex );
|
|
return ( 0 );
|
|
}
|
|
pthread_mutex_unlock( &crypt_mutex );
|
|
#ifdef SLAPD_MD5
|
|
} else if ( syntax != SYNTAX_BIN && strncasecmp( "{MD5}",
|
|
vals[i]->bv_val, (sizeof("{MD5}") - 1 ) ) == 0 ) {
|
|
ldap_MD5_CTX MD5context;
|
|
unsigned char MD5digest[20];
|
|
char base64digest[29]; /* ceiling(sizeof(input)/3) * 4 + 1 */
|
|
|
|
char *userpassword = vals[i]->bv_val + sizeof("{MD5}") - 1;
|
|
|
|
ldap_MD5Init(&MD5context);
|
|
ldap_MD5Update(&MD5context,
|
|
(unsigned char *) cred->bv_val,
|
|
strlen(cred->bv_val));
|
|
ldap_MD5Final(MD5digest, &MD5context);
|
|
|
|
if (b64_ntop(MD5digest, sizeof(MD5digest),
|
|
base64digest, sizeof(base64digest)) < 0)
|
|
{
|
|
return ( 1 );
|
|
}
|
|
|
|
if (strcmp(userpassword, base64digest) == 0) {
|
|
return ( 0 );
|
|
}
|
|
#endif /* SLAPD_MD5 */
|
|
#ifdef SLAPD_SHA1
|
|
} else if ( syntax != SYNTAX_BIN && strncasecmp( "{SHA}",
|
|
vals[i]->bv_val, (sizeof("{SHA}") - 1 ) ) == 0 ) {
|
|
ldap_SHA1_CTX SHA1context;
|
|
unsigned char SHA1digest[20];
|
|
char base64digest[29]; /* ceiling(sizeof(input)/3) * 4 + 1 */
|
|
|
|
char *userpassword = vals[i]->bv_val + sizeof("{SHA}") - 1;
|
|
|
|
ldap_SHA1Init(&SHA1context);
|
|
ldap_SHA1Update(&SHA1context,
|
|
(unsigned char *) cred->bv_val,
|
|
strlen(cred->bv_val));
|
|
ldap_SHA1Final(SHA1digest, &SHA1context);
|
|
|
|
if (b64_ntop(SHA1digest, sizeof(SHA1digest),
|
|
base64digest, sizeof(base64digest)) < 0)
|
|
{
|
|
return ( 1 );
|
|
}
|
|
|
|
if (strcmp(userpassword, base64digest) == 0) {
|
|
return ( 0 );
|
|
}
|
|
#endif /* SLAPD_SHA1 */
|
|
} else {
|
|
if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) {
|
|
return( 0 );
|
|
}
|
|
}
|
|
}
|
|
|
|
return( 1 );
|
|
}
|
|
#endif /* SLAPD_CRYPT */
|
|
|
|
int
|
|
ldbm_back_bind(
|
|
Backend *be,
|
|
Connection *conn,
|
|
Operation *op,
|
|
char *dn,
|
|
int method,
|
|
struct berval *cred
|
|
)
|
|
{
|
|
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
Entry *e;
|
|
Attribute *a;
|
|
int rc;
|
|
char *matched = NULL;
|
|
#ifdef HAVE_KERBEROS
|
|
char krbname[MAX_K_NAME_SZ + 1];
|
|
AUTH_DAT ad;
|
|
#endif
|
|
|
|
Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn, 0, 0);
|
|
|
|
/* get entry with reader lock */
|
|
if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
|
|
/* allow noauth binds */
|
|
if ( method == LDAP_AUTH_SIMPLE && cred->bv_len == 0 ) {
|
|
/*
|
|
* bind successful, but return 1 so we don't
|
|
* authorize based on noauth credentials
|
|
*/
|
|
send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
|
|
rc = 1;
|
|
} else if ( be_isroot_pw( be, dn, cred ) ) {
|
|
/* front end will send result */
|
|
rc = 0;
|
|
} else {
|
|
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT, matched, NULL );
|
|
rc = 1;
|
|
}
|
|
if ( matched != NULL ) {
|
|
free( matched );
|
|
}
|
|
return( rc );
|
|
}
|
|
|
|
/* check for deleted */
|
|
|
|
switch ( method ) {
|
|
case LDAP_AUTH_SIMPLE:
|
|
if ( cred->bv_len == 0 ) {
|
|
send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
|
|
|
|
/* stop front end from sending result */
|
|
rc = 1;
|
|
goto return_results;
|
|
} else if ( be_isroot_pw( be, dn, cred ) ) {
|
|
/* front end will send result */
|
|
rc = 0;
|
|
goto return_results;
|
|
}
|
|
|
|
if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
|
|
if ( be_isroot_pw( be, dn, cred ) ) {
|
|
/* front end will send result */
|
|
rc = 0;
|
|
goto return_results;
|
|
}
|
|
send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
|
|
NULL, NULL );
|
|
rc = 1;
|
|
goto return_results;
|
|
}
|
|
|
|
#ifdef SLAPD_CRYPT
|
|
if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
|
|
#else
|
|
if ( value_find( a->a_vals, cred, a->a_syntax, 0 ) != 0 )
|
|
#endif
|
|
{
|
|
if ( be_isroot_pw( be, dn, cred ) ) {
|
|
/* front end will send result */
|
|
rc = 0;
|
|
goto return_results;
|
|
}
|
|
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
|
|
NULL, NULL );
|
|
rc = 1;
|
|
goto return_results;
|
|
}
|
|
rc = 0;
|
|
break;
|
|
|
|
#ifdef HAVE_KERBEROS
|
|
case LDAP_AUTH_KRBV41:
|
|
if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
|
|
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
|
|
NULL, NULL );
|
|
rc = 0;
|
|
goto return_results;
|
|
}
|
|
sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
|
|
: "", ad.pinst, ad.prealm );
|
|
if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
|
|
/*
|
|
* no krbName values present: check against DN
|
|
*/
|
|
if ( strcasecmp( dn, krbname ) == 0 ) {
|
|
rc = 0; /* XXX wild ass guess */
|
|
break;
|
|
}
|
|
send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
|
|
NULL, NULL );
|
|
rc = 1;
|
|
goto return_results;
|
|
} else { /* look for krbName match */
|
|
struct berval krbval;
|
|
|
|
krbval.bv_val = krbname;
|
|
krbval.bv_len = strlen( krbname );
|
|
|
|
if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
|
|
send_ldap_result( conn, op,
|
|
LDAP_INVALID_CREDENTIALS, NULL, NULL );
|
|
rc = 1;
|
|
goto return_results;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LDAP_AUTH_KRBV42:
|
|
send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
|
|
/* stop front end from sending result */
|
|
rc = 1;
|
|
goto return_results;
|
|
#endif
|
|
|
|
default:
|
|
send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
|
|
NULL, "auth method not supported" );
|
|
rc = 1;
|
|
goto return_results;
|
|
}
|
|
|
|
return_results:;
|
|
/* free entry and reader lock */
|
|
cache_return_entry_r( &li->li_cache, e );
|
|
|
|
/* front end with send result on success (rc==0) */
|
|
return( rc );
|
|
}
|
|
|