OpenSolaris_b135/cmd/nscd/nscd_switch.h

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_NSCD_SWITCH_H
#define	_NSCD_SWITCH_H

#ifdef	__cplusplus
extern "C" {
#endif

#include <nss_dbdefs.h>
#include <thread.h>
#include <libscf.h>
#define	__NSS_PRIVATE_INTERFACE
#include "nsswitch_priv.h"
#undef	__NSS_PRIVATE_INTERFACE
#include "nscd_db.h"
#include "nscd_config.h"

/*
 * max. length of e.g. "passwd: files ldap"
 */
#define	MAX_NSSWITCH_CONFIG_STRING_SZ 256

/*
 * max. length of the name of a NSS database
 */
#define	MAX_NSSWITCH_CONFIG_DB_NAME_SZ 256

/*
 * nscd_nsw_config_t is an abstraction of the configuration
 * for a NSS database
 */
typedef struct {
	char				*db_name;
	char				*nsw_cfg_str;
	nss_db_params_t			fe_params;
	struct __nsw_switchconfig_v1	*nsw_config;
	int				max_src;
	int				*src_idx;	/* ptr to array of */
							/* src index */
	int				nobase;		/* not shared */
} nscd_nsw_config_t;

/*
 * nscd_be_info_t is an abstraction of a NSS backend
 */
typedef struct {
	void			*be_version;
	nss_backend_constr_t	be_constr;
	nss_backend_finder_t	*finder;
	void			*finder_priv;
} nscd_be_info_t;

/*
 * nscd_state_ctrl_t is used to control a nscd_nsw_state pool
 */
typedef struct {
	int			max;
	int			allocated;
	int			free;
	int			waiter;
	struct nscd_nsw_state	*first;
} nscd_state_ctrl_t;

/*
 * nscd_nsw_state_base_t represents the nscd_nsw_state pool
 * for a NSS database
 */
typedef struct nscd_nsw_state_base {
	int			dbi;	/* which database? */
	nscd_state_ctrl_t	nsw_state;
	nscd_state_ctrl_t	nsw_state_thr;
	int			used_by_thr;
	thread_t		tid;
	cond_t			thr_cond;
} nscd_nsw_state_base_t;

/*
 * nscd_nsw_state_t is an abstraction of all the data needed
 * to do lookup of NSS database (e.g. "passwd" or "hosts")
 */
extern	void *_nscd_be_version;		/* default version for supported be */
typedef struct nscd_nsw_state {
	int				dbi;	/* which database? */
	int				max_src; /* is == config->num_lookups */
	int				getent; /* used by getent */
	nscd_bool_t			recheck_be; /* if set, check/init be */
	nss_db_params_t			p;
	struct __nsw_switchconfig_v1	*config;
	nscd_nsw_config_t		**nsw_cfg_p;
	nscd_nsw_state_base_t		*base;
	nss_backend_t			**be; /* array of backends */
	nss_backend_constr_t		*be_constr; /* be constructor array */
	nscd_db_t			***be_db_pp;
	void				**be_version_p; /* version ptr array */
	struct nscd_nsw_state		*next;
} nscd_nsw_state_t;

/*
 * nscd_getent_ctx_base_t represents the nscd_getent_ctx_base_t pool
 * for a NSS database
 */
typedef struct nscd_getent_ctx_base {
	int			dbi;		/* which database? */
	int			max_getent_ctx;
	int			num_getent_ctx;
	struct nscd_getent_context *first;
} nscd_getent_ctx_base_t;

/*
 * nscd_getent_context_t is an abstraction of all the data needed
 * to enumerate a NSS database (e.g. "passwd" or "hosts")
 */
typedef struct nscd_getent_context {
	int				dbi;
	thread_t			thr_id;
	mutex_t				getent_mutex;
	int				aborted;
	int				in_use;
	int				num_reclaim_check;
	nscd_seq_num_t			seq_num;
	nscd_cookie_num_t		cookie_num;
	pid_t				pid;	/* door client's pid */
	int				n_src;	/* >=max_src: end of sequence */
	nscd_nsw_state_t		*nsw_state;
	nss_backend_t			*be;
	nscd_getent_ctx_base_t		*base;
	struct nscd_getent_context	*next;
	struct nscd_getent_context	*next_to_reclaim;
} nscd_getent_context_t;

/*
 * nscd_smf_state_t is used to keep track of the state of the smf
 * service associated with a NSS source (e.g. "passwd" or "hosts")
 */
typedef struct {
	char	*src_name;
	int	src_state;
} nscd_smf_state_t;

/*
 * nscd_smf_state_t is used to keep track of the state of the smf
 * service associated with a NSS source (e.g. "passwd" or "hosts")
 */
typedef struct {
	int			dbi;		/* database index */
	/*
	 * index of the database of which the switch policy
	 * should be used
	 */
	int			cfgdbi;
	/*
	 * index of the pseudo database that the NSS backend
	 * does search on
	 */
	int			compati;
	/*
	 * ptr to ptr to the siwtch config structure
	 */
	nscd_nsw_config_t	**nswcfg;
	/*
	 * frontend params passed to nss_search or nss_*ent
	 */
	struct nss_db_params	p;
	/*
	 * set to 1 if database is "hosts", else 2 if "ipnodes"
	 */
	int8_t			dnsi;
	/*
	 * set to 1 if require privilege to look up the database
	 */
	uint8_t			privdb;
} nscd_nsw_params_t;

/*
 * additional info returned by the switch engine
 */
typedef struct {
	void	*pbuf;	/* ptr to packed buffer */
	size_t	pbufsiz; /* length of the packed buffer */
	int	srci;	/* last source searched */
	int	errnum; /* errno from the backend */
	int	noarg; /* if set, backend does not use the arg structure */
	int	fallback; /* if set, may need to fall back to main nscd */
	int	datalen; /* pbuf->data_len (backend may change it) */
} nscd_sw_return_t;

/*
 * nscd cookies used for setent/getent/endent
 * - p0 cookie: returned by nscd to indicate
 *              the start of the enumeration position
 * - p1 cookie: returned/updated by nscd to indicate
 *              the current enumeration position
 */
#define	NSCD_P0_COOKIE_SEQNUM	-1
typedef struct {
	pid_t		p0_pid;
	time_t		p0_time;
	nscd_seq_num_t	p0_seqnum;
} nscd_getent_p0_cookie_t;

typedef struct {
	nscd_cookie_num_t	p1_cookie_num;
	nscd_seq_num_t		p1_seqnum;
} nscd_getent_p1_cookie_t;

/*
 * static tables or global data defined in other files
 */
extern int			_nscd_cfg_num_nsw_src;
extern int			_nscd_cfg_num_nsw_src_all;
extern int			_nscd_cfg_num_nsw_db;
extern int			_nscd_cfg_num_nsw_db_all;
extern int			_nscd_cfg_num_smf_services;
extern nscd_cfg_id_t		_nscd_cfg_nsw_src[];
extern nscd_cfg_id_t		*_nscd_cfg_nsw_src_all;
extern nscd_cfg_id_t		_nscd_cfg_nsw_db[];
extern nss_db_initf_t		nscd_nss_db_initf[];
extern nscd_cfg_id_t		_nscd_cfg_smf_services[];
extern nscd_smf_state_t		*nscd_smf_service_state;
extern nscd_db_t		***nscd_src_backend_db;
extern nscd_nsw_config_t	***nscd_nsw_config;
extern nscd_nsw_state_base_t	**nscd_nsw_state_base;
extern nscd_getent_ctx_base_t	**nscd_getent_ctx_base;
extern nscd_cfg_global_switch_t	nscd_switch_cfg_g;
extern nscd_cfg_switch_t	*nscd_switch_cfg;
extern nscd_cfg_stat_global_switch_t nscd_switch_stats_g;
extern nscd_cfg_stat_switch_t	*nscd_switch_stats;

#define	NSCD_NUM_SRC		_nscd_cfg_num_nsw_src_all
#define	NSCD_NUM_DB		_nscd_cfg_num_nsw_db_all
#define	NSCD_NUM_SMF_FMRI	_nscd_cfg_num_smf_services
#define	NSCD_NSW_SRC_NAME(i)	(_nscd_cfg_nsw_src_all + i)->name
#define	NSCD_NSW_DB_NAME(i)	_nscd_cfg_nsw_db[i].name
#define	NSCD_SMF_SVC_FMRI(i)	_nscd_cfg_smf_services[i].name
#define	NSCD_SMF_SVC_INDEX(i)	_nscd_cfg_smf_services[i].index
#define	NSCD_SMF_SVC_STATE(i)	nscd_smf_service_state[i].src_state
#define	NSCD_SW_CFG_G		nscd_switch_cfg_g
#define	NSCD_SW_CFG(i)		nscd_switch_cfg[i]
#define	NSCD_SW_STATS_G		nscd_switch_stats_g
#define	NSCD_SW_STATS(i)	nscd_switch_stats[i]

/*
 * special service states used by the switch engine
 */
#define	NSCD_SVC_STATE_UNINITED		-1
#define	NSCD_SVC_STATE_FOREIGN_SRC	-2
#define	NSCD_SVC_STATE_UNSUPPORTED_SRC	-3

/*
 * prototypes
 */

void
_nscd_put_nsw_state(
	nscd_nsw_state_t	*s);

void
_nscd_put_nsw_state_thread(
	nscd_nsw_state_t	*s);

nscd_rc_t
_nscd_get_nsw_state(
	nss_db_root_t		*rootp,
	nscd_nsw_params_t	*params);

nscd_rc_t
_nscd_get_nsw_state_thread(
	nss_db_root_t		*rootp,
	nscd_nsw_params_t	*params);

nscd_rc_t
_nscd_init_all_nsw_state_base();

nscd_rc_t
_nscd_init_nsw_state_base(
	int			dbi,
	int			compat_basei,
	int			lock);

nscd_rc_t
_nscd_init_all_getent_ctx();

nscd_rc_t
_nscd_init_getent_ctx_base(
	int			dbi,
	int			lock);

nscd_db_t
*_nscd_create_getent_ctxaddrDB();

nscd_rc_t
_nscd_get_getent_ctx(
	nss_getent_t		*contextpp,
	nscd_nsw_params_t	*params);

void
_nscd_put_getent_ctx(
	nscd_getent_context_t	*ctx);
void
_nscd_free_ctx_if_aborted(
	nscd_getent_context_t	*ctx);

int
_nscd_is_getent_ctx_in_use(
	nscd_getent_context_t	*ctx);

nscd_rc_t
_nscd_init_all_nsw_config();

nscd_rc_t
_nscd_init_all_nsw_be_info_db();

#ifdef NSCD_NSSWITCH_CONF_FROM_SMF_PROP
nscd_rc_t
_nscd_get_new_nsw_config(
	scf_handle_t		*hndl,
	const char		*fmri,
	scf_propertygroup_t	*pg);
#endif

nscd_rc_t
_nscd_get_new_service_state(
	int			index,
	scf_handle_t		*hndl,
	scf_property_t		*prop);

nscd_getent_context_t *
_nscd_is_getent_ctx(
	nscd_cookie_num_t	cookie_num);

nscd_rc_t
_nscd_create_sw_struct(
	int			dbi,
	int			compat_basei,
	const char		*dbn,
	const char		*cfgstr,
	void			*swcfgv1,
	nscd_nsw_params_t	*params);

nscd_rc_t
_nscd_create_new_config(
	nscd_nsw_params_t	*params);

void
_nscd_free_nsw_config(
	nscd_nsw_config_t	*nswcfg);

nscd_rc_t
_nscd_init_smf_monitor();

nscd_rc_t
_nscd_alloc_nsw_config();

nscd_rc_t
_nscd_alloc_service_state_table();

nscd_rc_t
_nscd_alloc_nsw_state_base();

nscd_rc_t
_nscd_alloc_nsw_be_info_db();

nscd_rc_t
_nscd_alloc_getent_ctx_base();

void
_nscd_free_all_nsw_state_base();

void
_nscd_free_all_getent_ctx_base();

void
_nscd_free_all_nsw_config();

void
_nscd_free_all_nsw_backend_info_db();

struct __nsw_switchconfig_v1 *
_nsw_getoneconfig_v1(
	const char		*name,
	char			*linep,
	enum __nsw_parse_err	*errp);
int
__nsw_freeconfig_v1(
	struct __nsw_switchconfig_v1 *conf);

int
_nscd_get_smf_state(int srci, int dbi, int recheck);

void
nss_psearch(void *buffer, size_t length);
void
nss_psetent(void *buffer, size_t length, pid_t pid);
void
nss_pgetent(void *buffer, size_t length);
void
nss_pendent(void *buffer, size_t length);
void
nss_pdelete(void *buffer, size_t length);

nscd_rc_t _nscd_alloc_switch_cfg();
nscd_rc_t _nscd_alloc_switch_stats();
nscd_db_t *_nscd_create_getent_ctx_addrDB();
nscd_db_t *_nscd_create_getent_ctxDB();

#ifdef	__cplusplus
}
#endif

#endif	/* _NSCD_SWITCH_H */