xref: /freebsd/crypto/krb5/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h */
3 /*
4  * Copyright (c) 2004-2005, Novell, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  *   * Redistributions of source code must retain the above copyright notice,
11  *       this list of conditions and the following disclaimer.
12  *   * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in the
14  *       documentation and/or other materials provided with the distribution.
15  *   * The copyright holder's name is not used to endorse or promote products
16  *       derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /* */
32 #ifndef _KDB_LDAP_H
33 #define _KDB_LDAP_H 1
34 
35 #include "k5-int.h"
36 #include <k5-thread.h>
37 #include <kdb5.h>
38 #include "ldap_krbcontainer.h"
39 #include "ldap_realm.h"
40 
41 /* We want the interfaces marked "deprecated" in OpenLDAP.  */
42 #define LDAP_DEPRECATED 1
43 #include <ldap.h>
44 
45 /* Check for acceptable versions.
46 
47    OpenLDAP version 2.2.6 is known to have some kind of problem that
48    is tickled by the use of multiple handles in this code.  Version
49    2.2.19 in Mac OS 10.4.7 seems to be buggy as well.  Version 2.2.24
50    doesn't have this problem.  Other in-between versions have not been
51    tested.  */
52 #ifndef BUILD_WITH_BROKEN_LDAP
53 # if defined(LDAP_API_FEATURE_X_OPENLDAP)
54 #  if LDAP_VENDOR_VERSION < 20224
55 #   error This code triggers bugs in old OpenLDAP implementations.  Please update to 2.2.24 or later.
56 #  endif
57 # endif
58 #endif /* BUILD_WITH_BROKEN_LDAP */
59 
60 extern struct timeval timelimit;
61 
62 #define  DEFAULT_CONNS_PER_SERVER    5
63 #define  REALM_READ_REFRESH_INTERVAL (5 * 60)
64 
65 #if !defined(LDAP_OPT_RESULT_CODE) && defined(LDAP_OPT_ERROR_NUMBER)
66 #define LDAP_OPT_RESULT_CODE LDAP_OPT_ERROR_NUMBER
67 #endif
68 
69 #define MAXINTLEN  10
70 
71 #define IGNORE_STATUS              0
72 #define CHECK_STATUS               1
73 
74 #define SETUP_CONTEXT() if (context == NULL || context->dal_handle == NULL \
75                             || context->dal_handle->db_context == NULL) { \
76         return EINVAL;                                                  \
77     }                                                                   \
78     dal_handle = context->dal_handle;                                   \
79     ldap_context = (krb5_ldap_context *) dal_handle->db_context;        \
80     if (ldap_context == NULL || ldap_context->server_info_list == NULL) \
81         return KRB5_KDB_DBNOTINITED;
82 
83 #define GET_HANDLE()  ld = NULL;                                        \
84     st = krb5_ldap_request_handle_from_pool(ldap_context, &ldap_server_handle); \
85     if (st != 0) {                                                      \
86         k5_wrapmsg(context, st, KRB5_KDB_ACCESS_ERROR,                  \
87                    "LDAP handle unavailable");                          \
88         st = KRB5_KDB_ACCESS_ERROR;                                     \
89         goto cleanup;                                                   \
90     }                                                                   \
91     ld = ldap_server_handle->ldap_handle;
92 
93 extern int set_ldap_error (krb5_context ctx, int st, int op);
94 
95 #define LDAP_SEARCH(base, scope, filter, attrs)   LDAP_SEARCH_1(base, scope, filter, attrs, CHECK_STATUS)
96 
97 #define LDAP_SEARCH_1(base, scope, filter, attrs, status_check)         \
98     tempst = 0;                                                         \
99     st = ldap_search_ext_s(ld, base, scope, filter, attrs, 0, NULL,     \
100                            NULL, &timelimit, LDAP_NO_LIMIT, &result);   \
101     if (translate_ldap_error(st, OP_SEARCH) == KRB5_KDB_ACCESS_ERROR) { \
102         tempst = krb5_ldap_rebind(ldap_context, &ldap_server_handle);   \
103         if (ldap_server_handle)                                         \
104             ld = ldap_server_handle->ldap_handle;                       \
105         if (tempst == 0)                                                \
106             st = ldap_search_ext_s(ld, base, scope, filter, attrs, 0,   \
107                                    NULL, NULL, &timelimit,              \
108                                    LDAP_NO_LIMIT, &result);             \
109     }                                                                   \
110                                                                         \
111     if (status_check != IGNORE_STATUS) {                                \
112         if (tempst != 0) {                                              \
113             k5_wrapmsg(context, st, KRB5_KDB_ACCESS_ERROR,              \
114                        "LDAP handle unavailable");                      \
115             st = KRB5_KDB_ACCESS_ERROR;                                 \
116             goto cleanup;                                               \
117         }                                                               \
118         if (st != LDAP_SUCCESS) {                                       \
119             st = set_ldap_error(context, st, OP_SEARCH);                \
120             goto cleanup;                                               \
121         }                                                               \
122     }
123 
124 
125 #define CHECK_CLASS_VALIDITY(st, mask, str)                             \
126     if (st != 0 || mask == 0) {                                         \
127         if (st == 0 && mask == 0) {                                     \
128             st = set_ldap_error(context, LDAP_OBJECT_CLASS_VIOLATION, OP_SEARCH); \
129         }                                                               \
130         k5_prependmsg(context, st, str);                                \
131         goto cleanup;                                                   \
132     }
133 
134 #define CHECK_NULL(ptr) if (ptr == NULL) {      \
135         st = ENOMEM;                            \
136         goto cleanup;                           \
137     }
138 
139 #define  STORE16_INT(ptr, val)  store_16_be(val, ptr)
140 #define  STORE32_INT(ptr, val)  store_32_be(val, ptr)
141 #define UNSTORE16_INT(ptr, val) (val = load_16_be(ptr))
142 #define UNSTORE32_INT(ptr, val) (val = load_32_be(ptr))
143 
144 #define  KDB_TL_USER_INFO      0xff
145 
146 #define KDB_TL_PRINCTYPE          0x01
147 #define KDB_TL_PRINCCOUNT         0x02
148 #define KDB_TL_USERDN             0x03
149 #define KDB_TL_KEYINFO            0x04
150 #define KDB_TL_MASK               0x05
151 /* 0x06 was KDB_TL_CONTAINERDN but is no longer used */
152 #define KDB_TL_LINKDN             0x07
153 
154 
155 #define CHECK_LDAP_HANDLE(lcontext)     if (!(ldap_context              \
156                                               && ldap_context->server_info_list)) { \
157         return KRB5_KDB_DBNOTINITED;                                    \
158     }
159 
160 #define HNDL_LOCK(lcontext) k5_mutex_lock(&lcontext->hndl_lock)
161 #define HNDL_UNLOCK(lcontext) k5_mutex_unlock(&lcontext->hndl_lock)
162 
163 /* ldap server info structure */
164 
165 typedef enum _server_type {PRIMARY, SECONDARY} krb5_ldap_server_type;
166 
167 typedef enum _server_status {OFF, ON, NOTSET} krb5_ldap_server_status;
168 
169 typedef struct _krb5_ldap_server_info krb5_ldap_server_info;
170 
171 typedef struct  _krb5_ldap_server_handle {
172     int                              msgid;
173     LDAP                             *ldap_handle;
174     krb5_ldap_server_info            *server_info;
175     struct _krb5_ldap_server_handle  *next;
176 } krb5_ldap_server_handle;
177 
178 struct _krb5_ldap_server_info {
179     krb5_ldap_server_type        server_type;
180     krb5_ldap_server_status      server_status;
181     krb5_ui_4                    num_conns;
182     krb5_ldap_server_handle      *ldap_server_handles;
183     time_t                       downtime;
184     char                        *server_name;
185     int                          modify_increment;
186     struct _krb5_ldap_server_info *next;
187 };
188 
189 
190 /* ldap server structure */
191 
192 typedef enum {SERVICE_DN_TYPE_SERVER, SERVICE_DN_TYPE_CLIENT} krb5_ldap_servicetype;
193 
194 typedef struct _krb5_ldap_context {
195     krb5_ldap_servicetype         service_type;
196     krb5_ldap_server_info         **server_info_list;
197     krb5_ui_4                     max_server_conns;
198     char                          *conf_section;
199     char                          *bind_dn;
200     char                          *bind_pwd;
201     char                          *service_password_file;
202     char                          *sasl_mech;
203     char                          *sasl_authcid;
204     char                          *sasl_authzid;
205     char                          *sasl_realm;
206     char                          *root_certificate_file;
207     krb5_ui_4                     cert_count; /* certificate count */
208     k5_mutex_t                    hndl_lock;
209     char                          *container_dn;
210     krb5_ldap_realm_params        *lrparams;
211     krb5_boolean                  disable_last_success;
212     krb5_boolean                  disable_lockout;
213     int                           ldap_debug;
214     krb5_context                  kcontext;   /* to set the error code and message */
215 } krb5_ldap_context;
216 
217 
218 typedef struct {
219     int           nkey;
220     struct berval **keys;
221 }KEY;
222 
223 #define k5ldap_inited(c) (c && c->db_context                            \
224                           && ((kdb5_dal_handle*)c->db_context)->db_context \
225                           && ((krb5_ldap_context *) ((kdb5_dal_handle*)c->db_context)->db_context))
226 
227 
228 /* misc functions */
229 
230 krb5_error_code
231 krb5_ldap_db_init(krb5_context, krb5_ldap_context *);
232 
233 krb5_error_code
234 krb5_ldap_db_single_init(krb5_ldap_context *);
235 
236 krb5_error_code
237 krb5_ldap_rebind(krb5_ldap_context *, krb5_ldap_server_handle **);
238 
239 krb5_error_code
240 krb5_ldap_get_age(krb5_context, char *, time_t *);
241 
242 krb5_error_code
243 krb5_ldap_lib_init(void);
244 
245 krb5_error_code
246 krb5_ldap_lib_cleanup(void);
247 
248 void *
249 krb5_ldap_alloc( krb5_context kcontext,  void *ptr, size_t size );
250 
251 void
252 krb5_ldap_free( krb5_context kcontext, void *ptr );
253 
254 krb5_error_code
255 krb5_ldap_create(krb5_context , char *, char **);
256 
257 krb5_error_code
258 krb5_ldap_open( krb5_context , char *,
259                 char **db_args,
260                 int mode );
261 krb5_error_code
262 krb5_ldap_close( krb5_context );
263 
264 krb5_error_code
265 krb5_ldap_free_ldap_context(krb5_ldap_context *);
266 
267 krb5_error_code
268 krb5_ldap_read_startup_information(krb5_context );
269 
270 krb5_boolean
271 has_modify_increment(krb5_context, const char *);
272 
273 void
274 krb5_ldap_free_server_context_params(krb5_ldap_context *ldap_context);
275 
276 krb5_error_code
277 krb5_ldap_check_policy_as(krb5_context kcontext, krb5_kdc_req *request,
278                           krb5_db_entry *client, krb5_db_entry *server,
279                           krb5_timestamp kdc_time, const char **status,
280                           krb5_pa_data ***e_data);
281 
282 void
283 krb5_ldap_audit_as_req(krb5_context kcontext, krb5_kdc_req *request,
284                        const krb5_address *local_addr,
285                        const krb5_address *remote_addr, krb5_db_entry *client,
286                        krb5_db_entry *server, krb5_timestamp authtime,
287                        krb5_error_code error_code);
288 
289 krb5_error_code
290 krb5_ldap_check_allowed_to_delegate(krb5_context context,
291                                     krb5_const_principal client,
292                                     const krb5_db_entry *server,
293                                     krb5_const_principal proxy);
294 
295 /* DAL functions */
296 
297 
298 krb5_error_code
299 krb5_ldap_lock( krb5_context, int );
300 
301 krb5_error_code
302 krb5_ldap_unlock( krb5_context );
303 
304 /* lockout.c */
305 krb5_error_code
306 krb5_ldap_lockout_check_policy(krb5_context context,
307                                krb5_db_entry *entry,
308                                krb5_timestamp stamp);
309 
310 krb5_error_code
311 krb5_ldap_lockout_audit(krb5_context context,
312                         krb5_db_entry *entry,
313                         krb5_timestamp stamp,
314                         krb5_error_code status);
315 
316 #endif
317