Squid Web Cache master
Loading...
Searching...
No Matches
support_sasl.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/*
10 * -----------------------------------------------------------------------------
11 *
12 * Author: Markus Moeller (markus_moeller at compuserve.com)
13 *
14 * Copyright (C) 2007 Markus Moeller. All rights reserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
29 *
30 * -----------------------------------------------------------------------------
31 */
32
33#include "squid.h"
34#include "util.h"
35
36#if HAVE_LDAP
37
38#include "support.h"
39
40#if HAVE_SASL_H
41#include <sasl.h>
42#elif HAVE_SASL_SASL_H
43#include <sasl/sasl.h>
44#endif
45
46#if HAVE_SASL_H || HAVE_SASL_SASL_H
47void *lutil_sasl_defaults(
48 LDAP * ld,
49 char *mech,
50 char *realm,
51 char *authcid,
52 char *passwd,
53 char *authzid);
54
55LDAP_SASL_INTERACT_PROC lutil_sasl_interact;
56
57int lutil_sasl_interact(
58 LDAP * ld,
59 unsigned flags,
60 void *defaults,
61 void *in);
62
63void lutil_sasl_freedefs(
64 void *defaults);
65
66/*
67 * SASL definitions for openldap support
68 */
69
70typedef struct lutil_sasl_defaults_s {
71 char *mech;
72 char *realm;
73 char *authcid;
74 char *passwd;
75 char *authzid;
76 char **resps;
77 int nresps;
78} lutilSASLdefaults;
79
80void *
81lutil_sasl_defaults(
82 LDAP * ld,
83 char *mech,
84 char *realm,
85 char *authcid,
86 char *passwd,
87 char *authzid)
88{
89 lutilSASLdefaults *defaults;
90
91 defaults = (lutilSASLdefaults *) xmalloc(sizeof(lutilSASLdefaults));
92
93 if (defaults == nullptr)
94 return nullptr;
95
96 defaults->mech = mech ? xstrdup(mech) : nullptr;
97 defaults->realm = realm ? xstrdup(realm) : nullptr;
98 defaults->authcid = authcid ? xstrdup(authcid) : nullptr;
99 defaults->passwd = passwd ? xstrdup(passwd) : nullptr;
100 defaults->authzid = authzid ? xstrdup(authzid) : nullptr;
101
102 if (defaults->mech == nullptr) {
103 ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &defaults->mech);
104 }
105 if (defaults->realm == nullptr) {
106 ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &defaults->realm);
107 }
108 if (defaults->authcid == nullptr) {
109 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authcid);
110 }
111 if (defaults->authzid == nullptr) {
112 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->authzid);
113 }
114 defaults->resps = nullptr;
115 defaults->nresps = 0;
116
117 return defaults;
118}
119
120static int
121interaction(
122 unsigned,
123 sasl_interact_t * interact,
124 lutilSASLdefaults * defaults)
125{
126 const char *dflt = interact->defresult;
127
128 switch (interact->id) {
129 case SASL_CB_GETREALM:
130 if (defaults)
131 dflt = defaults->realm;
132 break;
133 case SASL_CB_AUTHNAME:
134 if (defaults)
135 dflt = defaults->authcid;
136 break;
137 case SASL_CB_PASS:
138 if (defaults)
139 dflt = defaults->passwd;
140 break;
141 case SASL_CB_USER:
142 if (defaults)
143 dflt = defaults->authzid;
144 break;
145 case SASL_CB_NOECHOPROMPT:
146 break;
147 case SASL_CB_ECHOPROMPT:
148 break;
149 }
150
151 if (dflt && !*dflt)
152 dflt = nullptr;
153
154 /* input must be empty */
155 interact->result = (dflt && *dflt) ? dflt : "";
156 interact->len = (unsigned) strlen((const char *) interact->result);
157
158 return LDAP_SUCCESS;
159}
160
161int
162lutil_sasl_interact(
163 LDAP * ld,
164 unsigned flags,
165 void *defaults,
166 void *in)
167{
168 sasl_interact_t *interact = (sasl_interact_t *) in;
169
170 if (ld == nullptr)
171 return LDAP_PARAM_ERROR;
172
173 while (interact->id != SASL_CB_LIST_END) {
174 int rc = interaction(flags, interact, (lutilSASLdefaults *) defaults);
175
176 if (rc)
177 return rc;
178 ++interact;
179 }
180
181 return LDAP_SUCCESS;
182}
183
184void
185lutil_sasl_freedefs(
186 void *defaults)
187{
188 if (const auto defs = static_cast<lutilSASLdefaults*>(defaults)) {
189 xfree(defs->mech);
190 xfree(defs->realm);
191 xfree(defs->authcid);
192 xfree(defs->passwd);
193 xfree(defs->authzid);
194 xfree(defs->resps);
195
196 xfree(defs);
197 }
198}
199
200int
201tool_sasl_bind(LDAP * ld, char *binddn, char *ssl)
202{
203 /*
204 * unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
205 * unsigned sasl_flags = LDAP_SASL_QUIET;
206 */
207 /*
208 * Avoid SASL messages
209 */
210#if HAVE_SUN_LDAP_SDK
211 unsigned sasl_flags = LDAP_SASL_INTERACTIVE;
212#else
213 unsigned sasl_flags = LDAP_SASL_QUIET;
214#endif
215 char *sasl_realm = nullptr;
216 char *sasl_authc_id = nullptr;
217 char *sasl_authz_id = nullptr;
218 char *sasl_mech = (char *) "GSSAPI";
219 /*
220 * Force encryption
221 */
222 char *sasl_secprops;
223 /*
224 * char *sasl_secprops = (char *)"maxssf=56";
225 * char *sasl_secprops = nullptr;
226 */
227 struct berval passwd = {};
228 void *defaults;
229 int rc = LDAP_SUCCESS;
230
231 if (ssl)
232 sasl_secprops = (char *) "maxssf=0";
233 else
234 sasl_secprops = (char *) "maxssf=56";
235 /* sasl_secprops = (char *)"maxssf=0"; */
236 /* sasl_secprops = (char *)"maxssf=56"; */
237
238 if (sasl_secprops != nullptr) {
239 rc = ldap_set_option(ld, LDAP_OPT_X_SASL_SECPROPS,
240 (void *) sasl_secprops);
241 if (rc != LDAP_SUCCESS) {
242 error((char *) "%s| %s: ERROR: Could not set LDAP_OPT_X_SASL_SECPROPS: %s: %s\n", LogTime(), PROGRAM, sasl_secprops, ldap_err2string(rc));
243 return rc;
244 }
245 }
246 defaults = lutil_sasl_defaults(ld,
247 sasl_mech,
248 sasl_realm,
249 sasl_authc_id,
250 passwd.bv_val,
251 sasl_authz_id);
252
253 rc = ldap_sasl_interactive_bind_s(ld, binddn,
254 sasl_mech, nullptr, nullptr,
255 sasl_flags, lutil_sasl_interact, defaults);
256
257 lutil_sasl_freedefs(defaults);
258 if (rc != LDAP_SUCCESS) {
259 error((char *) "%s| %s: ERROR: ldap_sasl_interactive_bind_s error: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
260 }
261 return rc;
262}
263#else
264void dummy(void);
265void
266dummy(void)
267{
268 fprintf(stderr, "%s| %s: ERROR: Dummy function\n", LogTime(), PROGRAM);
269}
270
271#endif
272#endif
273
void error(char *format,...)
#define PROGRAM
Definition support.h:169
const char * LogTime(void)
static LDAP * ld
static const char * binddn
#define xfree
#define xstrdup
#define xmalloc
Comm::AcceptLimiter dummy