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