The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
krb5.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 83b6aa2e43b5cc2505baef721ca78f8de08d46d4 $
19 * @file krb5.h
20 * @brief Context management functions for rlm_krb5
21 *
22 * @copyright 2013 The FreeRADIUS server project
23 * @copyright 2013 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 */
25RCSID("$Id: 83b6aa2e43b5cc2505baef721ca78f8de08d46d4 $")
26
27#define LOG_PREFIX inst->name
28
29#include <freeradius-devel/util/debug.h>
30#include <freeradius-devel/server/base.h>
31#include "krb5.h"
32
33#ifdef HAVE_KRB5_GET_ERROR_MESSAGE
34# define KRB5_STRERROR_BUFSIZE (2048)
35
36static _Thread_local char *krb5_error_buffer;
37
38/*
39 * Explicitly cleanup the memory allocated to the error buffer.
40 */
41static int _krb5_logging_free(void *arg)
42{
43 return talloc_free(arg);
44}
45
46char const *rlm_krb5_error(rlm_krb5_t const *inst, krb5_context context, krb5_error_code code)
47{
48 char const *msg;
49 char *buffer;
50
51 if (!fr_cond_assert(inst)) return NULL;
52
53 buffer = krb5_error_buffer;
54 if (!buffer) {
55 buffer = talloc_array(NULL, char, KRB5_STRERROR_BUFSIZE);
56 if (!buffer) {
57 ERROR("Failed allocating memory for krb5 error buffer");
58 return NULL;
59 }
60
61 fr_atexit_thread_local(krb5_error_buffer, _krb5_logging_free, buffer);
62 }
63
64 msg = krb5_get_error_message(context, code);
65 if (msg) {
66 strlcpy(buffer, msg, KRB5_STRERROR_BUFSIZE);
67# ifdef HAVE_KRB5_FREE_ERROR_MESSAGE
68 krb5_free_error_message(context, msg);
69# elif defined(HAVE_KRB5_FREE_ERROR_STRING)
70 krb5_free_error_string(context, UNCONST(char *, msg));
71# else
72# error "No way to free error strings, missing krb5_free_error_message() and krb5_free_error_string()"
73# endif
74 } else {
75 strlcpy(buffer, "Unknown error", KRB5_STRERROR_BUFSIZE);
76 }
77
78 return buffer;
79}
80#endif
81
82/** Frees libkrb5 resources associated with the handle
83 *
84 * Must not be called directly.
85 *
86 * @param conn to free.
87 * @return 0 (always indicates success).
88 */
90 krb5_free_context(conn->context);
91
92 if (conn->keytab) krb5_kt_close(conn->context, conn->keytab);
93
94#ifdef HEIMDAL_KRB5
95 if (conn->ccache) krb5_cc_destroy(conn->context, conn->ccache);
96#endif
97
98 return 0;
99}
100
102{
104 krb5_error_code ret;
105
106 ret = krb5_init_context(&conn->context);
107 if (ret) {
108 ERROR("Context initialisation failed: %s", rlm_krb5_error(inst, NULL, ret));
109 return -1;
110 }
111 talloc_set_destructor(conn, _mod_conn_free);
112
113 ret = inst->keytabname ?
114 krb5_kt_resolve(conn->context, inst->keytabname, &conn->keytab) :
115 krb5_kt_default(conn->context, &conn->keytab);
116 if (ret) {
117 ERROR("Resolving keytab failed: %s", rlm_krb5_error(inst, conn->context, ret));
118 return -1;
119 }
120
121#ifdef HEIMDAL_KRB5
122 ret = krb5_cc_new_unique(conn->context, "MEMORY", NULL, &conn->ccache);
123 if (ret) {
124 ERROR("Credential cache creation failed: %s", rlm_krb5_error(inst, conn->context, ret));
125 return -1;
126 }
127
128 krb5_verify_opt_init(&conn->options);
129 krb5_verify_opt_set_ccache(&conn->options, conn->ccache);
130
131 krb5_verify_opt_set_keytab(&conn->options, conn->keytab);
132 krb5_verify_opt_set_secure(&conn->options, true);
133
134 if (inst->service) krb5_verify_opt_set_service(&conn->options, inst->service);
135#endif
136 return 0;
137}
138
139/** Create and return a new connection
140 *
141 * libkrb5(s) can talk to the KDC over TCP. Were assuming something sane is implemented
142 * by libkrb5 and that it does connection caching associated with contexts, so it's
143 * worth using a connection pool to preserve connections when workers die.
144 */
145void *krb5_mod_conn_create(TALLOC_CTX *ctx, void *instance, UNUSED fr_time_delta_t timeout)
146{
147 rlm_krb5_t *inst = talloc_get_type_abort(instance, rlm_krb5_t);
148 rlm_krb5_handle_t *conn;
149
150 MEM(conn = talloc_zero(ctx, rlm_krb5_handle_t));
151
152 if (krb5_handle_init(conn, inst) < 0) {
153 talloc_free(conn);
154 return NULL;
155 }
156
157 return conn;
158}
static int const char char buffer[256]
Definition acutest.h:576
log_entry msg
Definition acutest.h:794
#define fr_atexit_thread_local(_name, _free, _uctx)
Definition atexit.h:221
static int context
Definition radmin.c:71
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:167
#define RCSID(id)
Definition build.h:483
#define UNUSED
Definition build.h:315
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:139
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:41
int krb5_handle_init(rlm_krb5_handle_t *conn, void *uctx)
Definition krb5.c:101
void * krb5_mod_conn_create(TALLOC_CTX *ctx, void *instance, UNUSED fr_time_delta_t timeout)
Create and return a new connection.
Definition krb5.c:145
static int _mod_conn_free(rlm_krb5_handle_t *conn)
Frees libkrb5 resources associated with the handle.
Definition krb5.c:89
Context management functions for rlm_krb5.
krb5_keytab keytab
Definition krb5.h:38
#define rlm_krb5_error(_x, _y, _z)
Definition krb5.h:99
krb5_context context
Definition krb5.h:37
Instance configuration for rlm_krb5.
Definition krb5.h:50
talloc_free(reap)
eap_aka_sim_process_conf_t * inst
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition strlcpy.c:34
#define talloc_get_type_abort_const
Definition talloc.h:282
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80