/**************************************************
OpengateM - MAC address authentication system 
 module for Authentication by LDAP

Copyright (C) 2007 Opengate Project Team
Written by Yoshiaki Watanabe

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Email: watanaby@is.saga-u.ac.jp
**************************************************/
#include "opengatemmng.h"


#ifndef LDAP_NOT_INSTALLED
  #include <ldap.h>
  #include <lber.h>
#endif

/*****************************************/
/* Authenticate by LDAP */
/*****************************************/
int authLdap(char *userid, char *passwd)
{

#ifdef LDAP_NOT_INSTALLED
  err_msg("ERR at %s#%d: No LDAP. Install openldap-client and rebuild OpengateM.",
	    __FILE__,__LINE__);
  return DENY;
#else

  LDAP *ld;
  int desiredVersion = LDAP_VERSION3; 
  char *uri;                      /* ldap server URI */
  char filter[BUFFMAXLN]="";
  char *baseDn;
  LDAPMessage *result;
  LDAPMessage *entry;
  char *dn;
  int ret;
  struct berval cred = { strlen(passwd), passwd };
  struct berval *msgidp=NULL;

  /* get LDAP server URI from conf */
  uri=GetConfValue("AuthServer/Uri");
  if(isNull(uri)) uri=NULL; /* means ldap://localhost */
 
  /* get LDAP search base DN from conf */
  baseDn=GetConfValue("AuthServer/BaseDN");
  if(isNull(baseDn)) baseDn=NULL; /* set in uri */
  
  /* get handle */
  if(ldap_initialize(&ld, uri)!=LDAP_SUCCESS) { 
    err_msg("ERR at %s#%d: Can not initialize the LDAP server",
	    __FILE__,__LINE__);
    return DENY;
  }

  /* set LDAP version */
  if(ldap_set_option(ld,LDAP_OPT_PROTOCOL_VERSION,&desiredVersion) 
     != LDAP_OPT_SUCCESS){
    err_msg("ERR at %s#%d: error in LDAP set version",
	    __FILE__,__LINE__);
    return DENY;
  }

  /* set URI such as [ldaps://ldap.saga-u.ac.jp:999] */
  ret=ldap_set_option(ld, LDAP_OPT_URI, uri);
  if(ret==LDAP_PARAM_ERROR){
    err_msg("ERR at %s#%d: parameter error in LDAP set URI",
	    __FILE__,__LINE__);
    return DENY;
  }
  
  /* set filter '(uid=<userid>)' */
  strlcpy(filter, "(uid=", BUFFMAXLN);
  strlcat(filter, userid, BUFFMAXLN);
  strlcat(filter, ")", BUFFMAXLN);
  
  /* search LDAP entry */
  ret = ldap_search_ext_s(ld,baseDn,LDAP_SCOPE_SUBTREE,
		  filter,NULL,0,NULL,NULL,NULL,0,&result);
  if (ret !=LDAP_SUCCESS) {
    err_msg("ERR at %s#%d: error in LDAP search",
	    __FILE__,__LINE__);
    return DENY;
  }

  /* count of matched entry must be one */
  if(ldap_count_entries(ld,result)!=1){
    return DENY;
  }
 
  /* get the entry */
  entry=ldap_first_entry(ld,result); 
  
  /* get the DN */
  dn=ldap_get_dn(ld, entry);
  
  /* authenticate by binding */
  ret=ldap_sasl_bind_s(ld,dn,NULL,&cred,NULL,NULL,&msgidp);
  
  /* unbinding */
  ldap_unbind_ext_s(ld,NULL,NULL);

  /* return the auth result */
  if(ret==LDAP_SUCCESS){
    return ACCEPT;
  }
  else{
    return DENY;
  }
#endif
}

  
/***********************************
 **********************************/  
int AuthLdap(char *userid, char *passwd)
{
  int ret;

  if(debug>1) err_msg("DEBUG:=>authLdap(%s,passwd)",userid);
  ret=authLdap(userid,passwd);
  if(debug>1) err_msg("DEBUG:(%d)<=authLdap( )",ret);

  return ret;
}





