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