/********************************************************************\
Name: auth.c
Created by: Stefan Ritt
Copyright 2000 + Stefan Ritt
ELOG 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 3 of the License, or
(at your option) any later version.
ELOG 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 ELOG. If not, see <http://www.gnu.org/licenses/>.
Contents: Authentication subroutines. Currently supported:
- password file authentication
- kerberos5 password authentication
$Id: elog.c 2350 2010-12-23 10:45:10Z ritt $
\********************************************************************/
#include "elogd.h"
#ifdef HAVE_KRB5
#include <krb5.h>
#endif
#ifdef HAVE_LDAP
#include <ldap.h>
LDAP *ldap_ld;
char ldap_login_attr[64];
char ldap_dn_user[256];
char ldap_pw_user[64];
char ldap_userbase[256];
char ldap_bindDN[512];
#endif /* HAVE_LDAP */
extern LOGBOOK *lb_list;
/*==================================================================*/
/*---- Kerberos5 routines ------------------------------------------*/
#ifdef HAVE_KRB5
int auth_verify_password_krb5(LOGBOOK * lbs, const char *user, const char *password, char *error_str,
int error_size)
{
char *princ_name, str[256], realm[256];
krb5_error_code error;
krb5_principal princ;
krb5_context context;
krb5_creds creds;
krb5_get_init_creds_opt options;
if (krb5_init_context(&context) < 0)
return FALSE;
strlcpy(str, user, sizeof(str));
if (getcfg(lbs->name, "Kerberos Realm", realm, sizeof(realm))) {
strlcat(str, "@", sizeof(str));
strlcat(str, realm, sizeof(str));
}
if ((error = krb5_parse_name(context, str, &princ)) != 0) {
strlcpy(error_str, "<b>Kerberos error:</b> ", error_size);
strlcat(error_str, krb5_get_error_message(context, error), error_size);
strlcat(error_str, ". Please check your Kerberos configuration.", error_size);
return FALSE;
}
error = krb5_unparse_name(context, princ, &princ_name);
if (error) {
strlcpy(error_str, "<b>Kerberos error:</b> ", error_size);
strlcat(error_str, krb5_get_error_message(context, error), error_size);
strlcat(error_str, ". Please check your Kerberos configuration.", error_size);
return FALSE;
}
sprintf(str, "Using %s as server principal for authentication", princ_name);
write_logfile(lbs, str);
memset(&options, 0, sizeof(options));
krb5_get_init_creds_opt_init(&options);
memset(&creds, 0, sizeof(creds));
error = krb5_get_init_creds_password(context, &creds, princ,
(char *) password, NULL, NULL, 0, NULL, &options);
krb5_free_context(context);
if (error && error != KRB5KDC_ERR_PREAUTH_FAILED && error != KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN) {
sprintf(error_str, "<b>Kerberos error %d:</b> ", error);
strlcat(error_str, krb5_get_error_message(context, error), error_size);
strlcat(error_str, ". Please check your Kerberos configuration.", error_size);
return FALSE;
}
if (error)
return FALSE;
return TRUE;
}
int auth_change_password_krb5(LOGBOOK * lbs, const char *user, const char *old_pwd, const char *new_pwd,
char *error_str, int error_size)
{
char *princ_name, str[256], realm[256];
int result_code, n;
krb5_error_code error;
krb5_data result_code_string, result_string;
krb5_principal princ;
krb5_context context;
krb5_creds creds;
krb5_get_init_creds_opt options;
if (krb5_init_context(&context) < 0)
return FALSE;
strlcpy(str, user, sizeof(str));
if (getcfg(lbs->name, "Kerberos Realm", realm, sizeof(realm))) {
strlcat(str, "@", sizeof(str));
strlcat(str, realm, sizeof(str));
}
if ((error = krb5_parse_name(context, str, &princ)) != 0) {
strlcpy(error_str, "<b>Kerberos error:</b> ", error_size);
strlcat(error_str, krb5_get_error_message(context, error), error_size);
strlcat(error_str, ". Please check your Kerberos configuration.", error_size);
return FALSE;
}
error = krb5_unparse_name(context, princ, &princ_name);
sprintf(str, "Using %s as server principal for authentication", princ_name);
write_logfile(lbs, str);
memset(&options, 0, sizeof(options));
krb5_get_init_creds_opt_init(&options);
krb5_get_init_creds_opt_set_tkt_life(&options, 300);
krb5_get_init_creds_opt_set_forwardable(&options, FALSE);
krb5_get_init_creds_opt_set_proxiable(&options, FALSE);
memset(&creds, 0, sizeof(creds));
error = krb5_get_init_creds_password(context, &creds, princ,
(char *) old_pwd, NULL, NULL, 0, "kadmin/changepw", &options);
if (error) {
strlcpy(error_str, "<b>Kerberos error:</b> ", error_size);
strlcat(error_str, krb5_get_error_message(context, error), error_size);
strlcat(error_str, ". Please check your Kerberos configuration.", error_size);
return FALSE;
}
error = krb5_set_password(context, &creds, (char *) new_pwd, princ,
&result_code, &result_code_string, &result_string);
if (error) {
strlcpy(error_str, "<b>Kerberos error:</b> ", error_size);
strlcat(error_str, krb5_get_error_message(context, error), error_size);
strlcat(error_str, ". Please check your Kerberos configuration.", error_size);
return FALSE;
}
if (result_code > 0) {
if (result_code_string.length > 0) {
strlcpy(error_str, result_code_string.data, error_size);
if ((int) result_code_string.length < error_size)
error_str[result_code_string.length] = 0;
}
if (result_string.length > 0) {
strlcat(error_str, ": ", error_size);
n = strlen(error_str) + result_string.length;
strlcat(error_str, result_string.data, error_size);
if (n < error_size)
error_str[n] = 0;
}
}
krb5_free_data_contents(context, &result_code_string);
krb5_free_data_contents(context, &result_string);
krb5_free_cred_contents(context, &creds);
krb5_get_init_creds_opt_free(context, &options);
krb5_free_context(context);
if (result_code > 0)
return FALSE;
return TRUE;
}
#endif
/*---- LDAP routines ------------------------------------------*/
#ifdef HAVE_LDAP
int ldap_init(LOGBOOK *lbs, char *error_str, int error_size)
{
char str[512], ldap_server[256];
int version;
int bind=0;
// Read Config file
if (getcfg(lbs->name, "LDAP server", ldap_server, sizeof(ldap_server))) {
strlcpy(str, ldap_server, sizeof(str));
}
else {
strlcpy(error_str, "<b>LDAP initialization error</b> ", error_size);
strlcat(error_str, " Please check your LDAP configuration.", error_size);
strlcat(str, "ERR: Cannot find LDAP server entry!", sizeof(str));
write_logfile(lbs, str);
return FALSE;
}
if (!getcfg(lbs->name, "LDAP userbase", ldap_userbase, sizeof(ldap_userbase))) {
strlcpy(error_str, "<b>LDAP initialization error</b> ", error_size);
strlcat(error_str, " Please check your LDAP configuration.", error_size);
strlcat(str, ", ERR: Cannot find LDAP userbase (e.g. \'ou=People,dc=example,dc=org\')!", sizeof(str));
write_logfile(lbs, str);
return FALSE;
}
if (!getcfg(lbs->name, "LDAP login attribute", ldap_login_attr, sizeof(ldap_login_attr))) {
strlcpy(error_str, "<b>LDAP initialization error</b> ", error_size);
strlcat(error_str, " Please check your LDAP configuration.", error_size);
strlcat(str, ", ERR: Cannot find LDAP login attribute (e.g. uid, cn, ...)!", sizeof(str));
write_logfile(lbs, str);
return FALSE;
}
if (!getcfg(lbs->name, "LDAP DN User", ldap_dn_user, sizeof(ldap_dn_user))) {
strlcpy(error_str, "<b>LDAP initialization error</b> ", error_size);
strlcat(error_str, " Please check your LDAP configuration.", error_size);
strlcat(str, ", ERR: Cannot find LDAP login attribute (e.g. uid, cn, ...)!", sizeof(str));
write_logfile(lbs, str);
return FALSE;
}
if (!getcfg(lbs->name, "LDAP PW User", ldap_pw_user, sizeof(ldap_pw_user))) {
strlcpy(error_str, "<b>LDAP initialization error</b> ", error_size);
strlcat(error_str, " Please check your LDAP configuration.", error_size);
strlcat(str, ", ERR: Cannot find LDAP login attribute (e.g. uid, cn, ...)!", sizeof(str));
write_logfile(lbs, str);
return FALSE;
}
// Initialize/open LDAP connection
if(ldap_initialize( &ldap_ld, ldap_server )) {
perror("ldap_initialize");
strlcpy(error_str, "<b>LDAP initialization error</b> ", error_size);
strlcat(error_str, " Please check your LDAP configuration.", error_size);
return FALSE;
}
// Use the LDAP_OPT_PROTOCOL_VERSION session preference to specify that the client is LDAPv3 client
version = LDAP_VERSION3;
ldap_set_option(ldap_ld, LDAP_OPT_PROTOCOL_VERSION, &version);
write_logfile(lbs, str);
return TRUE;
}
int auth_verify_password_ldap(LOGBOOK *lbs, const char *user, const char *password, char *error_str,
int error_size)
{ LDAPMessage *result, *err, *entry;
int bind=0, i, rc=0, nb=0;
char str[512], filter[512];
char *attribute , *dn;
BerElement *ber;
BerValue **values;
ldap_ld = NULL;
memset(&ldap_bindDN[0], 0, sizeof(ldap_bindDN));
struct timeval timeOut = {3,0}; // 3 second connection/search timeout
// zerotime.tv_sec = zerotime.tv_usec = 0L;
if(!ldap_init(lbs,error_str,error_size)) {
strlcpy(error_str, "<b>LDAP initialization error</b> ", error_size);
strlcat(error_str, " Please check your LDAP configuration.", error_size);
return FALSE;
}
printf("\n dn: %s\n", ldap_dn_user );
//Bind with read account
bind = ldap_simple_bind_s(ldap_ld, ldap_dn_user, ldap_pw_user, LDAP_AUTH_SIMPLE);
if(bind != LDAP_SUCCESS) {
strlcpy(error_str, "<b>LDAP BIND error with read account</b> ", error_size);
strlcat(error_str, " Please check your LDAP configuration.", error_size);
return FALSE;
}
// search user
sprintf(filter, "(%s=%s)", ldap_login_attr, user);
rc = ldap_search_ext_s(
ldap_ld, // LDAP session handle
ldap_userbase, // Search Base
... 318 more lines ...
|