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