Print this page
NEX-14547 Get UNIX group info. from AD/LDAP with partial RFC2307 schema
NEX-13132 smbd dumping core in nss_ldap.so.1`getbymember
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libsldap/common/ns_connmgmt.h
+++ new/usr/src/lib/libsldap/common/ns_connmgmt.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + *
25 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 26 */
25 27
26 -
27 28 #ifndef _NS_CONNMGMT_H
28 29 #define _NS_CONNMGMT_H
29 30
30 -#pragma ident "%Z%%M% %I% %E% SMI"
31 -
32 31 #ifdef __cplusplus
33 32 extern "C" {
34 33 #endif
35 34
36 35 #include <thread.h>
37 36 #include "ns_sldap.h"
38 37 #include "ns_internal.h"
39 38 #include "ns_cache_door.h"
40 39
41 40 struct ns_conn_user; /* connection user, forward definition */
42 41 struct ns_conn_mt; /* multi-threaded (MT) connection, forward definition */
43 42 struct ns_conn_mgmt; /* connection management, forward definition */
44 43
45 44 #define NS_CONN_MT_USER_NO_MAX -1
46 45 #define NS_CONN_MT_USER_MAX NS_CONN_MT_USER_NO_MAX
47 46 #define NS_LIST_TRY_MAX 3
48 47
49 48 /*
50 49 * Structure for handling the waiter of a pending multi-threaded (MT) connection
51 50 */
52 51 typedef struct ns_conn_waiter {
53 52 cond_t waitcv;
54 53 uint8_t signaled;
55 54 struct ns_conn_user *key;
56 55 struct ns_conn_waiter *next, *prev;
57 56 } ns_conn_waiter_t;
58 57
59 58 /*
60 59 * type of a connection user
61 60 */
62 61 typedef enum {
63 62 NS_CONN_USER_SEARCH = 1,
64 63 NS_CONN_USER_WRITE = 2,
65 64 NS_CONN_USER_AUTH = 3,
66 65 NS_CONN_USER_GETENT = 4
67 66 } ns_conn_user_type_t;
68 67
69 68 /*
70 69 * state of a connection user
71 70 */
72 71 typedef enum {
73 72 NS_CONN_USER_UNINITED = 0,
74 73 NS_CONN_USER_ALLOCATED = 1,
75 74 NS_CONN_USER_FINDING = 2, /* looking for an MT connection */
76 75 NS_CONN_USER_WAITING = 3, /* waiting for an MT connection */
77 76 NS_CONN_USER_WOKEUP = 4,
78 77 NS_CONN_USER_CONNECT_ERROR = 5,
79 78 NS_CONN_USER_CONNECTED = 6,
80 79 NS_CONN_USER_DISCONNECTED = 7,
81 80 NS_CONN_USER_FREED = 8
82 81 } ns_conn_user_state_t;
83 82
84 83 /*
85 84 * A connection user represents a request processed by libsldap. It
86 85 * usually is a thread using the same connection from start to end.
87 86 * Different connection users of the same type can share the same
88 87 * connection opened for that type. But search and getent users can
89 88 * share the same connection opened for either search or getent. AUTH
90 89 * connection are not shareable.
91 90 *
92 91 * A getent user may have a longer lifespan and live outside of libsldap.
93 92 * This is because the associated search cookie is passed back to the caller
94 93 * via the firstEntry call and used in the subsequent nextEntry or endEntry
95 94 * calls. Even though the firstEntry and the nextEntry/endEntry calls may
96 95 * be running in a different thread, the connection being used will be the
97 96 * same. It is the one assigend during the firstEntry call.
98 97 */
99 98 struct ns_conn_user {
100 99 ns_conn_user_type_t type; /* search, write, auth, getent, ... */
101 100 ns_conn_user_state_t state;
102 101 thread_t tid; /* id of the thread starts the request */
103 102 struct ns_conn_user *next; /* next conn_user in the linked list */
104 103 struct ns_conn_mt *conn_mt; /* the MT connection being used */
105 104 struct ns_conn_mgmt *conn_mgmt; /* ref counted conn management */
106 105 void *userinfo; /* private data of the request */
107 106 ns_ldap_return_code ns_rc; /* error return code */
108 107 ns_ldap_error_t *ns_error; /* error info */
109 108 boolean_t referral; /* using a referred server ? */
110 109 boolean_t retry; /* retry the request on certain error? */
111 110 boolean_t keep_conn; /* keep the conn for reuse ? */
112 111 boolean_t use_mt_conn; /* using/used an MT connection ? */
113 112 boolean_t bad_mt_conn; /* MT connection is not usable ? */
114 113 };
115 114
116 115 /*
117 116 * state of an MT connection
118 117 */
119 118 typedef enum {
120 119 NS_CONN_MT_UNINITED = 0,
121 120 NS_CONN_MT_CONNECTING = 1,
122 121 NS_CONN_MT_CONNECT_ERROR = 2,
123 122 NS_CONN_MT_CONNECTED = 3,
124 123 NS_CONN_MT_CLOSING = 4
125 124 } ns_conn_mt_state_t;
126 125
127 126 /*
128 127 * An ns_conn_mt (or MT connection) represents an ldap connection
129 128 * that can be shared among multiple threads. It also represents
130 129 * the set of connection users using the ldap connection. It contains
131 130 * a pointer to the Connection structure that has the physical info
132 131 * of the connection (server name, address, ldap handle, etc). It
133 132 * also contains a linked list of all the conn_user using the ldap
134 133 * connection. The connection users can wait on an MT connection
135 134 * to become available or be told to abort and clean up when one of
136 135 * the connection user detects an error and knows that the connection
137 136 * is no longer usable. The error info is then saved in the structure
138 137 * for other users to consume.
139 138 *
140 139 * An MT connection is meant to be shared concurrently and persistent.
141 140 * Even when there's no current user, it will be kept by the connection
142 141 * management, waiting for the next user. It will be closed when
143 142 * a connection error is detected, when a better server should be
144 143 * used, when the Native LDAP configuration change, or when the libsldap
145 144 * is being unloaded.
146 145 */
147 146 typedef struct ns_conn_mt {
148 147 mutex_t lock;
149 148 ns_conn_mt_state_t state;
150 149 pid_t pid; /* process creates the connection */
151 150 thread_t tid; /* thread creates the connection */
152 151 struct ns_conn_mt *next; /* next conn_mt in the linked list */
153 152 ns_conn_user_t *cu_head; /* head of conn_user linked list */
154 153 ns_conn_user_t *cu_tail; /* tail of conn_user linked list */
155 154 struct ns_conn_mgmt *conn_mgmt; /* ref counted conn management */
156 155 ns_conn_waiter_t waiter; /* first of the connection waiters */
157 156 uint_t cu_cnt; /* number of the using conn_user */
158 157 int32_t cu_max; /* max. allowed number of conn_user */
159 158 uint_t waiter_cnt; /* number of waiters */
160 159 ns_conn_user_type_t opened_for; /* type of conn_user opened for */
161 160 Connection *conn; /* name, IP address, ldap handle, etc */
162 161 time_t create_time; /* time when connection created */
163 162 time_t access_time; /* time when last used */
164 163 ns_ldap_return_code ns_rc; /* saved error code */
165 164 ns_ldap_error_t *ns_error; /* saved error info */
166 165 boolean_t close_when_nouser; /* close connection when */
167 166 /* last user is done ? */
168 167 boolean_t detached; /* no longer in connection pool? */
169 168 boolean_t referral; /* using a referred server ? */
170 169 } ns_conn_mt_t;
171 170
172 171 /*
173 172 * state of a connection management
174 173 * (a connection pool sharing the same native LDAP configuration)
175 174 */
176 175 typedef enum {
177 176 NS_CONN_MGMT_UNINITED = 0,
178 177 NS_CONN_MGMT_INACTIVE = 1, /* conn sharing not yet requested */
179 178 NS_CONN_MGMT_ACTIVE = 2, /* connection sharing required/requested */
180 179 NS_CONN_MGMT_DETACHED = 3 /* on the way down, no new user allowed */
181 180 } ns_conn_mgmt_state_t;
182 181
183 182 /*
184 183 * An ns_conn_mgmt (or connection management) represents the set of MT
185 184 * connections using the same native LDAP configuration. It is a connection
186 185 * pool that can adjust the MT connection status and usage based on the
187 186 * change notifications it receives from the ldap_cachemgr daemon, OR When
188 187 * the change is detected at config refresh time. When a server status
189 188 * change (up or down) notification is received or detected, it will
190 189 * close the MT connections using the server. Or mark them as to-be-closed
191 190 * and close them when all users are done using them. When a config change
192 191 * notice is received, it will detach itself and allow a new ns_conn_mgmt be
193 192 * created for the new configuration. The old config would still be used
194 193 * by the detached ns_conn_mgmt. Both will be destroyed when all existing
195 194 * conn_user are done. Any conn_user and MT connection created after the
196 195 * configuration switch will use the new configuration.
197 196 *
198 197 * Note that there's always just one current ns_conn_mgmt. Its usage is
199 198 * reference counted. Any new conn_user or MT connection referencing
200 199 * the ns_conn_mgmt adds 1 to the count, any release of the ns_conn_mgmt
201 200 * decrement the count by 1. The ns_conn_mgmt can not be freed until
202 201 * the reference count becomes zero.
203 202 *
204 203 * Each ns_conn_mgmt references a native LDAP configuration. The config
205 204 * component of this library always maintains a global configuration. It is
206 205 * referred to as the current global config. The current ns_conn_mgmt
207 206 * uses that global config. When an ns_conn_mgmt is detached, or not
208 207 * longer active/current, the config it uses is no longer the current global
209 208 * one, which is referred as the per connection management config. When
210 209 * the ns_conn_mgmt is freed, the config will also be destroyed.
211 210 */
212 211
213 212 typedef struct ns_conn_mgmt {
214 213 mutex_t lock;
215 214 ns_conn_mgmt_state_t state;
216 215 pid_t pid; /* process creates the conn_mgmt */
217 216 thread_t procchg_tid; /* id of the change monitor thread */
218 217 ns_conn_mt_t *cm_head; /* head of the conn_mt linked list */
219 218 ns_conn_mt_t *cm_tail; /* tail of the conn_mt linked list */
220 219 mutex_t cfg_lock; /* lock serializes access to config */
221 220 ldap_get_chg_cookie_t cfg_cookie; /* used to detect if config changes */
222 221 ns_config_t *config; /* the native LDAP config being used */
223 222 char **pservers; /* preferred servers defined in config */
224 223 uint_t cm_cnt; /* number of MT connection in the pool */
225 224 uint_t ref_cnt; /* number of reference by conn_MT/conn_user */
226 225 boolean_t is_nscd; /* running in a nscd ? */
227 226 boolean_t is_peruser_nscd; /* running in a per-user nscd ? */
228 227 boolean_t ldap_mt; /* libldap supports multi-threaded client ? */
229 228 boolean_t do_mt_conn; /* need and able to do MT conn ? */
230 229 boolean_t shutting_down; /* on the way down ? */
231 230 boolean_t cfg_reloaded; /* config is not current ? */
232 231 boolean_t procchg_started; /* change monitor thread started ? */
233 232 boolean_t procchg_door_call; /* in door call and waiting ? */
234 233 boolean_t pservers_loaded; /* pservers array is set ? */
235 234 } ns_conn_mgmt_t;
236 235
237 236 /*
238 237 * For a connection management and the conn_mt connections it manages, it is
239 238 * very helpful to know exactly when the Native LDAP configuration changes
240 239 * and when the status of the configured servers change. If the config
241 240 * changes, new connection management will be created. If servers go up
242 241 * or down, conn_mt connections being used need to be dropped or switched.
243 242 * For processes other than the main nscd, the changes has to be detected
244 243 * in a less efficient way by libsldap. For the main nscd (not including
245 244 * peruser nscd), the connection management which has active conn_mt
246 245 * connections can rely on the ldap_cachemgr daemon to report if there's any
247 246 * change in servers' status or if the native LDAP configuration has changed.
248 247 *
249 248 * The mechanism for reporting of the changes is a door call sent from
250 249 * libsldap to ldap_cachemgr. The call will not be returned until changes
251 250 * detected by ldap_cachemgr. When the change info is passed back to
252 251 * libsldap, the change monitor thread will wake up from the door call
253 252 * and process the notification. For servers went from up to down, the
254 253 * associated MT connections will be closed, and then all conn_users'
255 254 * state will be marked as closing. When a conn_user notices it, the
256 255 * operations represented by that conn_user will be ended with error
257 256 * info. When a more preferred server is up, MT connections using
258 257 * less preferred servers will be marked as closed-when-all-user-done,
259 258 * so that new connection will be opened and using the preferred server.
260 259 * A configuration change causes the current connection management and
261 260 * the configuration it uses to become detached but continually being
262 261 * used by the old MT connections. Any new MT connection opened will
263 262 * be put in a new connection management and uses the new configuration
264 263 * immediately.
265 264 */
266 265 typedef enum {
267 266 NS_SERVER_UP = 1,
268 267 NS_SERVER_DOWN = 2
269 268 } ns_server_status_t;
270 269
271 270 typedef struct ns_server_status_change {
272 271 int num_server;
273 272 boolean_t config_changed;
274 273 ns_server_status_t *changes; /* array of status change */
275 274 char **servers; /* array of server */
276 275 } ns_server_status_change_t;
277 276
278 277 /*
279 278 * connection management functions
280 279 */
281 280 ns_conn_mgmt_t *__s_api_conn_mgmt_init();
282 281 int __s_api_setup_mt_ld(LDAP *ld);
283 282 int __s_api_check_mtckey();
284 283 void __s_api_use_prev_conn_mgmt(int, ns_config_t *);
285 284 ns_conn_user_t *__s_api_conn_user_init(int, void *, boolean_t);
286 285 void __s_api_conn_mt_return(ns_conn_user_t *);
287 286 void __s_api_conn_user_free(ns_conn_user_t *);
288 287 int __s_api_conn_mt_add(Connection *con, ns_conn_user_t *, ns_ldap_error_t **);
289 288 int __s_api_conn_mt_get(const char *, const int, const ns_cred_t *,
290 289 Connection **, ns_ldap_error_t **, ns_conn_user_t *);
291 290 void __s_api_conn_mt_remove(ns_conn_user_t *, int, ns_ldap_error_t **);
292 291 int __s_api_check_libldap_MT_conn_support(ns_conn_user_t *, LDAP *ld,
293 292 ns_ldap_error_t **);
294 293 void __s_api_conn_mt_close(ns_conn_user_t *, int, ns_ldap_error_t **);
295 294 void __s_api_reinit_conn_mgmt_new_config(ns_config_t *);
296 295 int __s_api_setup_retry_search(ns_conn_user_t **, ns_conn_user_type_t, int *,
297 296 int *, ns_ldap_error_t **);
298 297 int __s_api_setup_getnext(ns_conn_user_t *, int *, ns_ldap_error_t **);
299 298 void __s_api_shutdown_conn_mgmt();
300 299
301 300 #ifdef __cplusplus
302 301 }
303 302 #endif
304 303
305 304 #endif /* _NS_CONNMGMT_H */
|
↓ open down ↓ |
264 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX