/* ldap_pwd_ok.c written over a crate of beer by Keith Lewis (monash.edu.au) */

#include <strings.h>
#include <stdio.h>
#include <errno.h>
#include <lber.h>
#include <ldap.h>

/* Bas Meijer */
#include "config.h"

/* DEBUG can be 0-32, with increasing logging in 
/var/log/news.notice, 1 is fine on testing, if you're not sure
about it increase but, 32 is insecure for production since it logs the
password */

#define DEBUG 1

int ldap_pwd_ok ( char *ldaphost, char *user, char *passwd) {
	//char ldaphost[]="localhost";
	LDAP *ld;
	LDAPMessage *res, *e;
	char filter[128];
	char *attrs[] = { "dn", 0 };
	char *dn;

	strcpy(filter,"(uid=");
	strcat(filter,user);
	strcat(filter,")");

	if (( ld = ldap_open( ldaphost,LDAP_PORT)) == NULL ) {
		   perror( ldaphost );
		   exit( 1 );
	}

if(DEBUG>0) fprintf(stderr, "bind for search at %s\n",ldaphost); 


	if ( ldap_simple_bind_s( ld, LDAPSEARCH_BINDDN,  LDAPSEARCH_BIND_CRED )
		!= LDAP_SUCCESS ) {
		   ldap_perror( ld, "ldap_bind" ); 
		   return(0);
	}

if(DEBUG>1) fprintf(stderr, "searching dn for %s \n",user);  
	if ( ldap_search_s( ld,  LDAPSEARCH_BASE, LDAP_SCOPE_SUBTREE,
						 filter, attrs, 0, &res)
	   != 0 ) {
		ldap_perror( ld, "ldap_usearch" );
		return(0);
	}

if(DEBUG>2) fprintf(stderr,"getting first entry\n");  
	e = ldap_first_entry( ld, res );
	if(res == NULL){
		perror("failed search");
	}
	if ( e == (LDAPMessage *) 0 ) {
		ldap_perror( ld, "ldap_esearch" ); 
		return(0); 
	}
if(DEBUG>2) fprintf(stderr,"getting dn for %s\n",user);  
	dn = ldap_get_dn( ld, e);
	/* something wrong no value */
	if(!dn){	
		fprintf(stderr, "dn is not found in ldap://%s\n",ldaphost); 
		ldap_unbind(ld);
if(DEBUG>8) printf("user not found in ldap database\n");
		exit(3);
	}

	ldap_unbind(ld);
if(DEBUG>16) fprintf(stderr,"unbinding\n");

	if (( ld = ldap_open( ldaphost,LDAP_PORT)) == NULL ) {
if(DEBUG>1) fprintf(stderr, "cannot open %s for authbind",ldaphost ); 
		return(0);
	}

if(DEBUG) fprintf(stderr,"binding as %s at %s\n",dn,ldaphost); 

	if ( ldap_simple_bind_s( ld, dn,  passwd )
	!= LDAP_SUCCESS ) {
		/* invalid credentials */
		ldap_perror( ld, "ldap_fsearch" );
	if(DEBUG>32)	fprintf(stderr,"%s not authenticated with %s\n",user,passwd);  
		return(0);
	}
	return(1);
}

