Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joe Martin
OpenLDAP
Commits
91be6bea
Commit
91be6bea
authored
Jan 03, 2011
by
Quanah Gibson-Mount
Browse files
contrib/kinit
parent
b032b5ea
Changes
3
Hide whitespace changes
Inline
Side-by-side
CHANGES
View file @
91be6bea
OpenLDAP 2.4 Change Log
OpenLDAP 2.4.24 Engineering
Added contrib/kinit for kerberos tickets
Added contrib/noopsrch for entry counting (ITS#6598)
Added slapadd attribute value checking (ITS#6592)
Added slapcat continue mode for problematic DBs (ITS#6482)
...
...
contrib/slapd-modules/kinit/README
0 → 100644
View file @
91be6bea
This directory contains the "kinit" slapd module. It is a simple plugin to
have slapd request a Kerberos TGT and keep it renewed as long as slapd is
running.
The current implementation has only been tested against the MIT variant of
the Kerberos libraries. (Heimdal support might come later)
To use the overlay just load it into the slapd process:
moduleload </path/to>/kinit.so <principal> </path/to/key.tab>
The module accepts two arguments. The first one being the principal for which
to request the TGT (it defaults to "ldap/<your hostname>@<DEFAULTREALM>")
and the second one is the path to the keytab file to use for
authentication, defaulting to whatever your system wide kerberos settings
default to).
Currently no Makefile is provided. The following commands should work to
build it from inside the unpacked slapd sources, provided the required KRB5
header files and libaries are installed on your system:
gcc -fPIC -c -I ../../../include/ -I ../../../servers/slapd kinit.c
gcc -shared -o kinit.so kinit.o -lkrb5
---
This work is part of OpenLDAP Software <http://www.openldap.org/>.
Copyright 2010 The OpenLDAP Foundation.
Redistribution and use in source and binary forms, with or without
modification, are permitted only as authorized by the OpenLDAP
Public License.
A copy of this license is available in the file LICENSE in the
top-level directory of the distribution or, alternatively, at
<http://www.OpenLDAP.org/license.html>.
contrib/slapd-modules/kinit/kinit.c
0 → 100644
View file @
91be6bea
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2010 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
#include
<portable.h>
#ifndef SLAPD_MOD_KINIT
#define SLAPD_MOD_KINIT SLAPD_MOD_DYNAMIC
#endif
#ifdef SLAPD_MOD_KINIT
#include
<slap.h>
#include
"ldap_rq.h"
#include
<ac/errno.h>
#include
<ac/string.h>
#include
<krb5/krb5.h>
typedef
struct
kinit_data
{
krb5_context
ctx
;
krb5_ccache
ccache
;
krb5_keytab
keytab
;
krb5_principal
princ
;
krb5_get_init_creds_opt
*
opts
;
}
kinit_data
;
static
char
*
principal
;
static
char
*
kt_name
;
static
kinit_data
*
kid
;
static
void
log_krb5_errmsg
(
krb5_context
ctx
,
const
char
*
func
,
krb5_error_code
rc
)
{
const
char
*
errmsg
=
krb5_get_error_message
(
ctx
,
rc
);
Log2
(
LDAP_DEBUG_ANY
,
LDAP_LEVEL_ERR
,
"slapd-kinit: %s: %s
\n
"
,
func
,
errmsg
);
krb5_free_error_message
(
ctx
,
errmsg
);
return
;
}
static
int
kinit_check_tgt
(
kinit_data
*
kid
,
int
*
remaining
)
{
int
ret
=
3
;
krb5_principal
princ
;
krb5_error_code
rc
;
krb5_cc_cursor
cursor
;
krb5_creds
creds
;
char
*
name
;
time_t
now
=
time
(
NULL
);
rc
=
krb5_cc_get_principal
(
kid
->
ctx
,
kid
->
ccache
,
&
princ
);
if
(
rc
)
{
log_krb5_errmsg
(
kid
->
ctx
,
"krb5_cc_get_principal"
,
rc
);
return
2
;
}
else
{
if
(
!
krb5_principal_compare
(
kid
->
ctx
,
kid
->
princ
,
princ
))
{
Log0
(
LDAP_DEBUG_ANY
,
LDAP_LEVEL_ERR
,
"Principal in ccache does not match requested principal
\n
"
);
krb5_free_principal
(
kid
->
ctx
,
princ
);
return
2
;
}
}
rc
=
krb5_cc_start_seq_get
(
kid
->
ctx
,
kid
->
ccache
,
&
cursor
);
if
(
rc
)
{
log_krb5_errmsg
(
kid
->
ctx
,
"krb5_cc_start_seq_get"
,
rc
);
krb5_free_principal
(
kid
->
ctx
,
princ
);
return
-
1
;
}
while
(
!
(
rc
=
krb5_cc_next_cred
(
kid
->
ctx
,
kid
->
ccache
,
&
cursor
,
&
creds
)))
{
if
(
krb5_is_config_principal
(
kid
->
ctx
,
creds
.
server
))
{
krb5_free_cred_contents
(
kid
->
ctx
,
&
creds
);
continue
;
}
if
(
creds
.
server
->
length
==
2
&&
(
!
strcmp
(
creds
.
server
->
data
[
0
].
data
,
"krbtgt"
))
&&
(
!
strcmp
(
creds
.
server
->
data
[
1
].
data
,
princ
->
realm
.
data
)))
{
krb5_unparse_name
(
kid
->
ctx
,
creds
.
server
,
&
name
);
*
remaining
=
(
time_t
)
creds
.
times
.
endtime
-
now
;
if
(
*
remaining
<=
0
)
{
Log1
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"kinit_qtask: TGT (%s) expired
\n
"
,
name
);
}
else
{
Log4
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"kinit_qtask: TGT (%s) expires in %dh:%02dm:%02ds
\n
"
,
name
,
*
remaining
/
3600
,
(
*
remaining
%
3600
)
/
60
,
*
remaining
%
60
);
}
free
(
name
);
if
(
*
remaining
<=
30
)
{
if
(
creds
.
times
.
renew_till
-
60
>
now
)
{
int
renewal
=
creds
.
times
.
renew_till
-
now
;
Log3
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"kinit_qtask: Time remaining for renewal: %dh:%02dm:%02ds
\n
"
,
renewal
/
3600
,
(
renewal
%
3600
)
/
60
,
renewal
%
60
);
ret
=
1
;
}
else
{
Log0
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"kinit_qtask: Only short time left for renewal. "
"Trying to re-init.
\n
"
);
ret
=
2
;
}
}
else
{
ret
=
0
;
}
krb5_free_cred_contents
(
kid
->
ctx
,
&
creds
);
break
;
}
krb5_free_cred_contents
(
kid
->
ctx
,
&
creds
);
}
krb5_cc_end_seq_get
(
kid
->
ctx
,
kid
->
ccache
,
&
cursor
);
krb5_free_principal
(
kid
->
ctx
,
princ
);
return
ret
;
}
void
*
kinit_qtask
(
void
*
ctx
,
void
*
arg
)
{
struct
re_s
*
rtask
=
arg
;
kinit_data
*
kid
=
(
kinit_data
*
)
rtask
->
arg
;
krb5_error_code
rc
;
krb5_creds
creds
;
int
nextcheck
,
remaining
,
renew
=
0
;
Log0
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"kinit_qtask: running TGT check
\n
"
);
memset
(
&
creds
,
0
,
sizeof
(
creds
));
renew
=
kinit_check_tgt
(
kid
,
&
remaining
);
if
(
renew
>
0
)
{
if
(
renew
==
1
)
{
Log0
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"kinit_qtask: Trying to renew TGT: "
);
rc
=
krb5_get_renewed_creds
(
kid
->
ctx
,
&
creds
,
kid
->
princ
,
kid
->
ccache
,
NULL
);
if
(
rc
!=
0
)
{
Log0
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"Failed
\n
"
);
log_krb5_errmsg
(
kid
->
ctx
,
"kinit_qtask, Renewal failed: krb5_get_renewed_creds"
,
rc
);
renew
++
;
}
else
{
Log0
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"Success
\n
"
);
krb5_cc_initialize
(
kid
->
ctx
,
kid
->
ccache
,
creds
.
client
);
krb5_cc_store_cred
(
kid
->
ctx
,
kid
->
ccache
,
&
creds
);
krb5_free_cred_contents
(
kid
->
ctx
,
&
creds
);
renew
=
kinit_check_tgt
(
kid
,
&
remaining
);
}
}
if
(
renew
>
1
)
{
Log0
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"kinit_qtask: Trying to get new TGT: "
);
rc
=
krb5_get_init_creds_keytab
(
kid
->
ctx
,
&
creds
,
kid
->
princ
,
kid
->
keytab
,
0
,
NULL
,
kid
->
opts
);
if
(
rc
)
{
Log0
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"Failed
\n
"
);
log_krb5_errmsg
(
kid
->
ctx
,
"krb5_get_init_creds_keytab"
,
rc
);
}
else
{
Log0
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"Success
\n
"
);
renew
=
kinit_check_tgt
(
kid
,
&
remaining
);
}
krb5_free_cred_contents
(
kid
->
ctx
,
&
creds
);
}
}
if
(
renew
==
0
)
{
nextcheck
=
remaining
-
30
;
}
else
{
nextcheck
=
60
;
}
ldap_pvt_thread_mutex_lock
(
&
slapd_rq
.
rq_mutex
);
if
(
ldap_pvt_runqueue_isrunning
(
&
slapd_rq
,
rtask
))
{
ldap_pvt_runqueue_stoptask
(
&
slapd_rq
,
rtask
);
}
Log3
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"kinit_qtask: Next TGT check in %dh:%02dm:%02ds
\n
"
,
nextcheck
/
3600
,
(
nextcheck
%
3600
)
/
60
,
nextcheck
%
60
);
rtask
->
interval
.
tv_sec
=
nextcheck
;
ldap_pvt_runqueue_resched
(
&
slapd_rq
,
rtask
,
0
);
slap_wake_listener
();
ldap_pvt_thread_mutex_unlock
(
&
slapd_rq
.
rq_mutex
);
return
NULL
;
}
int
kinit_initialize
(
void
)
{
Log0
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"kinit_initialize
\n
"
);
krb5_error_code
rc
;
struct
re_s
*
task
=
NULL
;
kid
=
ch_calloc
(
1
,
sizeof
(
kinit_data
)
);
rc
=
krb5_init_context
(
&
kid
->
ctx
);
if
(
!
rc
)
rc
=
krb5_cc_default
(
kid
->
ctx
,
&
kid
->
ccache
);
if
(
!
rc
)
{
if
(
!
principal
)
{
int
len
=
STRLENOF
(
"ldap/"
)
+
global_host_bv
.
bv_len
+
1
;
principal
=
ch_calloc
(
len
,
1
);
snprintf
(
principal
,
len
,
"ldap/%s"
,
global_host_bv
.
bv_val
);
Log1
(
LDAP_DEBUG_TRACE
,
LDAP_LEVEL_DEBUG
,
"Principal <%s>
\n
"
,
principal
);
}
rc
=
krb5_parse_name
(
kid
->
ctx
,
principal
,
&
kid
->
princ
);
}
if
(
!
rc
&&
kt_name
)
{
rc
=
krb5_kt_resolve
(
kid
->
ctx
,
kt_name
,
&
kid
->
keytab
);
}
if
(
!
rc
)
rc
=
krb5_get_init_creds_opt_alloc
(
kid
->
ctx
,
&
kid
->
opts
);
if
(
!
rc
)
rc
=
krb5_get_init_creds_opt_set_out_ccache
(
kid
->
ctx
,
kid
->
opts
,
kid
->
ccache
);
if
(
!
rc
)
{
ldap_pvt_thread_mutex_lock
(
&
slapd_rq
.
rq_mutex
);
task
=
ldap_pvt_runqueue_insert
(
&
slapd_rq
,
10
,
kinit_qtask
,
(
void
*
)
kid
,
"kinit_qtask"
,
"ldap/bronsted.g17.lan@G17.LAN"
);
ldap_pvt_thread_mutex_unlock
(
&
slapd_rq
.
rq_mutex
);
}
if
(
rc
)
{
log_krb5_errmsg
(
kid
->
ctx
,
"kinit_initialize"
,
rc
);
rc
=
-
1
;
}
return
rc
;
}
#if SLAPD_MOD_KINIT == SLAPD_MOD_DYNAMIC
int
init_module
(
int
argc
,
char
*
argv
[])
{
if
(
argc
>
0
)
{
principal
=
ch_strdup
(
argv
[
0
]);
}
if
(
argc
>
1
)
{
kt_name
=
ch_strdup
(
argv
[
1
]);
}
if
(
argc
>
2
)
{
return
-
1
;
}
return
kinit_initialize
();
}
int
term_module
()
{
if
(
principal
)
ch_free
(
principal
);
if
(
kt_name
)
ch_free
(
kt_name
);
if
(
kid
)
{
struct
re_s
*
task
;
task
=
ldap_pvt_runqueue_find
(
&
slapd_rq
,
kinit_qtask
,
(
void
*
)
kid
);
if
(
task
)
{
if
(
ldap_pvt_runqueue_isrunning
(
&
slapd_rq
,
task
)
)
{
ldap_pvt_runqueue_stoptask
(
&
slapd_rq
,
task
);
}
ldap_pvt_runqueue_remove
(
&
slapd_rq
,
task
);
}
if
(
kid
->
ctx
)
{
if
(
kid
->
princ
)
krb5_free_principal
(
kid
->
ctx
,
kid
->
princ
);
if
(
kid
->
ccache
)
krb5_cc_close
(
kid
->
ctx
,
kid
->
ccache
);
if
(
kid
->
keytab
)
krb5_kt_close
(
kid
->
ctx
,
kid
->
keytab
);
if
(
kid
->
opts
)
krb5_get_init_creds_opt_free
(
kid
->
ctx
,
kid
->
opts
);
krb5_free_context
(
kid
->
ctx
);
}
ch_free
(
kid
);
}
return
0
;
}
#endif
#endif
/* SLAPD_MOD_KINIT */
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment