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