xref: /illumos-gate/usr/src/lib/libsldap/common/ns_internal.h (revision 8119dad84d6416f13557b0ba8e2aaf9064cbcfd3)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
25  * Copyright 2020 Joyent, Inc.
26  */
27 
28 
29 #ifndef	_NS_INTERNAL_H
30 #define	_NS_INTERNAL_H
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 #include <stdio.h>
37 #include <sys/types.h>
38 #include <sys/time.h>
39 #include <thread.h>
40 #include <lber.h>
41 #include <ldap.h>
42 #include "ns_sldap.h"
43 #include "ns_cache_door.h"
44 
45 /*
46  * INTERNALLY USED CONSTANTS
47  */
48 
49 #define	MAXERROR		2000
50 #define	TRUE			1
51 #define	FALSE			0
52 #define	NSLDAPDIRECTORY		"/var/ldap"
53 #define	NSCONFIGFILE		"/var/ldap/ldap_client_file"
54 #define	NSCONFIGREFRESH		"/var/ldap/ldap_client_file.refresh"
55 #define	NSCREDFILE		"/var/ldap/ldap_client_cred"
56 #define	NSCREDREFRESH		"/var/ldap/ldap_client_cred.refresh"
57 #define	ROTORSIZE		256
58 #define	MASK			0377
59 #define	LDAPMAXHARDLOOKUPTIME	256
60 #define	DONOTEDIT		\
61 	"Do not edit this file manually; your changes will be lost." \
62 	"Please use ldapclient(8) instead."
63 #define	MAXPORTNUMBER		65535
64 #define	MAXPORTNUMBER_STR	"65535"
65 #define	CREDFILE		0
66 #define	CONFIGFILE		1
67 #define	UIDNUMFILTER		"(&(objectclass=posixAccount)(uidnumber=%s))"
68 #define	UIDNUMFILTER_SSD	"(&(%%s)(uidnumber=%s))"
69 #define	UIDFILTER		"(&(objectclass=posixAccount)(uid=%s))"
70 #define	UIDFILTER_SSD		"(&(%%s)(uid=%s))"
71 #define	UIDDNFILTER		"(objectclass=posixAccount)"
72 
73 #define	HOSTFILTER		"(&(objectclass=ipHost)(cn=%s))"
74 #define	HOSTFILTER_SSD		"(&(%%s)(cn=%s))"
75 
76 #define	SIMPLEPAGECTRLFLAG	1
77 #define	VLVCTRLFLAG		2
78 
79 #define	LISTPAGESIZE		1000
80 #define	ENUMPAGESIZE		100
81 
82 #define	DEFMAX			8
83 #define	TOKENSEPARATOR		'='
84 #define	QUOTETOK		'"'
85 #define	SPACETOK		' '
86 #define	COMMATOK		','
87 #define	COLONTOK		':'
88 #define	QUESTTOK		'?'
89 #define	SEMITOK			';'
90 #define	TABTOK			'\t'
91 #define	OPARATOK		'('
92 #define	CPARATOK		')'
93 #define	BSLTOK			'\\'
94 #define	DOORLINESEP		"\07"
95 #define	DOORLINESEP_CHR		0x7
96 #define	COMMASEP		", "
97 #define	SPACESEP		" "
98 #define	SEMISEP			";"
99 #define	COLONSEP		":"
100 #define	COLSPSEP		": "
101 #define	EQUALSEP		"="
102 #define	EQUSPSEP		"= "
103 #define	LAST_VALUE		(int)NS_LDAP_HOST_CERTPATH_P
104 #define	BUFSIZE			BUFSIZ
105 #define	DEFAULTCONFIGNAME	"__default_config"
106 #define	EXP_DEFAULT_TTL		"43200"	/* 12 hours TTL */
107 #define	CRYPTMARK		"{NS1}"
108 #define	DOORBUFFERSIZE		8192
109 
110 #define	LDIF_FMT_STR		"%s: %s"
111 #define	FILE_FMT_STR		"%s= %s"
112 #define	DOOR_FMT_STR		"%s=%s"
113 
114 #define	SESSION_CACHE_INC	8
115 #define	CONID_OFFSET		1024
116 #define	NS_DEFAULT_BIND_TIMEOUT		30 /* timeout value in seconds */
117 #define	NS_DEFAULT_SEARCH_TIMEOUT	30 /* timeout value in seconds */
118 
119 /* max rdn length in conversion routines used by __ns_ldap_addTypedEntry() */
120 #define	RDNSIZE			512
121 
122 /*
123  * special service used by ldap_cachemgr to indicate a shadow update
124  * is to be done with the credential of the administrator identity
125  */
126 #define	NS_ADMIN_SHADOW_UPDATE	"shadow__admin_update"
127 
128 /* Phase 1 profile information */
129 #define	_PROFILE1_OBJECTCLASS	"SolarisNamingProfile"
130 #define	_PROFILE_CONTAINER	"profile"
131 #define	_PROFILE_FILTER		"(&(|(objectclass=%s)(objectclass=%s))(cn=%s))"
132 
133 /* Phase 2 profile information */
134 #define	_PROFILE2_OBJECTCLASS		"DUAConfigProfile"
135 
136 /* Common to all profiles */
137 #define	_P_CN			"cn"
138 
139 /* Native LDAP Phase 1 Specific Profile Attributes */
140 #define	_P1_SERVERS			"SolarisLDAPServers"
141 #define	_P1_SEARCHBASEDN		"SolarisSearchBaseDN"
142 #define	_P1_CACHETTL			"SolarisCacheTTL"
143 #define	_P1_BINDDN			"SolarisBindDN"
144 #define	_P1_BINDPASSWORD		"SolarisBindPassword"
145 #define	_P1_AUTHMETHOD			"SolarisAuthMethod"
146 #define	_P1_TRANSPORTSECURITY		"SolarisTransportSecurity"
147 #define	_P1_CERTIFICATEPATH		"SolarisCertificatePath"
148 #define	_P1_CERTIFICATEPASSWORD		"SolarisCertificatePassword"
149 #define	_P1_DATASEARCHDN		"SolarisDataSearchDN"
150 #define	_P1_SEARCHSCOPE			"SolarisSearchScope"
151 #define	_P1_SEARCHTIMELIMIT		"SolarisSearchTimeLimit"
152 #define	_P1_PREFERREDSERVER		"SolarisPreferredServer"
153 #define	_P1_PREFERREDSERVERONLY		"SolarisPreferredServerOnly"
154 #define	_P1_SEARCHREFERRAL		"SolarisSearchReferral"
155 #define	_P1_BINDTIMELIMIT		"SolarisBindTimeLimit"
156 
157 /* Native LDAP Phase 2 Specific Profile Attributes */
158 #define	_P2_PREFERREDSERVER		"preferredServerList"
159 #define	_P2_DEFAULTSERVER		"defaultServerList"
160 #define	_P2_SEARCHBASEDN		"defaultSearchBase"
161 #define	_P2_SEARCHSCOPE			"defaultSearchScope"
162 #define	_P2_AUTHMETHOD			"authenticationMethod"
163 #define	_P2_CREDENTIALLEVEL		"credentialLevel"
164 #define	_P2_SERVICESEARCHDESC		"serviceSearchDescriptor"
165 #define	_P2_SEARCHTIMELIMIT		"searchTimeLimit"
166 #define	_P2_BINDTIMELIMIT		"bindTimeLimit"
167 #define	_P2_FOLLOWREFERRALS		"followReferrals"
168 #define	_P2_PROFILETTL			"profileTTL"
169 #define	_P2_ATTRIBUTEMAP		"attributeMap"
170 #define	_P2_OBJECTCLASSMAP		"objectClassMap"
171 #define	_P2_SERVICECREDLEVEL		"serviceCredentialLevel"
172 #define	_P2_SERVICEAUTHMETHOD		"serviceAuthenticationMethod"
173 
174 /* Control & SASL information from RootDSE door call */
175 #define	_SASLMECHANISM			"supportedSASLmechanisms"
176 #define	_SASLMECHANISM_LEN		23
177 #define	_SUPPORTEDCONTROL		"supportedControl"
178 #define	_SUPPORTEDCONTROL_LEN		16
179 
180 #define	NS_HASH_MAX	257
181 #define	NS_HASH_SCHEMA_MAPPING_EXISTED	"=MAPPING EXISTED="
182 #define	NS_HASH_RC_SUCCESS		1
183 #define	NS_HASH_RC_NO_MEMORY		-1
184 #define	NS_HASH_RC_CONFIG_ERROR		-2
185 #define	NS_HASH_RC_EXISTED		-3
186 #define	NS_HASH_RC_SYNTAX_ERROR		-4
187 
188 /* Password management related error message from iDS ldap server */
189 #define	NS_PWDERR_MAXTRIES		\
190 	"Exceed password retry limit."
191 #define	NS_PWDERR_EXPIRED		\
192 	"password expired!"
193 #define	NS_PWDERR_ACCT_INACTIVATED	\
194 	"Account inactivated. Contact system administrator."
195 #define	NS_PWDERR_CHANGE_NOT_ALLOW	\
196 	"user is not allowed to change password"
197 #define	NS_PWDERR_INVALID_SYNTAX	\
198 	"invalid password syntax"
199 #define	NS_PWDERR_TRIVIAL_PASSWD	\
200 	"Password failed triviality check"
201 #define	NS_PWDERR_IN_HISTORY	\
202 	"password in history"
203 #define	NS_PWDERR_WITHIN_MIN_AGE	\
204 	"within password minimum age"
205 
206 /*
207  * INTERNALLY USED MACROS
208  */
209 
210 void	__s_api_debug_pause(int priority, int st, const char *mesg);
211 
212 #define	NULL_OR_STR(str)	(!(str) || *(str) == '\0' ? "<NULL>" : (str))
213 
214 /*
215  * MKERROR: builds the error structure and fills in the status and
216  * the message.  The message must be a freeable (non-static) string.
217  * If it fails to allocate memory for the error structure,
218  * it will return the retErr.
219  */
220 #define	MKERROR(priority, err, st, mesg, retErr) \
221 	if (((err) = calloc(1, sizeof (struct ns_ldap_error))) == NULL) \
222 		return (retErr); \
223 	(err)->message = mesg; \
224 	(err)->status = (st); \
225 	__s_api_debug_pause(priority, st, (err)->message);
226 
227 /*
228  * MKERROR_PWD_MGMT is almost the same as MKERROR
229  * except that it takes two more inputs to fill in the
230  * password management information part of the
231  * ns_ldap_error structure pointed to by err,
232  * and it does not log a syslog message.
233  */
234 #define	MKERROR_PWD_MGMT(err, st, mesg, pwd_status, sec_until_exp, retErr) \
235 	if (((err) = calloc(1, sizeof (struct ns_ldap_error))) == NULL) \
236 		return (retErr); \
237 	(err)->message = mesg; \
238 	(err)->status = (st); \
239 	(err)->pwd_mgmt.status = (pwd_status); \
240 	(err)->pwd_mgmt.sec_until_expired = (sec_until_exp);
241 
242 #ifdef DEBUG
243 #define	NSLDAPTRACE(variable, setequal, message) \
244 	if (variable > 0 || ((setequal != 0) && (variable == setequal))) { \
245 		char buf[BUFSIZ]; \
246 		(void) snprintf(buf, BUFSIZ, message); \
247 		(void) write(__ldap_debug_file, buf); \
248 	}
249 #endif
250 
251 /*
252  * INTERNAL DATA STRUCTURES
253  */
254 
255 /*
256  * configuration entry type
257  */
258 
259 typedef enum {
260 	SERVERCONFIG	= 1,
261 	CLIENTCONFIG	= 2,
262 	CREDCONFIG	= 3
263 } ns_conftype_t;
264 
265 /*
266  * datatype of a config entry
267  */
268 
269 typedef enum {
270 	NS_UNKNOWN	= 0,
271 	CHARPTR		= 1,		/* Single character pointer */
272 	ARRAYCP		= 2,		/* comma sep array of char pointers */
273 	ARRAYAUTH	= 3,		/* Array of auths */
274 	TIMET		= 4,		/* time relative value (TTL) */
275 	INT		= 5,		/* single integer */
276 	SSDLIST		= 6,		/* service search descriptor */
277 	ATTRMAP		= 7,		/* attribute mapping */
278 	OBJMAP		= 8,		/* objectclass mapping */
279 	SERVLIST	= 9,		/* serverlist (SP sep array) */
280 	ARRAYCRED	= 10,		/* Array of credentialLevels */
281 	SAMLIST		= 11,		/* serviceAuthenticationMethod */
282 	SCLLIST		= 12		/* serviceCredentialLevel */
283 } ns_datatype_t;
284 
285 typedef enum {
286 	NS_SUCCESS,
287 	NS_NOTFOUND,
288 	NS_PARSE_ERR
289 } ns_parse_status;
290 
291 typedef enum {
292 	NS_DOOR_FMT	= 1,
293 	NS_LDIF_FMT	= 2,
294 	NS_FILE_FMT	= 3
295 } ns_strfmt_t;
296 
297 /*
298  * This enum reduces the number of version string compares
299  * against NS_LDAP_VERSION_1 and NS_LDAP_VERSION_2
300  */
301 
302 typedef enum {
303 	NS_LDAP_V1	= 1000,
304 	NS_LDAP_V2	= 2000
305 } ns_version_t;
306 
307 /*
308  * enum<->string mapping construct
309  */
310 
311 typedef struct ns_enum_map {
312 	int	value;
313 	char	*name;
314 } ns_enum_map;
315 
316 #define	ENUM2INT(x)		((int)(x))
317 
318 #define	INT2PARAMINDEXENUM(x)	((ParamIndexType)(x))
319 #define	INT2SEARCHREFENUM(x)	((SearchRef_t)(x))
320 #define	INT2SCOPEENUM(x)	((ScopeType_t)(x))
321 #define	INT2AUTHENUM(x)		((AuthType_t)(x))
322 #define	INT2SECENUM(x)		((TlsType_t)(x))
323 #define	INT2PREFONLYENUM(x)	((PrefOnly_t)(x))
324 #define	INT2CREDLEVELENUM(x)	((CredLevel_t)(x))
325 #define	INT2SHADOWUPDATENUM(x)	((enableShadowUpdate_t)(x))
326 
327 #define	INT2LDAPRETURN(x)	((ns_ldap_return_code)(x))
328 #define	INT2CONFIGRETURN(x)	((ns_ldap_config_return_code)(x))
329 #define	INT2PARTIALRETURN(x)	((ns_ldap_partial_return_code)(x))
330 
331 /*
332  * This structure maps service name to rdn components
333  * for use in __ns_getDNs. It also defines the SSD-to-use
334  * service for use in __s_api_get_SSDtoUse_service.
335  * The idea of an SSD-to-use service is to reduce the configuration
336  * complexity. For a service, which does not have its own entries in
337  * the LDAP directory, SSD for it is useless, and should not be set.
338  * But since this service must share the container with at least
339  * one other service which does have it own entries, the SSD for
340  * this other service will be shared by this service.
341  * This other service is called the SSD-to-use service.
342  *
343  */
344 
345 typedef struct ns_service_map {
346 	char	*service;
347 	char	*rdn;
348 	char	*SSDtoUse_service;
349 } ns_service_map;
350 
351 /*
352  * This structure contains a single mapping from:
353  * service:orig -> list of mapped
354  */
355 
356 typedef enum {
357 	NS_ATTR_MAP,
358 	NS_OBJ_MAP
359 } ns_maptype_t;
360 
361 typedef struct ns_mapping {
362 	ns_maptype_t	type;
363 	char		*service;
364 	char		*orig;
365 	char		**map;
366 } ns_mapping_t;
367 
368 /*
369  * The following is the list of internal libsldap configuration data
370  * structures.  The configuration is populated normally once per
371  * application.  The assumption is that in applications can be
372  * relatively short lived (IE ls via nsswitch) so it is important to
373  * keep configuration to a minimum, but keep lookups fast.
374  *
375  * Assumptions:
376  * 1 configuration entry per domain, and almost always 1 domain
377  * per app.  Hooks exist for multiple domains per app.
378  *
379  * Configurations are read in from client file cache or from LDAP.
380  * Attribute/objectclass mappings are hashed to improve lookup
381  * speed.
382  */
383 
384 /*
385  * Hash entry types
386  */
387 typedef enum	_ns_hashtype_t {
388 	NS_HASH_AMAP	= 1,		/* attr map */
389 	NS_HASH_RAMAP	= 2,		/* reverse attr map */
390 	NS_HASH_OMAP	= 3,		/* oc map */
391 	NS_HASH_ROMAP	= 4,		/* reverse oc map */
392 	NS_HASH_VOID	= 5
393 } ns_hashtype_t;
394 
395 typedef struct ns_hash {
396 	ns_hashtype_t	h_type;
397 	ns_mapping_t	*h_map;
398 	struct ns_hash	*h_next;
399 	struct ns_hash	*h_llnext;
400 } ns_hash_t;
401 
402 /*
403  * This structure defines the format of an internal configuration
404  * parameter for ns_ldap client.
405  */
406 
407 typedef struct ns_param {
408 	ns_datatype_t	ns_ptype;
409 	int		ns_acnt;
410 	union {
411 		char	**ppc;
412 		int	*pi;
413 		char	*pc;
414 		int	i;
415 		time_t	tm;
416 	} ns_pu;
417 } ns_param_t;
418 
419 #define	ns_ppc	ns_pu.ppc
420 #define	ns_pi	ns_pu.pi
421 #define	ns_pc	ns_pu.pc
422 #define	ns_i	ns_pu.i
423 #define	ns_tm	ns_pu.tm
424 
425 /*
426  * This structure defines an instance of a configuration structure.
427  * paramList contains the current ns_ldap parameter configuration
428  * and hashTbl contain the current attribute/objectclass mappings.
429  * Parameters are indexed by using the value assigned to the parameter
430  * in ParamIndexType.
431  */
432 
433 typedef struct ns_config {
434 	char			*domainName;
435 	ns_version_t		version;
436 	ns_param_t		paramList[NS_LDAP_MAX_PIT_P];
437 	ns_hash_t		*hashTbl[NS_HASH_MAX];
438 	ns_hash_t		*llHead;
439 	ns_ldap_entry_t		*RootDSE;
440 	boolean_t		delete;
441 	mutex_t			config_mutex;
442 	int			nUse;
443 	ldap_get_chg_cookie_t	config_cookie;
444 } ns_config_t;
445 
446 /*
447  * This structure defines the mapping of the NSCONFIGFILE file
448  * statements into their corresponding SolarisNamingProfile,
449  * Posix Mapping LDAP attributes, and to their corresponding
450  * ParamIndexType enum mapping.  THe ParamIndexType enum
451  * definitions can be found in ns_ldap.h.  This structure also
452  * defines the default values that are used when a value either
453  * does not exist or is undefined.
454  */
455 
456 typedef struct ns_default_config {
457 	const char	*name;		/* config file parameter name */
458 	ParamIndexType	index;		/* config file enum index */
459 	ns_conftype_t	config_type;	/* CLIENT/SERVER/CREDCONFIG */
460 	ns_datatype_t	data_type;	/* ppc,pi,pc,int etc... */
461 	int		single_valued;	/* TRUE OR FALSE */
462 	ns_version_t	version;	/* Version # for attribute */
463 	const char	*profile_name;	/* profile schema attribute name */
464 	ns_param_t	defval;		/* config file parameter default */
465 	int		(*ns_verify)(ParamIndexType i,
466 				struct ns_default_config *def,
467 				ns_param_t *param,
468 				char *errbuf);
469 	ns_enum_map	*allowed;	/* allowed values */
470 } ns_default_config;
471 
472 
473 /*
474  * This typedef enumerates all the supported authentication
475  * mechanisms currently supported in this library
476  */
477 
478 typedef enum EnumAuthType {
479 	NS_LDAP_EA_NONE				= 0,
480 	NS_LDAP_EA_SIMPLE			= 1,
481 	NS_LDAP_EA_SASL_NONE			= 2,
482 	NS_LDAP_EA_SASL_CRAM_MD5		= 3,
483 	NS_LDAP_EA_SASL_DIGEST_MD5		= 4,
484 	NS_LDAP_EA_SASL_DIGEST_MD5_INT		= 5,
485 	NS_LDAP_EA_SASL_DIGEST_MD5_CONF		= 6,
486 	NS_LDAP_EA_SASL_EXTERNAL		= 7,
487 	NS_LDAP_EA_SASL_GSSAPI			= 8,
488 	NS_LDAP_EA_SASL_SPNEGO			= 9,	/* unsupported */
489 	NS_LDAP_EA_TLS_NONE			= 10,
490 	NS_LDAP_EA_TLS_SIMPLE			= 11,
491 	NS_LDAP_EA_TLS_SASL_NONE		= 12,
492 	NS_LDAP_EA_TLS_SASL_CRAM_MD5		= 13,
493 	NS_LDAP_EA_TLS_SASL_DIGEST_MD5		= 14,
494 	NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT	= 15,
495 	NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF	= 16,
496 	NS_LDAP_EA_TLS_SASL_EXTERNAL		= 17,
497 	NS_LDAP_EA_TLS_SASL_GSSAPI		= 18,	/* unsupported */
498 	NS_LDAP_EA_TLS_SASL_SPNEGO		= 19	/* unsupported */
499 } EnumAuthType_t;
500 
501 
502 /*
503  * this enum lists the various states of the search state machine
504  */
505 
506 typedef enum {
507 	INIT			= 1,
508 	EXIT			= 2,
509 	NEXT_SEARCH_DESCRIPTOR	= 3,
510 	GET_SESSION		= 4,
511 	NEXT_SESSION		= 5,
512 	RESTART_SESSION		= 6,
513 	NEXT_SEARCH		= 7,
514 	NEXT_VLV		= 8,
515 	NEXT_PAGE		= 9,
516 	ONE_SEARCH		= 10,
517 	DO_SEARCH		= 11,
518 	NEXT_RESULT		= 12,
519 	MULTI_RESULT		= 13,
520 	PROCESS_RESULT		= 14,
521 	END_PROCESS_RESULT	= 15,
522 	END_RESULT		= 16,
523 	NEXT_REFERRAL		= 17,
524 	GET_REFERRAL_SESSION	= 18,
525 	ERROR			= 19,
526 	LDAP_ERROR		= 20,
527 	GET_ACCT_MGMT_INFO	= 21,
528 	CLEAR_RESULTS		= 22,
529 	REINIT			= 23
530 } ns_state_t;
531 
532 /*
533  * this enum lists the various states of the write state machine
534  */
535 typedef enum {
536 	W_INIT			= 1,
537 	W_EXIT			= 2,
538 	GET_CONNECTION		= 3,
539 	SELECT_OPERATION_SYNC	= 4,
540 	SELECT_OPERATION_ASYNC	= 5,
541 	DO_ADD_SYNC		= 6,
542 	DO_DELETE_SYNC		= 7,
543 	DO_MODIFY_SYNC		= 8,
544 	DO_ADD_ASYNC		= 9,
545 	DO_DELETE_ASYNC		= 10,
546 	DO_MODIFY_ASYNC		= 11,
547 	GET_RESULT_SYNC		= 12,
548 	GET_RESULT_ASYNC	= 13,
549 	PARSE_RESULT		= 14,
550 	GET_REFERRAL_CONNECTION	= 15,
551 	W_LDAP_ERROR		= 16,
552 	W_ERROR			= 17
553 } ns_write_state_t;
554 
555 
556 typedef int ConnectionID;
557 
558 /*
559  * Server side sort type. Orginally the server side sort
560  * was set to "cn uid". This did not work with AD and
561  * hence single sort attribute was odopted. We dont
562  * know which server side sort will work with the
563  * Directory and hence we discover which method works.
564  */
565 typedef enum {
566 	SSS_UNKNOWN		= 0,
567 	SSS_SINGLE_ATTR		= 1,
568 	SSS_CN_UID_ATTRS	= 2
569 } ns_srvsidesort_t;
570 
571 /*
572  * This structure is used by ns_connect to create and manage
573  * one or more ldap connections within the library.
574  */
575 typedef struct connection {
576 	ConnectionID		connectionId;
577 	boolean_t		usedBit;	/* true if only used by */
578 						/* one thread and not shared */
579 						/* by other threads */
580 	pid_t			pid;		/* process id */
581 	char			*serverAddr;
582 	ns_cred_t		*auth;
583 	LDAP			*ld;
584 	thread_t		threadID;	/* thread ID using it */
585 	struct ns_ldap_cookie	*cookieInfo;
586 	char			**controls;		/* from server_info */
587 	char			**saslMechanisms;	/* from server_info */
588 } Connection;
589 
590 #define	ONE_STEP			1
591 
592 /*
593  * This structure is for referrals processing.
594  * The data are from referral URLs returned by
595  * LDAP servers
596  */
597 typedef struct ns_referral_info {
598 	struct ns_referral_info	*next;
599 	char			*refHost;
600 	int			refScope;
601 	char			*refDN;
602 	char			*refFilter;
603 } ns_referral_info_t;
604 
605 struct ns_ldap_cookie;
606 
607 /*
608  * Batch used by __ns_ldap_list_batch_xxx API
609  */
610 struct ns_ldap_list_batch {
611 	uint32_t		nactive;
612 	struct ns_ldap_cookie	*next_cookie;
613 	struct ns_ldap_cookie	*cookie_list;
614 };
615 
616 struct ns_conn_user;
617 typedef struct ns_conn_user ns_conn_user_t;
618 
619 /*
620  * This structure used internally in searches
621  */
622 
623 typedef struct ns_ldap_cookie {
624 	/* INPUTS */
625 		/* server list position */
626 
627 		/* service search descriptor list & position */
628 	ns_ldap_search_desc_t  **sdlist;
629 	ns_ldap_search_desc_t  **sdpos;
630 
631 		/* search filter callback */
632 	int			use_filtercb;
633 	int	(*init_filter_cb)(const ns_ldap_search_desc_t *desc,
634 			char **realfilter, const void *userdata);
635 
636 		/* user callback */
637 	int			use_usercb;
638 	int	(*callback)(const ns_ldap_entry_t *entry,
639 			const void *userdata);
640 	const void		*userdata;
641 
642 	int			followRef;
643 	int			use_paging;
644 	char			*service;
645 	char			*i_filter;
646 	const char * const	*i_attr;
647 	const char		*i_sortattr;
648 	const ns_cred_t		*i_auth;
649 	int			i_flags;
650 
651 	/* OUTPUTS */
652 	ns_ldap_result_t	*result;
653 	ns_ldap_entry_t		*nextEntry;
654 		/* Error data */
655 	int			err_rc;
656 	ns_ldap_error_t		*errorp;
657 
658 	/* PRIVATE */
659 	ns_state_t		state;
660 	ns_state_t		new_state;
661 	ns_state_t		next_state;
662 
663 	Connection		*conn;
664 #define	conn_auth_type	conn->auth->auth.type
665 	ConnectionID		connectionId;
666 
667 	/* paging VLV/SIMPLEPAGE data */
668 	int			listType;
669 	unsigned long		index;
670 	LDAPControl		**p_serverctrls;
671 	ns_srvsidesort_t	sortTypeTry;
672 	int			entryCount;
673 
674 	int			scope;
675 	char			*basedn;
676 	char			*filter;
677 	char			**attribute;
678 
679 	/* RESULT PROCESSING */
680 	int			msgId;
681 	LDAPMessage		*resultMsg;
682 
683 	char			**dns;
684 	char			*currentdn;
685 	int			flag;
686 	struct berval		*ctrlCookie;
687 
688 	/* REFERRALS PROCESSING */
689 	/* referralinfo list & position */
690 	ns_referral_info_t	*reflist;
691 	ns_referral_info_t	*refpos;
692 	/* search timeout value */
693 	struct timeval		search_timeout;
694 	/* response control to hold account management information */
695 	LDAPControl		**resultctrl;
696 	/* Flag to indicate password less account management is required */
697 	int			nopasswd_acct_mgmt;
698 	int			err_from_result;
699 	ns_conn_user_t		*conn_user;
700 
701 	/* BATCH PROCESSING */
702 	ns_ldap_list_batch_t	*batch;
703 	boolean_t		no_wait;
704 	boolean_t		reinit_on_retriable_err;
705 	int			retries;
706 	ns_ldap_result_t	**caller_result;
707 	ns_ldap_error_t		**caller_errorp;
708 	int			*caller_rc;
709 	struct ns_ldap_cookie	*next_cookie_in_batch;
710 } ns_ldap_cookie_t;
711 
712 /*
713  * This structure is part of the return value information for
714  * __s_api_requestServer.  The routine that requests a new server
715  * from the cache manager
716  */
717 typedef struct ns_server_info {
718 	char	*server;
719 	char	*serverFQDN;
720 	char	**controls;
721 	char	**saslMechanisms;
722 } ns_server_info_t;
723 
724 /*
725  * sasl callback function parameters
726  */
727 typedef struct ns_sasl_cb_param {
728 	char	*mech;
729 	char	*authid;
730 	char	*authzid;
731 	char	*passwd;
732 	char	*realm;
733 } ns_sasl_cb_param_t;
734 
735 /* Multiple threads per connection variable */
736 extern int MTperConn;
737 
738 /*
739  * INTERNAL GLOBAL DEFINITIONS AND FUNCTION DECLARATIONS
740  */
741 
742 #ifdef DEBUG
743 extern int	__ldap_debug_file;
744 extern int	__ldap_debug_api;
745 extern int	__ldap_debug_ldap;
746 extern int	__ldap_debug_servers;
747 #endif
748 
749 /* internal connection APIs */
750 void DropConnection(ConnectionID, int);
751 int __s_api_getServers(char *** servers, ns_ldap_error_t ** error);
752 
753 int __s_get_enum_value(ns_config_t *ptr, char *value, ParamIndexType i);
754 char *__s_get_auth_name(ns_config_t *ptr, AuthType_t type);
755 char *__s_get_security_name(ns_config_t *ptr, TlsType_t type);
756 char *__s_get_scope_name(ns_config_t *ptr, ScopeType_t type);
757 char *__s_get_pref_name(PrefOnly_t type);
758 char *__s_get_searchref_name(ns_config_t *ptr, SearchRef_t type);
759 char *__s_get_shadowupdate_name(enableShadowUpdate_t type);
760 char *__s_get_hostcertpath(void);
761 void __s_api_free_sessionPool();
762 int __s_api_requestServer(const char *request, const char *server,
763 	ns_server_info_t *ret, ns_ldap_error_t **error,  const char *addrType);
764 
765 
766 /* ************ internal sldap-api functions *********** */
767 void	__ns_ldap_freeEntry(ns_ldap_entry_t *ep);
768 void	__ns_ldap_freeASearchDesc(ns_ldap_search_desc_t *);
769 void	__s_api_split_key_value(char *buffer, char **name, char **value);
770 int	__s_api_printResult(ns_ldap_result_t *);
771 int	__s_api_getSearchScope(int *, ns_ldap_error_t **);
772 int	__s_api_getDNs(char ***, const char *,
773 	ns_ldap_error_t **);
774 int	__s_api_get_search_DNs_v1(char ***, const char *,
775 	ns_ldap_error_t **);
776 int	__s_api_getConnection(const char *, const int,
777 	const ns_cred_t *, int *,
778 	Connection **, ns_ldap_error_t **, int, int, ns_conn_user_t *);
779 char	**__s_api_cp2dArray(char **);
780 void	__s_api_free2dArray(char **);
781 
782 int	__s_api_isCtrlSupported(Connection *, char *);
783 ns_config_t *__ns_ldap_make_config(ns_ldap_result_t *result);
784 ns_auth_t  *__s_api_AuthEnumtoStruct(const EnumAuthType_t i);
785 boolean_t __s_api_peruser_proc(void);
786 boolean_t __s_api_nscd_proc(void);
787 char	*dvalue(char *);
788 char	*evalue(char *);
789 ns_ldap_error_t *__s_api_make_error(int, char *);
790 ns_ldap_error_t *__s_api_copy_error(ns_ldap_error_t *);
791 
792 /* ************ specific 'Standalone' functions ********** */
793 ns_ldap_return_code __s_api_ip2hostname(char *ipaddr, char **hostname);
794 struct hostent *__s_api_hostname2ip(const char *name,
795 				    struct hostent *result,
796 				    char *buffer,
797 				    int buflen,
798 				    int *h_errnop);
799 void	__s_api_setInitMode();
800 void	__s_api_unsetInitMode();
801 int	__s_api_isStandalone(void);
802 int __s_api_isInitializing();
803 ns_ldap_return_code __s_api_findRootDSE(const char *request,
804 					const char *server,
805 					const char *addrType,
806 					ns_server_info_t *ret,
807 					ns_ldap_error_t	**error);
808 ns_config_t *__s_api_create_config_door_str(char *config,
809 				ns_ldap_error_t **errorp);
810 
811 extern void	get_environment();
812 
813 /* internal Param APIs */
814 int		__ns_ldap_setParamValue(ns_config_t *ptr,
815 			const ParamIndexType type,
816 			const void *data, ns_ldap_error_t **error);
817 int		__s_api_get_type(const char *value, ParamIndexType *type);
818 int		__s_api_get_versiontype(ns_config_t *ptr, char *value,
819 					ParamIndexType *type);
820 int		__s_api_get_profiletype(char *value, ParamIndexType *type);
821 void		__s_api_init_config(ns_config_t *ptr);
822 void		__s_api_init_config_global(ns_config_t *ptr);
823 ns_parse_status __s_api_crosscheck(ns_config_t *domainptr, char *errstr,
824 					int check_dn);
825 ns_config_t	*__s_api_create_config(void);
826 ns_config_t	*__s_api_get_default_config(void);
827 ns_config_t	*__s_api_get_default_config_global(void);
828 ns_config_t	*__s_api_loadrefresh_config();
829 ns_config_t	*__s_api_loadrefresh_config_global();
830 void		__s_api_destroy_config(ns_config_t *ptr);
831 int		__s_api_get_configtype(ParamIndexType type);
832 const char	*__s_api_get_configname(ParamIndexType type);
833 char		*__s_api_strValue(ns_config_t *ptr, ParamIndexType i,
834 			ns_strfmt_t fmt);
835 void		__s_api_release_config(ns_config_t *cfg);
836 
837 /* internal attribute/objectclass mapping api's */
838 int		 __s_api_add_map2hash(ns_config_t *config,
839 				ns_hashtype_t type, ns_mapping_t *map);
840 void		__s_api_destroy_hash(ns_config_t *config);
841 int		__s_api_parse_map(char *cp, char **sid,
842 				char **origA, char ***mapA);
843 char		**__ns_ldap_mapAttributeList(const char *service,
844 				const char * const *origAttrList);
845 char		*__ns_ldap_mapAttribute(const char *service,
846 				const char *origAttr);
847 
848 /* internal configuration APIs */
849 void		__ns_ldap_setServer(int set);
850 ns_ldap_error_t	*__ns_ldap_LoadConfiguration();
851 ns_ldap_error_t	*__ns_ldap_LoadDoorInfo(LineBuf *configinfo, char *domainname,
852 				ns_config_t *new, int cred_only);
853 ns_ldap_error_t *__ns_ldap_DumpConfiguration(char *filename);
854 ns_ldap_error_t	*__ns_ldap_DumpLdif(char *filename);
855 int		__ns_ldap_cache_ping();
856 ns_ldap_error_t *__ns_ldap_print_config(int);
857 void		__ns_ldap_default_config();
858 int		__ns_ldap_download(const char *, char *, char *,
859 				ns_ldap_error_t **);
860 int __ns_ldap_check_dns_preq(int foreground, int mode_verbose, int mode_quiet,
861     const char *fname, ns_ldap_self_gssapi_config_t config,
862     ns_ldap_error_t **errpp);
863 
864 int __ns_ldap_check_gssapi_preq(int foreground, int mode_verbose,
865     int mode_quiet, ns_ldap_self_gssapi_config_t config,
866     ns_ldap_error_t **errpp);
867 
868 int __ns_ldap_check_all_preq(int foreground, int mode_verbose, int mode_quiet,
869     ns_ldap_self_gssapi_config_t config, ns_ldap_error_t **errpp);
870 
871 /* internal un-exposed APIs */
872 ns_cred_t	*__ns_ldap_dupAuth(const ns_cred_t *authp);
873 boolean_t	__s_api_is_auth_matched(const ns_cred_t *auth1,
874 		    const ns_cred_t *auth2);
875 int		__s_api_get_SSD_from_SSDtoUse_service(const char *service,
876 			ns_ldap_search_desc_t ***SSDlist,
877 			ns_ldap_error_t **errorp);
878 int		__s_api_prepend_automountmapname(const char *service,
879 			ns_ldap_search_desc_t ***SSDlist,
880 			ns_ldap_error_t ** errorp);
881 int		__s_api_prepend_automountmapname_to_dn(const char *service,
882 			char **basedn,
883 			ns_ldap_error_t ** errorp);
884 int		__s_api_convert_automountmapname(const char *service,
885 			char **dn, ns_ldap_error_t ** errorp);
886 int		__s_api_replace_mapped_attr_in_dn(
887 			const char *orig_attr, const char *mapped_attr,
888 			const char *dn, char **new_dn);
889 int		__s_api_append_default_basedn(
890 			const char *dn,
891 			char **new_dn,
892 			int *allocated,
893 			ns_ldap_error_t ** errorp);
894 int		__s_api_removeServer(const char *server);
895 void		__s_api_removeBadServers(char **server);
896 void		__s_api_free_server_info(ns_server_info_t *sinfo);
897 void		__s_api_freeConnection(Connection *con);
898 
899 /* internal referrals APIs */
900 int		__s_api_toFollowReferrals(const int flags,
901 			int *toFollow,
902 			ns_ldap_error_t **errorp);
903 int		__s_api_addRefInfo(ns_referral_info_t **head,
904 			char *url, char *baseDN, int *scope,
905 			char *filter, LDAP *ld);
906 void		__s_api_deleteRefInfo(ns_referral_info_t *head);
907 
908 /* callback routine for SSD filters */
909 int		__s_api_merge_SSD_filter(const ns_ldap_search_desc_t *desc,
910 			char **realfilter,
911 			const void *userdata);
912 
913 /* network address verification api */
914 int		__s_api_isipv4(char *addr);
915 int		__s_api_isipv6(char *addr);
916 int		__s_api_ishost(char *addr);
917 
918 /* password management routine */
919 ns_ldap_passwd_status_t
920 		__s_api_set_passwd_status(int errnum, char *errmsg);
921 int		__s_api_contain_passwd_control_oid(char **oids);
922 
923 /* password less account management routine */
924 int		__s_api_contain_account_usable_control_oid(char **oids);
925 
926 /* RFC 2307 section 5.6. Get a canonical name from entry */
927 char		*__s_api_get_canonical_name(ns_ldap_entry_t *entry,
928 			ns_ldap_attr_t *attrptr, int case_ignore);
929 
930 /* self/sasl/gssapi functions */
931 int		__s_api_sasl_bind_callback(
932 			LDAP		*ld,
933 			unsigned	flags,
934 			void		*defaults,
935 			void		*in);
936 
937 int		__s_api_self_gssapi_only_get(void);
938 
939 int		__print2buf(LineBuf *line, const char *toprint, char *sep);
940 
941 #ifdef __cplusplus
942 }
943 #endif
944 
945 #endif /* _NS_INTERNAL_H */
946