154925bf6Swillf /* 2159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 354925bf6Swillf * Use is subject to license terms. 454925bf6Swillf */ 554925bf6Swillf 654925bf6Swillf /* 754925bf6Swillf * lib/kdb/kdb_ldap/kdb_ldap.h 854925bf6Swillf * 954925bf6Swillf * Copyright (c) 2004-2005, Novell, Inc. 1054925bf6Swillf * All rights reserved. 1154925bf6Swillf * 1254925bf6Swillf * Redistribution and use in source and binary forms, with or without 1354925bf6Swillf * modification, are permitted provided that the following conditions are met: 1454925bf6Swillf * 1554925bf6Swillf * * Redistributions of source code must retain the above copyright notice, 1654925bf6Swillf * this list of conditions and the following disclaimer. 1754925bf6Swillf * * Redistributions in binary form must reproduce the above copyright 1854925bf6Swillf * notice, this list of conditions and the following disclaimer in the 1954925bf6Swillf * documentation and/or other materials provided with the distribution. 2054925bf6Swillf * * The copyright holder's name is not used to endorse or promote products 2154925bf6Swillf * derived from this software without specific prior written permission. 2254925bf6Swillf * 2354925bf6Swillf * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2454925bf6Swillf * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2554925bf6Swillf * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2654925bf6Swillf * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2754925bf6Swillf * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2854925bf6Swillf * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2954925bf6Swillf * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3054925bf6Swillf * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3154925bf6Swillf * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3254925bf6Swillf * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3354925bf6Swillf * POSSIBILITY OF SUCH DAMAGE. 3454925bf6Swillf */ 3554925bf6Swillf 3654925bf6Swillf /* */ 3754925bf6Swillf #ifndef _KDB_LDAP_H 3854925bf6Swillf #define _KDB_LDAP_H 1 3954925bf6Swillf 4054925bf6Swillf /* We want the interfaces marked "deprecated" in OpenLDAP. */ 4154925bf6Swillf #define LDAP_DEPRECATED 1 4254925bf6Swillf #include <ldap.h> 4354925bf6Swillf 4454925bf6Swillf /* Check for acceptable versions. 4554925bf6Swillf 4654925bf6Swillf OpenLDAP version 2.2.6 is known to have some kind of problem that 4754925bf6Swillf is tickled by the use of multiple handles in this code. Version 4854925bf6Swillf 2.2.19 in Mac OS 10.4.7 seems to be buggy as well. Version 2.2.24 4954925bf6Swillf doesn't have this problem. Other in-between versions have not been 5054925bf6Swillf tested. */ 5154925bf6Swillf #ifndef BUILD_WITH_BROKEN_LDAP 5254925bf6Swillf # if defined(LDAP_API_FEATURE_X_OPENLDAP) 5354925bf6Swillf # if LDAP_VENDOR_VERSION < 20224 5454925bf6Swillf # error This code triggers bugs in old OpenLDAP implementations. Please update to 2.2.24 or later. 5554925bf6Swillf # endif 5654925bf6Swillf # endif 5754925bf6Swillf #endif /* BUILD_WITH_BROKEN_LDAP */ 5854925bf6Swillf 5954925bf6Swillf #include <k5-thread.h> 6054925bf6Swillf #include <k5-platform.h> /* Solaris Kerberos */ 61159d09a2SMark Phalan #include <k5-platform-store_16.h> 62159d09a2SMark Phalan #include <k5-platform-store_32.h> 63159d09a2SMark Phalan #include <k5-platform-load_16.h> 64159d09a2SMark Phalan #include <k5-platform-load_32.h> 65159d09a2SMark Phalan 6654925bf6Swillf #include <kdb5.h> 6754925bf6Swillf #include "k5-int.h" 6854925bf6Swillf #include "ldap_krbcontainer.h" 6954925bf6Swillf #include "ldap_realm.h" 7054925bf6Swillf 7154925bf6Swillf extern struct timeval timelimit; 7254925bf6Swillf 7354925bf6Swillf /* Solaris Kerberos: need this define to get around sccs keyword expansion */ 7454925bf6Swillf #define DATE_FORMAT "%Y" "%m" "%d" "%H" "%M" "%SZ" 7554925bf6Swillf 7654925bf6Swillf #define SERV_COUNT 100 7754925bf6Swillf #define DEFAULT_CONNS_PER_SERVER 5 7854925bf6Swillf #define REALM_READ_REFRESH_INTERVAL (5 * 60) 7954925bf6Swillf 8054925bf6Swillf #ifdef HAVE_EDIRECTORY 8154925bf6Swillf #define SECURITY_CONTAINER "cn=Security" 8254925bf6Swillf #define KERBEROS_CONTAINER "cn=Kerberos,cn=Security" 8354925bf6Swillf #endif 8454925bf6Swillf 8554925bf6Swillf #if !defined(LDAP_OPT_RESULT_CODE) && defined(LDAP_OPT_ERROR_NUMBER) 8654925bf6Swillf #define LDAP_OPT_RESULT_CODE LDAP_OPT_ERROR_NUMBER 8754925bf6Swillf #endif 8854925bf6Swillf 8954925bf6Swillf #define NEG(val) (val <0) ? abs(val) : -val ; 9054925bf6Swillf #define MAXINTLEN 10 9154925bf6Swillf 9254925bf6Swillf #define IGNORE_STATUS 0 9354925bf6Swillf #define CHECK_STATUS 1 9454925bf6Swillf 9554925bf6Swillf #define SETUP_CONTEXT() if (context == NULL || context->db_context == NULL \ 9654925bf6Swillf || ((kdb5_dal_handle *)context->db_context)->db_context == NULL) { \ 9754925bf6Swillf return EINVAL; \ 9854925bf6Swillf } \ 9954925bf6Swillf dal_handle = (kdb5_dal_handle *)context->db_context; \ 10054925bf6Swillf ldap_context = (krb5_ldap_context *) dal_handle->db_context; \ 10154925bf6Swillf if (ldap_context == NULL || ldap_context->server_info_list == NULL) \ 10254925bf6Swillf return KRB5_KDB_DBNOTINITED; 10354925bf6Swillf 10454925bf6Swillf #define GET_HANDLE() ld = NULL; \ 10554925bf6Swillf st = krb5_ldap_request_handle_from_pool(ldap_context, &ldap_server_handle); \ 10654925bf6Swillf if (st != 0) { \ 10754925bf6Swillf prepend_err_str(context, "LDAP handle unavailable: ", KRB5_KDB_ACCESS_ERROR, st); \ 10854925bf6Swillf st = KRB5_KDB_ACCESS_ERROR; \ 10954925bf6Swillf goto cleanup; \ 11054925bf6Swillf } \ 11154925bf6Swillf ld = ldap_server_handle->ldap_handle; 11254925bf6Swillf 11354925bf6Swillf extern int set_ldap_error (krb5_context ctx, int st, int op); 11454925bf6Swillf extern void prepend_err_str (krb5_context ctx, const char *s, krb5_error_code err, krb5_error_code oerr); 11554925bf6Swillf 11654925bf6Swillf #define LDAP_SEARCH(base, scope, filter, attrs) LDAP_SEARCH_1(base, scope, filter, attrs, CHECK_STATUS) 11754925bf6Swillf 11854925bf6Swillf #define LDAP_SEARCH_1(base, scope, filter, attrs, status_check) \ 11954925bf6Swillf do { \ 12054925bf6Swillf st = ldap_search_ext_s(ld, base, scope, filter, attrs, 0, NULL, NULL, &timelimit, LDAP_NO_LIMIT, &result); \ 12154925bf6Swillf if (translate_ldap_error(st, OP_SEARCH) == KRB5_KDB_ACCESS_ERROR) { \ 12254925bf6Swillf tempst = krb5_ldap_rebind(ldap_context, &ldap_server_handle); \ 12354925bf6Swillf if (ldap_server_handle) \ 12454925bf6Swillf ld = ldap_server_handle->ldap_handle; \ 12554925bf6Swillf } \ 12654925bf6Swillf }while (translate_ldap_error(st, OP_SEARCH) == KRB5_KDB_ACCESS_ERROR && tempst == 0); \ 12754925bf6Swillf \ 12854925bf6Swillf if (status_check != IGNORE_STATUS) { \ 12954925bf6Swillf if (tempst != 0) { \ 13054925bf6Swillf prepend_err_str(context, "LDAP handle unavailable: ", KRB5_KDB_ACCESS_ERROR, st); \ 13154925bf6Swillf st = KRB5_KDB_ACCESS_ERROR; \ 13254925bf6Swillf goto cleanup; \ 13354925bf6Swillf } \ 13454925bf6Swillf if (st != LDAP_SUCCESS) { \ 13554925bf6Swillf st = set_ldap_error(context, st, OP_SEARCH); \ 13654925bf6Swillf goto cleanup; \ 13754925bf6Swillf } \ 13854925bf6Swillf } 13954925bf6Swillf 14054925bf6Swillf 14154925bf6Swillf #define CHECK_CLASS_VALIDITY(st, mask, str) \ 14254925bf6Swillf if (st != 0 || mask == 0) { \ 14354925bf6Swillf if (st == 0 && mask == 0) { \ 14454925bf6Swillf st = set_ldap_error(context, LDAP_OBJECT_CLASS_VIOLATION, OP_SEARCH); \ 14554925bf6Swillf } \ 14654925bf6Swillf prepend_err_str(context, str, st, st); \ 14754925bf6Swillf goto cleanup; \ 14854925bf6Swillf } 14954925bf6Swillf 15054925bf6Swillf #define CHECK_NULL(ptr) if (ptr == NULL) { \ 15154925bf6Swillf st = ENOMEM; \ 15254925bf6Swillf goto cleanup; \ 15354925bf6Swillf } 15454925bf6Swillf 15554925bf6Swillf #define STORE16_INT(ptr, val) store_16_be(val, ptr) 15654925bf6Swillf #define STORE32_INT(ptr, val) store_32_be(val, ptr) 15754925bf6Swillf #define UNSTORE16_INT(ptr, val) (val = load_16_be(ptr)) 15854925bf6Swillf #define UNSTORE32_INT(ptr, val) (val = load_32_be(ptr)) 15954925bf6Swillf 16054925bf6Swillf #define KRB5_CONF_KDC_BIND_DN "ldap_kdc_dn" 16154925bf6Swillf #define KRB5_CONF_ADMIN_BIND_DN "ldap_kadmind_dn" 16254925bf6Swillf #define KRB5_CONF_PWD_BIND_DN "ldap_passwd_dn" 16354925bf6Swillf 16454925bf6Swillf #define KDB_TL_USER_INFO 0x7ffe 16554925bf6Swillf 16654925bf6Swillf #define KDB_TL_PRINCTYPE 0x01 16754925bf6Swillf #define KDB_TL_PRINCCOUNT 0x02 16854925bf6Swillf #define KDB_TL_USERDN 0x03 16954925bf6Swillf #define KDB_TL_KEYINFO 0x04 17054925bf6Swillf #define KDB_TL_MASK 0x05 17154925bf6Swillf #define KDB_TL_CONTAINERDN 0x06 17254925bf6Swillf #define KDB_TL_LINKDN 0x07 17354925bf6Swillf 17454925bf6Swillf 17554925bf6Swillf #define CHECK_LDAP_HANDLE(lcontext) if (!(ldap_context \ 17654925bf6Swillf && ldap_context->server_info_list)) { \ 17754925bf6Swillf return KRB5_KDB_DBNOTINITED; \ 17854925bf6Swillf } 179*55fea89dSDan Cross 18054925bf6Swillf #define HNDL_LOCK(lcontext) k5_mutex_lock(&lcontext->hndl_lock) 18154925bf6Swillf #define HNDL_UNLOCK(lcontext) k5_mutex_unlock(&lcontext->hndl_lock) 18254925bf6Swillf 18354925bf6Swillf /* To be used later */ 18454925bf6Swillf typedef struct _krb5_ldap_certificates{ 18554925bf6Swillf char *certificate; 18654925bf6Swillf int certtype; 18754925bf6Swillf }krb5_ldap_certificates; 18854925bf6Swillf 18954925bf6Swillf /* ldap server info structure */ 19054925bf6Swillf 19154925bf6Swillf typedef enum _server_type {PRIMARY, SECONDARY} krb5_ldap_server_type; 19254925bf6Swillf 19354925bf6Swillf typedef enum _server_status {OFF, ON, NOTSET} krb5_ldap_server_status; 19454925bf6Swillf 19554925bf6Swillf typedef struct _krb5_ldap_server_info krb5_ldap_server_info; 19654925bf6Swillf 19754925bf6Swillf typedef struct _krb5_ldap_server_handle { 19854925bf6Swillf int msgid; 19954925bf6Swillf LDAP *ldap_handle; 20054925bf6Swillf krb5_boolean server_info_update_pending; 20154925bf6Swillf krb5_ldap_server_info *server_info; 20254925bf6Swillf struct _krb5_ldap_server_handle *next; 20354925bf6Swillf } krb5_ldap_server_handle; 20454925bf6Swillf 20554925bf6Swillf struct _krb5_ldap_server_info { 20654925bf6Swillf krb5_ldap_server_type server_type; 20754925bf6Swillf krb5_ldap_server_status server_status; 20854925bf6Swillf krb5_ui_4 num_conns; 20954925bf6Swillf krb5_ldap_server_handle *ldap_server_handles; 21054925bf6Swillf time_t downtime; 21154925bf6Swillf char *server_name; 21254925bf6Swillf #ifdef HAVE_EDIRECTORY 21354925bf6Swillf char *root_certificate_file; 21454925bf6Swillf #endif 21554925bf6Swillf struct _krb5_ldap_server_info *next; 21654925bf6Swillf }; 21754925bf6Swillf 21854925bf6Swillf 21954925bf6Swillf /* ldap server structure */ 22054925bf6Swillf 221*55fea89dSDan Cross typedef enum {SERVICE_DN_TYPE_SERVER, SERVICE_DN_TYPE_CLIENT} krb5_ldap_servicetype; 22254925bf6Swillf 22354925bf6Swillf typedef struct _krb5_ldap_context { 22454925bf6Swillf krb5_ldap_servicetype service_type; 22554925bf6Swillf krb5_ldap_server_info **server_info_list; 22654925bf6Swillf krb5_ui_4 max_server_conns; 22754925bf6Swillf char *conf_section; 22854925bf6Swillf char *bind_dn; 22954925bf6Swillf char *bind_pwd; 23054925bf6Swillf char *service_password_file; 23154925bf6Swillf char *root_certificate_file; 23254925bf6Swillf char *service_cert_path; 23354925bf6Swillf char *service_cert_pass; 23454925bf6Swillf krb5_ldap_certificates **certificates; 23554925bf6Swillf krb5_ui_4 cert_count; /* certificate count */ 23654925bf6Swillf k5_mutex_t hndl_lock; 23754925bf6Swillf krb5_ldap_krbcontainer_params *krbcontainer; 23854925bf6Swillf krb5_ldap_realm_params *lrparams; 23954925bf6Swillf krb5_context kcontext; /* to set the error code and message */ 24054925bf6Swillf } krb5_ldap_context; 24154925bf6Swillf 24254925bf6Swillf 24354925bf6Swillf typedef struct { 24454925bf6Swillf int nkey; 24554925bf6Swillf struct berval **keys; 24654925bf6Swillf }KEY; 24754925bf6Swillf 24854925bf6Swillf #define k5ldap_inited(c) (c && c->db_context \ 24954925bf6Swillf && ((kdb5_dal_handle*)c->db_context)->db_context \ 25054925bf6Swillf && ((krb5_ldap_context *) ((kdb5_dal_handle*)c->db_context)->db_context)) 25154925bf6Swillf 25254925bf6Swillf 25354925bf6Swillf /* misc functions */ 25454925bf6Swillf 25554925bf6Swillf krb5_error_code 25654925bf6Swillf krb5_ldap_db_init(krb5_context, krb5_ldap_context *); 25754925bf6Swillf 25854925bf6Swillf krb5_error_code 25954925bf6Swillf krb5_ldap_db_single_init(krb5_ldap_context *); 26054925bf6Swillf 26154925bf6Swillf krb5_error_code 26254925bf6Swillf krb5_ldap_rebind(krb5_ldap_context *, krb5_ldap_server_handle **); 26354925bf6Swillf 26454925bf6Swillf krb5_error_code 26554925bf6Swillf krb5_ldap_db_get_age(krb5_context, char *, time_t *); 26654925bf6Swillf 267*55fea89dSDan Cross krb5_error_code 26854925bf6Swillf krb5_ldap_lib_init(void); 26954925bf6Swillf 270*55fea89dSDan Cross krb5_error_code 27154925bf6Swillf krb5_ldap_lib_cleanup(void); 27254925bf6Swillf 273*55fea89dSDan Cross void * 27454925bf6Swillf krb5_ldap_alloc( krb5_context kcontext, void *ptr, size_t size ); 27554925bf6Swillf 276*55fea89dSDan Cross void 27754925bf6Swillf krb5_ldap_free( krb5_context kcontext, void *ptr ); 27854925bf6Swillf krb5_error_code 27954925bf6Swillf krb5_ldap_get_mkey(krb5_context, krb5_keyblock **); 28054925bf6Swillf 28154925bf6Swillf krb5_error_code 28254925bf6Swillf krb5_ldap_set_mkey(krb5_context, char *, krb5_keyblock *); 28354925bf6Swillf 28454925bf6Swillf krb5_error_code 28554925bf6Swillf krb5_ldap_create(krb5_context , char *, char **); 28654925bf6Swillf 287*55fea89dSDan Cross krb5_error_code 28854925bf6Swillf krb5_ldap_open( krb5_context , char *, 28954925bf6Swillf char **db_args, 29054925bf6Swillf int mode ); 291*55fea89dSDan Cross krb5_error_code 29254925bf6Swillf krb5_ldap_close( krb5_context ); 29354925bf6Swillf 29454925bf6Swillf krb5_error_code 29554925bf6Swillf krb5_ldap_free_ldap_context(krb5_ldap_context *); 29654925bf6Swillf 29754925bf6Swillf krb5_error_code 29854925bf6Swillf krb5_ldap_read_startup_information(krb5_context ); 29954925bf6Swillf 30054925bf6Swillf int 30154925bf6Swillf has_sasl_external_mech(krb5_context, char *); 30254925bf6Swillf 30354925bf6Swillf /* DAL functions */ 30454925bf6Swillf 30554925bf6Swillf 30654925bf6Swillf krb5_error_code 30754925bf6Swillf krb5_ldap_set_option( krb5_context, int, void * ); 30854925bf6Swillf 30954925bf6Swillf krb5_error_code 31054925bf6Swillf krb5_ldap_lock( krb5_context, int ); 31154925bf6Swillf 31254925bf6Swillf krb5_error_code 31354925bf6Swillf krb5_ldap_unlock( krb5_context ); 31454925bf6Swillf 31554925bf6Swillf krb5_error_code 31654925bf6Swillf krb5_ldap_supported_realms( krb5_context, char ** ); 31754925bf6Swillf 31854925bf6Swillf krb5_error_code 31954925bf6Swillf krb5_ldap_free_supported_realms( krb5_context, char ** ); 32054925bf6Swillf 32154925bf6Swillf const char * 32254925bf6Swillf krb5_ldap_errcode_2_string( krb5_context, long ); 32354925bf6Swillf 32454925bf6Swillf void 32554925bf6Swillf krb5_ldap_release_errcode_string (krb5_context, const char *); 32654925bf6Swillf 32754925bf6Swillf #ifndef HAVE_LDAP_INITIALIZE 32854925bf6Swillf /* Solaris Kerberos: added a use_SSL parameter */ 32954925bf6Swillf int 33054925bf6Swillf ldap_initialize(LDAP **, char *, int, char **); 33154925bf6Swillf #endif 33254925bf6Swillf #ifndef HAVE_LDAP_UNBIND_EXT_S 33354925bf6Swillf int 33454925bf6Swillf ldap_unbind_ext_s(LDAP *, LDAPControl **, LDAPControl **); 33554925bf6Swillf #endif 33654925bf6Swillf 33754925bf6Swillf #endif 338