1 /* 2 * Copyright 2007 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 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 /* We want the interfaces marked "deprecated" in OpenLDAP. */ 43 #define LDAP_DEPRECATED 1 44 #include <ldap.h> 45 46 /* Check for acceptable versions. 47 48 OpenLDAP version 2.2.6 is known to have some kind of problem that 49 is tickled by the use of multiple handles in this code. Version 50 2.2.19 in Mac OS 10.4.7 seems to be buggy as well. Version 2.2.24 51 doesn't have this problem. Other in-between versions have not been 52 tested. */ 53 #ifndef BUILD_WITH_BROKEN_LDAP 54 # if defined(LDAP_API_FEATURE_X_OPENLDAP) 55 # if LDAP_VENDOR_VERSION < 20224 56 # error This code triggers bugs in old OpenLDAP implementations. Please update to 2.2.24 or later. 57 # endif 58 # endif 59 #endif /* BUILD_WITH_BROKEN_LDAP */ 60 61 #include <k5-thread.h> 62 #include <k5-platform.h> /* Solaris Kerberos */ 63 #include <kdb5.h> 64 #include "k5-int.h" 65 #include "ldap_krbcontainer.h" 66 #include "ldap_realm.h" 67 68 extern struct timeval timelimit; 69 70 /* Solaris Kerberos: need this define to get around sccs keyword expansion */ 71 #define DATE_FORMAT "%Y" "%m" "%d" "%H" "%M" "%SZ" 72 73 #define SERV_COUNT 100 74 #define DEFAULT_CONNS_PER_SERVER 5 75 #define REALM_READ_REFRESH_INTERVAL (5 * 60) 76 77 #ifdef HAVE_EDIRECTORY 78 #define SECURITY_CONTAINER "cn=Security" 79 #define KERBEROS_CONTAINER "cn=Kerberos,cn=Security" 80 #endif 81 82 #if !defined(LDAP_OPT_RESULT_CODE) && defined(LDAP_OPT_ERROR_NUMBER) 83 #define LDAP_OPT_RESULT_CODE LDAP_OPT_ERROR_NUMBER 84 #endif 85 86 #define NEG(val) (val <0) ? abs(val) : -val ; 87 #define MAXINTLEN 10 88 89 #define IGNORE_STATUS 0 90 #define CHECK_STATUS 1 91 92 #define SETUP_CONTEXT() if (context == NULL || context->db_context == NULL \ 93 || ((kdb5_dal_handle *)context->db_context)->db_context == NULL) { \ 94 return EINVAL; \ 95 } \ 96 dal_handle = (kdb5_dal_handle *)context->db_context; \ 97 ldap_context = (krb5_ldap_context *) dal_handle->db_context; \ 98 if (ldap_context == NULL || ldap_context->server_info_list == NULL) \ 99 return KRB5_KDB_DBNOTINITED; 100 101 #define GET_HANDLE() ld = NULL; \ 102 st = krb5_ldap_request_handle_from_pool(ldap_context, &ldap_server_handle); \ 103 if (st != 0) { \ 104 prepend_err_str(context, "LDAP handle unavailable: ", KRB5_KDB_ACCESS_ERROR, st); \ 105 st = KRB5_KDB_ACCESS_ERROR; \ 106 goto cleanup; \ 107 } \ 108 ld = ldap_server_handle->ldap_handle; 109 110 extern int set_ldap_error (krb5_context ctx, int st, int op); 111 extern void prepend_err_str (krb5_context ctx, const char *s, krb5_error_code err, krb5_error_code oerr); 112 113 #define LDAP_SEARCH(base, scope, filter, attrs) LDAP_SEARCH_1(base, scope, filter, attrs, CHECK_STATUS) 114 115 #define LDAP_SEARCH_1(base, scope, filter, attrs, status_check) \ 116 do { \ 117 st = ldap_search_ext_s(ld, base, scope, filter, attrs, 0, NULL, NULL, &timelimit, LDAP_NO_LIMIT, &result); \ 118 if (translate_ldap_error(st, OP_SEARCH) == KRB5_KDB_ACCESS_ERROR) { \ 119 tempst = krb5_ldap_rebind(ldap_context, &ldap_server_handle); \ 120 if (ldap_server_handle) \ 121 ld = ldap_server_handle->ldap_handle; \ 122 } \ 123 }while (translate_ldap_error(st, OP_SEARCH) == KRB5_KDB_ACCESS_ERROR && tempst == 0); \ 124 \ 125 if (status_check != IGNORE_STATUS) { \ 126 if (tempst != 0) { \ 127 prepend_err_str(context, "LDAP handle unavailable: ", KRB5_KDB_ACCESS_ERROR, st); \ 128 st = KRB5_KDB_ACCESS_ERROR; \ 129 goto cleanup; \ 130 } \ 131 if (st != LDAP_SUCCESS) { \ 132 st = set_ldap_error(context, st, OP_SEARCH); \ 133 goto cleanup; \ 134 } \ 135 } 136 137 138 #define CHECK_CLASS_VALIDITY(st, mask, str) \ 139 if (st != 0 || mask == 0) { \ 140 if (st == 0 && mask == 0) { \ 141 st = set_ldap_error(context, LDAP_OBJECT_CLASS_VIOLATION, OP_SEARCH); \ 142 } \ 143 prepend_err_str(context, str, st, st); \ 144 goto cleanup; \ 145 } 146 147 #define CHECK_NULL(ptr) if (ptr == NULL) { \ 148 st = ENOMEM; \ 149 goto cleanup; \ 150 } 151 152 #define STORE16_INT(ptr, val) store_16_be(val, ptr) 153 #define STORE32_INT(ptr, val) store_32_be(val, ptr) 154 #define UNSTORE16_INT(ptr, val) (val = load_16_be(ptr)) 155 #define UNSTORE32_INT(ptr, val) (val = load_32_be(ptr)) 156 157 #define KRB5_CONF_KDC_BIND_DN "ldap_kdc_dn" 158 #define KRB5_CONF_ADMIN_BIND_DN "ldap_kadmind_dn" 159 #define KRB5_CONF_PWD_BIND_DN "ldap_passwd_dn" 160 161 #define KDB_TL_USER_INFO 0x7ffe 162 163 #define KDB_TL_PRINCTYPE 0x01 164 #define KDB_TL_PRINCCOUNT 0x02 165 #define KDB_TL_USERDN 0x03 166 #define KDB_TL_KEYINFO 0x04 167 #define KDB_TL_MASK 0x05 168 #define KDB_TL_CONTAINERDN 0x06 169 #define KDB_TL_LINKDN 0x07 170 171 172 #define CHECK_LDAP_HANDLE(lcontext) if (!(ldap_context \ 173 && ldap_context->server_info_list)) { \ 174 return KRB5_KDB_DBNOTINITED; \ 175 } 176 177 #define HNDL_LOCK(lcontext) k5_mutex_lock(&lcontext->hndl_lock) 178 #define HNDL_UNLOCK(lcontext) k5_mutex_unlock(&lcontext->hndl_lock) 179 180 /* To be used later */ 181 typedef struct _krb5_ldap_certificates{ 182 char *certificate; 183 int certtype; 184 }krb5_ldap_certificates; 185 186 /* ldap server info structure */ 187 188 typedef enum _server_type {PRIMARY, SECONDARY} krb5_ldap_server_type; 189 190 typedef enum _server_status {OFF, ON, NOTSET} krb5_ldap_server_status; 191 192 typedef struct _krb5_ldap_server_info krb5_ldap_server_info; 193 194 typedef struct _krb5_ldap_server_handle { 195 int msgid; 196 LDAP *ldap_handle; 197 krb5_boolean server_info_update_pending; 198 krb5_ldap_server_info *server_info; 199 struct _krb5_ldap_server_handle *next; 200 } krb5_ldap_server_handle; 201 202 struct _krb5_ldap_server_info { 203 krb5_ldap_server_type server_type; 204 krb5_ldap_server_status server_status; 205 krb5_ui_4 num_conns; 206 krb5_ldap_server_handle *ldap_server_handles; 207 time_t downtime; 208 char *server_name; 209 #ifdef HAVE_EDIRECTORY 210 char *root_certificate_file; 211 #endif 212 struct _krb5_ldap_server_info *next; 213 }; 214 215 216 /* ldap server structure */ 217 218 typedef enum {SERVICE_DN_TYPE_SERVER, SERVICE_DN_TYPE_CLIENT} krb5_ldap_servicetype; 219 220 typedef struct _krb5_ldap_context { 221 krb5_ldap_servicetype service_type; 222 krb5_ldap_server_info **server_info_list; 223 krb5_ui_4 max_server_conns; 224 char *conf_section; 225 char *bind_dn; 226 char *bind_pwd; 227 char *service_password_file; 228 char *root_certificate_file; 229 char *service_cert_path; 230 char *service_cert_pass; 231 krb5_ldap_certificates **certificates; 232 krb5_ui_4 cert_count; /* certificate count */ 233 k5_mutex_t hndl_lock; 234 krb5_ldap_krbcontainer_params *krbcontainer; 235 krb5_ldap_realm_params *lrparams; 236 krb5_context kcontext; /* to set the error code and message */ 237 } krb5_ldap_context; 238 239 240 typedef struct { 241 int nkey; 242 struct berval **keys; 243 }KEY; 244 245 #define k5ldap_inited(c) (c && c->db_context \ 246 && ((kdb5_dal_handle*)c->db_context)->db_context \ 247 && ((krb5_ldap_context *) ((kdb5_dal_handle*)c->db_context)->db_context)) 248 249 250 /* misc functions */ 251 252 krb5_error_code 253 krb5_ldap_db_init(krb5_context, krb5_ldap_context *); 254 255 krb5_error_code 256 krb5_ldap_db_single_init(krb5_ldap_context *); 257 258 krb5_error_code 259 krb5_ldap_rebind(krb5_ldap_context *, krb5_ldap_server_handle **); 260 261 krb5_error_code 262 krb5_ldap_db_get_age(krb5_context, char *, time_t *); 263 264 krb5_error_code 265 krb5_ldap_lib_init(void); 266 267 krb5_error_code 268 krb5_ldap_lib_cleanup(void); 269 270 void * 271 krb5_ldap_alloc( krb5_context kcontext, void *ptr, size_t size ); 272 273 void 274 krb5_ldap_free( krb5_context kcontext, void *ptr ); 275 krb5_error_code 276 krb5_ldap_get_mkey(krb5_context, krb5_keyblock **); 277 278 krb5_error_code 279 krb5_ldap_set_mkey(krb5_context, char *, krb5_keyblock *); 280 281 krb5_error_code 282 krb5_ldap_create(krb5_context , char *, char **); 283 284 krb5_error_code 285 krb5_ldap_open( krb5_context , char *, 286 char **db_args, 287 int mode ); 288 krb5_error_code 289 krb5_ldap_close( krb5_context ); 290 291 krb5_error_code 292 krb5_ldap_free_ldap_context(krb5_ldap_context *); 293 294 krb5_error_code 295 krb5_ldap_read_startup_information(krb5_context ); 296 297 int 298 has_sasl_external_mech(krb5_context, char *); 299 300 /* DAL functions */ 301 302 303 krb5_error_code 304 krb5_ldap_set_option( krb5_context, int, void * ); 305 306 krb5_error_code 307 krb5_ldap_lock( krb5_context, int ); 308 309 krb5_error_code 310 krb5_ldap_unlock( krb5_context ); 311 312 krb5_error_code 313 krb5_ldap_supported_realms( krb5_context, char ** ); 314 315 krb5_error_code 316 krb5_ldap_free_supported_realms( krb5_context, char ** ); 317 318 const char * 319 krb5_ldap_errcode_2_string( krb5_context, long ); 320 321 void 322 krb5_ldap_release_errcode_string (krb5_context, const char *); 323 324 #ifndef HAVE_LDAP_INITIALIZE 325 /* Solaris Kerberos: added a use_SSL parameter */ 326 int 327 ldap_initialize(LDAP **, char *, int, char **); 328 #endif 329 #ifndef HAVE_LDAP_UNBIND_EXT_S 330 int 331 ldap_unbind_ext_s(LDAP *, LDAPControl **, LDAPControl **); 332 #endif 333 334 #endif 335