ISC DHCP
4.4.3-P1
A reference DHCPv4 and DHCPv6 implementation
Loading...
Searching...
No Matches
ldap_krb_helper.c
Go to the documentation of this file.
1
/* ldap_krb_helper.c
2
3
Helper routings for allowing LDAP to read configuration with GSSAPI/krb auth */
4
5
/*
6
* Copyright (c) 2015-2017 by Internet Systems Consortium, Inc. ("ISC")
7
* Copyright (c) 2014 William B.
8
* All rights reserved.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
*
14
* 1. Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
16
* 2. Redistributions in binary form must reproduce the above copyright
17
* notice, this list of conditions and the following disclaimer in the
18
* documentation and/or other materials provided with the distribution.
19
* 3. Neither the name of The Internet Software Consortium nor the names
20
* of its contributors may be used to endorse or promote products derived
21
* from this software without specific prior written permission.
22
*
23
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
24
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
28
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
31
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35
* SUCH DAMAGE.
36
*
37
* This helper was written by William Brown <william@adelaide.edu.au>,
38
* inspired by krb5_helper.c from bind-dyndb-ldap by Simo Sorce (Redhat)
39
*/
40
#if defined(LDAP_USE_GSSAPI)
41
42
#include "
dhcpd.h
"
43
#include "
ldap_krb_helper.h
"
44
45
#include <string.h>
46
#include <stdio.h>
47
#include <unistd.h>
48
#include <time.h>
49
50
#define KRB_DEFAULT_KEYTAB "FILE:/etc/dhcp/dhcp.keytab"
51
#define KRB_MIN_TIME 300
52
53
#define CHECK_KRB5(ctx, err, msg, ...) \
54
do { \
55
if (err) { \
56
const char * errmsg = krb5_get_error_message(ctx, err); \
57
log_error("Err: %s -> %s\n", msg, errmsg); \
58
result = ISC_R_FAILURE; \
59
goto cleanup; \
60
} \
61
} while (0)
62
63
#define CHECK(ret_code, msg) \
64
if (ret_code != 0) { \
65
log_error("Error, %i %s\n", ret_code, msg); \
66
goto cleanup; \
67
}
68
69
static
isc_result_t
70
check_credentials
(
krb5_context
context
,
krb5_ccache
ccache
,
krb5_principal
service
)
71
{
72
char
*
realm
=
NULL
;
73
krb5_creds
creds
;
74
krb5_creds
mcreds
;
75
krb5_error_code
krberr
;
76
krb5_timestamp
now
;
77
isc_result_t
result
=
ISC_R_FAILURE
;
78
79
memset
(&
mcreds
, 0,
sizeof
(
mcreds
));
80
memset
(&
creds
, 0,
sizeof
(
creds
));
81
82
krberr
=
krb5_get_default_realm
(
context
, &
realm
);
83
CHECK_KRB5
(
context
,
krberr
,
"Failed to retrieve default realm"
);
84
85
krberr
=
krb5_build_principal
(
context
, &
mcreds
.server,
86
strlen
(
realm
),
realm
,
87
"krbtgt"
,
realm
,
NULL
);
88
CHECK_KRB5
(
context
,
krberr
,
"Failed to build 'krbtgt/REALM' principal"
);
89
90
mcreds
.client =
service
;
91
92
krberr
=
krb5_cc_retrieve_cred
(
context
,
ccache
, 0, &
mcreds
, &
creds
);
93
94
if
(
krberr
) {
95
const
char
*
errmsg
=
krb5_get_error_message
(
context
,
krberr
);
96
log_error
(
"Credentials are not present in cache (%s)\n"
,
errmsg
);
97
krb5_free_error_message
(
context
,
errmsg
);
98
result
=
ISC_R_FAILURE
;
99
goto
cleanup
;
100
}
101
CHECK_KRB5
(
context
,
krberr
,
"Credentials are not present in cache "
);
102
103
krberr
=
krb5_timeofday
(
context
, &
now
);
104
CHECK_KRB5
(
context
,
krberr
,
"Failed to get time of day"
);
105
106
107
if
(
now
> (
creds
.times.endtime +
KRB_MIN_TIME
)) {
108
log_error
(
"Credentials cache expired"
);
109
result
=
ISC_R_FAILURE
;
110
goto
cleanup
;
111
}
else
{
112
char
buf[255];
113
char
fill
=
' '
;
114
krb5_timestamp_to_sfstring
(
creds
.times.endtime, buf, 16, &
fill
);
115
log_info
(
"Credentials valid til %s\n"
, buf);
116
}
117
118
result
=
ISC_R_SUCCESS
;
119
120
cleanup
:
121
krb5_free_cred_contents
(
context
, &
creds
);
122
if
(
mcreds
.server)
krb5_free_principal
(
context
,
mcreds
.server);
123
if
(
realm
)
krb5_free_default_realm
(
context
,
realm
);
124
return
result
;
125
}
126
127
isc_result_t
128
krb5_get_tgt
(
const
char
*
principal
,
const
char
*
keyfile
)
129
{
130
isc_result_t
result
=
ISC_R_FAILURE
;
131
char
*
ccname
=
NULL
;
132
krb5_context
context
=
NULL
;
133
krb5_error_code
krberr
;
134
krb5_ccache
ccache
=
NULL
;
135
krb5_principal
kprincpw
=
NULL
;
136
krb5_creds
my_creds
;
137
krb5_creds
*
my_creds_ptr
=
NULL
;
138
krb5_get_init_creds_opt
options;
139
krb5_keytab
keytab
=
NULL
;
140
int
ret
;
141
142
if
(
keyfile
==
NULL
||
keyfile
[0] ==
'\0'
) {
143
keyfile
=
KRB_DEFAULT_KEYTAB
;
144
log_info
(
"Using default keytab %s\n"
,
keyfile
);
145
}
else
{
146
if
(
strncmp
(
keyfile
,
"FILE:"
, 5) != 0) {
147
log_error
(
"Unknown keytab path format: Does it start with FILE:?\n"
);
148
return
ISC_R_FAILURE
;
149
}
150
}
151
152
krberr
=
krb5_init_context
(&
context
);
153
CHECK_KRB5
(
NULL
,
krberr
,
"Kerberos context initialization failed"
);
154
155
result
=
ISC_R_SUCCESS
;
156
157
ccname
=
"MEMORY:dhcp_ld_krb5_cc"
;
158
log_info
(
"Using ccache %s\n"
,
ccname
);
159
160
ret
=
setenv
(
"KRB5CCNAME"
,
ccname
, 1);
161
if
(
ret
== -1) {
162
log_error
(
"Failed to setup environment\n"
);
163
result
=
ISC_R_FAILURE
;
164
goto
cleanup
;
165
}
166
167
krberr
=
krb5_cc_resolve
(
context
,
ccname
, &
ccache
);
168
CHECK_KRB5
(
context
,
krberr
,
"Couldnt resolve ccache '%s'"
,
ccname
);
169
170
krberr
=
krb5_parse_name
(
context
,
principal
, &
kprincpw
);
171
CHECK_KRB5
(
context
,
krberr
,
"Failed to parse princ '%s'"
,
princpal
);
172
173
result
=
check_credentials
(
context
,
ccache
,
kprincpw
);
174
if
(
result
==
ISC_R_SUCCESS
) {
175
log_info
(
"Found valid kerberos credentials\n"
);
176
goto
cleanup
;
177
}
else
{
178
log_error
(
"No valid krb5 credentials\n"
);
179
}
180
181
krberr
=
krb5_kt_resolve
(
context
,
keyfile
, &
keytab
);
182
CHECK_KRB5
(
context
,
krberr
,
183
"Failed to resolve kt files '%s'\n"
,
keyfile
);
184
185
memset
(&
my_creds
, 0,
sizeof
(
my_creds
));
186
memset
(&options, 0,
sizeof
(options));
187
188
krb5_get_init_creds_opt_set_tkt_life
(&options,
KRB_MIN_TIME
* 2);
189
krb5_get_init_creds_opt_set_address_list
(&options,
NULL
);
190
krb5_get_init_creds_opt_set_forwardable
(&options, 0);
191
krb5_get_init_creds_opt_set_proxiable
(&options, 0);
192
193
krberr
=
krb5_get_init_creds_keytab
(
context
, &
my_creds
,
kprincpw
,
194
keytab
, 0,
NULL
, &options);
195
CHECK_KRB5
(
context
,
krberr
,
"Failed to get initial credentials TGT\n"
);
196
197
my_creds_ptr
= &
my_creds
;
198
199
krberr
=
krb5_cc_initialize
(
context
,
ccache
,
kprincpw
);
200
CHECK_KRB5
(
context
,
krberr
,
"Failed to init ccache\n"
);
201
202
krberr
=
krb5_cc_store_cred
(
context
,
ccache
, &
my_creds
);
203
CHECK_KRB5
(
context
,
krberr
,
"Failed to store credentials\n"
);
204
205
result
=
ISC_R_SUCCESS
;
206
log_info
(
"Successfully init krb tgt %s"
,
principal
);
207
208
cleanup
:
209
if
(
ccache
)
krb5_cc_close
(
context
,
ccache
);
210
if
(
keytab
)
krb5_kt_close
(
context
,
keytab
);
211
if
(
kprincpw
)
krb5_free_principal
(
context
,
kprincpw
);
212
if
(
my_creds_ptr
)
krb5_free_cred_contents
(
context
, &
my_creds
);
213
if
(
context
)
krb5_free_context
(
context
);
214
return
result
;
215
}
216
217
#endif
/* defined(LDAP_USE_GSSAPI) */
dhcpd.h
cur_time
#define cur_time
Definition
dhcpd.h:2126
cleanup
void cleanup(void)
ISC_R_SUCCESS
#define ISC_R_SUCCESS
ldap_krb_helper.h
log_error
int log_error(const char *,...) __attribute__((__format__(__printf__
log_info
int int log_info(const char *,...) __attribute__((__format__(__printf__
server
ldap_krb_helper.c
Generated on Wed Jul 19 2023 00:00:00 for ISC DHCP by
1.9.8