/** * Is this "special" key handled by the focused control? (bypassing * the dialog manager) */ gcc_pure static bool check_special_key(ContainerWindow *container, const MSG &msg) { return is_special_key(msg.wParam) && check_key(container, msg); }
/* * FUNCTION: update_map_from_dit() * * DESCRIPTION: Core code called to update an entire map. * Information is recovered from LDAP and used to build a duplicate * copy of the live maps. When this is complete the maps are * locked and then overwritten by the new copy. * * INPUTS: map_ctrl containing lots of information about the map and a * pointer to it's lock which will be required. * Flag indicating if progress logging is required. * * OUTPUTS: SUCCESS = Map updated * FAILURE = Map not updated */ suc_code update_map_from_dit(map_ctrl *map, bool_t log_flag) { __nis_table_mapping_t *t; __nis_rule_value_t *rv; __nis_ldap_search_t *ls; __nis_object_dn_t *objectDN = NULL; datum *datval, *datkey; int nr = 0, i, j, nv, numDNs; int statP = SUCCESS, flag; char *objname, **dn; /* Name of temporary entries DBM file */ char *temp_entries; /* Name of temporary TTL DBM file */ char *temp_ttl; /* Temporary DBM handles */ DBM *temp_entries_db; DBM *temp_ttl_db; map_ctrl temp_map; datum key; char *myself = "update_map_from_dit"; bool_t secure_flag; int entry_count = 1; int next_print = PRINT_FREQ; int search_flag = SUCCESS; int m; /* list of maps whose keys will be transliterated to lowercase */ char *xlate_to_lcase_maps[] = { "hosts.byname", "ipnodes.byname", NULL }; bool_t xlate_to_lcase = FALSE; if (!map || !map->map_name || !map->domain) { return (FAILURE); } __nisdb_get_tsd()->escapeFlag = '\0'; /* * netgroup.byxxx maps are a special case. They are regenerated from * the netgroup map, not the DIT, so handle special case. */ if ((0 == strcmp(map->map_name, NETGROUP_BYHOST)) || 0 == (strcmp(map->map_name, NETGROUP_BYUSER))) { return (update_netgroup_byxxx(map)); } /* Get the mapping information for the map */ if ((t = mappingFromMap(map->map_name, map->domain, &statP)) == 0) { if (statP == MAP_NO_MAPPING_EXISTS) logmsg(MSG_NOTIMECHECK, LOG_WARNING, "%s: No mapping information available for %s,%s", myself, map->map_name, map->domain); return (FAILURE); } /* Allocate and set up names */ if (SUCCESS != alloc_temp_names(map->map_path, &temp_entries, &temp_ttl)) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Unable to create map names for %s", myself, map->map_path); return (FAILURE); } /* Create temp entry and TTL file */ if ((temp_entries_db = dbm_open(temp_entries, O_RDWR | O_CREAT, 0644)) == NULL) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not open %s", myself, temp_entries); sfree(temp_entries); sfree(temp_ttl); return (FAILURE); } if ((temp_ttl_db = dbm_open(temp_ttl, O_RDWR | O_CREAT, 0644)) == NULL) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not open %s", myself, temp_ttl); dbm_close(temp_entries_db); delete_map(temp_entries); sfree(temp_entries); sfree(temp_ttl); return (FAILURE); } /* Initialize domainContext tsd */ __nisdb_get_tsd()->domainContext = 0; for (i = 0; i < ypDomains.numDomains; i++) { if (0 == ypDomains.domainLabels[i]) continue; if (0 == strcasecmp(map->domain, ypDomains.domainLabels[i])) { __nisdb_get_tsd()->domainContext = ypDomains.domains[i]; break; } } if (!(objname = getFullMapName(map->map_name, map->domain))) { if (temp_entries_db) dbm_close(temp_entries_db); if (temp_ttl_db) dbm_close(temp_ttl_db); delete_map(temp_entries); sfree(temp_entries); delete_map(temp_ttl); sfree(temp_ttl); return (FAILURE); } /* * set xlate_to_lcase to TRUE if map_name is found in * xlate_to_lcase_maps[] */ m = 0; while (xlate_to_lcase_maps[m] != NULL) { if (strncmp(map->map_name, xlate_to_lcase_maps[m], strlen(xlate_to_lcase_maps[m])) == 0) { xlate_to_lcase = TRUE; break; } ++m; } /* Try each mapping for the map */ for (flag = 0; t != 0 && search_flag != FAILURE; t = t->next) { /* Check if the mapping is the correct one */ if (strcmp(objname, t->objName) != 0) { continue; } /* Check if rulesFromLDAP are provided */ if (t->numRulesFromLDAP == 0) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: No rulesFromLDAP available for %s (%s)", myself, t->dbId, map->map_name); continue; } /* Set flag to indicate update is enabled */ flag = 1; /* Create ldap request for enumeration */ for (objectDN = t->objectDN; objectDN && objectDN->read.base; objectDN = objectDN->next) { if ((ls = createLdapRequest(t, 0, 0, 1, NULL, objectDN)) == 0) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Failed to create " "ldapSearch request for " "%s (%s) for base %s", myself, t->dbId, map->map_name, objectDN->read.base); statP = FAILURE; search_flag = FAILURE; break; } if (log_flag) { printf("Waiting for LDAP search results.\n"); } /* Query LDAP */ nr = (ls->isDN)?0:-1; rv = ldapSearch(ls, &nr, 0, &statP); freeLdapSearch(ls); if (rv == 0) { if (statP == LDAP_NO_SUCH_OBJECT) { /* * No Entry exists in the ldap server. Not * a problem. Maybe there are just no entries * in this map. */ continue; } logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: ldapSearch error %d " "(%s) for %s (%s) for base %s", myself, statP, ldap_err2string(statP), t->dbId, map->map_name, objectDN->read.base); statP = FAILURE; search_flag = FAILURE; break; } if (log_flag) { printf("Processing search results.\n"); } /* Obtain list of DNs for logging */ if ((dn = findDNs(myself, rv, nr, 0, &numDNs)) == 0) { statP = FAILURE; search_flag = FAILURE; break; } /* For each entry in the result do the following */ for (i = 0; i < nr; i++) { /* Convert LDAP data to NIS equivalents */ statP = buildNISRuleValue(t, &rv[i], map->domain); if (statP == MAP_INDEXLIST_ERROR) continue; if (statP != SUCCESS) { logmsg(MSG_NOTIMECHECK, LOG_WARNING, "%s: Conversion error %d (LDAP to " "name=value pairs) " "for (dn: %s) for " "%s (%s) for base %s", myself, statP, NIL(dn[i]), t->dbId, map->map_name, objectDN->read.base); continue; } /* Obtain the datum for value */ datval = ruleValueToDatum(t, &rv[i], &statP); if (datval == 0) { logmsg(MSG_NOTIMECHECK, LOG_WARNING, "%s: Conversion error %d " "(name=value pairs to NIS)" " for (dn: %s) for " "%s (%s) for base %s", myself, statP, NIL(dn[i]), t->dbId, map->map_name, objectDN->read.base); continue; } /* Obtain the datum for key */ datkey = getKeyFromRuleValue(t, &rv[i], &nv, &statP, xlate_to_lcase); if (datkey == 0) { logmsg(MSG_NOTIMECHECK, LOG_WARNING, "%s: Unable to obtain NIS " "key from LDAP data (dn:%s) " "for %s (%s) for base %s", myself, NIL(dn[i]), t->dbId, map->map_name, objectDN->read.base); sfree(datval->dptr); sfree(datval); continue; } /* Write to the temporary map */ for (j = 0; j < nv; j++, entry_count ++) { if (datkey[j].dsize == 0) continue; errno = 0; /* DBM_INSERT to match */ /* singleReadFromDIT */ if (dbm_store(temp_entries_db, datkey[j], *datval, DBM_INSERT) < 0) { /* * For some cases errno may * still be 0 but dbm_error * isn't informative at all. */ logmsg(MSG_NOTIMECHECK, LOG_WARNING, "%s: dbm store error " "(errno=%d) " "for (key=%s, value=%s) " "for %s (%s) for base %s", myself, errno, datkey[j].dptr, datval->dptr, t->dbId, map->map_name, objectDN->read.base); /* clear the error */ dbm_clearerr(temp_entries_db); } sfree(datkey[j].dptr); if (log_flag && (entry_count >= next_print)) { printf("%d entries processed\n", entry_count); next_print *= 2; } } sfree(datkey); sfree(datval->dptr); sfree(datval); } freeRuleValue(rv, nr); freeDNs(dn, numDNs); } /* End of for over objectDN */ } sfree(objname); if (t != 0 || flag == 0 || search_flag == FAILURE) { if (temp_entries_db) dbm_close(temp_entries_db); if (temp_ttl_db) dbm_close(temp_ttl_db); delete_map(temp_entries); sfree(temp_entries); delete_map(temp_ttl); sfree(temp_ttl); return (statP); } /* Set up enough of map_ctrl to call update_entry_ttl */ temp_map.map_name = map->map_name; temp_map.domain = map->domain; temp_map.ttl = temp_ttl_db; /* Generate new TTL file */ key = dbm_firstkey(temp_entries_db); while (key.dptr != 0) { if (!is_special_key(&key)) /* * We don't want all the entries to time out at the * same time so create random TTLs. */ if (FAILURE == update_entry_ttl(&temp_map, &key, TTL_RAND)) logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not update TTL for " "(key=%s) for map %s,%s", myself, NIL(key.dptr), map->map_name, map->domain); key = dbm_nextkey(temp_entries_db); } /* Update map TTL */ if (SUCCESS != update_map_ttl(&temp_map)) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not update map TTL " "for %s,%s", myself, map->map_name, map->domain); } /* Set up 'special' nis entries */ add_special_entries(temp_entries_db, map, &secure_flag); /* Close temp DBM files */ dbm_close(temp_entries_db); dbm_close(temp_ttl_db); /* Lock access to the map for copy */ lock_map_ctrl(map); /* Move temp maps to real ones */ rename_map(temp_entries, map->map_path, secure_flag); rename_map(temp_ttl, map->ttl_path, secure_flag); /* Free file names */ sfree(temp_entries); sfree(temp_ttl); /* Unlock map */ unlock_map_ctrl(map); return (SUCCESS); }
gcc_pure static bool check_special_key(ContainerWindow *container, const SDL_Event &event) { return is_special_key(get_key_code(event)) && check_key(container, event); }
/* * FUNCTION: update_netgroup_byxxx() * * DESCRIPTION: Updates the netgroup.byxxx series of maps based on the current * netgroup file. We invoke revnetgroup so that if any changes * are made to this utility the same changes are made here. * * INPUTS: map_ctrl containing lots of information about the map and a * pointer to it's lock which will be required. * * OUTPUTS: SUCCESS = Map updated * FAILURE = Map not updated */ suc_code update_netgroup_byxxx(map_ctrl *map) { /* Name of temporary entries DBM file */ char *temp_entries; /* Name of temporary TTL DBM file */ char *temp_ttl; /* Temporary DBM handles */ DBM *temp_entries_db; DBM *temp_ttl_db; map_ctrl temp_map; char *myself = "update_netgroup_byxxx"; char *cmdbuf; int cmd_length; datum key; map_ctrl *netgroupmap; int res; /* Temporary revnetgroup files */ const char *byhost = NETGROUP_BYHOST "_REV" TEMP_POSTFIX; const char *byuser = NETGROUP_BYUSER "_REV" TEMP_POSTFIX; const char *temp_file_name; /* * We need to use two different temporary files: one for netgroup.byhost * and other for netgroup.byuser, since these two maps can be updated * simultaneously. These temporary files will hold the output of * revnetgroup [-h|-u] command. They are then used to generate the * corresponding dbm files and thereafter deleted. */ if (0 == strcmp(map->map_name, NETGROUP_BYHOST)) temp_file_name = byhost; else temp_file_name = byuser; /* Alloc enough cmd buf for revnet cmd */ cmd_length = strlen("/usr/sbin/makedbm -u ") + (strlen(map->map_path) - strlen(map->map_name)) + strlen(NETGROUP_MAP) + strlen(" | /usr/sbin/revnetgroup -h > ") + (strlen(map->map_path) - strlen(map->map_name)) + strlen(temp_file_name) + 1; cmdbuf = am(myself, cmd_length); if (NULL == cmdbuf) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not alloc cmdbuf.", myself); return (FAILURE); } /* * If necessary update (and wait for) netgroups map. This is a lot of * work but if the netgroup map itself is not being accessed it may * contain information that is not up to date with the DIT. * * We use the cmdbuf to store the qualified netgroup map name there will * be enough space for this but we are not yet creating the cmd. */ strlcpy(cmdbuf, map->map_path, strlen(map->map_path) - strlen(map->map_name) + 1); strcat(cmdbuf, NETGROUP_MAP); netgroupmap = (map_ctrl *)shim_dbm_open(cmdbuf, O_RDWR | O_CREAT, 0644); if (NULL == netgroupmap) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not update %s.", myself, cmdbuf); sfree(cmdbuf); return (FAILURE); } if (has_map_expired(netgroupmap)) { lock_map_ctrl(netgroupmap); update_map_if_required(netgroupmap, TRUE); unlock_map_ctrl(netgroupmap); } shim_dbm_close((DBM *)netgroupmap); /* Dump netgroup file through revnetgroup to a temp file */ strcpy(cmdbuf, "/usr/sbin/makedbm -u "); /* Unmake the netgroup file in same domain as map */ strncat(cmdbuf, map->map_path, strlen(map->map_path) - strlen(map->map_name)); strcat(cmdbuf, NETGROUP_MAP); if (0 == strcmp(map->map_name, NETGROUP_BYHOST)) { strcat(cmdbuf, " | /usr/sbin/revnetgroup -h > "); } else { strcat(cmdbuf, " | /usr/sbin/revnetgroup -u > "); } /* Create temp file file in same domain as map */ strncat(cmdbuf, map->map_path, strlen(map->map_path) - strlen(map->map_name)); strcat(cmdbuf, temp_file_name); if (0 > system(cmdbuf)) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not run \"%s\" " "(errno=%d)", myself, cmdbuf, errno); sfree(cmdbuf); return (FAILURE); } sfree(cmdbuf); /* Allocate and set up names */ if (SUCCESS != alloc_temp_names(map->map_path, &temp_entries, &temp_ttl)) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Unable to create map names for %s", myself, map->map_path); return (FAILURE); } /* Make the temporary DBM file */ cmdbuf = am(myself, strlen("/usr/sbin/makedbm") + (strlen(map->map_path) - strlen(map->map_name)) + strlen(temp_file_name) + strlen(temp_entries) + 3); if (NULL == cmdbuf) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not allocate cmdbuf.", myself); sfree(temp_entries); sfree(temp_ttl); return (FAILURE); } strcpy(cmdbuf, "/usr/sbin/makedbm "); strncat(cmdbuf, map->map_path, strlen(map->map_path) - strlen(map->map_name)); strcat(cmdbuf, temp_file_name); strcat(cmdbuf, " "); strcat(cmdbuf, temp_entries); if (0 > system(cmdbuf)) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not run \"%s\" " "(errno=%d)", myself, cmdbuf, errno); sfree(cmdbuf); sfree(temp_entries); sfree(temp_ttl); return (FAILURE); } /* Already have enough command buffer to rm temporary file */ strlcpy(cmdbuf, map->map_path, strlen(map->map_path) - strlen(map->map_name) + 1); strcat(cmdbuf, temp_file_name); res = unlink(cmdbuf); /* If the temp file did not exist no problem. Probably had no entries */ if ((0 != res) && (ENOENT != errno)) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not delete \"%s\" " "(errno=%d)", myself, cmdbuf, errno); sfree(temp_entries); sfree(temp_ttl); sfree(cmdbuf); return (FAILURE); } sfree(cmdbuf); if ((temp_entries_db = dbm_open(temp_entries, O_RDWR | O_CREAT, 0644)) == NULL) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not open %s", myself, temp_entries); sfree(temp_entries); sfree(temp_ttl); return (FAILURE); } if ((temp_ttl_db = dbm_open(temp_ttl, O_RDWR | O_CREAT, 0644)) == NULL) { logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not open %s", myself, temp_ttl); dbm_close(temp_entries_db); sfree(temp_entries); sfree(temp_ttl); return (FAILURE); } /* * Set up enough of map_ctrl to call update_entry_ttl. Since there is * no mapping, and thus not TTL, defined for these maps use the TTL * values for netgroup map */ temp_map.map_name = NETGROUP_MAP; temp_map.domain = map->domain; temp_map.ttl = temp_ttl_db; /* * Generate new TTL file. Since these maps work only on the whole map * expiry these will not actually be used but there presence makes it * easier to handle these maps in the same way as other maps. */ key = dbm_firstkey(temp_entries_db); while (key.dptr != 0) { if (!is_special_key(&key)) /* * For these maps want all timouts to be maximum */ if (FAILURE == update_entry_ttl(&temp_map, &key, TTL_MAX)) logmsg(MSG_NOTIMECHECK, LOG_ERR, "%s: Could not update TTL for " "(key=%s) for map %s,%s", myself, NIL(key.dptr), map->map_name, map->domain); key = dbm_nextkey(temp_entries_db); } /* Update map TTL */ update_map_ttl(&temp_map); /* Close temp DBM files */ dbm_close(temp_entries_db); dbm_close(temp_ttl_db); /* Lock access to the map for copy */ lock_map_ctrl(map); /* Move temp maps to real ones */ rename_map(temp_entries, map->map_path, FALSE); rename_map(temp_ttl, map->ttl_path, FALSE); /* Free file names */ sfree(temp_entries); sfree(temp_ttl); /* Unlock map */ unlock_map_ctrl(map); return (SUCCESS); }