]>
Commit | Line | Data |
---|---|---|
3d551623 PG |
1 | diff --git a/CHANGELOG b/CHANGELOG |
2 | index a9e509d..85af0ad 100644 | |
3 | --- a/CHANGELOG | |
4 | +++ b/CHANGELOG | |
5 | @@ -49,6 +49,7 @@ | |
6 | - fix incorrect read/write size of startup status token (Matthias Koenig). | |
7 | - fix off-by-one error for lookup of map keys exactly 255 characters long. | |
8 | - improve handling of server not available. | |
9 | +- fix LDAP_URI server selection. | |
10 | ||
11 | 18/06/2007 autofs-5.0.2 | |
12 | ----------------------- | |
13 | diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c | |
14 | index 18733f3..303b7f2 100644 | |
15 | --- a/modules/cyrus-sasl.c | |
16 | +++ b/modules/cyrus-sasl.c | |
17 | @@ -75,6 +75,7 @@ static const char *krb5ccval = "MEMORY:_autofstkt"; | |
18 | static pthread_mutex_t krb5cc_mutex = PTHREAD_MUTEX_INITIALIZER; | |
19 | static unsigned int krb5cc_in_use = 0; | |
20 | ||
21 | +static unsigned int init_callbacks = 1; | |
22 | static int sasl_log_func(void *, int, const char *); | |
23 | static int getpass_func(sasl_conn_t *, void *, int, sasl_secret_t **); | |
24 | static int getuser_func(void *, int, const char **, unsigned *); | |
25 | @@ -386,7 +387,7 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt) | |
26 | ||
27 | debug(logopt, | |
28 | "initializing kerberos ticket: client principal %s ", | |
29 | - ctxt->client_princ ? "" : "autofsclient"); | |
30 | + ctxt->client_princ ? ctxt->client_princ : "autofsclient"); | |
31 | ||
32 | ret = krb5_init_context(&ctxt->krb5ctxt); | |
33 | if (ret) { | |
34 | @@ -599,8 +600,8 @@ sasl_bind_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const c | |
35 | ||
36 | /* OK and CONTINUE are the only non-fatal return codes here. */ | |
37 | if ((result != SASL_OK) && (result != SASL_CONTINUE)) { | |
38 | - error(logopt, "sasl_client start failed with error: %s", | |
39 | - sasl_errdetail(conn)); | |
40 | + warn(logopt, "sasl_client_start failed for %s", host); | |
41 | + debug(logopt, "sasl_client_start: %s", sasl_errdetail(conn)); | |
42 | ldap_memfree(host); | |
43 | sasl_dispose(&conn); | |
44 | return NULL; | |
45 | @@ -721,23 +722,30 @@ autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) | |
46 | sasl_conn_t *conn; | |
47 | ||
48 | /* Start up Cyrus SASL--only needs to be done once. */ | |
49 | - if (sasl_client_init(callbacks) != SASL_OK) { | |
50 | + if (init_callbacks && sasl_client_init(callbacks) != SASL_OK) { | |
51 | error(logopt, "sasl_client_init failed"); | |
52 | return -1; | |
53 | } | |
54 | + init_callbacks = 0; | |
55 | ||
56 | sasl_auth_id = ctxt->user; | |
57 | sasl_auth_secret = ctxt->secret; | |
58 | ||
59 | /* | |
60 | - * If sasl_mech was not filled in, it means that there was no | |
61 | - * mechanism specified in the configuration file. Try to auto- | |
62 | - * select one. | |
63 | + * If LDAP_AUTH_AUTODETECT is set, it means that there was no | |
64 | + * mechanism specified in the configuration file or auto | |
65 | + * selection has been requested, so try to auto-select an | |
66 | + * auth mechanism. | |
67 | */ | |
68 | - if (ctxt->sasl_mech) | |
69 | + if (!(ctxt->auth_required & LDAP_AUTH_AUTODETECT)) | |
70 | conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech); | |
71 | - else | |
72 | + else { | |
73 | + if (ctxt->sasl_mech) { | |
74 | + free(ctxt->sasl_mech); | |
75 | + ctxt->sasl_mech = NULL; | |
76 | + } | |
77 | conn = sasl_choose_mech(logopt, ldap, ctxt); | |
78 | + } | |
79 | ||
80 | if (conn) { | |
81 | sasl_dispose(&conn); | |
82 | diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c | |
83 | index 7effbf1..93f0477 100644 | |
84 | --- a/modules/lookup_ldap.c | |
85 | +++ b/modules/lookup_ldap.c | |
86 | @@ -402,8 +402,7 @@ static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) | |
87 | debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s", | |
88 | ctxt->auth_required, ctxt->sasl_mech); | |
89 | ||
90 | - if (ctxt->sasl_mech || | |
91 | - (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT))) { | |
92 | + if (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)) { | |
93 | rv = autofs_sasl_bind(logopt, ldap, ctxt); | |
94 | debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv); | |
95 | } else { | |
96 | @@ -497,7 +496,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c | |
97 | * Determine which authentication mechanism to use if we require | |
98 | * authentication. | |
99 | */ | |
100 | - if (ctxt->auth_required & LDAP_AUTH_REQUIRED) { | |
101 | + if (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)) { | |
102 | ldap = auth_init(logopt, uri, ctxt); | |
103 | if (!ldap && ctxt->auth_required & LDAP_AUTH_AUTODETECT) | |
104 | info(logopt, | |
105 | @@ -510,6 +509,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c | |
106 | ||
107 | if (!do_bind(logopt, ldap, ctxt)) { | |
108 | unbind_ldap_connection(logopt, ldap, ctxt); | |
109 | + autofs_sasl_done(ctxt); | |
110 | error(logopt, MODPREFIX "cannot bind to server"); | |
111 | return NULL; | |
112 | } | |
113 | @@ -541,6 +541,7 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) | |
114 | while(p != ctxt->uri) { | |
115 | this = list_entry(p, struct ldap_uri, list); | |
116 | p = p->next; | |
117 | + debug(logopt, "trying server %s", this->uri); | |
118 | ldap = connect_to_server(logopt, this->uri, ctxt); | |
119 | if (ldap) { | |
120 | info(logopt, "connected to uri %s", this->uri); | |
121 | @@ -563,22 +564,23 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) | |
122 | ||
123 | static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) | |
124 | { | |
125 | + struct ldap_uri *this; | |
126 | LDAP *ldap; | |
127 | ||
128 | if (ctxt->server || !ctxt->uri) { | |
129 | ldap = do_connect(logopt, ctxt->server, ctxt); | |
130 | return ldap; | |
131 | - } else { | |
132 | - struct ldap_uri *this; | |
133 | - this = list_entry(ctxt->uri->next, struct ldap_uri, list); | |
134 | - ldap = do_connect(logopt, this->uri, ctxt); | |
135 | - if (ldap) | |
136 | - return ldap; | |
137 | - /* Failed to connect, put at end of list */ | |
138 | - list_del_init(&this->list); | |
139 | - list_add_tail(&this->list, ctxt->uri); | |
140 | } | |
141 | ||
142 | + this = list_entry(ctxt->uri->next, struct ldap_uri, list); | |
143 | + ldap = do_connect(logopt, this->uri, ctxt); | |
144 | + if (ldap) | |
145 | + return ldap; | |
146 | + | |
147 | + /* Failed to connect, put at end of list */ | |
148 | + list_del_init(&this->list); | |
149 | + list_add_tail(&this->list, ctxt->uri); | |
150 | + | |
151 | #ifdef WITH_SASL | |
152 | autofs_sasl_done(ctxt); | |
153 | #endif | |
154 | @@ -844,6 +846,8 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt) | |
155 | ctxt->tls_required = tls_required; | |
156 | ctxt->auth_required = auth_required; | |
157 | ctxt->sasl_mech = authtype; | |
158 | + if (!authtype && (auth_required & LDAP_AUTH_REQUIRED)) | |
159 | + ctxt->auth_required |= LDAP_AUTH_AUTODETECT; | |
160 | ctxt->user = user; | |
161 | ctxt->secret = secret; | |
162 | ctxt->client_princ = client_princ; | |
163 | @@ -886,16 +890,6 @@ static LDAP *auth_init(unsigned logopt, const char *uri, struct lookup_context * | |
164 | int ret; | |
165 | LDAP *ldap; | |
166 | ||
167 | - /* | |
168 | - * First, check to see if a preferred authentication method was | |
169 | - * specified by the user. parse_ldap_config will return error | |
170 | - * if the permissions on the file were incorrect, or if the | |
171 | - * specified authentication type is not valid. | |
172 | - */ | |
173 | - ret = parse_ldap_config(logopt, ctxt); | |
174 | - if (ret) | |
175 | - return NULL; | |
176 | - | |
177 | ldap = init_ldap_connection(logopt, uri, ctxt); | |
178 | if (!ldap) | |
179 | return NULL; | |
180 | @@ -909,10 +903,8 @@ static LDAP *auth_init(unsigned logopt, const char *uri, struct lookup_context * | |
181 | * the credential cache and the client and service principals. | |
182 | */ | |
183 | ret = autofs_sasl_init(logopt, ldap, ctxt); | |
184 | - if (ret) { | |
185 | - ctxt->sasl_mech = NULL; | |
186 | + if (ret) | |
187 | return NULL; | |
188 | - } | |
189 | ||
190 | return ldap; | |
191 | } | |
192 | @@ -1134,6 +1126,8 @@ static void free_context(struct lookup_context *ctxt) | |
193 | free(ctxt->user); | |
194 | if (ctxt->secret) | |
195 | free(ctxt->secret); | |
196 | + if (ctxt->client_princ) | |
197 | + free(ctxt->client_princ); | |
198 | if (ctxt->mapname) | |
199 | free(ctxt->mapname); | |
200 | if (ctxt->qdn) | |
201 | @@ -1184,6 +1178,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co | |
202 | struct lookup_context *ctxt; | |
203 | char buf[MAX_ERR_BUF]; | |
204 | LDAP *ldap = NULL; | |
205 | + int ret; | |
206 | ||
207 | *context = NULL; | |
208 | ||
209 | @@ -1224,6 +1219,20 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co | |
210 | } | |
211 | } | |
212 | ||
213 | +#ifdef WITH_SASL | |
214 | + /* | |
215 | + * First, check to see if a preferred authentication method was | |
216 | + * specified by the user. parse_ldap_config will return error | |
217 | + * if the permissions on the file were incorrect, or if the | |
218 | + * specified authentication type is not valid. | |
219 | + */ | |
220 | + ret = parse_ldap_config(LOGOPT_NONE, ctxt); | |
221 | + if (ret) { | |
222 | + free_context(ctxt); | |
223 | + return 1; | |
224 | + } | |
225 | +#endif | |
226 | + | |
227 | if (ctxt->server || !ctxt->uri) { | |
228 | ldap = connect_to_server(LOGOPT_NONE, ctxt->server, ctxt); | |
229 | if (!ldap) { |