1 /*
2 * lib/kdb/kdb_ldap/ldap_krbcontainer.c
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 #include "ldap_main.h"
32 #include "kdb_ldap.h"
33 #include "ldap_err.h"
34 #include <libintl.h>
35
36 char *policyrefattribute[] = {"krbTicketPolicyReference",NULL};
37 char *krbcontainerrefattr[] = {"krbContainerReference", NULL};
38
39 /*
40 * Free the krb5_ldap_krbcontainer_params
41 */
42
43 void
krb5_ldap_free_krbcontainer_params(krb5_ldap_krbcontainer_params * cparams)44 krb5_ldap_free_krbcontainer_params(krb5_ldap_krbcontainer_params *cparams)
45 {
46 if (cparams == NULL)
47 return;
48
49 if (cparams->policyreference)
50 krb5_xfree(cparams->policyreference);
51
52 if (cparams->parent)
53 krb5_xfree(cparams->parent);
54
55 if (cparams->DN)
56 krb5_xfree(cparams->DN);
57
58 krb5_xfree(cparams);
59
60 return;
61 }
62
63 /*
64 * Read the kerberos container. Kerberos container dn is read from the krb5.conf file.
65 * In case of eDirectory, if the dn is not present in the conf file, refer Security Container
66 * to fetch the dn information.
67 *
68 * Reading kerberos container includes reading the policyreference attribute and the policy
69 * object to read the attributes associated with it.
70 */
71
72 krb5_error_code
krb5_ldap_read_krbcontainer_params(krb5_context context,krb5_ldap_krbcontainer_params ** cparamp)73 krb5_ldap_read_krbcontainer_params(krb5_context context,
74 krb5_ldap_krbcontainer_params **cparamp)
75
76 {
77 krb5_error_code st=0, tempst=0;
78 LDAP *ld=NULL;
79 LDAPMessage *result=NULL, *ent=NULL;
80 krb5_ldap_krbcontainer_params *cparams=NULL;
81 kdb5_dal_handle *dal_handle=NULL;
82 krb5_ldap_context *ldap_context=NULL;
83 krb5_ldap_server_handle *ldap_server_handle=NULL;
84
85 SETUP_CONTEXT();
86 GET_HANDLE();
87
88 cparams =(krb5_ldap_krbcontainer_params *) malloc(sizeof(krb5_ldap_krbcontainer_params));
89 CHECK_NULL(cparams);
90 memset((char *) cparams, 0, sizeof(krb5_ldap_krbcontainer_params));
91
92 /* read kerberos containter location from [dbmodules] section of krb5.conf file */
93 if (ldap_context->conf_section) {
94 if ((st=profile_get_string(context->profile, KDB_MODULE_SECTION, ldap_context->conf_section,
95 "ldap_kerberos_container_dn", NULL,
96 &cparams->DN)) != 0) {
97 krb5_set_error_message(context, st, gettext("Error reading kerberos container location "
98 "from krb5.conf"));
99 goto cleanup;
100 }
101 }
102
103 /* read kerberos containter location from [dbdefaults] section of krb5.conf file */
104 if (cparams->DN == NULL) {
105 if ((st=profile_get_string(context->profile, KDB_MODULE_DEF_SECTION,
106 "ldap_kerberos_container_dn", NULL,
107 NULL, &cparams->DN)) != 0) {
108 krb5_set_error_message(context, st, gettext("Error reading kerberos container location "
109 "from krb5.conf"));
110 goto cleanup;
111 }
112 }
113
114 #ifndef HAVE_EDIRECTORY
115 /*
116 * In case eDirectory, we can fall back to security container if the kerberos container location
117 * is missing in the conf file. In openldap we will have to return an error.
118 */
119 if (cparams->DN == NULL) {
120 st = KRB5_KDB_SERVER_INTERNAL_ERR;
121 krb5_set_error_message(context, st, gettext("Kerberos container location not specified"));
122 goto cleanup;
123 }
124 #endif
125
126 if (cparams->DN != NULL) {
127 /* NOTE: krbmaxtktlife, krbmaxrenewableage ... present on Kerberos Container is
128 * not read
129 */
130 LDAP_SEARCH_1(cparams->DN, LDAP_SCOPE_BASE, "(objectclass=krbContainer)", policyrefattribute, IGNORE_STATUS);
131 if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_OBJECT) {
132 st = set_ldap_error(context, st, OP_SEARCH);
133 goto cleanup;
134 }
135
136 if (st == LDAP_NO_SUCH_OBJECT) {
137 st = KRB5_KDB_NOENTRY;
138 goto cleanup;
139 }
140 }
141
142 #ifdef HAVE_EDIRECTORY
143 /*
144 * If the kerberos location in the conf file is missing or invalid, fall back to the
145 * security container. If the kerberos location in the security container is also missing
146 * then fall back to the default value
147 */
148 if ((cparams->DN == NULL) || (st == LDAP_NO_SUCH_OBJECT)) {
149 /*
150 * kerberos container can be anywhere. locate it by reading the security
151 * container to find the location.
152 */
153 LDAP_SEARCH(SECURITY_CONTAINER, LDAP_SCOPE_BASE, NULL, krbcontainerrefattr);
154 if ((ent = ldap_first_entry(ld, result)) != NULL) {
155 if ((st=krb5_ldap_get_string(ld, ent, "krbcontainerreference",
156 &(cparams->DN), NULL)) != 0)
157 goto cleanup;
158 if (cparams->DN == NULL) {
159 cparams->DN = strdup(KERBEROS_CONTAINER);
160 CHECK_NULL(cparams->DN);
161 }
162 }
163 ldap_msgfree(result);
164
165 /* NOTE: krbmaxtktlife, krbmaxrenewableage ... attributes present on
166 * Kerberos Container is not read
167 */
168 LDAP_SEARCH(cparams->DN, LDAP_SCOPE_BASE, "(objectclass=krbContainer)", policyrefattribute);
169 }
170 #endif
171
172 if ((ent = ldap_first_entry(ld, result))) {
173 if ((st=krb5_ldap_get_string(ld, ent, "krbticketpolicyreference",
174 &(cparams->policyreference), NULL)) != 0)
175 goto cleanup;
176 }
177 ldap_msgfree(result);
178
179 if (cparams->policyreference != NULL) {
180 LDAP_SEARCH_1(cparams->policyreference, LDAP_SCOPE_BASE, NULL, policy_attributes, IGNORE_STATUS);
181 if (st != LDAP_SUCCESS && st!= LDAP_NO_SUCH_OBJECT) {
182 st = set_ldap_error(context, st, OP_SEARCH);
183 goto cleanup;
184 }
185 st = LDAP_SUCCESS; /* reset the return status in case it is LDAP_NO_SUCH_OBJECT */
186
187 ent=ldap_first_entry(ld, result);
188 if (ent != NULL) {
189 krb5_ldap_get_value(ld, ent, "krbmaxtktlife", &(cparams->max_life));
190 krb5_ldap_get_value(ld, ent, "krbmaxrenewableage", &(cparams->max_renewable_life));
191 krb5_ldap_get_value(ld, ent, "krbticketflags", &(cparams->tktflags));
192 }
193 ldap_msgfree(result);
194 }
195 *cparamp=cparams;
196
197 cleanup:
198 if (st != 0) {
199 krb5_ldap_free_krbcontainer_params(cparams);
200 *cparamp=NULL;
201 }
202 krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
203 return st;
204 }
205