changeset 4046:18a99a0d9b30

6496124 nscd: Unable to login with pam_unix_auth error 6520079 getent fails to match networks entries from nis or nisplus 6531269 the nscd exploits dynamic linking a little too much
author michen
date Mon, 16 Apr 2007 15:29:31 -0700
parents acbc9bc026ca
children a400e4a801fd
files usr/src/cmd/nscd/nscd_cfgdef.h usr/src/cmd/nscd/nscd_config.c usr/src/cmd/nscd/nscd_config.h usr/src/cmd/nscd/nscd_init.c usr/src/cmd/nscd/nscd_nswconfig.c usr/src/cmd/nscd/nscd_selfcred.c usr/src/cmd/nscd/nscd_switch.c usr/src/cmd/nscd/nscd_switch.h usr/src/lib/libc/port/gen/nss_dbdefs.c usr/src/lib/nsswitch/nis/common/getnetent.c usr/src/lib/nsswitch/nisplus/common/getnetent.c
diffstat 11 files changed, 449 insertions(+), 353 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/nscd/nscd_cfgdef.h	Mon Apr 16 15:18:11 2007 -0700
+++ b/usr/src/cmd/nscd/nscd_cfgdef.h	Mon Apr 16 15:29:31 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -220,7 +220,7 @@
 		{-1, pn}, type, (NSCD_CFG_PFLAG_GROUP | pflag), \
 		0, 0, 0,\
 		NSCD_SIZEOF(g_in_t, gf), offsetof(g_in_t, gf), -1, \
-		pcheck_p, nfunc_name, vfunc_name, NULL, NULL \
+		pcheck_p, nfunc_name, vfunc_name \
 	}
 
 #define	NSCD_CFG_PARAM_DESC(pn, type, pflag, pf, p_in_t, \
@@ -229,7 +229,7 @@
 		{-1, pn}, type, pflag, \
 		NSCD_SIZEOF(p_in_t, pf), offsetof(p_in_t, pf), -1, \
 		NSCD_SIZEOF(g_in_t, gf), offsetof(g_in_t, gf), -1, \
-		pcheck_p, nfunc_name, vfunc_name, NULL, NULL \
+		pcheck_p, nfunc_name, vfunc_name \
 	}
 
 #define	NSCD_CFG_PGROUP_DESC_NULL \
@@ -237,9 +237,32 @@
 		{-1, NULL}, -1, NSCD_CFG_PFLAG_GROUP, \
 		0, 0, 0, \
 		0, 0, 0, \
-		NULL, NULL, NULL, NULL, NULL \
+		NULL, NULL, NULL \
 	}
-#define	NSCD_CFG_FUNC_NAME_AS_GROUP	"(as_group)"
+
+/* nscd internal cfg_*_notify() cfg_*_verify() and cfg_*_get_stat()  */
+extern	nscd_rc_t	_nscd_cfg_log_notify();
+extern	nscd_rc_t	_nscd_cfg_log_verify();
+extern	nscd_rc_t	_nscd_cfg_frontend_notify();
+extern	nscd_rc_t	_nscd_cfg_frontend_verify();
+extern	nscd_rc_t	_nscd_cfg_selfcred_notify();
+extern	nscd_rc_t	_nscd_cfg_selfcred_verify();
+extern	nscd_rc_t	_nscd_cfg_switch_notify();
+extern	nscd_rc_t	_nscd_cfg_switch_verify();
+extern	nscd_rc_t	_nscd_cfg_cache_notify();
+extern	nscd_rc_t	_nscd_cfg_cache_verify();
+extern	nscd_rc_t	_nscd_cfg_log_get_stat();
+extern	nscd_rc_t	_nscd_cfg_switch_get_stat();
+extern	nscd_rc_t	_nscd_cfg_cache_get_stat();
+
+/*
+ * the following macros are used to indicate a parameter's
+ * notify/verify/get_stat functions are the same as those
+ * of the group
+ */
+#define	NSCD_CFG_FUNC_NOTIFY_AS_GROUP	((nscd_cfg_func_notify_t)-1)
+#define	NSCD_CFG_FUNC_VERIFY_AS_GROUP	((nscd_cfg_func_verify_t)-1)
+#define	NSCD_CFG_FUNC_GET_STAT_AS_GROUP	((nscd_cfg_func_get_stat_t)-1)
 
 /*
  * the static config parameter description table
@@ -254,8 +277,8 @@
 		log,
 		nscd_cfg_global_data_t,
 		NULL,
-		"_nscd_cfg_log_notify",
-		"_nscd_cfg_log_verify"),
+		_nscd_cfg_log_notify,
+		_nscd_cfg_log_verify),
 
 	NSCD_CFG_PARAM_DESC(
 		"logfile",
@@ -267,8 +290,8 @@
 		log,
 		nscd_cfg_global_data_t,
 		&NSCD_CFG_LOGFILE_PCHECK,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"debug-level",
@@ -279,8 +302,8 @@
 		log,
 		nscd_cfg_global_data_t,
 		&NSCD_CFG_LOGLEVEL_PCHECK,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"debug-components",
@@ -291,8 +314,8 @@
 		log,
 		nscd_cfg_global_data_t,
 		&NSCD_CFG_LOGCOMP_PCHECK,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PGROUP_DESC(
 		"param-group-global-frontend",
@@ -302,8 +325,8 @@
 		fe,
 		nscd_cfg_global_data_t,
 		NULL,
-		"_nscd_cfg_frontend_notify",
-		"_nscd_cfg_frontend_verify"),
+		_nscd_cfg_frontend_notify,
+		_nscd_cfg_frontend_verify),
 
 	NSCD_CFG_PARAM_DESC(
 		"common-worker-threads",
@@ -315,8 +338,8 @@
 		fe,
 		nscd_cfg_global_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"cache-hit-threads",
@@ -328,8 +351,8 @@
 		fe,
 		nscd_cfg_global_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PGROUP_DESC(
 		"param-group-global-selfcred",
@@ -339,8 +362,8 @@
 		sc,
 		nscd_cfg_global_data_t,
 		NULL,
-		"_nscd_cfg_selfcred_notify",
-		"_nscd_cfg_selfcred_verify"),
+		_nscd_cfg_selfcred_notify,
+		_nscd_cfg_selfcred_verify),
 
 	NSCD_CFG_PARAM_DESC(
 		"enable-selfcred",
@@ -351,8 +374,8 @@
 		sc,
 		nscd_cfg_global_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"max-per-user-nscd",
@@ -363,8 +386,8 @@
 		sc,
 		nscd_cfg_global_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"per-user-nscd-ttl",
@@ -375,8 +398,8 @@
 		sc,
 		nscd_cfg_global_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PGROUP_DESC(
 		"param-group-global-switch",
@@ -386,8 +409,8 @@
 		sw,
 		nscd_cfg_global_data_t,
 		NULL,
-		"_nscd_cfg_switch_notify",
-		"_nscd_cfg_switch_verify"),
+		_nscd_cfg_switch_notify,
+		_nscd_cfg_switch_verify),
 
 	NSCD_CFG_PARAM_DESC(
 		"global-enable-lookup",
@@ -398,8 +421,8 @@
 		sw,
 		nscd_cfg_global_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"global-enable-loopback-checking",
@@ -410,8 +433,8 @@
 		sw,
 		nscd_cfg_global_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"global-check-smf-state-interval",
@@ -422,8 +445,8 @@
 		sw,
 		nscd_cfg_global_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PGROUP_DESC(
 		"param-group-global-cache",
@@ -434,8 +457,8 @@
 		cache,
 		nscd_cfg_global_data_t,
 		NULL,
-		"_nscd_cfg_cache_notify",
-		"_nscd_cfg_cache_verify"),
+		_nscd_cfg_cache_notify,
+		_nscd_cfg_cache_verify),
 
 	NSCD_CFG_PARAM_DESC(
 		"global-enable-cache",
@@ -446,8 +469,8 @@
 		cache,
 		nscd_cfg_global_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	/* non-global config param from this point on */
 
@@ -458,8 +481,8 @@
 		fe,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		"_nscd_cfg_frontend_notify",
-		"_nscd_cfg_frontend_verify"),
+		_nscd_cfg_frontend_notify,
+		_nscd_cfg_frontend_verify),
 
 	NSCD_CFG_PARAM_DESC(
 		"worker-thread-per-nsw-db",
@@ -470,8 +493,8 @@
 		fe,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PGROUP_DESC(
 		"param-group-switch",
@@ -481,8 +504,8 @@
 		sw,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		"_nscd_cfg_switch_notify",
-		"_nscd_cfg_switch_verify"),
+		_nscd_cfg_switch_notify,
+		_nscd_cfg_switch_verify),
 
 	NSCD_CFG_PARAM_DESC(
 		"nsw-config-string",
@@ -494,8 +517,8 @@
 		sw,
 		nscd_cfg_nsw_db_data_t,
 		&NSCD_CFG_NSWCFGSTR_PCHECK,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"nsw-config-database",
@@ -507,8 +530,8 @@
 		sw,
 		nscd_cfg_nsw_db_data_t,
 		&NSCD_CFG_NSWCFGSTR_PCHECK,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"enable-lookup",
@@ -519,8 +542,8 @@
 		sw,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"enable-loopback-checking",
@@ -531,8 +554,8 @@
 		sw,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"max-nsw-state-per-db",
@@ -543,8 +566,8 @@
 		sw,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"max-nsw-state-per-thread",
@@ -555,8 +578,8 @@
 		sw,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"max-getent-ctx-per-db",
@@ -567,8 +590,8 @@
 		sw,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PGROUP_DESC(
 		"param-group-cache",
@@ -577,8 +600,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		"_nscd_cfg_cache_notify",
-		"_nscd_cfg_cache_verify"),
+		_nscd_cfg_cache_notify,
+		_nscd_cfg_cache_verify),
 
 	NSCD_CFG_PARAM_DESC(
 		"enable-cache",
@@ -589,8 +612,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"enable-per-user-cache",
@@ -601,8 +624,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"avoid-nameservice",
@@ -613,8 +636,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"check-files",
@@ -625,8 +648,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"check-file-interval",
@@ -637,8 +660,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"positive-time-to-live",
@@ -649,8 +672,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"negative-time-to-live",
@@ -661,8 +684,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"keep-hot-count",
@@ -673,8 +696,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"hint-size",
@@ -685,8 +708,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"maximum-entries-allowed",
@@ -697,8 +720,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"suggested-size",
@@ -709,8 +732,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PARAM_DESC(
 		"old-data-ok",
@@ -721,8 +744,8 @@
 		cache,
 		nscd_cfg_nsw_db_data_t,
 		NULL,
-		NSCD_CFG_FUNC_NAME_AS_GROUP,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_NOTIFY_AS_GROUP,
+		NSCD_CFG_FUNC_VERIFY_AS_GROUP),
 
 	NSCD_CFG_PGROUP_DESC_NULL
 };
@@ -739,7 +762,7 @@
 
 	NSCD_CFG_GROUP_INFO_GLOBAL_LOG,
 	NULL,
-	NSCD_LOG_LEVEL_ERROR,	/* debug_level */
+	NSCD_LOG_LEVEL_NONE,	/* debug_level */
 	NSCD_LOG_CACHE,		/* debug_comp */
 
 	},
@@ -983,7 +1006,7 @@
 		{-1, sn}, type, NSCD_CFG_SFLAG_GROUP | sflag, gi, \
 		0, 0, 0,\
 		NSCD_SIZEOF(g_in_t, gf), offsetof(g_in_t, gf), -1, \
-		gsfunc_name, NULL \
+		gsfunc_name \
 	}
 
 #define	NSCD_CFG_STAT_DESC(sn, type, sflag, sf, s_in_t, \
@@ -992,7 +1015,7 @@
 		{-1, sn}, type, sflag, NSCD_CFG_GROUP_INFO_NULL, \
 		NSCD_SIZEOF(s_in_t, sf), offsetof(s_in_t, sf), -1, \
 		NSCD_SIZEOF(g_in_t, gf), offsetof(g_in_t, gf), -1, \
-		gsfunc_name, NULL \
+		gsfunc_name \
 	}
 
 #define	NSCD_CFG_SGROUP_DESC_NULL \
@@ -1000,7 +1023,7 @@
 		{-1, NULL}, -1, NSCD_CFG_SFLAG_GROUP, NULL, \
 		0, 0, 0, \
 		0, 0, 0, \
-		NULL, NULL \
+		NULL \
 	}
 
 /*
@@ -1015,7 +1038,7 @@
 		NSCD_CFG_STAT_GROUP_INFO_GLOBAL_LOG,
 		log,
 		nscd_cfg_stat_global_data_t,
-		"_nscd_cfg_log_get_stat"),
+		_nscd_cfg_log_get_stat),
 
 	NSCD_CFG_STAT_DESC(
 		"entries-logged",
@@ -1025,7 +1048,7 @@
 		nscd_cfg_stat_global_log_t,
 		log,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_SGROUP_DESC(
 		"stat-group-global-switch",
@@ -1034,7 +1057,7 @@
 		NSCD_CFG_STAT_GROUP_INFO_GLOBAL_SWITCH,
 		sw,
 		nscd_cfg_stat_global_data_t,
-		"_nscd_cfg_switch_get_stat"),
+		_nscd_cfg_switch_get_stat),
 
 	NSCD_CFG_STAT_DESC(
 		"global-lookup-request-received",
@@ -1044,7 +1067,7 @@
 		nscd_cfg_stat_global_switch_t,
 		sw,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-lookup-request-queued",
@@ -1054,7 +1077,7 @@
 		nscd_cfg_stat_global_switch_t,
 		sw,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-lookup-request-in-progress",
@@ -1064,7 +1087,7 @@
 		nscd_cfg_stat_global_switch_t,
 		sw,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-lookup-request-succeeded",
@@ -1074,7 +1097,7 @@
 		nscd_cfg_stat_global_switch_t,
 		sw,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-lookup-request-failed",
@@ -1084,7 +1107,7 @@
 		nscd_cfg_stat_global_switch_t,
 		sw,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-loopback-nsw-db-skipped",
@@ -1094,7 +1117,7 @@
 		nscd_cfg_stat_global_switch_t,
 		sw,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_SGROUP_DESC(
 		"stat-group-global-cache",
@@ -1103,7 +1126,7 @@
 		NSCD_CFG_STAT_GROUP_INFO_CACHE,
 		cache,
 		nscd_cfg_stat_global_data_t,
-		"_nscd_cfg_cache_get_stat"),
+		_nscd_cfg_cache_get_stat),
 
 	NSCD_CFG_STAT_DESC(
 		"global-cache-hits-on-positive",
@@ -1113,7 +1136,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-cache-hits-on-negative",
@@ -1123,7 +1146,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-cache-misses-on-positive",
@@ -1133,7 +1156,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-cache-misses-on-negative",
@@ -1143,7 +1166,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-cache-queries-queued",
@@ -1153,7 +1176,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-total-cache-entries",
@@ -1163,7 +1186,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-complete-cache-invalidations",
@@ -1173,7 +1196,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-cache-queries-dropped",
@@ -1183,7 +1206,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"global-cache-hit-rate",
@@ -1193,7 +1216,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_global_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	/* non-global stat from this point on */
 
@@ -1204,7 +1227,7 @@
 		NSCD_CFG_STAT_GROUP_INFO_SWITCH,
 		cache,
 		nscd_cfg_stat_nsw_db_data_t,
-		"_nscd_cfg_switch_get_stat"),
+		_nscd_cfg_switch_get_stat),
 
 	NSCD_CFG_STAT_DESC(
 		"lookup-request-received",
@@ -1214,7 +1237,7 @@
 		nscd_cfg_stat_switch_t,
 		sw,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"lookup-request-queued",
@@ -1224,7 +1247,7 @@
 		nscd_cfg_stat_switch_t,
 		sw,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"lookup-request-in-progress",
@@ -1234,7 +1257,7 @@
 		nscd_cfg_stat_switch_t,
 		sw,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"lookup-request-succeeded",
@@ -1244,7 +1267,7 @@
 		nscd_cfg_stat_switch_t,
 		sw,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"lookup-request-failed",
@@ -1254,7 +1277,7 @@
 		nscd_cfg_stat_switch_t,
 		sw,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"loopback-nsw-db-skipped",
@@ -1264,7 +1287,7 @@
 		nscd_cfg_stat_switch_t,
 		sw,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_SGROUP_DESC(
 		"stat-group-cache",
@@ -1273,7 +1296,7 @@
 		NSCD_CFG_STAT_GROUP_INFO_CACHE,
 		cache,
 		nscd_cfg_stat_nsw_db_data_t,
-		"_nscd_cfg_cache_get_stat"),
+		_nscd_cfg_cache_get_stat),
 
 	NSCD_CFG_STAT_DESC(
 		"cache-hits-on-positive",
@@ -1283,7 +1306,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"cache-hits-on-negative",
@@ -1293,7 +1316,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"cache-misses-on-positive",
@@ -1303,7 +1326,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"cache-misses-on-negative",
@@ -1313,7 +1336,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"cache-queries-queued",
@@ -1323,7 +1346,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"total-cache-entries",
@@ -1333,7 +1356,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"complete-cache-invalidations",
@@ -1343,7 +1366,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"cache-hit-rate",
@@ -1353,7 +1376,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 	NSCD_CFG_STAT_DESC(
 		"cache-queries-dropped",
@@ -1363,7 +1386,7 @@
 		nscd_cfg_stat_cache_t,
 		cache,
 		nscd_cfg_stat_nsw_db_data_t,
-		NSCD_CFG_FUNC_NAME_AS_GROUP),
+		NSCD_CFG_FUNC_GET_STAT_AS_GROUP),
 
 
 	NSCD_CFG_SGROUP_DESC_NULL
--- a/usr/src/cmd/nscd/nscd_config.c	Mon Apr 16 15:18:11 2007 -0700
+++ b/usr/src/cmd/nscd/nscd_config.c	Mon Apr 16 15:29:31 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -171,63 +171,6 @@
 		NSCD_CFG_LIST_PARAM));
 }
 
-/* find function pointer in the executable via dlopen(0) */
-static nscd_rc_t
-_nscd_cfg_init_funcs(
-	char			*name,
-	void			**func_p,
-	nscd_cfg_error_t	**errorp)
-{
-	char			*me = "_nscd_cfg_init_funcs";
-	char			msg[NSCD_CFG_MAX_ERR_MSG_LEN];
-	static void		*handle = NULL;
-	void			*sym;
-	nscd_rc_t		rc = NSCD_SUCCESS;
-
-	if (name == NULL && handle != NULL) {
-		(void) dlclose(handle);
-		return (rc);
-	}
-	if (name == NULL)
-		return (rc);
-
-	if (handle == NULL) {
-		handle = dlopen((const char *)0, RTLD_LAZY);
-		if (handle == NULL) {
-
-			rc = NSCD_CFG_DLOPEN_ERROR;
-			(void) snprintf(msg, sizeof (msg),
-			gettext("unable to dlopen the nscd executable: %s"),
-				dlerror());
-			goto error_exit;
-		}
-	}
-
-	if (func_p) {
-		if ((sym = dlsym(handle, name)) == NULL) {
-
-			rc = NSCD_CFG_DLSYM_ERROR;
-			(void) snprintf(msg, sizeof (msg),
-gettext("unable to get the address of a symbol in the nscd executable: %s"),
-				dlerror());
-			goto error_exit;
-		} else
-			(void) memcpy(func_p, &sym, sizeof (void *));
-	}
-
-	return (rc);
-
-	error_exit:
-
-	_NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR)
-	(me, "%s\n", msg);
-	if (errorp != NULL)
-		*errorp = _nscd_cfg_make_error(rc, msg);
-
-	return (rc);
-}
-
-
 /*
  * FUNCTION: _nscd_cfg_create_paramDB
  *
@@ -426,37 +369,6 @@
 	return (NSCD_SUCCESS);
 }
 
-/*
- * get the address of a function in the nscd executable
- * and store it in where 'dest_p' points to
- */
-static nscd_rc_t
-_nscd_cfg_get_funcp(
-	char			*name,
-	void			*dest_p,
-	void			**gfunc_a,
-	nscd_cfg_error_t	**errorp)
-{
-
-	void			*func;
-	nscd_rc_t		rc;
-
-	if (gfunc_a != NULL) {
-
-		if (strcmp(name, NSCD_CFG_FUNC_NAME_AS_GROUP) == 0)
-			(void) memcpy(dest_p, gfunc_a, sizeof (void *));
-
-		return (NSCD_SUCCESS);
-	}
-
-	rc = _nscd_cfg_init_funcs(name, &func, errorp);
-	if (rc != NSCD_SUCCESS)
-		return (rc);
-	(void) memcpy(dest_p, &func, sizeof (func));
-
-	return (NSCD_SUCCESS);
-}
-
 static nscd_rc_t
 _nscd_cfg_init_param()
 {
@@ -501,26 +413,12 @@
 			fn = 0;
 			gdesc = desc;
 			g_info.bitmap = NSCD_CFG_BITMAP_ZERO;
-			nfunc = NULL;
-			vfunc = NULL;
 
 			/*
 			 * set the notify/verify functions
 			 */
-			if (gdesc->nfunc_name != NULL) {
-				rc = _nscd_cfg_get_funcp(gdesc->nfunc_name,
-					&gdesc->notify, NULL, NULL);
-				if (rc != NSCD_SUCCESS)
-					return (rc);
-				nfunc = (void *)gdesc->notify;
-			}
-			if (gdesc->vfunc_name != NULL) {
-				rc = _nscd_cfg_get_funcp(gdesc->vfunc_name,
-					&gdesc->verify, NULL, NULL);
-				if (rc != NSCD_SUCCESS)
-					return (rc);
-				vfunc = (void *)gdesc->verify;
-			}
+			nfunc = (void *)gdesc->notify;
+			vfunc = (void *)gdesc->verify;
 		} else {
 			if (i == 0) {
 
@@ -545,17 +443,13 @@
 			/*
 			 * set the notify/verify functions
 			 */
-			if (desc->nfunc_name != NULL) {
-				rc = _nscd_cfg_get_funcp(desc->nfunc_name,
-					&desc->notify, &nfunc, NULL);
-				if (rc != NSCD_SUCCESS)
-					return (rc);
+			if (desc->notify == NSCD_CFG_FUNC_NOTIFY_AS_GROUP) {
+				(void) memcpy(&desc->notify, &nfunc,
+					sizeof (void *));
 			}
-			if (desc->vfunc_name != NULL) {
-				rc = _nscd_cfg_get_funcp(desc->vfunc_name,
-					&desc->verify, &vfunc, NULL);
-				if (rc != NSCD_SUCCESS)
-					return (rc);
+			if (desc->verify == NSCD_CFG_FUNC_VERIFY_AS_GROUP) {
+				(void) memcpy(&desc->verify, &vfunc,
+					sizeof (void *));
 			}
 		}
 
@@ -645,18 +539,11 @@
 			fn = 0;
 			gdesc = desc;
 			g_info.bitmap = NSCD_CFG_BITMAP_ZERO;
-			gsfunc = NULL;
 
 			/*
 			 * set the get_stat function
 			 */
-			if (gdesc->gsfunc_name != NULL) {
-				rc = _nscd_cfg_get_funcp(gdesc->gsfunc_name,
-					&gdesc->get_stat, NULL, NULL);
-				if (rc != NSCD_SUCCESS)
-					return (rc);
-				gsfunc = (void *)gdesc->get_stat;
-			}
+			gsfunc = (void *)gdesc->get_stat;
 		} else {
 			if (i == 0) {
 
@@ -681,11 +568,9 @@
 			/*
 			 * set the get_stat function
 			 */
-			if (desc->gsfunc_name != NULL) {
-				rc = _nscd_cfg_get_funcp(desc->gsfunc_name,
-					&desc->get_stat, &gsfunc, NULL);
-				if (rc != NSCD_SUCCESS)
-					return (rc);
+			if (desc->get_stat == NSCD_CFG_FUNC_GET_STAT_AS_GROUP) {
+				(void) memcpy(&desc->get_stat, &gsfunc,
+					sizeof (void *));
 			}
 		}
 
--- a/usr/src/cmd/nscd/nscd_config.h	Mon Apr 16 15:18:11 2007 -0700
+++ b/usr/src/cmd/nscd/nscd_config.h	Mon Apr 16 15:29:31 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -260,6 +260,18 @@
  * to a set of data used for preliminary check of a parameter
  * value (range, length, null checking etc).
  */
+typedef	nscd_rc_t	(*nscd_cfg_func_notify_t)(void *,
+			struct nscd_cfg_param_desc *,
+			nscd_cfg_id_t *,
+			nscd_cfg_flag_t,
+			nscd_cfg_error_t **,
+			void *);
+typedef	nscd_rc_t	(*nscd_cfg_func_verify_t)(void *,
+			struct	nscd_cfg_param_desc *,
+			nscd_cfg_id_t *,
+			nscd_cfg_flag_t,
+			nscd_cfg_error_t **,
+			void **);
 typedef struct nscd_cfg_param_desc {
 	nscd_cfg_id_t		id;
 	nscd_cfg_data_type_t	type;
@@ -271,20 +283,8 @@
 	size_t	g_offset;
 	int	g_index;
 	void	*p_check;
-	char	*nfunc_name;
-	char	*vfunc_name;
-	nscd_rc_t	(*notify)(void			*data,
-			struct nscd_cfg_param_desc	*pdesc,
-			nscd_cfg_id_t			*nswdb,
-			nscd_cfg_flag_t			dflag,
-			nscd_cfg_error_t		**errorp,
-			void				*cookie);
-	nscd_rc_t	(*verify)(void			*data,
-			struct	nscd_cfg_param_desc	*pdesc,
-			nscd_cfg_id_t			*nswdb,
-			nscd_cfg_flag_t			dflag,
-			nscd_cfg_error_t		**errorp,
-			void				**cookie);
+	nscd_cfg_func_notify_t	notify;
+	nscd_cfg_func_verify_t	verify;
 } nscd_cfg_param_desc_t;
 
 /*
@@ -465,6 +465,13 @@
  * the stat data if the NSCD_CFG_DFLAG_STATIC_DATA bit is
  * not set in dflag.
  */
+struct nscd_cfg_stat_desc;
+typedef	nscd_rc_t	(*nscd_cfg_func_get_stat_t)(void **,
+			struct nscd_cfg_stat_desc *,
+			nscd_cfg_id_t *,
+			nscd_cfg_flag_t *,
+			void (**) (void *),
+			nscd_cfg_error_t **);
 typedef struct nscd_cfg_stat_desc {
 	nscd_cfg_id_t		id;
 	nscd_cfg_data_type_t	type;
@@ -476,14 +483,7 @@
 	int	g_size;
 	size_t	g_offset;
 	int	g_index;
-	char	*gsfunc_name;
-	nscd_rc_t	(*get_stat)(void		**stat,
-			struct nscd_cfg_stat_desc	*sdesc,
-			nscd_cfg_id_t			*nswdb,
-			nscd_cfg_flag_t			*dflag,
-			void				(**free_stat)
-							(void *stat),
-			nscd_cfg_error_t		**errorp);
+	nscd_cfg_func_get_stat_t get_stat;
 } nscd_cfg_stat_desc_t;
 
 /*
--- a/usr/src/cmd/nscd/nscd_init.c	Mon Apr 16 15:18:11 2007 -0700
+++ b/usr/src/cmd/nscd/nscd_init.c	Mon Apr 16 15:29:31 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -126,15 +126,6 @@
 	}
 
 	/*
-	 * populate the backend info databases
-	 */
-	if ((rc = _nscd_populate_nsw_backend_info()) != NSCD_SUCCESS) {
-		_NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR)
-		(me, "_nscd_init_all_nsw_be_info_db failed (rc = %d)\n", rc);
-		return (rc);
-	}
-
-	/*
 	 * initialize config/stats management
 	 */
 	rc = _nscd_cfg_init(&err);
--- a/usr/src/cmd/nscd/nscd_nswconfig.c	Mon Apr 16 15:18:11 2007 -0700
+++ b/usr/src/cmd/nscd/nscd_nswconfig.c	Mon Apr 16 15:29:31 2007 -0700
@@ -19,12 +19,16 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
+#include <nss_common.h>
+#include <dlfcn.h>
+#include <alloca.h>
+
 #include <stdlib.h>
 #include <libscf_priv.h>
 #include <string.h>
@@ -34,12 +38,30 @@
 #include "nscd_db.h"
 
 /*
+ * _nscd_nss_finders is used to replace the nss_default_finders in libc
+ * to allow nscd to have more control over the dl handles when using
+ * dlsym to get the address of the nss backend instance constructors
+ */
+static nss_backend_constr_t _nscd_per_src_lookup(void *,
+	const char *, const char *, void **);
+static void _nscd_per_src_delete(void *, nss_backend_constr_t);
+
+static nss_backend_finder_t _nscd_per_src = {
+	_nscd_per_src_lookup,
+	_nscd_per_src_delete,
+	0,
+	0 };
+
+nss_backend_finder_t *_nscd_nss_finders = &_nscd_per_src;
+
+/*
  * nscd database for each source. It contains backend
  * info (nscd_be_info_t) for each naming database.
  * Protected by nscd_src_backend_db_lock.
  */
 nscd_db_t	***nscd_src_backend_db;
-static rwlock_t nscd_src_backend_db_lock = DEFAULTRWLOCK;
+int		*nscd_src_backend_db_loaded;
+static		rwlock_t nscd_src_backend_db_lock = DEFAULTRWLOCK;
 
 /*
  * nsswitch config monitored by nscd. Protected by
@@ -149,6 +171,7 @@
 
 		nscd_src_backend_db[i] = (nscd_db_t **)_nscd_set(
 			(nscd_acc_data_t *)db, NULL);
+		nscd_src_backend_db_loaded[i] = 0;
 	}
 	(void) rw_unlock(&nscd_src_backend_db_lock);
 }
@@ -169,6 +192,7 @@
 	char			*src = NSCD_NSW_SRC_NAME(srci);
 	const char		*dbn;
 	char			*me = "_nscd_populate_nsw_backend_info_db";
+	void			*handle = NULL;
 
 	for (i = 0; i < NSCD_NUM_DB; i++) {
 
@@ -186,12 +210,12 @@
 				bf = bf->next) {
 			nss_backend_constr_t c;
 
-			c = (*bf->lookup)(bf->lookup_priv, dbn, src,
-				&be_info.finder_priv);
+			c = (*bf->lookup)(handle, dbn, src, &handle);
 
 			if (c != 0) {
 				be_info.be_constr = c;
 				be_info.finder = bf;
+				be_info.finder_priv = handle;
 				break;
 			}
 		}
@@ -226,8 +250,9 @@
 		bi = (nscd_be_info_t *)*(db_entry->data_array);
 		*bi = be_info;
 
-		(void) _nscd_rdlock((nscd_acc_data_t *)
+		(void) _nscd_wrlock((nscd_acc_data_t *)
 				nscd_src_backend_db[srci]);
+		nscd_src_backend_db_loaded[srci] = 1;
 		(void) _nscd_add_db_entry(*nscd_src_backend_db[srci],
 			dbn, db_entry, NSCD_ADD_DB_ENTRY_LAST);
 		(void) _nscd_rw_unlock((nscd_acc_data_t *)
@@ -327,7 +352,8 @@
 			strcmp(lkp->service_name,
 			NSCD_NSW_SRC_NAME(k)) != 0; k++);
 
-		if (k < NSCD_NUM_SRC && NSCD_NSW_SRC_NAME(k) == NULL) {
+		if (k < NSCD_NUM_SRC &&
+			nscd_src_backend_db_loaded[k] == 0) {
 			_NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG)
 			(me, "unknown nsw source name %s\n",
 			lkp->service_name);
@@ -412,7 +438,7 @@
 	 */
 	nsw_cfg->fe_params.max_active_per_src = 10;
 	nsw_cfg->fe_params.max_dormant_per_src = 1;
-	nsw_cfg->fe_params.finders = nss_default_finders;
+	nsw_cfg->fe_params.finders = _nscd_nss_finders;
 	if (params != NULL) {
 		nsw_cfg->fe_params = params->p;
 
@@ -545,7 +571,7 @@
 	 */
 	nsw_cfg->fe_params.max_active_per_src = 10;
 	nsw_cfg->fe_params.max_dormant_per_src = 1;
-	nsw_cfg->fe_params.finders = nss_default_finders;
+	nsw_cfg->fe_params.finders = _nscd_nss_finders;
 	(void) (nscd_nss_db_initf[dbi])(&nsw_cfg->fe_params);
 
 	/*
@@ -658,6 +684,11 @@
 	nscd_src_backend_db = calloc(NSCD_NUM_SRC, sizeof (nscd_db_t **));
 	if (nscd_src_backend_db == NULL)
 		return (NSCD_NO_MEMORY);
+	nscd_src_backend_db_loaded = calloc(NSCD_NUM_SRC, sizeof (int));
+	if (nscd_src_backend_db_loaded == NULL) {
+		free(nscd_src_backend_db);
+		return (NSCD_NO_MEMORY);
+	}
 
 	/* also allocate/init the nsswitch source index/name array */
 	_nscd_cfg_nsw_src_all = (nscd_cfg_id_t *)calloc(
@@ -686,3 +717,60 @@
 
 	return (NSCD_SUCCESS);
 }
+
+/*
+ * The following defines nscd's own lookup and delete functions
+ * that are to be stored in nss_backend_finder_t which is used
+ * by _nscd_populate_nsw_backend_info_db() to initialize the
+ * various nss backend instances
+ */
+
+static const int  dlopen_version  = 1;
+#ifndef NSS_DLOPEN_FORMAT
+#define	NSS_DLOPEN_FORMAT "nss_%s.so.%d"
+#endif
+#ifndef NSS_DLSYM_FORMAT
+#define	NSS_DLSYM_FORMAT "_nss_%s_%s_constr"
+#endif
+static const char dlopen_format[] = NSS_DLOPEN_FORMAT;
+static const char dlsym_format [] = NSS_DLSYM_FORMAT;
+static const size_t  format_maxlen   = sizeof (dlsym_format) - 4;
+
+/*ARGSUSED*/
+static nss_backend_constr_t
+_nscd_per_src_lookup(void *handle, const char *db_name, const char *src_name,
+	void **delete_privp)
+{
+	char			*name;
+	void			*dlhandle;
+	void			*sym;
+	size_t			len;
+	nss_backend_constr_t	res = NULL;
+
+	len = format_maxlen + strlen(db_name) + strlen(src_name);
+	name = alloca(len);
+	dlhandle = handle;
+	if ((dlhandle = handle) == NULL) {
+		(void) sprintf(name, dlopen_format, src_name, dlopen_version);
+		dlhandle = dlopen(name, RTLD_LAZY);
+	}
+
+	if (dlhandle != NULL) {
+		(void) sprintf(name, dlsym_format, src_name, db_name);
+		if ((sym = dlsym(dlhandle, name)) == 0) {
+			if (handle == NULL)
+				(void) dlclose(dlhandle);
+		} else {
+			*delete_privp = dlhandle;
+			res = (nss_backend_constr_t)sym;
+		}
+	}
+	return (res);
+}
+
+/*ARGSUSED*/
+static void
+_nscd_per_src_delete(void *delete_priv, nss_backend_constr_t dummy)
+{
+	(void) dlclose(delete_priv);
+}
--- a/usr/src/cmd/nscd/nscd_selfcred.c	Mon Apr 16 15:18:11 2007 -0700
+++ b/usr/src/cmd/nscd/nscd_selfcred.c	Mon Apr 16 15:29:31 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -1211,6 +1211,12 @@
 		free(selfcred_dbs);
 	selfcred_dbs = _nscd_srcs_in_db_nsw_policy(1, &srcs);
 
+	if (selfcred_dbs == NULL) {
+		is_on =  0;
+		checked = 1;
+		return (0);
+	}
+
 	/*
 	 * also check the ldap backend to see if
 	 * the configuration there is good for
@@ -1224,8 +1230,7 @@
 			ldap_on = 1;
 	}
 
-	is_on = pu_nscd_enabled == nscd_true &&
-			ldap_on && selfcred_dbs != NULL;
+	is_on = (pu_nscd_enabled == nscd_true) && ldap_on;
 
 	checked = 1;
 
--- a/usr/src/cmd/nscd/nscd_switch.c	Mon Apr 16 15:18:11 2007 -0700
+++ b/usr/src/cmd/nscd/nscd_switch.c	Mon Apr 16 15:29:31 2007 -0700
@@ -377,7 +377,8 @@
 
 /*
  * Determine if a request should be done locally in the getXbyY caller's
- * process. Return none zero if yes, 0 otherwise.
+ * process. Return none zero if yes, 0 otherwise. This should be called
+ * before the switch engine steps through the backends/sources.
  * This function returnis 1 if:
  *   -- the database is exec_attr and the search_flag is GET_ALL
  */
@@ -406,6 +407,37 @@
 	return (rc);
 }
 
+/*
+ * Determine if a request should be done locally in the getXbyY caller's
+ * process. Return none zero if yes, 0 otherwise. This should be called
+ * before the switch engine invokes any backend.
+ * This function returnis 1 if:
+ *   -- the database is shadow and the source is nisplus
+ */
+static int
+try_local2(
+	int	dbi,
+	int	srci)
+{
+	int	rc = 0;
+	char	*me = "try_local2";
+
+	if (*NSCD_NSW_DB_NAME(dbi) == 's' &&
+		strcmp(NSCD_NSW_DB_NAME(dbi), NSS_DBNAM_SHADOW) == 0) {
+		if (strcmp(NSCD_NSW_SRC_NAME(srci), "nisplus") == 0)
+			rc = 1;
+	}
+
+	if (rc != 0) {
+
+		_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
+		(me, "TRYLOCAL: database: shadow, source: nisplus\n");
+	}
+
+	return (rc);
+}
+
+
 static nscd_rc_t
 get_gss_func(void **func_p)
 {
@@ -714,7 +746,8 @@
 		smf_state = _nscd_get_smf_state(srci, dbi, 0);
 
 		/* stop if the source is one that should be TRYLOCAL */
-		if (smf_state == NSCD_SVC_STATE_UNKNOWN_SRC) {
+		if (smf_state == NSCD_SVC_STATE_UNKNOWN_SRC ||
+			(params.privdb && try_local2(dbi, srci) == 1)) {
 			_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE,
 					NSCD_LOG_LEVEL_DEBUG)
 			(me, "returning TRYLOCAL ... \n");
@@ -1058,7 +1091,8 @@
 		srci = (*s->nsw_cfg_p)->src_idx[i];
 		st = _nscd_get_smf_state(srci, params.dbi, 1);
 		if (st == NSCD_SVC_STATE_UNKNOWN_SRC ||
-				st == NSCD_SVC_STATE_UNINITED) {
+			st == NSCD_SVC_STATE_UNINITED || (params.privdb &&
+			try_local2(params.dbi, srci) == 1)) {
 			nss_endent_u(rootp, initf, contextpp);
 
 			_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE,
--- a/usr/src/cmd/nscd/nscd_switch.h	Mon Apr 16 15:18:11 2007 -0700
+++ b/usr/src/cmd/nscd/nscd_switch.h	Mon Apr 16 15:29:31 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -410,7 +410,6 @@
 nscd_rc_t _nscd_alloc_switch_cfg();
 nscd_rc_t _nscd_alloc_switch_stats();
 nscd_db_t *_nscd_create_getent_ctx_addrDB();
-nscd_rc_t _nscd_populate_nsw_backend_info();
 nscd_db_t *_nscd_create_getent_ctxDB();
 
 #ifdef	__cplusplus
--- a/usr/src/lib/libc/port/gen/nss_dbdefs.c	Mon Apr 16 15:18:11 2007 -0700
+++ b/usr/src/lib/libc/port/gen/nss_dbdefs.c	Mon Apr 16 15:29:31 2007 -0700
@@ -197,33 +197,35 @@
 	const char	*initfn;	/* init function name */
 	const char	*strfn;		/* str2X function name */
 	const char	*cstrfn;	/* cstr2X function name */
+	void		*initfnp;	/* init function pointer */
+	void		*strfnp;	/* str2X function pointer */
 	uint32_t	dbop;		/* NSS_DBOP_* */
 	const char	*tostr;		/* key2str cvt str */
 } getXbyY_to_dbop_t;
 
 #define	NSS_MK_GETXYDBOP(x, y, f, e)	\
 	{ NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, "str2" f, \
-		NULL, NSS_DBOP_##x##_##y, (e) }
+		NULL, NULL, NULL, NSS_DBOP_##x##_##y, (e) }
 
 #define	NSS_MK_GETXYDBOPA(x, a, f, e)	\
 	{ NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, "str2" f, \
-		NULL, NSS_DBOP_##a, (e) }
+		NULL, NULL, NULL, NSS_DBOP_##a, (e) }
 
 #define	NSS_MK_GETXYDBOPB(x, b, a, f, s, e)	\
 	{ NSS_DBNAM_##x, NSS_DEFCONF_##b, "_nss_initf_" f, s,  \
-		NULL, NSS_DBOP_##a, (e) }
+		NULL, NULL, NULL, NSS_DBOP_##a, (e) }
 
 #define	NSS_MK_GETXYDBOPC(x, a, f, s, e)	\
 	{ NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, s, \
-		NULL, NSS_DBOP_##x##_##a, (e) }
+		NULL, NULL, NULL, NSS_DBOP_##x##_##a, (e) }
 
 #define	NSS_MK_GETXYDBOPD(x, y, i, f, e)	\
 	{ NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" i, "str2" f, \
-		NULL, NSS_DBOP_##x##_##y, (e) }
+		NULL, NULL, NULL, NSS_DBOP_##x##_##y, (e) }
 
 #define	NSS_MK_GETXYDBOPCSTR(x, a, f, s, e)	\
 	{ NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, s, \
-		"process_cstr", NSS_DBOP_##x##_##a, (e) }
+		"process_cstr", NULL, NULL, NSS_DBOP_##x##_##a, (e) }
 
 /*
  * The getXbyY_to_dbop structure is hashed on first call in order to
@@ -1037,29 +1039,68 @@
 nss_pinit_funcs(int index, nss_db_initf_t *initf, nss_str2ent_t *s2e)
 {
 	const char	*name;
-	void	*handle;
-	void	*sym;
+	void		*htmp = NULL;
+	void		*sym;
+	static void	*handle = NULL;
+	static mutex_t	handle_lock = DEFAULTMUTEX;
+	static mutex_t	initf_lock = DEFAULTMUTEX;
+	static mutex_t	s2e_lock = DEFAULTMUTEX;
 
-	if ((handle = dlopen((const char *)0, RTLD_LAZY)) != NULL) {
-		if (initf) {
-			name = getXbyY_to_dbop[index].initfn;
-			if ((sym = dlsym(handle, name)) == 0) {
-				(void) dlclose(handle);
+	if (handle == NULL) {
+		lmutex_lock(&handle_lock);
+		if (handle == NULL) {
+			htmp = dlopen((const char *)0, RTLD_LAZY);
+			if (htmp == NULL) {
+				lmutex_unlock(&handle_lock);
 				return (NSS_ERROR);
 			} else {
-				*initf = (nss_db_initf_t)sym;
+				membar_producer();
+				handle = htmp;
 			}
 		}
-		if (s2e) {
-			name = getXbyY_to_dbop[index].strfn;
-			if ((sym = dlsym(handle, name)) == 0) {
-				(void) dlclose(handle);
-				return (NSS_ERROR);
-			} else {
-				*s2e = (nss_str2ent_t)sym;
+		lmutex_unlock(&handle_lock);
+	}
+	membar_consumer();
+
+	if (initf) {
+		if (getXbyY_to_dbop[index].initfnp != NULL) {
+			membar_consumer();
+			*initf = (nss_db_initf_t)getXbyY_to_dbop[index].initfnp;
+		} else {
+			lmutex_lock(&initf_lock);
+			if (getXbyY_to_dbop[index].initfnp == NULL) {
+				name = getXbyY_to_dbop[index].initfn;
+				if ((sym = dlsym(handle, name)) == 0) {
+					lmutex_unlock(&initf_lock);
+					return (NSS_ERROR);
+				}
+				getXbyY_to_dbop[index].initfnp = sym;
 			}
+			membar_producer();
+			*initf = (nss_db_initf_t)getXbyY_to_dbop[index].initfnp;
+			lmutex_unlock(&initf_lock);
 		}
 	}
+	if (s2e) {
+		if (getXbyY_to_dbop[index].strfnp != NULL) {
+			membar_consumer();
+			*s2e = (nss_str2ent_t)getXbyY_to_dbop[index].strfnp;
+		} else {
+			lmutex_lock(&s2e_lock);
+			if (getXbyY_to_dbop[index].strfnp == NULL) {
+				name = getXbyY_to_dbop[index].strfn;
+				if ((sym = dlsym(handle, name)) == 0) {
+					lmutex_unlock(&s2e_lock);
+					return (NSS_ERROR);
+				}
+				getXbyY_to_dbop[index].strfnp = sym;
+			}
+			membar_producer();
+			*s2e = (nss_str2ent_t)getXbyY_to_dbop[index].strfnp;
+			lmutex_unlock(&s2e_lock);
+		}
+	}
+
 	return (NSS_SUCCESS);
 }
 
--- a/usr/src/lib/nsswitch/nis/common/getnetent.c	Mon Apr 16 15:18:11 2007 -0700
+++ b/usr/src/lib/nsswitch/nis/common/getnetent.c	Mon Apr 16 15:29:31 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -19,11 +18,13 @@
  *
  * CDDL HEADER END
  */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
 /*
  *	nis/getnetent.c -- "nis" backend for nsswitch "networks" database
- *
- *	Copyright (c) 1988-1992 Sun Microsystems Inc
- *	All Rights Reserved.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -36,17 +37,17 @@
 #include <arpa/inet.h>
 #include <string.h>
 
-static int nettoa(int anet, char *buf, int buflen);
+static int nettoa(int anet, char *buf, int buflen, char **pnull);
 
 static nss_status_t
 getbyname(be, a)
 	nis_backend_ptr_t	be;
 	void			*a;
 {
-	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *) a;
+	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *)a;
 
 	return (_nss_nis_lookup(be, argp, 1, "networks.byname",
-			      argp->key.name, 0));
+		argp->key.name, 0));
 }
 
 static nss_status_t
@@ -54,12 +55,25 @@
 	nis_backend_ptr_t	be;
 	void			*a;
 {
-	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *) a;
+	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *)a;
 	char			addrstr[16];
+	char			*pnull;
+	nss_status_t		rc;
+
+	if (nettoa((int)argp->key.netaddr.net, addrstr, 16, &pnull) != 0)
+		return (NSS_UNAVAIL);	/* it's really ENOMEM */
+	rc = _nss_nis_lookup(be, argp, 1, "networks.byaddr", addrstr, 0);
 
-	if (nettoa((int) argp->key.netaddr.net, addrstr, 16) != 0)
-		return (NSS_UNAVAIL);	/* it's really ENOMEM */
-	return (_nss_nis_lookup(be, argp, 1, "networks.byaddr", addrstr, 0));
+	/*
+	 * if not found, try again with the untruncated address string
+	 * that has the trailing zero(s)
+	 */
+	if (rc == NSS_NOTFOUND && pnull != NULL) {
+		*pnull = '.';
+		rc = _nss_nis_lookup(be, argp, 1, "networks.byaddr",
+			addrstr, 0);
+	}
+	return (rc);
 }
 
 static nis_backend_op_t net_ops[] = {
@@ -84,18 +98,18 @@
 /*
  * Takes an unsigned integer in host order, and returns a printable
  * string for it as a network number.  To allow for the possibility of
- * naming subnets, only trailing dot-zeros are truncated.
+ * naming subnets, only trailing dot-zeros are truncated. The location
+ * where the string is truncated (or set to '\0') is returned in *pnull.
  */
 static int
-nettoa(anet, buf, buflen)
-	int		anet;
-	char	*buf;
-	int		buflen;		
+nettoa(int anet, char *buf, int buflen, char **pnull)
 {
 	char *p;
 	struct in_addr in;
 	int addr;
 
+	*pnull = NULL;
+
 	if (buf == 0)
 		return (1);
 	in = inet_makeaddr(anet, INADDR_ANY);
@@ -106,6 +120,7 @@
 		if (p == NULL)
 			return (1);
 		*p = 0;
+		*pnull = p;
 	} else if ((IN_CLASSB_HOST & htonl(addr)) == 0) {
 		p = strchr(buf, '.');
 		if (p == NULL)
@@ -114,11 +129,13 @@
 		if (p == NULL)
 			return (1);
 		*p = 0;
+		*pnull = p;
 	} else if ((IN_CLASSC_HOST & htonl(addr)) == 0) {
 		p = strrchr(buf, '.');
 		if (p == NULL)
 			return (1);
 		*p = 0;
+		*pnull = p;
 	}
 	return (0);
 }
--- a/usr/src/lib/nsswitch/nisplus/common/getnetent.c	Mon Apr 16 15:18:11 2007 -0700
+++ b/usr/src/lib/nsswitch/nisplus/common/getnetent.c	Mon Apr 16 15:29:31 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -36,7 +36,7 @@
 #include "nisplus_common.h"
 #include "nisplus_tables.h"
 
-static int nettoa(int anet, char *buf, int buflen);
+static int nettoa(int anet, char *buf, int buflen, char **pnull);
 
 static nss_status_t
 getbyname(be, a)
@@ -57,13 +57,24 @@
 	nisplus_backend_ptr_t	be;
 	void			*a;
 {
-	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *)a;
+	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
 	char		addrstr[16];
+	char		*pnull;
+	nss_status_t	rc;
+
+	if (nettoa((int)argp->key.netaddr.net, addrstr, 16, &pnull) != 0)
+		return (NSS_UNAVAIL);   /* it's really ENOMEM */
+	rc = _nss_nisplus_lookup(be, argp, NET_TAG_ADDR, addrstr);
 
-	if (nettoa((int)argp->key.netaddr.net, addrstr, 16) != 0)
-		return (NSS_UNAVAIL);   /* it's really ENOMEM */
-
-	return (_nss_nisplus_lookup(be, argp, NET_TAG_ADDR, addrstr));
+	/*
+	 * if not found, try again with the untruncated address string
+	 * that has the trailing zero(s)
+	 */
+	if (rc == NSS_NOTFOUND && pnull != NULL) {
+		*pnull = '.';
+		rc = _nss_nisplus_lookup(be, argp, NET_TAG_ADDR, addrstr);
+	}
+	return (rc);
 }
 
 
@@ -155,18 +166,17 @@
 /*
  * Takes an unsigned integer in host order, and returns a printable
  * string for it as a network number.  To allow for the possibility of
- * naming subnets, only trailing dot-zeros are truncated.
+ * naming subnets, only trailing dot-zeros are truncated. The location
+ * where the string is truncated (or set to '\0') is returned in *pnull.
  */
 static int
-nettoa(anet, buf, buflen)
-	int		anet;
-	char		*buf;
-	int		buflen;
+nettoa(int anet, char *buf, int buflen, char **pnull)
 {
 	char		*p;
 	struct in_addr	in;
 	int		addr;
 
+	*pnull = NULL;
 	if (buf == 0)
 		return (1);
 	in = inet_makeaddr(anet, INADDR_ANY);
@@ -177,6 +187,7 @@
 		if (p == NULL)
 			return (1);
 		*p = 0;
+		*pnull = p;
 	} else if ((IN_CLASSB_HOST & htonl(addr)) == 0) {
 		p = strchr(buf, '.');
 		if (p == NULL)
@@ -185,11 +196,13 @@
 		if (p == NULL)
 			return (1);
 		*p = 0;
+		*pnull = p;
 	} else if ((IN_CLASSC_HOST & htonl(addr)) == 0) {
 		p = strrchr(buf, '.');
 		if (p == NULL)
 			return (1);
 		*p = 0;
+		*pnull = p;
 	}
 	return (0);
 }