xref: /illumos-gate/usr/src/lib/libnisdb/nis_db.cc (revision b3bec642)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
536e852a1SRaja Andra  * Common Development and Distribution License (the "License").
636e852a1SRaja Andra  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
227c478bd9Sstevel@tonic-gate  *	nis_db.cc
237c478bd9Sstevel@tonic-gate  *
2436e852a1SRaja Andra  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2536e852a1SRaja Andra  * Use is subject to license terms.
26a87701e9SGary Mills  *
27a87701e9SGary Mills  * Copyright 2015 RackTop Systems.
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <sys/param.h>
327c478bd9Sstevel@tonic-gate #include <strings.h>
337c478bd9Sstevel@tonic-gate #include <syslog.h>
347c478bd9Sstevel@tonic-gate #include "nisdb_mt.h"
357c478bd9Sstevel@tonic-gate #include "db_headers.h"
367c478bd9Sstevel@tonic-gate #include "db_entry.h"
377c478bd9Sstevel@tonic-gate #include "db.h"
387c478bd9Sstevel@tonic-gate #include "db_dictionary.h"
397c478bd9Sstevel@tonic-gate #include "db_pickle.h"
407c478bd9Sstevel@tonic-gate #include "nis_db.h"
417c478bd9Sstevel@tonic-gate #include "nis_ldap.h"
427c478bd9Sstevel@tonic-gate #include "ldap_util.h"
437c478bd9Sstevel@tonic-gate #include "ldap_parse.h"
447c478bd9Sstevel@tonic-gate #include "ldap_glob.h"
457c478bd9Sstevel@tonic-gate #include "ldap_xdr.h"
467c478bd9Sstevel@tonic-gate #include "ldap_glob.h"
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate db_dictionary	curdict;
497c478bd9Sstevel@tonic-gate db_dictionary	tempdict; /* a temporary one */
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate db_dictionary *InUseDictionary = &curdict;
527c478bd9Sstevel@tonic-gate db_dictionary *FreeDictionary = &tempdict;
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate extern "C" {
557c478bd9Sstevel@tonic-gate static db_result	*db_add_entry_x(char *tab, int numattrs,
567c478bd9Sstevel@tonic-gate 					nis_attr *attrname, entry_obj * newobj,
577c478bd9Sstevel@tonic-gate 					int skiplog, int nosync);
587c478bd9Sstevel@tonic-gate db_status		db_table_exists(char *table_name);
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate /*
617c478bd9Sstevel@tonic-gate  * (Imported from rpc.nisd/nis_xx_proc.c)
627c478bd9Sstevel@tonic-gate  *
637c478bd9Sstevel@tonic-gate  * 'tbl_prototype' is used to create a table that holds a directory.
647c478bd9Sstevel@tonic-gate  */
657c478bd9Sstevel@tonic-gate static table_col cols[2] = {
668d0852b7SRichard Lowe 	{(char *)"object", TA_BINARY+TA_XDR, 0},
678d0852b7SRichard Lowe 	{(char *)"name", TA_CASE+TA_SEARCHABLE, 0}
687c478bd9Sstevel@tonic-gate };
697c478bd9Sstevel@tonic-gate 
708d0852b7SRichard Lowe table_obj tbl_prototype = { (char *)"DIRECTORY", 2, ' ', {2, &cols[0]}, NULL };
717c478bd9Sstevel@tonic-gate }
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /*
747c478bd9Sstevel@tonic-gate  * Free resources associated with a db_result structure
757c478bd9Sstevel@tonic-gate  */
767c478bd9Sstevel@tonic-gate void
db_free_result(db_result * dr)777c478bd9Sstevel@tonic-gate db_free_result(db_result *dr)
787c478bd9Sstevel@tonic-gate {
797c478bd9Sstevel@tonic-gate 	int	i;
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 	if (dr == 0)
827c478bd9Sstevel@tonic-gate 		return;
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 	/* Can't have valid objects */
857c478bd9Sstevel@tonic-gate 	if (dr->status != DB_SUCCESS) {
867c478bd9Sstevel@tonic-gate 		free(dr);
877c478bd9Sstevel@tonic-gate 		return;
887c478bd9Sstevel@tonic-gate 	}
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	for (i = 0; i < dr->objects.objects_len; i++)
917c478bd9Sstevel@tonic-gate 		free_entry(dr->objects.objects_val[i]);
927c478bd9Sstevel@tonic-gate 	free(dr->objects.objects_val);
937c478bd9Sstevel@tonic-gate 	free(dr);
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate /* Return an empty db_result structure with its status field set to 's'. */
987c478bd9Sstevel@tonic-gate db_result*
empty_result(db_status s)997c478bd9Sstevel@tonic-gate empty_result(db_status s)
1007c478bd9Sstevel@tonic-gate {
1017c478bd9Sstevel@tonic-gate 	db_result * res = new db_result;
1027c478bd9Sstevel@tonic-gate 	if (res != NULL)  {
1037c478bd9Sstevel@tonic-gate 		res->status = s;
1047c478bd9Sstevel@tonic-gate 		res->nextinfo.db_next_desc_len = 0;
1057c478bd9Sstevel@tonic-gate 		res->nextinfo.db_next_desc_val = NULL;
1067c478bd9Sstevel@tonic-gate 		res->objects.objects_len = 0;
1077c478bd9Sstevel@tonic-gate 		res->objects.objects_val = NULL;
1087c478bd9Sstevel@tonic-gate 	} else {
1097c478bd9Sstevel@tonic-gate 		WARNING("nis_db::empty_result: cannot allocate space");
1107c478bd9Sstevel@tonic-gate 	}
1117c478bd9Sstevel@tonic-gate 	return (res);
1127c478bd9Sstevel@tonic-gate }
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate static db_result*
set_result(db_result * res,db_status s)1157c478bd9Sstevel@tonic-gate set_result(db_result* res, db_status s)
1167c478bd9Sstevel@tonic-gate {
1177c478bd9Sstevel@tonic-gate 	if (res != NULL)  {
1187c478bd9Sstevel@tonic-gate 		res->status = s;
1197c478bd9Sstevel@tonic-gate 	}
1207c478bd9Sstevel@tonic-gate 	return (res);
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate /*
1247c478bd9Sstevel@tonic-gate  * Given a FQ object name for a table or directory, return the (db *)
1257c478bd9Sstevel@tonic-gate  * corresponding to the object.
1267c478bd9Sstevel@tonic-gate  */
1277c478bd9Sstevel@tonic-gate db *
tableDB(char * tableName)1287c478bd9Sstevel@tonic-gate tableDB(char *tableName) {
1297c478bd9Sstevel@tonic-gate 	db_table_desc	*tbl = 0;
1307c478bd9Sstevel@tonic-gate 	char		*intName;
1317c478bd9Sstevel@tonic-gate 	db		*dbase;
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	intName = internalTableName(tableName);
1347c478bd9Sstevel@tonic-gate 	if (intName == 0)
1357c478bd9Sstevel@tonic-gate 		return (0);
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	dbase = InUseDictionary->find_table(intName, &tbl);
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	sfree(intName);
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 	return (dbase);
1427c478bd9Sstevel@tonic-gate }
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate extern "C" {
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate bool_t
db_in_dict_file(char * name)1477c478bd9Sstevel@tonic-gate db_in_dict_file(char *name)
1487c478bd9Sstevel@tonic-gate {
149a87701e9SGary Mills 	return (InUseDictionary->find_table_desc(name) != NULL);
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate 
1538d0852b7SRichard Lowe const char
db_perror(db_status dbstat)1547c478bd9Sstevel@tonic-gate *db_perror(db_status dbstat)
1557c478bd9Sstevel@tonic-gate {
1568d0852b7SRichard Lowe 	const char *str = NULL;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	switch (dbstat) {
1597c478bd9Sstevel@tonic-gate 		case DB_SUCCESS:
1607c478bd9Sstevel@tonic-gate 			str = "Success";
1617c478bd9Sstevel@tonic-gate 			break;
1627c478bd9Sstevel@tonic-gate 		case DB_NOTFOUND:
1637c478bd9Sstevel@tonic-gate 			str = "Not Found";
1647c478bd9Sstevel@tonic-gate 			break;
1657c478bd9Sstevel@tonic-gate 		case DB_BADTABLE:
1667c478bd9Sstevel@tonic-gate 			str = "Bad Table";
1677c478bd9Sstevel@tonic-gate 			break;
1687c478bd9Sstevel@tonic-gate 		case DB_BADQUERY:
1697c478bd9Sstevel@tonic-gate 			str = "Bad Query";
1707c478bd9Sstevel@tonic-gate 			break;
1717c478bd9Sstevel@tonic-gate 		case DB_BADOBJECT:
1727c478bd9Sstevel@tonic-gate 			str = "Bad Object";
1737c478bd9Sstevel@tonic-gate 			break;
1747c478bd9Sstevel@tonic-gate 		case DB_MEMORY_LIMIT:
1757c478bd9Sstevel@tonic-gate 			str = "Memory limit exceeded";
1767c478bd9Sstevel@tonic-gate 			break;
1777c478bd9Sstevel@tonic-gate 		case DB_STORAGE_LIMIT:
1787c478bd9Sstevel@tonic-gate 			str = "Database storage limit exceeded";
1797c478bd9Sstevel@tonic-gate 			break;
1807c478bd9Sstevel@tonic-gate 		case DB_INTERNAL_ERROR:
1817c478bd9Sstevel@tonic-gate 			str = "Database internal error";
1827c478bd9Sstevel@tonic-gate 			break;
1837c478bd9Sstevel@tonic-gate 		case DB_SYNC_FAILED:
1847c478bd9Sstevel@tonic-gate 			str = "Sync of log file failed";
1857c478bd9Sstevel@tonic-gate 			break;
1867c478bd9Sstevel@tonic-gate 		default:
1877c478bd9Sstevel@tonic-gate 			str = "Unknown Error";
1887c478bd9Sstevel@tonic-gate 			break;
1897c478bd9Sstevel@tonic-gate 	}
1907c478bd9Sstevel@tonic-gate 	return (str);
1917c478bd9Sstevel@tonic-gate }
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate bool_t
db_extract_dict_entries(char * newdict,char ** fs,int fscnt)1947c478bd9Sstevel@tonic-gate db_extract_dict_entries(char *newdict, char **fs, int fscnt)
1957c478bd9Sstevel@tonic-gate {
1967c478bd9Sstevel@tonic-gate 	/*
1977c478bd9Sstevel@tonic-gate 	 * Use the "FreeDictionary" ptr for the backup
1987c478bd9Sstevel@tonic-gate 	 * dictionary.
1997c478bd9Sstevel@tonic-gate 	 */
2007c478bd9Sstevel@tonic-gate 	if (!FreeDictionary->inittemp(newdict, *InUseDictionary))
2017c478bd9Sstevel@tonic-gate 		return (FALSE);
2027c478bd9Sstevel@tonic-gate 	return (InUseDictionary->extract_entries (*FreeDictionary,
2037c478bd9Sstevel@tonic-gate 		fs, fscnt));
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate bool_t
db_copy_file(char * infile,char * outfile)2077c478bd9Sstevel@tonic-gate db_copy_file(char *infile, char *outfile)
2087c478bd9Sstevel@tonic-gate {
2097c478bd9Sstevel@tonic-gate 	return (InUseDictionary->copyfile(infile, outfile));
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate /*
2157c478bd9Sstevel@tonic-gate  * The tok and repl parameters will allow us to merge two dictionaries
2167c478bd9Sstevel@tonic-gate  * that reference tables from different domains (master/replica in live
2177c478bd9Sstevel@tonic-gate  * in different domains). If set to NULL, then the dictionary merge is
2187c478bd9Sstevel@tonic-gate  * done as normal (no name changing).
2197c478bd9Sstevel@tonic-gate  */
2207c478bd9Sstevel@tonic-gate db_status
db_begin_merge_dict(char * newdict,char * tok,char * repl)2217c478bd9Sstevel@tonic-gate db_begin_merge_dict(char *newdict, char *tok, char *repl)
2227c478bd9Sstevel@tonic-gate {
2237c478bd9Sstevel@tonic-gate 	db_status dbstat;
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	/*
2267c478bd9Sstevel@tonic-gate 	 * It is assumed that InUseDictionary has already been initialized.
2277c478bd9Sstevel@tonic-gate 	 */
2287c478bd9Sstevel@tonic-gate 	dbstat = InUseDictionary->checkpoint();
2297c478bd9Sstevel@tonic-gate 	if (dbstat != DB_SUCCESS)
2307c478bd9Sstevel@tonic-gate 		return (dbstat);
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	/*
2337c478bd9Sstevel@tonic-gate 	 * Use the "FreeDictionary" ptr for the backup
2347c478bd9Sstevel@tonic-gate 	 * dictionary.
2357c478bd9Sstevel@tonic-gate 	 */
2367c478bd9Sstevel@tonic-gate 	if (!FreeDictionary->init(newdict))
2377c478bd9Sstevel@tonic-gate 		return (DB_INTERNAL_ERROR);
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	return (InUseDictionary->merge_dict(*FreeDictionary,
2407c478bd9Sstevel@tonic-gate 		tok, repl));
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate db_status
db_end_merge_dict()2457c478bd9Sstevel@tonic-gate db_end_merge_dict()
2467c478bd9Sstevel@tonic-gate {
2477c478bd9Sstevel@tonic-gate 	db_status	dbstat;
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 	dbstat = InUseDictionary->checkpoint();
2507c478bd9Sstevel@tonic-gate 	if (dbstat != DB_SUCCESS) {
2517c478bd9Sstevel@tonic-gate 		return (dbstat);
2527c478bd9Sstevel@tonic-gate 	}
2537c478bd9Sstevel@tonic-gate 	dbstat = InUseDictionary->db_shutdown();
2547c478bd9Sstevel@tonic-gate 	if (dbstat != DB_SUCCESS) {
2557c478bd9Sstevel@tonic-gate 		return (dbstat);
2567c478bd9Sstevel@tonic-gate 	}
2577c478bd9Sstevel@tonic-gate 	dbstat = FreeDictionary->db_shutdown();
2587c478bd9Sstevel@tonic-gate 	if (dbstat != DB_SUCCESS) {
2597c478bd9Sstevel@tonic-gate 		return (dbstat);
2607c478bd9Sstevel@tonic-gate 	}
2617c478bd9Sstevel@tonic-gate 	return (dbstat);
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate db_status
db_abort_merge_dict()2677c478bd9Sstevel@tonic-gate db_abort_merge_dict()
2687c478bd9Sstevel@tonic-gate {
2697c478bd9Sstevel@tonic-gate 	db_status	dbstat;
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	dbstat = InUseDictionary->db_shutdown();
2727c478bd9Sstevel@tonic-gate 	if (dbstat != DB_SUCCESS)
2737c478bd9Sstevel@tonic-gate 		return (dbstat);
2747c478bd9Sstevel@tonic-gate 	dbstat = FreeDictionary->db_shutdown();
275*b3bec642SToomas Soome 	return (dbstat);
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate /*
2807c478bd9Sstevel@tonic-gate  * Initialize system (dictionary) using file 'filename'.  If system cannot
2817c478bd9Sstevel@tonic-gate  * be read from file, it is initialized to be empty. Returns TRUE if
2827c478bd9Sstevel@tonic-gate  * initialization succeeds, FALSE otherwise.
2837c478bd9Sstevel@tonic-gate  * This function must be called before any other.
2847c478bd9Sstevel@tonic-gate */
2857c478bd9Sstevel@tonic-gate bool_t
db_initialize(char * filename)2867c478bd9Sstevel@tonic-gate db_initialize(char * filename)
2877c478bd9Sstevel@tonic-gate {
2887c478bd9Sstevel@tonic-gate 	return (InUseDictionary->init(filename));
2897c478bd9Sstevel@tonic-gate }
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate /*
2937c478bd9Sstevel@tonic-gate  * Massage the dictionary file by replacing the specified token with the
2947c478bd9Sstevel@tonic-gate  * the replacement string. This function is needed to provide backwards
2957c478bd9Sstevel@tonic-gate  * compatibility for providing a transportable dictionary file. The idea
2967c478bd9Sstevel@tonic-gate  * is that rpc.nisd will call this function when it wants to change the
2977c478bd9Sstevel@tonic-gate  * /var/nis/<hostname> strings with something like /var/nis/data.
2987c478bd9Sstevel@tonic-gate  *
2997c478bd9Sstevel@tonic-gate  */
3007c478bd9Sstevel@tonic-gate db_status
db_massage_dict(char * newdictname,char * tok,char * repl)3017c478bd9Sstevel@tonic-gate db_massage_dict(char *newdictname, char *tok, char *repl)
3027c478bd9Sstevel@tonic-gate {
3037c478bd9Sstevel@tonic-gate 	return (InUseDictionary->massage_dict(newdictname, tok, repl));
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate /*
3097c478bd9Sstevel@tonic-gate  * Create new table using given table name and table descriptor.
3107c478bd9Sstevel@tonic-gate  * Returns DB_SUCCESS if successful; appropriate error code otherwise.
3117c478bd9Sstevel@tonic-gate */
3127c478bd9Sstevel@tonic-gate db_status
db_create_table(char * table_name,table_obj * table_desc)3137c478bd9Sstevel@tonic-gate db_create_table(char * table_name, table_obj * table_desc)
3147c478bd9Sstevel@tonic-gate {
3157c478bd9Sstevel@tonic-gate 	return (InUseDictionary->add_table(table_name, table_desc));
3167c478bd9Sstevel@tonic-gate }
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate /*
3197c478bd9Sstevel@tonic-gate  * Destroys table named by 'table_name.'  Returns DB_SUCCESS if successful,
3207c478bd9Sstevel@tonic-gate  * error code otherwise.  Note that currently, the removed table is no
3217c478bd9Sstevel@tonic-gate  * longer accessible from this interface and all files associated with it
3227c478bd9Sstevel@tonic-gate  * are removed from stable storage.
3237c478bd9Sstevel@tonic-gate */
3247c478bd9Sstevel@tonic-gate db_status
db_destroy_table(char * table_name)3257c478bd9Sstevel@tonic-gate db_destroy_table(char * table_name)
3267c478bd9Sstevel@tonic-gate {
3277c478bd9Sstevel@tonic-gate 	return (InUseDictionary->delete_table(table_name));
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate /*
3327c478bd9Sstevel@tonic-gate * Return a copy of the first entry in the specified table, that satisfies
3337c478bd9Sstevel@tonic-gate * the given attributes.  The returned structure 'db_result' contains the status,
3347c478bd9Sstevel@tonic-gate * the  copy of the object, and a 'db_next_desc' to be used for the 'next'
3357c478bd9Sstevel@tonic-gate * operation.
3367c478bd9Sstevel@tonic-gate  */
3377c478bd9Sstevel@tonic-gate db_result *
db_first_entry(char * table_name,int numattrs,nis_attr * attrname)3387c478bd9Sstevel@tonic-gate db_first_entry(char * table_name, int numattrs, nis_attr * attrname)
3397c478bd9Sstevel@tonic-gate {
3407c478bd9Sstevel@tonic-gate 	db_result * safety = empty_result(DB_SUCCESS);
3417c478bd9Sstevel@tonic-gate 	db_table_desc * tbl = NULL;
3427c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(table_name, &tbl);
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 	if (tbl == NULL || dbase == NULL)
3457c478bd9Sstevel@tonic-gate 		return (set_result(safety, DB_BADTABLE));
3467c478bd9Sstevel@tonic-gate 	else {
3477c478bd9Sstevel@tonic-gate 		db_result * res = NULL;
3487c478bd9Sstevel@tonic-gate 		db_query *query = NULL;
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate 		if (numattrs != 0) {
3517c478bd9Sstevel@tonic-gate 			query = InUseDictionary->translate_to_query(tbl,
3527c478bd9Sstevel@tonic-gate 					numattrs, attrname);
3537c478bd9Sstevel@tonic-gate 			if (query == NULL)
3547c478bd9Sstevel@tonic-gate 				return (set_result(safety,
3557c478bd9Sstevel@tonic-gate 						DB_BADQUERY));
3567c478bd9Sstevel@tonic-gate 		}
3577c478bd9Sstevel@tonic-gate 		res = dbase->execute(DB_FIRST, query, NULL, NULL);
3587c478bd9Sstevel@tonic-gate 		if (query) delete query;
3597c478bd9Sstevel@tonic-gate 		if (safety) delete safety;
3607c478bd9Sstevel@tonic-gate 		return (res);
3617c478bd9Sstevel@tonic-gate 	}
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate /*
3657c478bd9Sstevel@tonic-gate  * Return a copy of the next entry in the specified table as specified by
3667c478bd9Sstevel@tonic-gate  * the 'next_desc'.  The returned structure 'db_result' contains the status,
3677c478bd9Sstevel@tonic-gate  * a copy of the object, and a db_next_desc to be used for a subsequent
3687c478bd9Sstevel@tonic-gate  * 'next' operation.
3697c478bd9Sstevel@tonic-gate */
3707c478bd9Sstevel@tonic-gate db_result *
db_next_entry(char * table_name,db_next_desc * next_desc)3717c478bd9Sstevel@tonic-gate db_next_entry(char * table_name, db_next_desc * next_desc)
3727c478bd9Sstevel@tonic-gate {
3737c478bd9Sstevel@tonic-gate 	db_result * safety = empty_result(DB_SUCCESS);
3747c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(table_name);
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	if (dbase != NULL) {
3777c478bd9Sstevel@tonic-gate 		if (safety) delete safety;
3787c478bd9Sstevel@tonic-gate 		return (dbase->execute(DB_NEXT, NULL, NULL, next_desc));
3797c478bd9Sstevel@tonic-gate 	} else
3807c478bd9Sstevel@tonic-gate 		return (set_result(safety, DB_BADTABLE));
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate /*
3847c478bd9Sstevel@tonic-gate  * Indicate to the system that you are no longer interested in the rest of the
3857c478bd9Sstevel@tonic-gate  * results identified by [next_desc].  After executing this operation, the
3867c478bd9Sstevel@tonic-gate  * [next_desc] is no longer valid (cannot  be used as an argument for next).
3877c478bd9Sstevel@tonic-gate */
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate db_result *
db_reset_next_entry(char * table_name,db_next_desc * next_desc)3907c478bd9Sstevel@tonic-gate db_reset_next_entry(char * table_name, db_next_desc * next_desc)
3917c478bd9Sstevel@tonic-gate {
3927c478bd9Sstevel@tonic-gate 	db_result * safety = empty_result(DB_SUCCESS);
3937c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(table_name);
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 	if (dbase != NULL) {
3967c478bd9Sstevel@tonic-gate 		if (safety) delete safety;
3977c478bd9Sstevel@tonic-gate 		return (dbase->execute(DB_RESET_NEXT,
3987c478bd9Sstevel@tonic-gate 					NULL, NULL, next_desc));
3997c478bd9Sstevel@tonic-gate 	} else
4007c478bd9Sstevel@tonic-gate 		return (set_result(safety, DB_BADTABLE));
4017c478bd9Sstevel@tonic-gate }
4027c478bd9Sstevel@tonic-gate 
4037c478bd9Sstevel@tonic-gate /*
4047c478bd9Sstevel@tonic-gate  * Returns copies of entries that satisfy the given attributes from table.
4057c478bd9Sstevel@tonic-gate  * Returns the status and entries in a db_result structure.
4067c478bd9Sstevel@tonic-gate  * If no attributes are specified, DB_BADQUERY is returned.
4077c478bd9Sstevel@tonic-gate */
4087c478bd9Sstevel@tonic-gate db_result *
__db_list_entries(char * table_name,int numattrs,nis_attr * attrname,bool_t useDeferred)4097c478bd9Sstevel@tonic-gate __db_list_entries(char * table_name, int numattrs, nis_attr * attrname,
4107c478bd9Sstevel@tonic-gate 			bool_t useDeferred)
4117c478bd9Sstevel@tonic-gate {
4127c478bd9Sstevel@tonic-gate 	db_result * safety = empty_result(DB_SUCCESS);
4137c478bd9Sstevel@tonic-gate 	db_table_desc * tbl = NULL;
4147c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(table_name, &tbl,
4157c478bd9Sstevel@tonic-gate 							useDeferred);
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 	if (tbl == NULL || dbase == NULL)
4187c478bd9Sstevel@tonic-gate 		return (set_result(safety, DB_BADTABLE));
4197c478bd9Sstevel@tonic-gate 	else {
4207c478bd9Sstevel@tonic-gate 		db_result * res = NULL;
4217c478bd9Sstevel@tonic-gate 		if (numattrs != 0) {
4227c478bd9Sstevel@tonic-gate 			db_query *query;
4237c478bd9Sstevel@tonic-gate 			query = InUseDictionary->translate_to_query(tbl,
4247c478bd9Sstevel@tonic-gate 						    numattrs, attrname);
4257c478bd9Sstevel@tonic-gate 			if (query == NULL)
4267c478bd9Sstevel@tonic-gate 				return (set_result(safety,
4277c478bd9Sstevel@tonic-gate 							DB_BADQUERY));
4287c478bd9Sstevel@tonic-gate 			res = dbase->execute(DB_LOOKUP, query,
4297c478bd9Sstevel@tonic-gate 							NULL, NULL);
4307c478bd9Sstevel@tonic-gate 			delete query;
4317c478bd9Sstevel@tonic-gate 		} else {
4327c478bd9Sstevel@tonic-gate 			res = dbase->execute(DB_ALL, NULL, NULL, NULL);
4337c478bd9Sstevel@tonic-gate 		}
4347c478bd9Sstevel@tonic-gate 		if (safety) delete safety;
4357c478bd9Sstevel@tonic-gate 		return (res);
4367c478bd9Sstevel@tonic-gate 	}
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate db_result *
db_list_entries(char * table_name,int numattrs,nis_attr * attrname)4407c478bd9Sstevel@tonic-gate db_list_entries(char *table_name, int numattrs, nis_attr *attrname) {
4417c478bd9Sstevel@tonic-gate 	return (__db_list_entries(table_name, numattrs, attrname, TRUE));
4427c478bd9Sstevel@tonic-gate }
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate /*
4457c478bd9Sstevel@tonic-gate  * Input:	A fully qualified object name (example: "x.y.z").
4467c478bd9Sstevel@tonic-gate  * Output:	Returns the first level of the object name ("x").
4477c478bd9Sstevel@tonic-gate  *		If 'tableP' is non-NULL, '*tableP' will contain
4487c478bd9Sstevel@tonic-gate  *		the internal table name for "y.z".
4497c478bd9Sstevel@tonic-gate  *
4507c478bd9Sstevel@tonic-gate  * Both the return value and '*tableP' must be freed by the caller.
4517c478bd9Sstevel@tonic-gate  */
4527c478bd9Sstevel@tonic-gate char *
entryName(const char * msg,char * objName,char ** tableP)4538d0852b7SRichard Lowe entryName(const char *msg, char *objName, char **tableP) {
4548d0852b7SRichard Lowe 	char		*name, *table, *dir;
4558d0852b7SRichard Lowe 	const char	*myself = "entryName";
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate 	if (msg == 0)
4587c478bd9Sstevel@tonic-gate 		msg = myself;
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 	name = sdup(msg, T, objName);
4617c478bd9Sstevel@tonic-gate 	if (name == 0)
4627c478bd9Sstevel@tonic-gate 		return (0);
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 	dir = strchr(name, '.');
4657c478bd9Sstevel@tonic-gate 	if (dir == 0) {
4667c478bd9Sstevel@tonic-gate 		sfree(name);
4677c478bd9Sstevel@tonic-gate 		return (0);
4687c478bd9Sstevel@tonic-gate 	}
4697c478bd9Sstevel@tonic-gate 	*(dir++) = '\0';
4707c478bd9Sstevel@tonic-gate 
4717c478bd9Sstevel@tonic-gate 	if (tableP == 0)
4727c478bd9Sstevel@tonic-gate 		return (name);
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	table = internalTableName(dir);
4757c478bd9Sstevel@tonic-gate 	if (table == 0) {
4767c478bd9Sstevel@tonic-gate 		sfree(name);
4777c478bd9Sstevel@tonic-gate 		return (0);
4787c478bd9Sstevel@tonic-gate 	}
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 	*tableP = table;
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 	return (name);
4837c478bd9Sstevel@tonic-gate }
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate #define	RETSTAT(obj, status) \
4867c478bd9Sstevel@tonic-gate 	{ \
4877c478bd9Sstevel@tonic-gate 		if (statP != 0) \
4887c478bd9Sstevel@tonic-gate 			*statP = status; \
4897c478bd9Sstevel@tonic-gate 		return (obj); \
4907c478bd9Sstevel@tonic-gate 	}
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate /*
4937c478bd9Sstevel@tonic-gate  * Given a fully qualified object name, retrive a copy of the object,
4947c478bd9Sstevel@tonic-gate  * using the NIS+ DB only (i.e., no LDAP). Avoids using nis_leaf_of()
4957c478bd9Sstevel@tonic-gate  * etc., since they aren't re-entrant.
4967c478bd9Sstevel@tonic-gate  */
4977c478bd9Sstevel@tonic-gate nis_object *
dbFindObject(char * objName,db_status * statP)4987c478bd9Sstevel@tonic-gate dbFindObject(char *objName, db_status *statP) {
4997c478bd9Sstevel@tonic-gate 	char		buf[MAXPATHLEN+NIS_MAXNAMELEN+1];
5007c478bd9Sstevel@tonic-gate 	char		*name, *table = 0;
5017c478bd9Sstevel@tonic-gate 	nis_attr	attr;
5027c478bd9Sstevel@tonic-gate 	db		*dbase;
5037c478bd9Sstevel@tonic-gate 	db_result	*res;
5047c478bd9Sstevel@tonic-gate 	db_table_desc	*tbl = 0;
5057c478bd9Sstevel@tonic-gate 	db_query	*query;
5067c478bd9Sstevel@tonic-gate 	db_mindex	*mindex;
5077c478bd9Sstevel@tonic-gate 	nis_object	*o;
5087c478bd9Sstevel@tonic-gate 	int		lstat;
5098d0852b7SRichard Lowe 	const char	*myself = "dbFindObject";
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate 	if (objName == 0)
5127c478bd9Sstevel@tonic-gate 		RETSTAT(0, DB_BADQUERY);
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 	/* The root dir is treated specially */
5157c478bd9Sstevel@tonic-gate 	table = internalTableName(objName);
5167c478bd9Sstevel@tonic-gate 	if (table == 0)
5177c478bd9Sstevel@tonic-gate 		RETSTAT(0, DB_BADQUERY);
5187c478bd9Sstevel@tonic-gate 	if (strcmp(ROOTDIRFILE, table) == 0) {
5197c478bd9Sstevel@tonic-gate 		sfree(table);
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate 		o = get_root_object();
5227c478bd9Sstevel@tonic-gate 		if (o == 0)
5237c478bd9Sstevel@tonic-gate 			RETSTAT(0, DB_NOTFOUND);
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate 		RETSTAT(o, DB_SUCCESS);
5267c478bd9Sstevel@tonic-gate 	}
5277c478bd9Sstevel@tonic-gate 
5287c478bd9Sstevel@tonic-gate 	/* If not the root dir, find the directory where the entry lives */
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 	sfree(table);
5317c478bd9Sstevel@tonic-gate 	name = entryName(myself, objName, &table);
5327c478bd9Sstevel@tonic-gate 	if (name == 0 || table == 0) {
5337c478bd9Sstevel@tonic-gate 		sfree(name);
5347c478bd9Sstevel@tonic-gate 		RETSTAT(0, DB_MEMORY_LIMIT);
5357c478bd9Sstevel@tonic-gate 	}
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate 	dbase = InUseDictionary->find_table_noLDAP(table, &tbl, TRUE, TRUE);
5387c478bd9Sstevel@tonic-gate 	sfree(table);
5397c478bd9Sstevel@tonic-gate 	if (dbase != 0)
5407c478bd9Sstevel@tonic-gate 		mindex = dbase->mindex();
5417c478bd9Sstevel@tonic-gate 	if (dbase == 0 || tbl == 0 || mindex == 0) {
5427c478bd9Sstevel@tonic-gate 		sfree(name);
5437c478bd9Sstevel@tonic-gate 		RETSTAT(0, DB_BADTABLE);
5447c478bd9Sstevel@tonic-gate 	}
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate 	WRITELOCKNR(mindex, lstat, "mindex w dbFindObject");
5477c478bd9Sstevel@tonic-gate 	if (lstat != 0) {
5487c478bd9Sstevel@tonic-gate 		sfree(name);
5497c478bd9Sstevel@tonic-gate 		RETSTAT(0, DB_LOCK_ERROR);
5507c478bd9Sstevel@tonic-gate 	}
5517c478bd9Sstevel@tonic-gate 
5528d0852b7SRichard Lowe 	attr.zattr_ndx = (char *)"name";
5537c478bd9Sstevel@tonic-gate 	attr.zattr_val.zattr_val_val = name;
5547c478bd9Sstevel@tonic-gate 	attr.zattr_val.zattr_val_len = slen(name) + 1;
5557c478bd9Sstevel@tonic-gate 
5567c478bd9Sstevel@tonic-gate 	query = InUseDictionary->translate_to_query(tbl, 1, &attr);
5577c478bd9Sstevel@tonic-gate 	if (query == 0) {
5587c478bd9Sstevel@tonic-gate 		sfree(name);
5597c478bd9Sstevel@tonic-gate 		WRITEUNLOCKNR(mindex, lstat, "mindex wu dbFindObject");
5607c478bd9Sstevel@tonic-gate 		RETSTAT(0, DB_BADQUERY);
5617c478bd9Sstevel@tonic-gate 	}
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 	/* Only want to look in the local DB */
5647c478bd9Sstevel@tonic-gate 	mindex->setNoLDAPquery();
5657c478bd9Sstevel@tonic-gate 
5667c478bd9Sstevel@tonic-gate 	res = dbase->execute(DB_LOOKUP, query, 0, 0);
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate 	mindex->clearNoLDAPquery();
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 	delete query;
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 	sfree(name);
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	WRITEUNLOCKNR(mindex, lstat, "mindex wu dbFindObject");
5757c478bd9Sstevel@tonic-gate 	if (lstat != 0) {
5767c478bd9Sstevel@tonic-gate 		db_free_result(res);
5777c478bd9Sstevel@tonic-gate 		RETSTAT(0, DB_LOCK_ERROR);
5787c478bd9Sstevel@tonic-gate 	}
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate 	if (res == 0)
5817c478bd9Sstevel@tonic-gate 		RETSTAT(0, DB_MEMORY_LIMIT);
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate 	if (res->status != DB_SUCCESS) {
5847c478bd9Sstevel@tonic-gate 		db_status	st = res->status;
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate 		db_free_result(res);
5877c478bd9Sstevel@tonic-gate 		RETSTAT(0, st);
5887c478bd9Sstevel@tonic-gate 	}
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate 	if (res->objects.objects_len != 1 || res->objects.objects_val == 0 ||
5917c478bd9Sstevel@tonic-gate 			res->objects.objects_val[0] == 0) {
5927c478bd9Sstevel@tonic-gate 		db_free_result(res);
5937c478bd9Sstevel@tonic-gate 		RETSTAT(0, DB_BADOBJECT);
5947c478bd9Sstevel@tonic-gate 	}
5957c478bd9Sstevel@tonic-gate 
5967c478bd9Sstevel@tonic-gate 	o = unmakePseudoEntryObj(res->objects.objects_val[0], 0);
5977c478bd9Sstevel@tonic-gate 
5987c478bd9Sstevel@tonic-gate 	db_free_result(res);
5997c478bd9Sstevel@tonic-gate 
6007c478bd9Sstevel@tonic-gate 	if (o == 0) {
6017c478bd9Sstevel@tonic-gate 		RETSTAT(0, DB_BADOBJECT);
6027c478bd9Sstevel@tonic-gate 	}
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate 	RETSTAT(o, DB_SUCCESS);
6057c478bd9Sstevel@tonic-gate }
6067c478bd9Sstevel@tonic-gate 
6077c478bd9Sstevel@tonic-gate /*
6087c478bd9Sstevel@tonic-gate  * Return the object specified by 't' or 'objName' from LDAP. Set
6097c478bd9Sstevel@tonic-gate  * the LDAP status in '*statP'.
6107c478bd9Sstevel@tonic-gate  */
6117c478bd9Sstevel@tonic-gate nis_object *
ldapFindObj(__nis_table_mapping_t * t,char * objName,int * statP)6127c478bd9Sstevel@tonic-gate ldapFindObj(__nis_table_mapping_t *t, char *objName, int *statP) {
6137c478bd9Sstevel@tonic-gate 	nis_object	*o;
6147c478bd9Sstevel@tonic-gate 	int		stat;
6158d0852b7SRichard Lowe 	const char	*myself = "ldapFindObj";
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate 	if (t == 0) {
6187c478bd9Sstevel@tonic-gate 		char	*table, tbuf[MAXPATHLEN + NIS_MAXNAMELEN + 1];
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate 		if (objName == 0) {
6217c478bd9Sstevel@tonic-gate 			if (statP != 0)
6227c478bd9Sstevel@tonic-gate 				*statP = LDAP_PARAM_ERROR;
6237c478bd9Sstevel@tonic-gate 			return (0);
6247c478bd9Sstevel@tonic-gate 		}
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate 		/* Look for mapping */
6277c478bd9Sstevel@tonic-gate 		table = internal_table_name(objName, tbuf);
6287c478bd9Sstevel@tonic-gate 		if (table == 0) {
6297c478bd9Sstevel@tonic-gate 			if (statP != 0)
6307c478bd9Sstevel@tonic-gate 				*statP = LDAP_PARAM_ERROR;
6317c478bd9Sstevel@tonic-gate 			return (0);
6327c478bd9Sstevel@tonic-gate 		}
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 		t = (__nis_table_mapping_t *)__nis_find_item_mt(table,
6357c478bd9Sstevel@tonic-gate 						&ldapMappingList, 0, 0);
6367c478bd9Sstevel@tonic-gate 		if (t == 0) {
6377c478bd9Sstevel@tonic-gate 			/* Not really an error; just not mapped */
6387c478bd9Sstevel@tonic-gate 			*statP = LDAP_SUCCESS;
6397c478bd9Sstevel@tonic-gate 			return (0);
6407c478bd9Sstevel@tonic-gate 		}
6417c478bd9Sstevel@tonic-gate 	}
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate 	o = 0;
6447c478bd9Sstevel@tonic-gate 	stat = objFromLDAP(t, &o, 0, 0);
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 	if (statP != 0)
6477c478bd9Sstevel@tonic-gate 		*statP = stat;
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate 	return (o);
6507c478bd9Sstevel@tonic-gate }
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate /*
6537c478bd9Sstevel@tonic-gate  * Look for the specified object, first locally, then in LDAP.
6547c478bd9Sstevel@tonic-gate  */
6557c478bd9Sstevel@tonic-gate nis_object *
findObj(char * name,db_status * statP,int * lstatP)6567c478bd9Sstevel@tonic-gate findObj(char *name, db_status *statP, int *lstatP) {
6577c478bd9Sstevel@tonic-gate 	nis_object	*o;
6587c478bd9Sstevel@tonic-gate 	db_status	stat = DB_SUCCESS;
6597c478bd9Sstevel@tonic-gate 	int		lstat = LDAP_SUCCESS;
6608d0852b7SRichard Lowe 	const char	*myself = "findObj";
6617c478bd9Sstevel@tonic-gate 
6627c478bd9Sstevel@tonic-gate 	o = dbFindObject(name, &stat);
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate 	if (o == 0) {
6657c478bd9Sstevel@tonic-gate 		if (stat != DB_NOTFOUND)
6667c478bd9Sstevel@tonic-gate 			logmsg(MSG_NOTIMECHECK, LOG_INFO,
6677c478bd9Sstevel@tonic-gate 				"%s: DB error %d looking for \"%s\"",
6687c478bd9Sstevel@tonic-gate 				myself, stat, NIL(name));
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 		o = ldapFindObj(0, name, &lstat);
6717c478bd9Sstevel@tonic-gate 		if (o == 0) {
6727c478bd9Sstevel@tonic-gate 			if (lstat != LDAP_SUCCESS &&
6737c478bd9Sstevel@tonic-gate 					lstat != LDAP_NO_SUCH_OBJECT)
6747c478bd9Sstevel@tonic-gate 				logmsg(MSG_NOTIMECHECK, LOG_INFO,
6757c478bd9Sstevel@tonic-gate 				"%s: LDAP error looking for \"%s\": %s",
6767c478bd9Sstevel@tonic-gate 					myself, NIL(name),
6777c478bd9Sstevel@tonic-gate 					ldap_err2string(lstat));
6787c478bd9Sstevel@tonic-gate 		}
6797c478bd9Sstevel@tonic-gate 	}
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 	if (statP != 0)
6827c478bd9Sstevel@tonic-gate 		*statP = stat;
6837c478bd9Sstevel@tonic-gate 	if (lstatP != 0)
6847c478bd9Sstevel@tonic-gate 		*lstatP = lstat;
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 	return (o);
6877c478bd9Sstevel@tonic-gate }
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate /*
6907c478bd9Sstevel@tonic-gate  * Delete the specified object from the local DB.
6917c478bd9Sstevel@tonic-gate  */
6927c478bd9Sstevel@tonic-gate db_status
dbDeleteObj(char * objName)6937c478bd9Sstevel@tonic-gate dbDeleteObj(char *objName) {
6947c478bd9Sstevel@tonic-gate 	nisdb_tsd_t	*tsd = __nisdb_get_tsd();
6957c478bd9Sstevel@tonic-gate 	nis_object	*o;
6967c478bd9Sstevel@tonic-gate 	db_status	stat;
6977c478bd9Sstevel@tonic-gate 	nisdb_obj_del_t	*nod, *tmp;
6987c478bd9Sstevel@tonic-gate 	int		xid;
6998d0852b7SRichard Lowe 	const char	*myself = "dbDeleteObj";
7007c478bd9Sstevel@tonic-gate 
7017c478bd9Sstevel@tonic-gate 	if (objName == 0)
7027c478bd9Sstevel@tonic-gate 		return (DB_SUCCESS);
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate 	/*
7057c478bd9Sstevel@tonic-gate 	 * Since in-structure locks can't completely protect
7067c478bd9Sstevel@tonic-gate 	 * during structure deletion, we just note that the
7077c478bd9Sstevel@tonic-gate 	 * object should be deleted, and leave that for a
7087c478bd9Sstevel@tonic-gate 	 * (slightly) later time in rpc.nisd, where we can
7097c478bd9Sstevel@tonic-gate 	 * use the rpc.nisd's table/directory locks for
7107c478bd9Sstevel@tonic-gate 	 * protection.
7117c478bd9Sstevel@tonic-gate 	 */
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate 	if (tsd == 0)
7147c478bd9Sstevel@tonic-gate 		return (DB_INTERNAL_ERROR);
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate 	o = dbFindObject(objName, &stat);
7177c478bd9Sstevel@tonic-gate 	if (o == 0) {
7187c478bd9Sstevel@tonic-gate 		if (stat == DB_NOTFOUND)
7197c478bd9Sstevel@tonic-gate 			return (DB_SUCCESS);
7207c478bd9Sstevel@tonic-gate 		else
7217c478bd9Sstevel@tonic-gate 			return (stat);
7227c478bd9Sstevel@tonic-gate 	}
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate 	/*
7257c478bd9Sstevel@tonic-gate 	 * In order to prevent a chicken-and-egg problem (if the
7267c478bd9Sstevel@tonic-gate 	 * object doesn't exist in LDAP, is that because we just
7277c478bd9Sstevel@tonic-gate 	 * haven't written it to LDAP yet, or because it's been
7287c478bd9Sstevel@tonic-gate 	 * removed), we only allow object deletion if we're the
7297c478bd9Sstevel@tonic-gate 	 * master for it.
7307c478bd9Sstevel@tonic-gate 	 */
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate 	nod = (nisdb_obj_del_t *)am(myself, sizeof (*nod));
7337c478bd9Sstevel@tonic-gate 	if (nod == 0) {
7347c478bd9Sstevel@tonic-gate 		nis_destroy_object(o);
7357c478bd9Sstevel@tonic-gate 		return (DB_MEMORY_LIMIT);
7367c478bd9Sstevel@tonic-gate 	}
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 	nod->objType = o->zo_data.zo_type;
7397c478bd9Sstevel@tonic-gate 	nis_destroy_object(o);
7407c478bd9Sstevel@tonic-gate 
7417c478bd9Sstevel@tonic-gate 	nod->objName = sdup(myself, T, objName);
7427c478bd9Sstevel@tonic-gate 	if (nod->objName == 0) {
7437c478bd9Sstevel@tonic-gate 		sfree(nod);
7447c478bd9Sstevel@tonic-gate 		return (DB_MEMORY_LIMIT);
7457c478bd9Sstevel@tonic-gate 	}
7467c478bd9Sstevel@tonic-gate 
7477c478bd9Sstevel@tonic-gate 	/* Check for a dup */
7487c478bd9Sstevel@tonic-gate 	for (tmp = tsd->objDelList; tmp != 0;
7497c478bd9Sstevel@tonic-gate 			tmp = (nisdb_obj_del_t *)tmp->next) {
7507c478bd9Sstevel@tonic-gate 		if (strcmp(nod->objName, tmp->objName) == 0) {
7517c478bd9Sstevel@tonic-gate 			sfree(nod->objName);
7527c478bd9Sstevel@tonic-gate 			sfree(nod);
7537c478bd9Sstevel@tonic-gate 			return (DB_SUCCESS);
7547c478bd9Sstevel@tonic-gate 		}
7557c478bd9Sstevel@tonic-gate 	}
7567c478bd9Sstevel@tonic-gate 
7577c478bd9Sstevel@tonic-gate 	/* Insert at start of list */
7587c478bd9Sstevel@tonic-gate 	nod->next = tsd->objDelList;
7597c478bd9Sstevel@tonic-gate 	tsd->objDelList = nod;
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate 	return (DB_SUCCESS);
7627c478bd9Sstevel@tonic-gate }
7637c478bd9Sstevel@tonic-gate 
7647c478bd9Sstevel@tonic-gate /*
7657c478bd9Sstevel@tonic-gate  * Touch (i.e., update the expiration time for) the specified object.
7667c478bd9Sstevel@tonic-gate  */
7677c478bd9Sstevel@tonic-gate db_status
dbTouchObj(char * objName)7687c478bd9Sstevel@tonic-gate dbTouchObj(char *objName) {
7697c478bd9Sstevel@tonic-gate 	char		*ent, *table;
7707c478bd9Sstevel@tonic-gate 	db		*dbase;
7717c478bd9Sstevel@tonic-gate 	db_table_desc	*tbl = 0;
7727c478bd9Sstevel@tonic-gate 	db_mindex	*mindex;
7737c478bd9Sstevel@tonic-gate 	nis_attr	attr;
7747c478bd9Sstevel@tonic-gate 	db_query	*query;
7757c478bd9Sstevel@tonic-gate 	db_status	stat;
7768d0852b7SRichard Lowe 	const char	*myself = "dbTouchObj";
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate 	table = internalTableName(objName);
7797c478bd9Sstevel@tonic-gate 	if (table == 0)
7807c478bd9Sstevel@tonic-gate 		return (DB_BADQUERY);
7817c478bd9Sstevel@tonic-gate 
7827c478bd9Sstevel@tonic-gate 	if (strcmp(ROOTDIRFILE, table) == 0) {
7837c478bd9Sstevel@tonic-gate 		sfree(table);
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 		if (touchRootDir() == 0)
7867c478bd9Sstevel@tonic-gate 			return (DB_SUCCESS);
7877c478bd9Sstevel@tonic-gate 		else
7887c478bd9Sstevel@tonic-gate 			return (DB_INTERNAL_ERROR);
7897c478bd9Sstevel@tonic-gate 	}
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate 	sfree(table);
7927c478bd9Sstevel@tonic-gate 	table = 0;
7937c478bd9Sstevel@tonic-gate 	ent = entryName(myself, objName, &table);
7947c478bd9Sstevel@tonic-gate 	if (ent == 0 || table == 0) {
7957c478bd9Sstevel@tonic-gate 		sfree(ent);
7967c478bd9Sstevel@tonic-gate 		return (DB_MEMORY_LIMIT);
7977c478bd9Sstevel@tonic-gate 	}
7987c478bd9Sstevel@tonic-gate 
7997c478bd9Sstevel@tonic-gate 	dbase = InUseDictionary->find_table(table, &tbl, TRUE);
8007c478bd9Sstevel@tonic-gate 	if (dbase != 0)
8017c478bd9Sstevel@tonic-gate 		mindex = dbase->mindex();
8027c478bd9Sstevel@tonic-gate 	if (dbase == 0 || tbl == 0 || mindex == 0) {
8037c478bd9Sstevel@tonic-gate 		sfree(ent);
8047c478bd9Sstevel@tonic-gate 		sfree(table);
8057c478bd9Sstevel@tonic-gate 		return (DB_BADTABLE);
8067c478bd9Sstevel@tonic-gate 	}
8077c478bd9Sstevel@tonic-gate 
8088d0852b7SRichard Lowe 	attr.zattr_ndx = (char *)"name";
8097c478bd9Sstevel@tonic-gate 	attr.zattr_val.zattr_val_val = ent;
8107c478bd9Sstevel@tonic-gate 	attr.zattr_val.zattr_val_len = slen(ent) + 1;
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate 	query = InUseDictionary->translate_to_query(tbl, 1, &attr);
8137c478bd9Sstevel@tonic-gate 	if (query == 0) {
8147c478bd9Sstevel@tonic-gate 		sfree(ent);
8157c478bd9Sstevel@tonic-gate 		sfree(table);
8167c478bd9Sstevel@tonic-gate 		return (DB_BADQUERY);
8177c478bd9Sstevel@tonic-gate 	}
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate 	mindex->touchEntry(query);
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 	sfree(ent);
8227c478bd9Sstevel@tonic-gate 	sfree(table);
8237c478bd9Sstevel@tonic-gate 	delete query;
8247c478bd9Sstevel@tonic-gate 
8257c478bd9Sstevel@tonic-gate 	return (DB_SUCCESS);
8267c478bd9Sstevel@tonic-gate }
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate /*
8297c478bd9Sstevel@tonic-gate  * Create a NIS_TABLE_OBJ.
8307c478bd9Sstevel@tonic-gate  * Borrows heavily from rpc.nisd/nis_db.c:__create_table().
8317c478bd9Sstevel@tonic-gate  */
8327c478bd9Sstevel@tonic-gate db_status
dbCreateTable(char * intName,nis_object * obj)8337c478bd9Sstevel@tonic-gate dbCreateTable(char *intName, nis_object *obj) {
8347c478bd9Sstevel@tonic-gate 	table_col	tc[NIS_MAXCOLUMNS+1];
8357c478bd9Sstevel@tonic-gate 	table_obj	tobj, *t;
8367c478bd9Sstevel@tonic-gate 	int		i;
8378d0852b7SRichard Lowe 	const char	*myself = "dbCreateTable";
8387c478bd9Sstevel@tonic-gate 
8397c478bd9Sstevel@tonic-gate 	if (intName == 0 || obj == 0)
8407c478bd9Sstevel@tonic-gate 		return (DB_BADTABLE);
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate 	t = &(obj->TA_data);
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate 	/* Make sure there are searchable columns */
8457c478bd9Sstevel@tonic-gate 	for (i = 0; i < t->ta_cols.ta_cols_len; i++) {
8467c478bd9Sstevel@tonic-gate 		if (t->ta_cols.ta_cols_val[i].tc_flags & TA_SEARCHABLE)
8477c478bd9Sstevel@tonic-gate 			break;
8487c478bd9Sstevel@tonic-gate 	}
8497c478bd9Sstevel@tonic-gate 	if (i >= t->ta_cols.ta_cols_len) {
8507c478bd9Sstevel@tonic-gate 		logmsg(MSG_NOTIMECHECK, LOG_INFO,
8517c478bd9Sstevel@tonic-gate 			"%s: No searchable columns in \"%s\" (\"%s\")",
8527c478bd9Sstevel@tonic-gate 			myself, NIL(obj->zo_name), NIL(intName));
8537c478bd9Sstevel@tonic-gate 		return (DB_BADTABLE);
8547c478bd9Sstevel@tonic-gate 	}
8557c478bd9Sstevel@tonic-gate 
8567c478bd9Sstevel@tonic-gate 	tobj = *t;
8577c478bd9Sstevel@tonic-gate 	/* Shift columns one step right */
8587c478bd9Sstevel@tonic-gate 	for (i = 0; i < tobj.ta_cols.ta_cols_len; i++) {
8597c478bd9Sstevel@tonic-gate 		tc[i+1] = tobj.ta_cols.ta_cols_val[i];
8607c478bd9Sstevel@tonic-gate 	}
8617c478bd9Sstevel@tonic-gate 	tc[0].tc_name = 0;
8627c478bd9Sstevel@tonic-gate 	tc[0].tc_flags = TA_XDR | TA_BINARY;
8637c478bd9Sstevel@tonic-gate 	tc[0].tc_rights = 0;
8647c478bd9Sstevel@tonic-gate 	tobj.ta_cols.ta_cols_len += 1;
8657c478bd9Sstevel@tonic-gate 	tobj.ta_cols.ta_cols_val = tc;
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate 	return (db_create_table(intName, &tobj));
8687c478bd9Sstevel@tonic-gate }
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate #define	TABLE_COL(o, n)	o->TA_data.ta_cols.ta_cols_val[n]
8717c478bd9Sstevel@tonic-gate 
8727c478bd9Sstevel@tonic-gate /*
8737c478bd9Sstevel@tonic-gate  * Refresh (if necessary, create), the specified object in the local DB.
8747c478bd9Sstevel@tonic-gate  */
8757c478bd9Sstevel@tonic-gate db_status
dbRefreshObj(char * name,nis_object * o)8767c478bd9Sstevel@tonic-gate dbRefreshObj(char *name, nis_object *o) {
8777c478bd9Sstevel@tonic-gate 	char		*objName;
8787c478bd9Sstevel@tonic-gate 	__nis_buffer_t	b = {0, 0};
8797c478bd9Sstevel@tonic-gate 	nis_object	*curObj;
8807c478bd9Sstevel@tonic-gate 	db_status	stat;
8817c478bd9Sstevel@tonic-gate 	char		*ent, *table, *objTable;
8827c478bd9Sstevel@tonic-gate 	int		rstat, isDir = 0, isTable = 0;
8838d0852b7SRichard Lowe 	const char	*myself = "refreshObj";
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate 	if (o == 0)
8867c478bd9Sstevel@tonic-gate 		/* Delete it */
8877c478bd9Sstevel@tonic-gate 		return (dbDeleteObj(name));
8887c478bd9Sstevel@tonic-gate 
8897c478bd9Sstevel@tonic-gate 	/* We don't work on entry objects */
8907c478bd9Sstevel@tonic-gate 	if (o->zo_data.zo_type == NIS_ENTRY_OBJ)
8917c478bd9Sstevel@tonic-gate 		return (DB_BADOBJECT);
8927c478bd9Sstevel@tonic-gate 
8937c478bd9Sstevel@tonic-gate 	if (name != 0)
8947c478bd9Sstevel@tonic-gate 		objName = name;
8957c478bd9Sstevel@tonic-gate 	else {
8967c478bd9Sstevel@tonic-gate 		bp2buf(myself, &b, "%s.%s", NIL(o->zo_name), NIL(o->zo_domain));
8977c478bd9Sstevel@tonic-gate 		objName = b.buf;
8987c478bd9Sstevel@tonic-gate 	}
8997c478bd9Sstevel@tonic-gate 
9007c478bd9Sstevel@tonic-gate 	curObj = dbFindObject(objName, &stat);
9017c478bd9Sstevel@tonic-gate 	if (curObj == 0 && stat != DB_NOTFOUND) {
9027c478bd9Sstevel@tonic-gate 		sfree(b.buf);
9037c478bd9Sstevel@tonic-gate 		return (stat);
9047c478bd9Sstevel@tonic-gate 	}
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate 	/*
9077c478bd9Sstevel@tonic-gate 	 * If the object doesn't change, just touch it to update the
9087c478bd9Sstevel@tonic-gate 	 * expiration time.
9097c478bd9Sstevel@tonic-gate 	 */
9107c478bd9Sstevel@tonic-gate 	if (curObj != 0) {
9117c478bd9Sstevel@tonic-gate 		if (sameNisPlusObj(o, curObj)) {
9127c478bd9Sstevel@tonic-gate 			sfree(b.buf);
9137c478bd9Sstevel@tonic-gate 			nis_destroy_object(curObj);
9147c478bd9Sstevel@tonic-gate 			return (dbTouchObj(objName));
9157c478bd9Sstevel@tonic-gate 		}
9167c478bd9Sstevel@tonic-gate 
9177c478bd9Sstevel@tonic-gate 		/* Otherwise, check that the name and type is the same */
9187c478bd9Sstevel@tonic-gate 		if (o->zo_data.zo_type != curObj->zo_data.zo_type ||
9197c478bd9Sstevel@tonic-gate 			o->zo_name == 0 || curObj->zo_name == 0 ||
9207c478bd9Sstevel@tonic-gate 			o->zo_domain == 0 || curObj->zo_domain == 0 ||
9217c478bd9Sstevel@tonic-gate 			strcmp(o->zo_name, curObj->zo_name) != 0 ||
9227c478bd9Sstevel@tonic-gate 			strcmp(o->zo_domain, curObj->zo_domain) != 0) {
9237c478bd9Sstevel@tonic-gate 			sfree(b.buf);
9247c478bd9Sstevel@tonic-gate 			nis_destroy_object(curObj);
9257c478bd9Sstevel@tonic-gate 			return (DB_BADOBJECT);
9267c478bd9Sstevel@tonic-gate 		}
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate 		/*
9297c478bd9Sstevel@tonic-gate 		 * If the object is a table, we can't allow the scheme
9307c478bd9Sstevel@tonic-gate 		 * to change.
9317c478bd9Sstevel@tonic-gate 		 */
9327c478bd9Sstevel@tonic-gate 		if (o->zo_data.zo_type == NIS_TABLE_OBJ) {
9337c478bd9Sstevel@tonic-gate 			int	i;
9347c478bd9Sstevel@tonic-gate 
9357c478bd9Sstevel@tonic-gate 			if (o->TA_data.ta_maxcol !=
9367c478bd9Sstevel@tonic-gate 					curObj->TA_data.ta_maxcol) {
9377c478bd9Sstevel@tonic-gate 				sfree(b.buf);
9387c478bd9Sstevel@tonic-gate 				nis_destroy_object(curObj);
9397c478bd9Sstevel@tonic-gate 				return (DB_BADOBJECT);
9407c478bd9Sstevel@tonic-gate 			}
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate 			for (i = 0; i < o->TA_data.ta_maxcol; i++) {
9437c478bd9Sstevel@tonic-gate 				if ((TABLE_COL(o, i).tc_flags &
9447c478bd9Sstevel@tonic-gate 						TA_SEARCHABLE) !=
9457c478bd9Sstevel@tonic-gate 					(TABLE_COL(curObj, i).tc_flags &
9467c478bd9Sstevel@tonic-gate 						TA_SEARCHABLE)) {
9477c478bd9Sstevel@tonic-gate 					sfree(b.buf);
9487c478bd9Sstevel@tonic-gate 					nis_destroy_object(curObj);
9497c478bd9Sstevel@tonic-gate 					return (DB_BADOBJECT);
9507c478bd9Sstevel@tonic-gate 				}
9517c478bd9Sstevel@tonic-gate 			}
9527c478bd9Sstevel@tonic-gate 		}
9537c478bd9Sstevel@tonic-gate 	} else {
9547c478bd9Sstevel@tonic-gate 		/*
9557c478bd9Sstevel@tonic-gate 		 * If we're creating a directory object, make a note
9567c478bd9Sstevel@tonic-gate 		 * so that we can add it to the serving list and create
9577c478bd9Sstevel@tonic-gate 		 * the disk file. Similarly, if creating a table, we
9587c478bd9Sstevel@tonic-gate 		 * also need to create the disk file.
9597c478bd9Sstevel@tonic-gate 		 */
9607c478bd9Sstevel@tonic-gate 		if (o->zo_data.zo_type == NIS_DIRECTORY_OBJ)
9617c478bd9Sstevel@tonic-gate 			isDir = 1;
9627c478bd9Sstevel@tonic-gate 		else if (o->zo_data.zo_type == NIS_TABLE_OBJ)
9637c478bd9Sstevel@tonic-gate 			isTable = 1;
9647c478bd9Sstevel@tonic-gate 	}
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate 	objTable = internalTableName(objName);
9677c478bd9Sstevel@tonic-gate 	if (objTable == 0) {
9687c478bd9Sstevel@tonic-gate 		sfree(b.buf);
9697c478bd9Sstevel@tonic-gate 		if (curObj != 0)
9707c478bd9Sstevel@tonic-gate 			nis_destroy_object(curObj);
9717c478bd9Sstevel@tonic-gate 		return (DB_BADQUERY);
9727c478bd9Sstevel@tonic-gate 	}
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate 	if (strcmp(ROOTDIRFILE, objTable) == 0) {
9757c478bd9Sstevel@tonic-gate 		sfree(objTable);
9767c478bd9Sstevel@tonic-gate 
9778d0852b7SRichard Lowe 		rstat = update_root_object((nis_name)ROOTOBJFILE, o);
9787c478bd9Sstevel@tonic-gate 		if (rstat == 1)
9797c478bd9Sstevel@tonic-gate 			stat = DB_SUCCESS;
9807c478bd9Sstevel@tonic-gate 		else
9817c478bd9Sstevel@tonic-gate 			stat = DB_INTERNAL_ERROR;
9827c478bd9Sstevel@tonic-gate 	} else {
9837c478bd9Sstevel@tonic-gate 		nis_attr	attr;
9847c478bd9Sstevel@tonic-gate 		entry_object	*e, eo;
9857c478bd9Sstevel@tonic-gate 		entry_col	ec[2];
9867c478bd9Sstevel@tonic-gate 		db		*dbase;
9877c478bd9Sstevel@tonic-gate 		db_table_desc	*tbl = 0;
9887c478bd9Sstevel@tonic-gate 		db_mindex	*mindex;
9897c478bd9Sstevel@tonic-gate 		db_result	*dbres;
9907c478bd9Sstevel@tonic-gate 		int		lstat;
9917c478bd9Sstevel@tonic-gate 
9927c478bd9Sstevel@tonic-gate 		/* Find parent */
9937c478bd9Sstevel@tonic-gate 		ent = entryName(myself, objName, &table);
9947c478bd9Sstevel@tonic-gate 		if (ent == 0 || table == 0) {
9957c478bd9Sstevel@tonic-gate 			sfree(b.buf);
9967c478bd9Sstevel@tonic-gate 			sfree(objTable);
9977c478bd9Sstevel@tonic-gate 			sfree(ent);
9987c478bd9Sstevel@tonic-gate 			if (curObj != 0)
9997c478bd9Sstevel@tonic-gate 				nis_destroy_object(curObj);
10007c478bd9Sstevel@tonic-gate 			return (DB_MEMORY_LIMIT);
10017c478bd9Sstevel@tonic-gate 		}
10027c478bd9Sstevel@tonic-gate 
10037c478bd9Sstevel@tonic-gate 		/*
10047c478bd9Sstevel@tonic-gate 		 * Calling vanilla find_table() here (which might go to
10057c478bd9Sstevel@tonic-gate 		 * LDAP and recurse back to ourselves) so that it should
10067c478bd9Sstevel@tonic-gate 		 * work to create a hierarchy of directories.
10077c478bd9Sstevel@tonic-gate 		 */
10087c478bd9Sstevel@tonic-gate 		dbase = InUseDictionary->find_table(table, &tbl, TRUE);
10097c478bd9Sstevel@tonic-gate 		if (dbase != 0)
10107c478bd9Sstevel@tonic-gate 			mindex = dbase->mindex();
10117c478bd9Sstevel@tonic-gate 		if (dbase == 0 || tbl == 0 || mindex == 0) {
10127c478bd9Sstevel@tonic-gate 			sfree(b.buf);
10137c478bd9Sstevel@tonic-gate 			sfree(objTable);
10147c478bd9Sstevel@tonic-gate 			sfree(ent);
10157c478bd9Sstevel@tonic-gate 			sfree(table);
10167c478bd9Sstevel@tonic-gate 			if (curObj != 0)
10177c478bd9Sstevel@tonic-gate 				nis_destroy_object(curObj);
10187c478bd9Sstevel@tonic-gate 			return (DB_BADTABLE);
10197c478bd9Sstevel@tonic-gate 		}
10207c478bd9Sstevel@tonic-gate 
10217c478bd9Sstevel@tonic-gate 		/* Construct suitable nis_attr and entry_object */
10228d0852b7SRichard Lowe 		attr.zattr_ndx = (char *)"name";
10237c478bd9Sstevel@tonic-gate 		attr.zattr_val.zattr_val_val = ent;
10247c478bd9Sstevel@tonic-gate 		attr.zattr_val.zattr_val_len = slen(ent) + 1;
10257c478bd9Sstevel@tonic-gate 
10267c478bd9Sstevel@tonic-gate 		ec[1].ec_flags = 0;
10277c478bd9Sstevel@tonic-gate 		ec[1].ec_value.ec_value_val = ent;
10287c478bd9Sstevel@tonic-gate 		ec[1].ec_value.ec_value_len = attr.zattr_val.zattr_val_len;
10297c478bd9Sstevel@tonic-gate 
10308d0852b7SRichard Lowe 		eo.en_type = (char *)"IN_DIRECTORY";
10317c478bd9Sstevel@tonic-gate 		eo.en_cols.en_cols_val = ec;
10327c478bd9Sstevel@tonic-gate 		eo.en_cols.en_cols_len = 2;
10337c478bd9Sstevel@tonic-gate 
10347c478bd9Sstevel@tonic-gate 		e = makePseudoEntryObj(o, &eo, 0);
10357c478bd9Sstevel@tonic-gate 		if (e == 0) {
10367c478bd9Sstevel@tonic-gate 			sfree(objTable);
10377c478bd9Sstevel@tonic-gate 			sfree(table);
10387c478bd9Sstevel@tonic-gate 			sfree(ent);
10397c478bd9Sstevel@tonic-gate 			if (curObj != 0)
10407c478bd9Sstevel@tonic-gate 				nis_destroy_object(curObj);
10417c478bd9Sstevel@tonic-gate 			return (DB_INTERNAL_ERROR);
10427c478bd9Sstevel@tonic-gate 		}
10437c478bd9Sstevel@tonic-gate 
10447c478bd9Sstevel@tonic-gate 		/* Only want to update the local DB */
10457c478bd9Sstevel@tonic-gate 
10467c478bd9Sstevel@tonic-gate 		WRITELOCKNR(mindex, lstat, "mindex w dbRefreshObj");
10477c478bd9Sstevel@tonic-gate 		if (lstat != 0) {
10487c478bd9Sstevel@tonic-gate 			sfree(objTable);
10497c478bd9Sstevel@tonic-gate 			sfree(table);
10507c478bd9Sstevel@tonic-gate 			sfree(ent);
10517c478bd9Sstevel@tonic-gate 			if (curObj != 0)
10527c478bd9Sstevel@tonic-gate 				nis_destroy_object(curObj);
10537c478bd9Sstevel@tonic-gate 			return (DB_LOCK_ERROR);
10547c478bd9Sstevel@tonic-gate 		}
10557c478bd9Sstevel@tonic-gate 		mindex->setNoWriteThrough();
10567c478bd9Sstevel@tonic-gate 		mindex->setNoLDAPquery();
10577c478bd9Sstevel@tonic-gate 
10587c478bd9Sstevel@tonic-gate 		dbres = db_add_entry_x(table, 1, &attr, e, 0, 0);
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate 		mindex->clearNoLDAPquery();
10617c478bd9Sstevel@tonic-gate 		mindex->clearNoWriteThrough();
10627c478bd9Sstevel@tonic-gate 		WRITEUNLOCKNR(mindex, lstat, "mindex wu dbRefreshObj");
10637c478bd9Sstevel@tonic-gate 		if (lstat != 0) {
10647c478bd9Sstevel@tonic-gate 			sfree(objTable);
10657c478bd9Sstevel@tonic-gate 			sfree(table);
10667c478bd9Sstevel@tonic-gate 			sfree(ent);
10677c478bd9Sstevel@tonic-gate 			if (curObj != 0)
10687c478bd9Sstevel@tonic-gate 				nis_destroy_object(curObj);
10697c478bd9Sstevel@tonic-gate 			db_free_result(dbres);
10707c478bd9Sstevel@tonic-gate 			return (DB_LOCK_ERROR);
10717c478bd9Sstevel@tonic-gate 		}
10727c478bd9Sstevel@tonic-gate 
10737c478bd9Sstevel@tonic-gate 		sfree(ent);
10747c478bd9Sstevel@tonic-gate 		sfree(table);
10757c478bd9Sstevel@tonic-gate 
10767c478bd9Sstevel@tonic-gate 		if (dbres == 0)
10777c478bd9Sstevel@tonic-gate 			stat = DB_MEMORY_LIMIT;
10787c478bd9Sstevel@tonic-gate 		else
10797c478bd9Sstevel@tonic-gate 			stat = dbres->status;
10807c478bd9Sstevel@tonic-gate 
10817c478bd9Sstevel@tonic-gate 		db_free_result(dbres);
10827c478bd9Sstevel@tonic-gate 
10837c478bd9Sstevel@tonic-gate 		/*
10847c478bd9Sstevel@tonic-gate 		 * If successful so far, add the transaction.
10857c478bd9Sstevel@tonic-gate 		 */
10867c478bd9Sstevel@tonic-gate 		if (stat == DB_SUCCESS) {
10877c478bd9Sstevel@tonic-gate 			int		xid, st;
10887c478bd9Sstevel@tonic-gate 			db_status	ds;
10897c478bd9Sstevel@tonic-gate 			nis_object	*dirObj;
10907c478bd9Sstevel@tonic-gate 
10917c478bd9Sstevel@tonic-gate 			/* Find the directory where this is added */
10927c478bd9Sstevel@tonic-gate 			dirObj = dbFindObject(o->zo_domain, &ds);
10937c478bd9Sstevel@tonic-gate 			if (dirObj == 0) {
10947c478bd9Sstevel@tonic-gate 				sfree(objTable);
10957c478bd9Sstevel@tonic-gate 				if (curObj != 0)
10967c478bd9Sstevel@tonic-gate 					nis_destroy_object(curObj);
10977c478bd9Sstevel@tonic-gate 				return (ds);
10987c478bd9Sstevel@tonic-gate 			}
10997c478bd9Sstevel@tonic-gate 
11007c478bd9Sstevel@tonic-gate 			xid = beginTransaction();
11017c478bd9Sstevel@tonic-gate 			if (xid == 0) {
11027c478bd9Sstevel@tonic-gate 				sfree(objTable);
11037c478bd9Sstevel@tonic-gate 				if (curObj != 0)
11047c478bd9Sstevel@tonic-gate 					nis_destroy_object(curObj);
11057c478bd9Sstevel@tonic-gate 				nis_destroy_object(dirObj);
11067c478bd9Sstevel@tonic-gate 				return (DB_INTERNAL_ERROR);
11077c478bd9Sstevel@tonic-gate 			}
11087c478bd9Sstevel@tonic-gate 
11097c478bd9Sstevel@tonic-gate 			st = addUpdate((curObj == 0) ? ADD_NAME : MOD_NAME_NEW,
11107c478bd9Sstevel@tonic-gate 					objName, 0, 0, o, curObj, 0);
11117c478bd9Sstevel@tonic-gate 			if (st != 0) {
11127c478bd9Sstevel@tonic-gate 				(void) abort_transaction(xid);
11137c478bd9Sstevel@tonic-gate 				sfree(objTable);
11147c478bd9Sstevel@tonic-gate 				if (curObj != 0)
11157c478bd9Sstevel@tonic-gate 					nis_destroy_object(curObj);
11167c478bd9Sstevel@tonic-gate 				nis_destroy_object(dirObj);
11177c478bd9Sstevel@tonic-gate 				return (DB_INTERNAL_ERROR);
11187c478bd9Sstevel@tonic-gate 			}
11197c478bd9Sstevel@tonic-gate 
11207c478bd9Sstevel@tonic-gate 			st = endTransaction(xid, dirObj);
11217c478bd9Sstevel@tonic-gate 			if (st != 0)
11227c478bd9Sstevel@tonic-gate 				stat = DB_INTERNAL_ERROR;
11237c478bd9Sstevel@tonic-gate 
11247c478bd9Sstevel@tonic-gate 			if (curObj != 0)
11257c478bd9Sstevel@tonic-gate 				nis_destroy_object(curObj);
11267c478bd9Sstevel@tonic-gate 			nis_destroy_object(dirObj);
11277c478bd9Sstevel@tonic-gate 		}
11287c478bd9Sstevel@tonic-gate 
11297c478bd9Sstevel@tonic-gate 		/*
11307c478bd9Sstevel@tonic-gate 		 * If it's a table or directory, create the DB file.
11317c478bd9Sstevel@tonic-gate 		 * If a directory, also add it to the serving list.
11327c478bd9Sstevel@tonic-gate 		 */
11337c478bd9Sstevel@tonic-gate 		if (stat == DB_SUCCESS &&(isDir || isTable)) {
11347c478bd9Sstevel@tonic-gate 			if (isDir) {
11357c478bd9Sstevel@tonic-gate 				stat = db_create_table(objTable,
11367c478bd9Sstevel@tonic-gate 							&tbl_prototype);
11377c478bd9Sstevel@tonic-gate 			} else {
11387c478bd9Sstevel@tonic-gate 				stat = dbCreateTable(objTable, o);
11397c478bd9Sstevel@tonic-gate 			}
11407c478bd9Sstevel@tonic-gate 		}
11417c478bd9Sstevel@tonic-gate 		sfree(objTable);
11427c478bd9Sstevel@tonic-gate 	}
11437c478bd9Sstevel@tonic-gate 
11447c478bd9Sstevel@tonic-gate 	sfree(b.buf);
11457c478bd9Sstevel@tonic-gate 
11467c478bd9Sstevel@tonic-gate 	return (stat);
11477c478bd9Sstevel@tonic-gate }
11487c478bd9Sstevel@tonic-gate 
11497c478bd9Sstevel@tonic-gate /*
11507c478bd9Sstevel@tonic-gate  * Replace the object stored with the mapping 't'. Return TRUE if
11517c478bd9Sstevel@tonic-gate  * at least one object was replaced, FALSE otherwise.
11527c478bd9Sstevel@tonic-gate  */
11537c478bd9Sstevel@tonic-gate bool_t
replaceMappingObj(__nis_table_mapping_t * t,nis_object * n)11547c478bd9Sstevel@tonic-gate replaceMappingObj(__nis_table_mapping_t *t, nis_object *n) {
11557c478bd9Sstevel@tonic-gate 	__nis_table_mapping_t	*x;
11567c478bd9Sstevel@tonic-gate 	nis_object		*old = 0;
11577c478bd9Sstevel@tonic-gate 	int			assigned = 0;
11587c478bd9Sstevel@tonic-gate 
11597c478bd9Sstevel@tonic-gate 	/*
11607c478bd9Sstevel@tonic-gate 	 * The alternate mappings are usually mostly copies
11617c478bd9Sstevel@tonic-gate 	 * of the original, so we try to make sure that we
11627c478bd9Sstevel@tonic-gate 	 * don't free the same nis_object twice.
11637c478bd9Sstevel@tonic-gate 	 */
11647c478bd9Sstevel@tonic-gate 	for (x = t; x != 0; x = (__nis_table_mapping_t *)x->next) {
11657c478bd9Sstevel@tonic-gate 		if (old == 0) {
11667c478bd9Sstevel@tonic-gate 			old = x->obj;
11677c478bd9Sstevel@tonic-gate 			if (x->obj != 0)
11687c478bd9Sstevel@tonic-gate 				nis_destroy_object(x->obj);
11697c478bd9Sstevel@tonic-gate 		} else {
11707c478bd9Sstevel@tonic-gate 			if (x->obj != old && x->obj != 0)
11717c478bd9Sstevel@tonic-gate 				nis_destroy_object(x->obj);
11727c478bd9Sstevel@tonic-gate 		}
11737c478bd9Sstevel@tonic-gate 		x->obj = n;
11747c478bd9Sstevel@tonic-gate 		assigned++;
11757c478bd9Sstevel@tonic-gate 	}
11767c478bd9Sstevel@tonic-gate 
11777c478bd9Sstevel@tonic-gate 	return (assigned > 0);
11787c478bd9Sstevel@tonic-gate }
11797c478bd9Sstevel@tonic-gate 
11807c478bd9Sstevel@tonic-gate /*
118136e852a1SRaja Andra  * Set object type, column info, and obj for the specified
11827c478bd9Sstevel@tonic-gate  * mapping 't' from the object 'o'. Returns zero if 'o' was unused,
11837c478bd9Sstevel@tonic-gate  * and should be freed by the caller, larger than zero otherwise.
11847c478bd9Sstevel@tonic-gate  */
11857c478bd9Sstevel@tonic-gate int
setMappingObjTypeEtc(__nis_table_mapping_t * t,nis_object * o)11867c478bd9Sstevel@tonic-gate setMappingObjTypeEtc(__nis_table_mapping_t *t, nis_object *o) {
11877c478bd9Sstevel@tonic-gate 	__nis_table_mapping_t	*x;
11887c478bd9Sstevel@tonic-gate 	int			ls, ret;
118936e852a1SRaja Andra 	int	                i;
11907c478bd9Sstevel@tonic-gate 
11917c478bd9Sstevel@tonic-gate 	if (t == 0 || o == 0)
11927c478bd9Sstevel@tonic-gate 		return (0);
11937c478bd9Sstevel@tonic-gate 
11947c478bd9Sstevel@tonic-gate 	t->objType = o->zo_data.zo_type;
11957c478bd9Sstevel@tonic-gate 	for (x = t; x != 0; x = (__nis_table_mapping_t *)x->next) {
11967c478bd9Sstevel@tonic-gate 		if (x != t) {
11977c478bd9Sstevel@tonic-gate 			x->objType = t->objType;
11987c478bd9Sstevel@tonic-gate 		}
11997c478bd9Sstevel@tonic-gate 		if (x->objType == NIS_TABLE_OBJ) {
12007c478bd9Sstevel@tonic-gate 			/*
12017c478bd9Sstevel@tonic-gate 			 * If we have rules, this mapping is for table entries,
12027c478bd9Sstevel@tonic-gate 			 * and we need the column names. Otherwise, remove the
12037c478bd9Sstevel@tonic-gate 			 * column names (if any).
12047c478bd9Sstevel@tonic-gate 			 */
120536e852a1SRaja Andra 
120636e852a1SRaja Andra                         for (i = 0; i < x->numColumns; i++)
120736e852a1SRaja Andra 			sfree(x->column[i]);
120836e852a1SRaja Andra 		        sfree(x->column);
120936e852a1SRaja Andra 			x->column = 0;
121036e852a1SRaja Andra 			x->numColumns = 0;
12117c478bd9Sstevel@tonic-gate 		}
12127c478bd9Sstevel@tonic-gate 	}
12137c478bd9Sstevel@tonic-gate 	ret = replaceMappingObj(t, o);
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 	return (ret);
12167c478bd9Sstevel@tonic-gate }
12177c478bd9Sstevel@tonic-gate 
12187c478bd9Sstevel@tonic-gate /*
12197c478bd9Sstevel@tonic-gate  * Retrieve the specified object (internal DB name) from LDAP, and
12207c478bd9Sstevel@tonic-gate  * refresh/create as appropriate.
12217c478bd9Sstevel@tonic-gate  */
12227c478bd9Sstevel@tonic-gate db_status
dbCreateFromLDAP(char * intName,int * ldapStat)12237c478bd9Sstevel@tonic-gate dbCreateFromLDAP(char *intName, int *ldapStat) {
12247c478bd9Sstevel@tonic-gate 	__nis_table_mapping_t	*t;
12257c478bd9Sstevel@tonic-gate 	int			lstat, doDestroy;
12267c478bd9Sstevel@tonic-gate 	nis_object		*obj = 0;
12277c478bd9Sstevel@tonic-gate 	db_status		dstat;
12288d0852b7SRichard Lowe 	const char		*myself = "dbCreateFromLDAP";
12297c478bd9Sstevel@tonic-gate 
12307c478bd9Sstevel@tonic-gate 	if (!useLDAPrespository) {
12317c478bd9Sstevel@tonic-gate 		if (ldapStat != 0)
12327c478bd9Sstevel@tonic-gate 			*ldapStat = LDAP_SUCCESS;
12337c478bd9Sstevel@tonic-gate 		return (DB_SUCCESS);
12347c478bd9Sstevel@tonic-gate 	}
12357c478bd9Sstevel@tonic-gate 
12367c478bd9Sstevel@tonic-gate 	t = (__nis_table_mapping_t *)__nis_find_item_mt(intName,
12377c478bd9Sstevel@tonic-gate 							&ldapMappingList,
12387c478bd9Sstevel@tonic-gate 							0, 0);
12397c478bd9Sstevel@tonic-gate 
12407c478bd9Sstevel@tonic-gate 	/* No mapping isn't a failure */
12417c478bd9Sstevel@tonic-gate 	if (t == 0) {
12427c478bd9Sstevel@tonic-gate 		if (ldapStat != 0)
12437c478bd9Sstevel@tonic-gate 			*ldapStat = LDAP_SUCCESS;
12447c478bd9Sstevel@tonic-gate 		return (DB_NOTFOUND);
12457c478bd9Sstevel@tonic-gate 	}
12467c478bd9Sstevel@tonic-gate 
12477c478bd9Sstevel@tonic-gate 	lstat = objFromLDAP(t, &obj, 0, 0);
12487c478bd9Sstevel@tonic-gate 	if (ldapStat != 0)
12497c478bd9Sstevel@tonic-gate 		*ldapStat = lstat;
12507c478bd9Sstevel@tonic-gate 	if (lstat != LDAP_SUCCESS)
12517c478bd9Sstevel@tonic-gate 		return (DB_NOTFOUND);
12527c478bd9Sstevel@tonic-gate 
12537c478bd9Sstevel@tonic-gate 	/*
12547c478bd9Sstevel@tonic-gate 	 * If the LDAP operation was successful, but 'obj' is NULL,
12557c478bd9Sstevel@tonic-gate 	 * there's no mapping for this object, and we're done.
12567c478bd9Sstevel@tonic-gate 	 */
12577c478bd9Sstevel@tonic-gate 	if (obj == 0)
12587c478bd9Sstevel@tonic-gate 		return (DB_SUCCESS);
12597c478bd9Sstevel@tonic-gate 
12607c478bd9Sstevel@tonic-gate 	/* Update the mapping with object info */
12617c478bd9Sstevel@tonic-gate 	doDestroy = setMappingObjTypeEtc(t, obj) == 0;
12627c478bd9Sstevel@tonic-gate 
12637c478bd9Sstevel@tonic-gate 	dstat = dbRefreshObj(t->objName, obj);
12647c478bd9Sstevel@tonic-gate 
12657c478bd9Sstevel@tonic-gate 	if (doDestroy)
12667c478bd9Sstevel@tonic-gate 		nis_destroy_object(obj);
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate 	return (dstat);
12697c478bd9Sstevel@tonic-gate }
12707c478bd9Sstevel@tonic-gate 
12717c478bd9Sstevel@tonic-gate /*
12727c478bd9Sstevel@tonic-gate  * Up- (fromLDAP==0) or down- (fromLDAP==1) load all LDAP mapped data.
12737c478bd9Sstevel@tonic-gate  * Returns an LDAP error status.
12747c478bd9Sstevel@tonic-gate  */
12757c478bd9Sstevel@tonic-gate int
loadAllLDAP(int fromLDAP,void * cookie,db_status * dstatP)12767c478bd9Sstevel@tonic-gate loadAllLDAP(int fromLDAP, void *cookie, db_status *dstatP) {
12777c478bd9Sstevel@tonic-gate 	__nis_table_mapping_t	*t, *start;
12787c478bd9Sstevel@tonic-gate 	int			stat = LDAP_SUCCESS;
12797c478bd9Sstevel@tonic-gate 	db_status		dstat = DB_SUCCESS;
12807c478bd9Sstevel@tonic-gate 	db			*dbase;
12817c478bd9Sstevel@tonic-gate 	db_table_desc		*tbl = 0;
12827c478bd9Sstevel@tonic-gate 	db_mindex		*mindex;
12838d0852b7SRichard Lowe 	const char		*myself = "loadAllLDAP";
12847c478bd9Sstevel@tonic-gate 
12857c478bd9Sstevel@tonic-gate 	/*
12867c478bd9Sstevel@tonic-gate 	 * If the 'cookie' and '*cookie' are non-NULL, start scanning
12877c478bd9Sstevel@tonic-gate 	 * the mappings from '*cookie'. When we return with an error,
12887c478bd9Sstevel@tonic-gate 	 * we set '*cookie' to point to the mapping being processed.
12897c478bd9Sstevel@tonic-gate 	 * This enables our caller to react appropriately, and retry
12907c478bd9Sstevel@tonic-gate 	 * if desired.
12917c478bd9Sstevel@tonic-gate 	 *
12927c478bd9Sstevel@tonic-gate 	 * The cookie is opaque to our caller, who's only allowed to
12937c478bd9Sstevel@tonic-gate 	 * initialize *cookie to NULL.
12947c478bd9Sstevel@tonic-gate 	 */
12957c478bd9Sstevel@tonic-gate 	if (cookie != 0) {
12967c478bd9Sstevel@tonic-gate 		start = *((__nis_table_mapping_t **)cookie);
12977c478bd9Sstevel@tonic-gate 		if (start == 0)
12987c478bd9Sstevel@tonic-gate 			start = ldapMappingSeq;
12997c478bd9Sstevel@tonic-gate 	} else {
13007c478bd9Sstevel@tonic-gate 		start = ldapMappingSeq;
13017c478bd9Sstevel@tonic-gate 	}
13027c478bd9Sstevel@tonic-gate 
13037c478bd9Sstevel@tonic-gate 	for (t = start; t != 0; t = (__nis_table_mapping_t *)t->seqNext) {
13047c478bd9Sstevel@tonic-gate 		__nis_table_mapping_t	**tp;
13057c478bd9Sstevel@tonic-gate 		int			nm;
13067c478bd9Sstevel@tonic-gate 
13077c478bd9Sstevel@tonic-gate 		if (fromLDAP) {
13087c478bd9Sstevel@tonic-gate 			/* Are there any mappings for the object proper ? */
13097c478bd9Sstevel@tonic-gate 			tp = selectTableMapping(t, 0, 0, 1, t->dbId, &nm);
13107c478bd9Sstevel@tonic-gate 			if (tp != 0 && nm > 0) {
13117c478bd9Sstevel@tonic-gate 				dstat = dbCreateFromLDAP(t->objPath, &stat);
13127c478bd9Sstevel@tonic-gate 				if (dstat != DB_SUCCESS) {
13137c478bd9Sstevel@tonic-gate 					logmsg(MSG_NOTIMECHECK, LOG_ERR,
13147c478bd9Sstevel@tonic-gate 				"%s: DB error %d creating \"%s\": %s",
13157c478bd9Sstevel@tonic-gate 						myself, dstat, NIL(t->objName),
13167c478bd9Sstevel@tonic-gate 						ldap_err2string(stat));
13177c478bd9Sstevel@tonic-gate 					if (cookie != 0)
13187c478bd9Sstevel@tonic-gate 						*((__nis_table_mapping_t **)
13197c478bd9Sstevel@tonic-gate 							cookie) = t;
13207c478bd9Sstevel@tonic-gate 					if (dstatP != 0)
13217c478bd9Sstevel@tonic-gate 						*dstatP = dstat;
13227c478bd9Sstevel@tonic-gate 					else if (stat == LDAP_SUCCESS)
13237c478bd9Sstevel@tonic-gate 						stat = LDAP_OPERATIONS_ERROR;
13247c478bd9Sstevel@tonic-gate 					sfree(tp);
13257c478bd9Sstevel@tonic-gate 					return (stat);
13267c478bd9Sstevel@tonic-gate 				}
13277c478bd9Sstevel@tonic-gate 			}
13287c478bd9Sstevel@tonic-gate 			sfree(tp);
13297c478bd9Sstevel@tonic-gate 
13307c478bd9Sstevel@tonic-gate 			/* Any mappings for table entries ? */
13317c478bd9Sstevel@tonic-gate 			tp = selectTableMapping(t, 0, 0, 0, t->dbId, &nm);
13327c478bd9Sstevel@tonic-gate 			if (tp == 0 || nm <= 0) {
13337c478bd9Sstevel@tonic-gate 				sfree(tp);
13347c478bd9Sstevel@tonic-gate 				continue;
13357c478bd9Sstevel@tonic-gate 			}
13367c478bd9Sstevel@tonic-gate 			sfree(tp);
13377c478bd9Sstevel@tonic-gate 
13387c478bd9Sstevel@tonic-gate 			/*
13397c478bd9Sstevel@tonic-gate 			 * The object itself must exist in the local
13407c478bd9Sstevel@tonic-gate 			 * DB by now. Get the db_mindex and let
13417c478bd9Sstevel@tonic-gate 			 * db_mindex::queryLDAP() do the work; if
13427c478bd9Sstevel@tonic-gate 			 * the object isn't a table, queryLDAP()
13437c478bd9Sstevel@tonic-gate 			 * will do nothing and return success.
13447c478bd9Sstevel@tonic-gate 			 */
13457c478bd9Sstevel@tonic-gate 			dbase = InUseDictionary->find_table(t->objPath,
13467c478bd9Sstevel@tonic-gate 							&tbl, TRUE);
13477c478bd9Sstevel@tonic-gate 			if (dbase != 0)
13487c478bd9Sstevel@tonic-gate 				mindex = dbase->mindex();
13497c478bd9Sstevel@tonic-gate 			if (dbase == 0 || tbl == 0 || mindex == 0) {
13507c478bd9Sstevel@tonic-gate 				logmsg(MSG_NOTIMECHECK, LOG_ERR,
13517c478bd9Sstevel@tonic-gate 				"%s: No local DB entry for \"%s\" (%s:%s)",
13527c478bd9Sstevel@tonic-gate 					myself, NIL(t->objPath),
13537c478bd9Sstevel@tonic-gate 					NIL(t->dbId), NIL(t->objName));
13547c478bd9Sstevel@tonic-gate 				if (cookie != 0)
13557c478bd9Sstevel@tonic-gate 					*((__nis_table_mapping_t **)cookie) =
13567c478bd9Sstevel@tonic-gate 						t;
13577c478bd9Sstevel@tonic-gate 				if (dstatP != 0)
13587c478bd9Sstevel@tonic-gate 					*dstatP = DB_BADTABLE;
13597c478bd9Sstevel@tonic-gate 				return ((dstatP != 0) ?
13607c478bd9Sstevel@tonic-gate 					LDAP_SUCCESS : LDAP_OPERATIONS_ERROR);
13617c478bd9Sstevel@tonic-gate 			}
13627c478bd9Sstevel@tonic-gate 			mindex->setInitialLoad();
13637c478bd9Sstevel@tonic-gate 			stat = mindex->queryLDAP(0, t->dbId, 0);
13647c478bd9Sstevel@tonic-gate 			mindex->clearInitialLoad();
13657c478bd9Sstevel@tonic-gate 			if (stat != LDAP_SUCCESS) {
13667c478bd9Sstevel@tonic-gate 				logmsg(MSG_NOTIMECHECK, LOG_ERR,
13677c478bd9Sstevel@tonic-gate 			"%s: LDAP error retrieving entries for %s:%s: %s",
13687c478bd9Sstevel@tonic-gate 					myself, NIL(t->dbId), NIL(t->objName),
13697c478bd9Sstevel@tonic-gate 					ldap_err2string(stat));
13707c478bd9Sstevel@tonic-gate 				if (cookie != 0)
13717c478bd9Sstevel@tonic-gate 					*((__nis_table_mapping_t **)cookie) =
13727c478bd9Sstevel@tonic-gate 						t;
13737c478bd9Sstevel@tonic-gate 				if (dstatP != 0)
13747c478bd9Sstevel@tonic-gate 					*dstatP = DB_SUCCESS;
13757c478bd9Sstevel@tonic-gate 				return (stat);
13767c478bd9Sstevel@tonic-gate 			}
13777c478bd9Sstevel@tonic-gate 		} else {
13787c478bd9Sstevel@tonic-gate 			nis_object	*obj;
13797c478bd9Sstevel@tonic-gate 			char		*ent, *objPath;
13807c478bd9Sstevel@tonic-gate 			int		freeObjPath = 0;
13817c478bd9Sstevel@tonic-gate 
13827c478bd9Sstevel@tonic-gate 			/*
13837c478bd9Sstevel@tonic-gate 			 * Up-loading to LDAP, so the object must
13847c478bd9Sstevel@tonic-gate 			 * already exist in the local DB.
13857c478bd9Sstevel@tonic-gate 			 */
13867c478bd9Sstevel@tonic-gate 			obj = dbFindObject(t->objName, &dstat);
13877c478bd9Sstevel@tonic-gate 			if (obj == 0) {
13887c478bd9Sstevel@tonic-gate 				if (dstat == DB_NOTFOUND)
13897c478bd9Sstevel@tonic-gate 					logmsg(MSG_NOTIMECHECK, LOG_WARNING,
13907c478bd9Sstevel@tonic-gate 		"%s: No local DB object for \"%s\" (%s:%s); skipping up-load",
13917c478bd9Sstevel@tonic-gate 						myself, NIL(t->objPath),
13927c478bd9Sstevel@tonic-gate 						NIL(t->dbId),
13937c478bd9Sstevel@tonic-gate 						NIL(t->objName));
13947c478bd9Sstevel@tonic-gate 				else
13957c478bd9Sstevel@tonic-gate 					logmsg(MSG_NOTIMECHECK, LOG_WARNING,
13967c478bd9Sstevel@tonic-gate 			"%s: DB error %d for \"%s\" (%s:%s); skipping up-load",
13977c478bd9Sstevel@tonic-gate 						myself, dstat,
13987c478bd9Sstevel@tonic-gate 						NIL(t->objPath),
13997c478bd9Sstevel@tonic-gate 						NIL(t->dbId),
14007c478bd9Sstevel@tonic-gate 						NIL(t->objName));
14017c478bd9Sstevel@tonic-gate 				continue;
14027c478bd9Sstevel@tonic-gate 			}
14037c478bd9Sstevel@tonic-gate 
14047c478bd9Sstevel@tonic-gate 			/*
14057c478bd9Sstevel@tonic-gate 			 * If it's a table or directory, there will be
14067c478bd9Sstevel@tonic-gate 			 * a dictionary entry for the object itself.
14077c478bd9Sstevel@tonic-gate 			 * Otherwise, we need the dictionary entry for
14087c478bd9Sstevel@tonic-gate 			 * the parent directory.
14097c478bd9Sstevel@tonic-gate 			 *
14107c478bd9Sstevel@tonic-gate 			 * For a table, we need the db_mindex for both the
14117c478bd9Sstevel@tonic-gate 			 * table object itself, as well as for the parent
14127c478bd9Sstevel@tonic-gate 			 * directory (in order to store table entries).
14137c478bd9Sstevel@tonic-gate 			 * We start with the latter.
14147c478bd9Sstevel@tonic-gate 			 */
14157c478bd9Sstevel@tonic-gate 			if (obj->zo_data.zo_type == NIS_DIRECTORY_OBJ) {
14167c478bd9Sstevel@tonic-gate 				objPath = t->objPath;
14177c478bd9Sstevel@tonic-gate 				ent = 0;
14187c478bd9Sstevel@tonic-gate 			} else {
14197c478bd9Sstevel@tonic-gate 				objPath = 0;
14208d0852b7SRichard Lowe 				ent = entryName(myself, t->objName,
14218d0852b7SRichard Lowe 				    &objPath);
14227c478bd9Sstevel@tonic-gate 				if (ent == 0 || objPath == 0) {
14237c478bd9Sstevel@tonic-gate 					logmsg(MSG_NOTIMECHECK, LOG_ERR,
14247c478bd9Sstevel@tonic-gate 	"%s: Error deriving entry/DB-table names for %s:%s; skipping up-load",
14257c478bd9Sstevel@tonic-gate 						myself, NIL(t->dbId),
14267c478bd9Sstevel@tonic-gate 						NIL(t->objName));
14277c478bd9Sstevel@tonic-gate 					sfree(ent);
14287c478bd9Sstevel@tonic-gate 					sfree(objPath);
14297c478bd9Sstevel@tonic-gate 					nis_destroy_object(obj);
14307c478bd9Sstevel@tonic-gate 					obj = 0;
14317c478bd9Sstevel@tonic-gate 					continue;
14327c478bd9Sstevel@tonic-gate 				}
14337c478bd9Sstevel@tonic-gate 				freeObjPath = 1;
14347c478bd9Sstevel@tonic-gate 			}
14357c478bd9Sstevel@tonic-gate 
14367c478bd9Sstevel@tonic-gate 			dbase = InUseDictionary->find_table(objPath,
14377c478bd9Sstevel@tonic-gate 							&tbl, TRUE);
14387c478bd9Sstevel@tonic-gate 			if (dbase != 0)
14397c478bd9Sstevel@tonic-gate 				mindex = dbase->mindex();
14407c478bd9Sstevel@tonic-gate 			if (dbase == 0 || tbl == 0 || mindex == 0) {
14417c478bd9Sstevel@tonic-gate 				logmsg(MSG_NOTIMECHECK, LOG_WARNING,
14427c478bd9Sstevel@tonic-gate 		"%s: No local DB entry for \"%s\" (%s:%s); skipping up-load",
14437c478bd9Sstevel@tonic-gate 					myself, objPath,
14447c478bd9Sstevel@tonic-gate 					NIL(t->dbId), NIL(t->objName));
14457c478bd9Sstevel@tonic-gate 				sfree(ent);
14467c478bd9Sstevel@tonic-gate 				if (freeObjPath)
14477c478bd9Sstevel@tonic-gate 					sfree(objPath);
14487c478bd9Sstevel@tonic-gate 				nis_destroy_object(obj);
14497c478bd9Sstevel@tonic-gate 				obj = 0;
14507c478bd9Sstevel@tonic-gate 				continue;
14517c478bd9Sstevel@tonic-gate 			}
14527c478bd9Sstevel@tonic-gate 
14537c478bd9Sstevel@tonic-gate 			/*
14547c478bd9Sstevel@tonic-gate 			 * Our next action(s) depend on the object type:
14557c478bd9Sstevel@tonic-gate 			 *
14567c478bd9Sstevel@tonic-gate 			 *	directory	Store dir object
14577c478bd9Sstevel@tonic-gate 			 *
14587c478bd9Sstevel@tonic-gate 			 *	table		Store table obj, as well
14597c478bd9Sstevel@tonic-gate 			 *			as any entries in the
14607c478bd9Sstevel@tonic-gate 			 *			table
14617c478bd9Sstevel@tonic-gate 			 *
14627c478bd9Sstevel@tonic-gate 			 *	other		Store object; we need to
14637c478bd9Sstevel@tonic-gate 			 *			build a db_query specifying
14647c478bd9Sstevel@tonic-gate 			 *			the first-level name of the
14657c478bd9Sstevel@tonic-gate 			 *			object.
14667c478bd9Sstevel@tonic-gate 			 *
14677c478bd9Sstevel@tonic-gate 			 * storeLDAP() will just do nothing and return
14687c478bd9Sstevel@tonic-gate 			 * success if we try to, say, store a table object
14697c478bd9Sstevel@tonic-gate 			 * when only the table entries are mapped. Hence,
14707c478bd9Sstevel@tonic-gate 			 * we don't have to worry about those distinctions
14717c478bd9Sstevel@tonic-gate 			 * here.
14727c478bd9Sstevel@tonic-gate 			 */
14737c478bd9Sstevel@tonic-gate 			if (obj->zo_data.zo_type == NIS_DIRECTORY_OBJ) {
14747c478bd9Sstevel@tonic-gate 				stat = mindex->storeLDAP(0, 0, obj, 0, t->dbId);
14757c478bd9Sstevel@tonic-gate 			} else {
14767c478bd9Sstevel@tonic-gate 				nis_attr	attr;
14777c478bd9Sstevel@tonic-gate 				db_query	*q;
14787c478bd9Sstevel@tonic-gate 
14798d0852b7SRichard Lowe 				attr.zattr_ndx = (char *)"name";
14807c478bd9Sstevel@tonic-gate 				attr.zattr_val.zattr_val_val = ent;
14817c478bd9Sstevel@tonic-gate 				attr.zattr_val.zattr_val_len = slen(ent) + 1;
14827c478bd9Sstevel@tonic-gate 
14837c478bd9Sstevel@tonic-gate 				q = new db_query(mindex->getScheme(), 1, &attr);
14847c478bd9Sstevel@tonic-gate 				if (q == 0) {
14857c478bd9Sstevel@tonic-gate 					logmsg(MSG_NOTIMECHECK, LOG_ERR,
14867c478bd9Sstevel@tonic-gate 	"%s: error creating db_query for \"%s\" in \"%s\"; skipping up-load",
14877c478bd9Sstevel@tonic-gate 						myself, ent, objPath);
14887c478bd9Sstevel@tonic-gate 					sfree(ent);
14897c478bd9Sstevel@tonic-gate 					if (freeObjPath)
14907c478bd9Sstevel@tonic-gate 						sfree(objPath);
14917c478bd9Sstevel@tonic-gate 					nis_destroy_object(obj);
14927c478bd9Sstevel@tonic-gate 					obj = 0;
14937c478bd9Sstevel@tonic-gate 					continue;
14947c478bd9Sstevel@tonic-gate 				}
14957c478bd9Sstevel@tonic-gate 
14967c478bd9Sstevel@tonic-gate 				stat = mindex->storeLDAP(q, 0, obj, 0, t->dbId);
14977c478bd9Sstevel@tonic-gate 
14987c478bd9Sstevel@tonic-gate 				delete q;
14997c478bd9Sstevel@tonic-gate 
15007c478bd9Sstevel@tonic-gate 			}
15017c478bd9Sstevel@tonic-gate 
15027c478bd9Sstevel@tonic-gate 			sfree(ent);
15037c478bd9Sstevel@tonic-gate 			if (freeObjPath)
15047c478bd9Sstevel@tonic-gate 				sfree(objPath);
15057c478bd9Sstevel@tonic-gate 
15067c478bd9Sstevel@tonic-gate 			if (stat != LDAP_SUCCESS) {
15077c478bd9Sstevel@tonic-gate 				logmsg(MSG_NOTIMECHECK, LOG_ERR,
15087c478bd9Sstevel@tonic-gate 			"%s: Error storing %s:%s to LDAP: %s",
15097c478bd9Sstevel@tonic-gate 					myself, NIL(t->dbId), NIL(t->objName),
15107c478bd9Sstevel@tonic-gate 					ldap_err2string(stat));
15117c478bd9Sstevel@tonic-gate 				nis_destroy_object(obj);
15127c478bd9Sstevel@tonic-gate 				obj = 0;
15137c478bd9Sstevel@tonic-gate 				if (cookie != 0)
15147c478bd9Sstevel@tonic-gate 					*((__nis_table_mapping_t **)
15157c478bd9Sstevel@tonic-gate 						cookie) = t;
15167c478bd9Sstevel@tonic-gate 				if (dstatP != 0)
15177c478bd9Sstevel@tonic-gate 					*dstatP = DB_SUCCESS;
15187c478bd9Sstevel@tonic-gate 				return (stat);
15197c478bd9Sstevel@tonic-gate 			}
15207c478bd9Sstevel@tonic-gate 
15217c478bd9Sstevel@tonic-gate 			/* Any mappings for table entries ? */
15227c478bd9Sstevel@tonic-gate 			tp = selectTableMapping(t, 0, 0, 0, t->dbId, &nm);
15237c478bd9Sstevel@tonic-gate 			if (tp == 0 || nm <= 0) {
15247c478bd9Sstevel@tonic-gate 				sfree(tp);
15257c478bd9Sstevel@tonic-gate 				nis_destroy_object(obj);
15267c478bd9Sstevel@tonic-gate 				obj = 0;
15277c478bd9Sstevel@tonic-gate 				continue;
15287c478bd9Sstevel@tonic-gate 			}
15297c478bd9Sstevel@tonic-gate 			sfree(tp);
15307c478bd9Sstevel@tonic-gate 
15317c478bd9Sstevel@tonic-gate 			/*
15327c478bd9Sstevel@tonic-gate 			 * If it's a table, we also need to store the table
15337c478bd9Sstevel@tonic-gate 			 * entries.
15347c478bd9Sstevel@tonic-gate 			 */
15357c478bd9Sstevel@tonic-gate 			if (obj->zo_data.zo_type == NIS_TABLE_OBJ) {
15367c478bd9Sstevel@tonic-gate 				tbl = 0;
15377c478bd9Sstevel@tonic-gate 				dbase = InUseDictionary->find_table(t->objPath,
15387c478bd9Sstevel@tonic-gate 								&tbl, TRUE);
15397c478bd9Sstevel@tonic-gate 				if (dbase != 0)
15407c478bd9Sstevel@tonic-gate 				mindex = dbase->mindex();
15417c478bd9Sstevel@tonic-gate 				if (dbase == 0 || tbl == 0 || mindex == 0) {
15427c478bd9Sstevel@tonic-gate 					logmsg(MSG_NOTIMECHECK, LOG_WARNING,
15437c478bd9Sstevel@tonic-gate 	"%s: No local DB entry for \"%s\" (%s:%s); skipping entry up-load",
15447c478bd9Sstevel@tonic-gate 						myself, NIL(t->objPath),
15457c478bd9Sstevel@tonic-gate 						NIL(t->dbId), NIL(t->objName));
15467c478bd9Sstevel@tonic-gate 					nis_destroy_object(obj);
15477c478bd9Sstevel@tonic-gate 					obj = 0;
15487c478bd9Sstevel@tonic-gate 					continue;
15497c478bd9Sstevel@tonic-gate 				}
15507c478bd9Sstevel@tonic-gate 
15517c478bd9Sstevel@tonic-gate 				stat = mindex->storeLDAP(0, 0, obj, 0, t->dbId);
15527c478bd9Sstevel@tonic-gate 
15537c478bd9Sstevel@tonic-gate 				if (stat != LDAP_SUCCESS) {
15547c478bd9Sstevel@tonic-gate 					logmsg(MSG_NOTIMECHECK, LOG_ERR,
15557c478bd9Sstevel@tonic-gate 				"%s: Error storing %s:%s entries to LDAP: %s",
15567c478bd9Sstevel@tonic-gate 						myself, NIL(t->dbId),
15577c478bd9Sstevel@tonic-gate 						NIL(t->objName),
15587c478bd9Sstevel@tonic-gate 						ldap_err2string(stat));
15597c478bd9Sstevel@tonic-gate 					nis_destroy_object(obj);
15607c478bd9Sstevel@tonic-gate 					obj = 0;
15617c478bd9Sstevel@tonic-gate 					if (cookie != 0)
15627c478bd9Sstevel@tonic-gate 						*((__nis_table_mapping_t **)
15637c478bd9Sstevel@tonic-gate 							cookie) = t;
15647c478bd9Sstevel@tonic-gate 					if (dstatP != 0)
15657c478bd9Sstevel@tonic-gate 						*dstatP = DB_SUCCESS;
15667c478bd9Sstevel@tonic-gate 					return (stat);
15677c478bd9Sstevel@tonic-gate 				}
15687c478bd9Sstevel@tonic-gate 			}
15697c478bd9Sstevel@tonic-gate 			nis_destroy_object(obj);
15707c478bd9Sstevel@tonic-gate 			obj = 0;
15717c478bd9Sstevel@tonic-gate 		}
15727c478bd9Sstevel@tonic-gate 	}
15737c478bd9Sstevel@tonic-gate 
15747c478bd9Sstevel@tonic-gate 	if (dstatP != 0)
15757c478bd9Sstevel@tonic-gate 		*dstatP = dstat;
15767c478bd9Sstevel@tonic-gate 	return (stat);
15777c478bd9Sstevel@tonic-gate }
15787c478bd9Sstevel@tonic-gate 
15797c478bd9Sstevel@tonic-gate /*
15807c478bd9Sstevel@tonic-gate  * Object identified by given attribute name is added to specified table.
15817c478bd9Sstevel@tonic-gate  * If object already exists, it is replaced.  If more than one object
15827c478bd9Sstevel@tonic-gate  * matches the given attribute name, DB_NOTUNIQUE is returned.
15837c478bd9Sstevel@tonic-gate  */
15847c478bd9Sstevel@tonic-gate static
15857c478bd9Sstevel@tonic-gate db_result *
db_add_entry_x(char * tab,int numattrs,nis_attr * attrname,entry_obj * newobj,int skiplog,int nosync)15867c478bd9Sstevel@tonic-gate db_add_entry_x(char * tab, int numattrs, nis_attr * attrname,
15877c478bd9Sstevel@tonic-gate 		entry_obj * newobj, int skiplog, int nosync)
15887c478bd9Sstevel@tonic-gate {
15897c478bd9Sstevel@tonic-gate 	db_result * safety = empty_result(DB_SUCCESS);
15907c478bd9Sstevel@tonic-gate 	db_table_desc * tbl = NULL;
15917c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(tab, &tbl, FALSE);
15927c478bd9Sstevel@tonic-gate 
15937c478bd9Sstevel@tonic-gate 	if (tbl == NULL || dbase == NULL) {
15947c478bd9Sstevel@tonic-gate 		return (set_result(safety, DB_BADTABLE));
15957c478bd9Sstevel@tonic-gate 	} else if (skiplog) {
15967c478bd9Sstevel@tonic-gate 		db_result * res;
15977c478bd9Sstevel@tonic-gate 		res = dbase->execute(DB_ADD_NOLOG, NULL,
15987c478bd9Sstevel@tonic-gate 			    (entry_object *) newobj, NULL);
15997c478bd9Sstevel@tonic-gate 		if (safety) delete safety;
16007c478bd9Sstevel@tonic-gate 		return (res);
16017c478bd9Sstevel@tonic-gate 	} else {
16027c478bd9Sstevel@tonic-gate 		db_result *res;
16037c478bd9Sstevel@tonic-gate 		db_query *
16047c478bd9Sstevel@tonic-gate 		query = InUseDictionary->translate_to_query(tbl,
16057c478bd9Sstevel@tonic-gate 						numattrs, attrname);
16067c478bd9Sstevel@tonic-gate 		if (query == NULL)
16077c478bd9Sstevel@tonic-gate 			return (set_result(safety, DB_BADQUERY));
16087c478bd9Sstevel@tonic-gate 		if (nosync)
16097c478bd9Sstevel@tonic-gate 			res = dbase->execute(DB_ADD_NOSYNC,
16107c478bd9Sstevel@tonic-gate 				query, (entry_object *) newobj, NULL);
16117c478bd9Sstevel@tonic-gate 		else
16127c478bd9Sstevel@tonic-gate 			res = dbase->execute(DB_ADD, query,
16137c478bd9Sstevel@tonic-gate 				(entry_object *) newobj, NULL);
16147c478bd9Sstevel@tonic-gate 		delete query;
16157c478bd9Sstevel@tonic-gate 		if (safety) delete safety;
16167c478bd9Sstevel@tonic-gate 		return (res);
16177c478bd9Sstevel@tonic-gate 	}
16187c478bd9Sstevel@tonic-gate }
16197c478bd9Sstevel@tonic-gate 
16207c478bd9Sstevel@tonic-gate db_result *
db_add_entry(char * tab,int numattrs,nis_attr * attrname,entry_obj * newobj)16217c478bd9Sstevel@tonic-gate db_add_entry(char * tab, int numattrs, nis_attr * attrname,
16227c478bd9Sstevel@tonic-gate 		entry_obj * newobj)
16237c478bd9Sstevel@tonic-gate {
16247c478bd9Sstevel@tonic-gate 	return (db_add_entry_x(tab, numattrs, attrname, newobj, 0, 0));
16257c478bd9Sstevel@tonic-gate }
16267c478bd9Sstevel@tonic-gate 
16277c478bd9Sstevel@tonic-gate db_result *
__db_add_entry_nolog(char * tab,int numattrs,nis_attr * attrname,entry_obj * newobj)16287c478bd9Sstevel@tonic-gate __db_add_entry_nolog(char * tab, int numattrs, nis_attr * attrname,
16297c478bd9Sstevel@tonic-gate 		entry_obj * newobj)
16307c478bd9Sstevel@tonic-gate {
16317c478bd9Sstevel@tonic-gate 	return (db_add_entry_x(tab, numattrs, attrname, newobj, 1, 0));
16327c478bd9Sstevel@tonic-gate }
16337c478bd9Sstevel@tonic-gate 
16347c478bd9Sstevel@tonic-gate db_result *
__db_add_entry_nosync(char * tab,int numattrs,nis_attr * attrname,entry_obj * newobj)16357c478bd9Sstevel@tonic-gate __db_add_entry_nosync(char * tab, int numattrs, nis_attr * attrname,
16367c478bd9Sstevel@tonic-gate 			entry_obj * newobj)
16377c478bd9Sstevel@tonic-gate {
16387c478bd9Sstevel@tonic-gate 	return (db_add_entry_x(tab, numattrs, attrname, newobj, 0, 1));
16397c478bd9Sstevel@tonic-gate }
16407c478bd9Sstevel@tonic-gate 
16417c478bd9Sstevel@tonic-gate /*
16427c478bd9Sstevel@tonic-gate  * Remove object identified by given attributes from specified table.
16437c478bd9Sstevel@tonic-gate  * If no attribute is supplied, all entries in table are removed.
16447c478bd9Sstevel@tonic-gate  * If attributes identify more than one object, all objects are removed.
16457c478bd9Sstevel@tonic-gate */
16467c478bd9Sstevel@tonic-gate 
16477c478bd9Sstevel@tonic-gate db_result *
db_remove_entry_x(char * table_name,int num_attrs,nis_attr * attrname,int nosync)16487c478bd9Sstevel@tonic-gate db_remove_entry_x(char * table_name, int num_attrs, nis_attr * attrname,
16497c478bd9Sstevel@tonic-gate 			int nosync)
16507c478bd9Sstevel@tonic-gate {
16517c478bd9Sstevel@tonic-gate 	db_result * safety = empty_result(DB_SUCCESS);
16527c478bd9Sstevel@tonic-gate 	db_table_desc * tbl = NULL;
16537c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(table_name, &tbl, FALSE);
16547c478bd9Sstevel@tonic-gate 	db_result * res;
16557c478bd9Sstevel@tonic-gate 
16567c478bd9Sstevel@tonic-gate 	if (tbl == NULL || dbase == NULL)
16577c478bd9Sstevel@tonic-gate 		return (set_result(safety, DB_BADTABLE));
16587c478bd9Sstevel@tonic-gate 	else {
16597c478bd9Sstevel@tonic-gate 		if (num_attrs != 0) {
16607c478bd9Sstevel@tonic-gate 			db_query *query;
16617c478bd9Sstevel@tonic-gate 			query = InUseDictionary->translate_to_query(tbl,
16627c478bd9Sstevel@tonic-gate 					num_attrs, attrname);
16637c478bd9Sstevel@tonic-gate 			if (query == NULL)
16647c478bd9Sstevel@tonic-gate 				return (set_result(safety,
16657c478bd9Sstevel@tonic-gate 						DB_BADQUERY));
16667c478bd9Sstevel@tonic-gate 			if (nosync)
16677c478bd9Sstevel@tonic-gate 				res = dbase->execute(DB_REMOVE_NOSYNC,
16687c478bd9Sstevel@tonic-gate 						query, NULL, NULL);
16697c478bd9Sstevel@tonic-gate 			else
16707c478bd9Sstevel@tonic-gate 				res = dbase->execute(DB_REMOVE, query,
16717c478bd9Sstevel@tonic-gate 						NULL, NULL);
16727c478bd9Sstevel@tonic-gate 			delete query;
16737c478bd9Sstevel@tonic-gate 		} else {
16747c478bd9Sstevel@tonic-gate 			if (nosync)
16757c478bd9Sstevel@tonic-gate 				res = dbase->execute(DB_REMOVE_NOSYNC,
16767c478bd9Sstevel@tonic-gate 					NULL, NULL, NULL);
16777c478bd9Sstevel@tonic-gate 			else
16787c478bd9Sstevel@tonic-gate 				res = dbase->execute(DB_REMOVE,
16797c478bd9Sstevel@tonic-gate 					NULL, NULL, NULL);
16807c478bd9Sstevel@tonic-gate 		}
16817c478bd9Sstevel@tonic-gate 		if (safety) delete safety;
16827c478bd9Sstevel@tonic-gate 		return (res);
16837c478bd9Sstevel@tonic-gate 	}
16847c478bd9Sstevel@tonic-gate }
16857c478bd9Sstevel@tonic-gate 
16867c478bd9Sstevel@tonic-gate db_result *
db_remove_entry(char * table_name,int num_attrs,nis_attr * attrname)16877c478bd9Sstevel@tonic-gate db_remove_entry(char * table_name, int num_attrs, nis_attr * attrname)
16887c478bd9Sstevel@tonic-gate {
16897c478bd9Sstevel@tonic-gate 	return (db_remove_entry_x(table_name, num_attrs, attrname, 0));
16907c478bd9Sstevel@tonic-gate }
16917c478bd9Sstevel@tonic-gate 
16927c478bd9Sstevel@tonic-gate db_result *
__db_remove_entry_nosync(char * table_name,int num_attrs,nis_attr * attrname)16937c478bd9Sstevel@tonic-gate __db_remove_entry_nosync(char * table_name, int num_attrs, nis_attr * attrname)
16947c478bd9Sstevel@tonic-gate {
16957c478bd9Sstevel@tonic-gate 	return (db_remove_entry_x(table_name, num_attrs, attrname, 1));
16967c478bd9Sstevel@tonic-gate }
16977c478bd9Sstevel@tonic-gate 
16987c478bd9Sstevel@tonic-gate /* Return a copy of the version of specified table. */
16997c478bd9Sstevel@tonic-gate vers *
db_version(char * table_name)17007c478bd9Sstevel@tonic-gate db_version(char * table_name)
17017c478bd9Sstevel@tonic-gate {
17027c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(table_name);
17037c478bd9Sstevel@tonic-gate 
17047c478bd9Sstevel@tonic-gate 	if (dbase == NULL)
17057c478bd9Sstevel@tonic-gate 		return (NULL);
17067c478bd9Sstevel@tonic-gate 	vers* v = new vers(dbase->get_version());
17077c478bd9Sstevel@tonic-gate 	if (v == NULL)
17087c478bd9Sstevel@tonic-gate 		WARNING("nis_db::db_version: cannot allocate space");
17097c478bd9Sstevel@tonic-gate 	return (v);
17107c478bd9Sstevel@tonic-gate }
17117c478bd9Sstevel@tonic-gate 
17127c478bd9Sstevel@tonic-gate /* Return log entries since (later than) given version 'v' of table. */
17137c478bd9Sstevel@tonic-gate db_log_list *
db_log_entries_since(char * table_name,vers * v)17147c478bd9Sstevel@tonic-gate db_log_entries_since(char * table_name, vers * v)
17157c478bd9Sstevel@tonic-gate {
17167c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(table_name);
17177c478bd9Sstevel@tonic-gate 
17187c478bd9Sstevel@tonic-gate 	if (dbase == NULL)
17197c478bd9Sstevel@tonic-gate 		return (NULL);
17207c478bd9Sstevel@tonic-gate 	return (dbase->get_log_entries_since(v));
17217c478bd9Sstevel@tonic-gate }
17227c478bd9Sstevel@tonic-gate 
17237c478bd9Sstevel@tonic-gate db_status
db_sync_log(char * table_name)17247c478bd9Sstevel@tonic-gate db_sync_log(char *table_name) {
17257c478bd9Sstevel@tonic-gate 
17267c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(table_name);
17277c478bd9Sstevel@tonic-gate 
17287c478bd9Sstevel@tonic-gate 	if (dbase == NULL)
17297c478bd9Sstevel@tonic-gate 		return (DB_BADTABLE);
17307c478bd9Sstevel@tonic-gate 	return (dbase->sync_log());
17317c478bd9Sstevel@tonic-gate }
17327c478bd9Sstevel@tonic-gate 
17337c478bd9Sstevel@tonic-gate /*
17347c478bd9Sstevel@tonic-gate  * Apply the given update specified in 'entry' to the specified table.
17357c478bd9Sstevel@tonic-gate  * Returns DB_SUCCESS if update was executed.
17367c478bd9Sstevel@tonic-gate  * Returns DB_NOTFOUND if update occurs too early to be applied.
17377c478bd9Sstevel@tonic-gate */
17387c478bd9Sstevel@tonic-gate db_status
db_apply_log_entry(char * table_name,db_log_entry * entry)17397c478bd9Sstevel@tonic-gate db_apply_log_entry(char * table_name, db_log_entry * entry)
17407c478bd9Sstevel@tonic-gate {
17417c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(table_name, NULL, FALSE);
17427c478bd9Sstevel@tonic-gate 
17437c478bd9Sstevel@tonic-gate 	if (dbase == NULL)
17447c478bd9Sstevel@tonic-gate 		return (DB_BADTABLE);
17457c478bd9Sstevel@tonic-gate 	if (dbase->execute_log_entry(entry))
17467c478bd9Sstevel@tonic-gate 		return (DB_SUCCESS);   /* got executed */
17477c478bd9Sstevel@tonic-gate 	else
17487c478bd9Sstevel@tonic-gate 		return (DB_NOTFOUND);  /* not executed */
17497c478bd9Sstevel@tonic-gate }
17507c478bd9Sstevel@tonic-gate 
17517c478bd9Sstevel@tonic-gate /*
17527c478bd9Sstevel@tonic-gate  * Checkpoint specified table (i.e. incorporate logged updates to main
17537c478bd9Sstevel@tonic-gate  * database file).  If table_name is NULL, checkpoint all tables that
17547c478bd9Sstevel@tonic-gate  * needs it.
17557c478bd9Sstevel@tonic-gate */
17567c478bd9Sstevel@tonic-gate db_status
db_checkpoint(char * table_name)17577c478bd9Sstevel@tonic-gate db_checkpoint(char * table_name)
17587c478bd9Sstevel@tonic-gate {
17597c478bd9Sstevel@tonic-gate 	return (InUseDictionary->db_checkpoint(table_name));
17607c478bd9Sstevel@tonic-gate }
17617c478bd9Sstevel@tonic-gate 
17627c478bd9Sstevel@tonic-gate /* Print names of tables in system. */
17637c478bd9Sstevel@tonic-gate void
db_print_table_names()17647c478bd9Sstevel@tonic-gate db_print_table_names()
17657c478bd9Sstevel@tonic-gate {
17667c478bd9Sstevel@tonic-gate 	int i;
17677c478bd9Sstevel@tonic-gate 	db_table_names * answer = InUseDictionary->get_table_names();
17687c478bd9Sstevel@tonic-gate 
17697c478bd9Sstevel@tonic-gate 	if (answer != NULL) {
17707c478bd9Sstevel@tonic-gate 		for (i = 0; i < answer->db_table_names_len; i++) {
17717c478bd9Sstevel@tonic-gate 			printf("%s\n", answer->db_table_names_val[i]);
17727c478bd9Sstevel@tonic-gate 			delete answer->db_table_names_val[i];
17737c478bd9Sstevel@tonic-gate 		}
17747c478bd9Sstevel@tonic-gate 		delete answer->db_table_names_val;
17757c478bd9Sstevel@tonic-gate 		delete answer;
17767c478bd9Sstevel@tonic-gate 	}
17777c478bd9Sstevel@tonic-gate }
17787c478bd9Sstevel@tonic-gate 
17797c478bd9Sstevel@tonic-gate /* Print statistics of specified table to stdout. */
17807c478bd9Sstevel@tonic-gate db_status
db_stats(char * table_name)17817c478bd9Sstevel@tonic-gate db_stats(char * table_name)
17827c478bd9Sstevel@tonic-gate {
17837c478bd9Sstevel@tonic-gate 	db_table_desc * tbl = NULL;
17847c478bd9Sstevel@tonic-gate 	db *dbase = InUseDictionary->find_table(table_name, &tbl);
17857c478bd9Sstevel@tonic-gate 
17867c478bd9Sstevel@tonic-gate 	if (tbl == NULL || dbase == NULL || tbl->scheme == NULL)
17877c478bd9Sstevel@tonic-gate 		return (DB_BADTABLE);
17887c478bd9Sstevel@tonic-gate 
17897c478bd9Sstevel@tonic-gate 	dbase->print();
17907c478bd9Sstevel@tonic-gate 	tbl->scheme->print();
17917c478bd9Sstevel@tonic-gate 	return (DB_SUCCESS);
17927c478bd9Sstevel@tonic-gate }
17937c478bd9Sstevel@tonic-gate 
17947c478bd9Sstevel@tonic-gate 
17957c478bd9Sstevel@tonic-gate /* Print statistics of indices of specified table to stdout. */
17967c478bd9Sstevel@tonic-gate db_status
db_print_all_indices(char * table_name)17977c478bd9Sstevel@tonic-gate db_print_all_indices(char * table_name)
17987c478bd9Sstevel@tonic-gate {
17997c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(table_name);
18007c478bd9Sstevel@tonic-gate 
18017c478bd9Sstevel@tonic-gate 	if (dbase == NULL)
18027c478bd9Sstevel@tonic-gate 		return (DB_BADTABLE);
18037c478bd9Sstevel@tonic-gate 	dbase->print_all_indices();
18047c478bd9Sstevel@tonic-gate 	return (DB_SUCCESS);
18057c478bd9Sstevel@tonic-gate }
18067c478bd9Sstevel@tonic-gate 
18077c478bd9Sstevel@tonic-gate /* Print specified index of table to stdout. */
18087c478bd9Sstevel@tonic-gate db_status
db_print_index(char * table_name,int which)18097c478bd9Sstevel@tonic-gate db_print_index(char * table_name, int which)
18107c478bd9Sstevel@tonic-gate {
18117c478bd9Sstevel@tonic-gate 	db * dbase = InUseDictionary->find_table(table_name);
18127c478bd9Sstevel@tonic-gate 
18137c478bd9Sstevel@tonic-gate 	if (dbase == NULL)
18147c478bd9Sstevel@tonic-gate 		return (DB_BADTABLE);
18157c478bd9Sstevel@tonic-gate 	dbase->print_index(which);
18167c478bd9Sstevel@tonic-gate 	return (DB_SUCCESS);
18177c478bd9Sstevel@tonic-gate }
18187c478bd9Sstevel@tonic-gate 
18197c478bd9Sstevel@tonic-gate /* close open files */
18207c478bd9Sstevel@tonic-gate db_status
db_standby(char * table_name)18217c478bd9Sstevel@tonic-gate db_standby(char * table_name)
18227c478bd9Sstevel@tonic-gate {
18237c478bd9Sstevel@tonic-gate 	return (InUseDictionary->db_standby(table_name));
18247c478bd9Sstevel@tonic-gate }
18257c478bd9Sstevel@tonic-gate 
18267c478bd9Sstevel@tonic-gate /* Returns DB_SUCCESS if table exists; DB_BADTABLE if table does not exist. */
18277c478bd9Sstevel@tonic-gate db_status
db_table_exists(char * table_name)18287c478bd9Sstevel@tonic-gate db_table_exists(char * table_name)
18297c478bd9Sstevel@tonic-gate {
18307c478bd9Sstevel@tonic-gate 	db_table_desc *dbtab = InUseDictionary->find_table_desc(table_name);
18317c478bd9Sstevel@tonic-gate 
18327c478bd9Sstevel@tonic-gate 	if (dbtab == NULL)
18337c478bd9Sstevel@tonic-gate 		return (DB_BADTABLE);
18347c478bd9Sstevel@tonic-gate 	return (DB_SUCCESS);
18357c478bd9Sstevel@tonic-gate }
18367c478bd9Sstevel@tonic-gate 
18377c478bd9Sstevel@tonic-gate /*
18387c478bd9Sstevel@tonic-gate  * Returns DB_SUCCESS if table exists; DB_BADTABLE if table does not exist.
18397c478bd9Sstevel@tonic-gate  *  If table already loaded, unload it.
18407c478bd9Sstevel@tonic-gate */
18417c478bd9Sstevel@tonic-gate db_status
db_unload_table(char * table_name)18427c478bd9Sstevel@tonic-gate db_unload_table(char * table_name)
18437c478bd9Sstevel@tonic-gate {
18447c478bd9Sstevel@tonic-gate 	db_table_desc *
18457c478bd9Sstevel@tonic-gate 	dbtab = InUseDictionary->find_table_desc(table_name);
18467c478bd9Sstevel@tonic-gate 	if (dbtab == NULL)
18477c478bd9Sstevel@tonic-gate 		return (DB_BADTABLE);
18487c478bd9Sstevel@tonic-gate 	// unload
18497c478bd9Sstevel@tonic-gate 	if (dbtab->database != NULL) {
18507c478bd9Sstevel@tonic-gate 		delete dbtab->database;
18517c478bd9Sstevel@tonic-gate 		dbtab->database = NULL;
18527c478bd9Sstevel@tonic-gate 	}
18537c478bd9Sstevel@tonic-gate 	return (DB_SUCCESS);
18547c478bd9Sstevel@tonic-gate }
18557c478bd9Sstevel@tonic-gate 
18567c478bd9Sstevel@tonic-gate /*
18577c478bd9Sstevel@tonic-gate  * Put the specified table in deferred mode, which means that updates go
18587c478bd9Sstevel@tonic-gate  * to the original table, but reads are satisfied out of a copy (which we
18597c478bd9Sstevel@tonic-gate  * make here). Thus, "defer" refers to the table as seen by read requests,
18607c478bd9Sstevel@tonic-gate  * since for them, changes are deferred.
18617c478bd9Sstevel@tonic-gate  */
18627c478bd9Sstevel@tonic-gate db_status
__db_defer(char * table_name)18637c478bd9Sstevel@tonic-gate __db_defer(char *table_name) {
18647c478bd9Sstevel@tonic-gate 	db_status	stat;
18657c478bd9Sstevel@tonic-gate 
18667c478bd9Sstevel@tonic-gate 	stat = InUseDictionary->defer(table_name);
18677c478bd9Sstevel@tonic-gate 	return (stat);
18687c478bd9Sstevel@tonic-gate }
18697c478bd9Sstevel@tonic-gate 
18707c478bd9Sstevel@tonic-gate /*
18717c478bd9Sstevel@tonic-gate  * Commit deferred changes for the specified table. I.e., make visible
18727c478bd9Sstevel@tonic-gate  * any updates made since the table was deferred.
18737c478bd9Sstevel@tonic-gate  */
18747c478bd9Sstevel@tonic-gate db_status
__db_commit(char * table_name)18757c478bd9Sstevel@tonic-gate __db_commit(char *table_name) {
18767c478bd9Sstevel@tonic-gate 	db_status	stat;
18777c478bd9Sstevel@tonic-gate 
18787c478bd9Sstevel@tonic-gate 	stat = InUseDictionary->commit(table_name);
18797c478bd9Sstevel@tonic-gate 	return (stat);
18807c478bd9Sstevel@tonic-gate }
18817c478bd9Sstevel@tonic-gate 
18827c478bd9Sstevel@tonic-gate /*
18837c478bd9Sstevel@tonic-gate  * Rollback, i.e., return to the state before we entered deferred mode.
18847c478bd9Sstevel@tonic-gate  */
18857c478bd9Sstevel@tonic-gate db_status
__db_rollback(char * table_name)18867c478bd9Sstevel@tonic-gate __db_rollback(char *table_name) {
18877c478bd9Sstevel@tonic-gate 	db_status	stat;
18887c478bd9Sstevel@tonic-gate 
18897c478bd9Sstevel@tonic-gate 	stat = InUseDictionary->rollback(table_name);
18907c478bd9Sstevel@tonic-gate 	return (stat);
18917c478bd9Sstevel@tonic-gate }
18927c478bd9Sstevel@tonic-gate 
18937c478bd9Sstevel@tonic-gate db_status
__db_configure(char * table_name)18947c478bd9Sstevel@tonic-gate __db_configure(char *table_name) {
18957c478bd9Sstevel@tonic-gate 	db_status	stat;
18967c478bd9Sstevel@tonic-gate 	char		tablePath[MAXPATHLEN + NIS_MAXNAMELEN + 1];
18977c478bd9Sstevel@tonic-gate 	db		*dbase = InUseDictionary->find_table(table_name, NULL);
18987c478bd9Sstevel@tonic-gate 
18997c478bd9Sstevel@tonic-gate 	if (dbase == NULL || table_name == 0)
19007c478bd9Sstevel@tonic-gate 		return (DB_BADTABLE);
19017c478bd9Sstevel@tonic-gate 
19027c478bd9Sstevel@tonic-gate 	if (strlen(table_name) >= sizeof (tablePath))
19037c478bd9Sstevel@tonic-gate 		return (DB_BADQUERY);
19047c478bd9Sstevel@tonic-gate 
19057c478bd9Sstevel@tonic-gate 	if (internal_table_name(table_name, tablePath) == 0)
19067c478bd9Sstevel@tonic-gate 		return (DB_STORAGE_LIMIT);
19077c478bd9Sstevel@tonic-gate 
19087c478bd9Sstevel@tonic-gate 	if (dbase->configure(tablePath))
19097c478bd9Sstevel@tonic-gate 		stat = DB_SUCCESS;
19107c478bd9Sstevel@tonic-gate 	else
19117c478bd9Sstevel@tonic-gate 		stat = DB_INTERNAL_ERROR;
19127c478bd9Sstevel@tonic-gate 
19137c478bd9Sstevel@tonic-gate 	return (stat);
19147c478bd9Sstevel@tonic-gate }
19157c478bd9Sstevel@tonic-gate 
19167c478bd9Sstevel@tonic-gate /*
19177c478bd9Sstevel@tonic-gate  * During some rpc.nisd operations (such as when recovering the trans.log),
19187c478bd9Sstevel@tonic-gate  * we don't want to use the LDAP repository, so we provide a main switch.
19197c478bd9Sstevel@tonic-gate  * Note that we expect this to be used only when rpc.nisd is single-threaded,
19207c478bd9Sstevel@tonic-gate  * so there is no need for synchronization when reading or modifying the
19217c478bd9Sstevel@tonic-gate  * value of the main switch.
19227c478bd9Sstevel@tonic-gate  */
19237c478bd9Sstevel@tonic-gate int	useLDAPrespository = 1;
19247c478bd9Sstevel@tonic-gate 
19257c478bd9Sstevel@tonic-gate void
__db_disallowLDAP(void)19267c478bd9Sstevel@tonic-gate __db_disallowLDAP(void) {
19277c478bd9Sstevel@tonic-gate 	useLDAPrespository = 0;
19287c478bd9Sstevel@tonic-gate }
19297c478bd9Sstevel@tonic-gate 
19307c478bd9Sstevel@tonic-gate void
__db_allowLDAP(void)19317c478bd9Sstevel@tonic-gate __db_allowLDAP(void) {
19327c478bd9Sstevel@tonic-gate 	useLDAPrespository = 1;
19337c478bd9Sstevel@tonic-gate }
19347c478bd9Sstevel@tonic-gate 
19357c478bd9Sstevel@tonic-gate }  /* extern "C" */
1936