#include <unistd.h>
#include <stdlib.h>
#include <syslog.h>
#include <ndbm.h>
#include <string.h>
#include <sys/param.h>
#include "ypsym.h"
#include "ypdefs.h"
#include "shim.h"
#include "yptol.h"
#include "../ldap_util.h"
extern int hash(char *s);
extern bool_t add_map_domain_to_list(char *domain, char ***map_list);
static map_id_elt_t *map_id_list[MAXHASH];
static int max_map = 0;
USE_DBM
USE_YPDBPATH
map_ctrl *
create_map_ctrl(char *name)
{
char *myself = "create_map_ctrl";
map_ctrl *map;
map = (map_ctrl *)am(myself, sizeof (map_ctrl));
if (NULL == map) {
logmsg(MSG_NOTIMECHECK, LOG_ERR, "Could not alloc map_ctrl");
return (NULL);
}
map->entries = NULL;
map->hash_val = 0;
map->map_name = NULL;
map->domain = NULL;
map->map_path = NULL;
map->ttl = NULL;
map->ttl_path = NULL;
map->trad_map_path = NULL;
map->key_data.dptr = NULL;
map->open_mode = 0;
map->open_flags = 0;
if (SUCCESS != map_ctrl_init(map, name)) {
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"Could not initialize map_ctrl for %s", name);
free_map_ctrl(map);
return (NULL);
}
return (map);
}
suc_code
map_ctrl_init(map_ctrl *map, char *name)
{
char *myself = "map_ctrl_init";
char *p, *q;
map->map_path = (char *)strdup(name);
if (NULL == map->map_path) {
logmsg(MSG_NOMEM, LOG_ERR,
"Could not duplicate map path %s", map);
return (FAILURE);
}
p = strrchr(name, SEP_CHAR);
if (NULL == p) {
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"Could not find separator in map path %s", map);
return (FAILURE);
}
q = p + 1;
if (yptol_mode) {
if (0 == strncmp(q, NTOL_PREFIX, strlen(NTOL_PREFIX)))
q += strlen(NTOL_PREFIX);
} else {
if (0 == strncmp(q, NTOL_PREFIX, strlen(NTOL_PREFIX)))
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"Working in non N2L mode and path %s "
"contains N2L prefix", name);
}
map->map_name = strdup(q);
if (NULL == map->map_name) {
logmsg(MSG_NOMEM, LOG_ERR,
"Could not duplicate map name %s", q);
return (FAILURE);
}
for (q = p-1; (SEP_CHAR != *q) && (q > name); q--);
if (q <= name) {
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"Could not find domain in map path %s", name);
return (FAILURE);
}
map->domain = (char *)am(myself, p - q);
if (NULL == map->domain) {
logmsg(MSG_NOMEM, LOG_ERR,
"Could not alloc memory for domain in path %s", name);
return (FAILURE);
}
(void) strncpy(map->domain, q + 1, p-q-1);
map->domain[p-q-1] = '\0';
if (yptol_mode) {
map->trad_map_path = (char *)am(myself, strlen(map->map_name) +
+ strlen(dbm_pag) + (p - name) + 2);
if (NULL == map->trad_map_path) {
logmsg(MSG_NOMEM, LOG_ERR,
"Could not alocate memory for "
"traditional map path derived from %s", name);
return (FAILURE);
}
strncpy(map->trad_map_path, name, p - name + 1);
map->trad_map_path[p - name + 1] = '\0';
strcat(map->trad_map_path, map->map_name);
strcat(map->trad_map_path, dbm_pag);
map->ttl_path = (char *)am(myself, strlen(map->map_path) +
strlen(TTL_POSTFIX) + 1);
if (NULL == map->ttl_path) {
logmsg(MSG_NOMEM, LOG_ERR,
"Could not alocate memory for "
"ttl path derived from %s", name);
return (FAILURE);
}
strcpy(map->ttl_path, map->map_path);
strcat(map->ttl_path, TTL_POSTFIX);
}
map->hash_val = hash(name);
map->magic = MAP_MAGIC;
map->entries = NULL;
map->ttl = NULL;
map->key_data.dptr = NULL;
map->key_data.dsize = 0;
return (SUCCESS);
}
map_ctrl *
get_map_ctrl(DBM *db)
{
if (((map_ctrl *)db)->magic != MAP_MAGIC) {
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"SHIM called with DBM ptr not map_crtl ptr");
return (NULL);
}
return ((map_ctrl *)db);
}
map_ctrl *
dup_map_ctrl(map_ctrl *old_map)
{
map_ctrl *new_map;
new_map = create_map_ctrl(old_map->map_path);
if (NULL == new_map)
return (NULL);
if (NULL != old_map->entries) {
new_map->open_flags = old_map->open_flags;
new_map->open_mode = old_map->open_mode;
if (FAILURE == open_yptol_files(new_map)) {
free_map_ctrl(new_map);
return (NULL);
}
}
return (new_map);
}
void
free_map_ctrl(map_ctrl *map)
{
if (NULL != map->entries) {
dbm_close(map->entries);
map->entries = NULL;
}
if (NULL != map->map_name) {
sfree(map->map_name);
map->map_name = NULL;
}
if (NULL != map->map_path) {
sfree(map->map_path);
map->map_path = NULL;
}
if (NULL != map->domain) {
sfree(map->domain);
map->domain = NULL;
}
if (yptol_mode) {
if (NULL != map->ttl) {
dbm_close(map->ttl);
map->ttl = NULL;
}
if (NULL != map->trad_map_path) {
sfree(map->trad_map_path);
map->trad_map_path = NULL;
}
if (NULL != map->ttl_path) {
sfree(map->ttl_path);
map->ttl_path = NULL;
}
if (NULL != map->key_data.dptr) {
sfree(map->key_data.dptr);
map->key_data.dptr = NULL;
map->key_data.dsize = 0;
}
}
map->magic = 0;
sfree(map);
}
char *
get_map_name(DBM *db)
{
map_ctrl *map = (map_ctrl *)db;
if (NULL == map)
return (NULL);
return (map->map_name);
}
void
set_key_data(map_ctrl *map, datum *data)
{
char *myself = "set_key_data";
if (NULL != map->key_data.dptr) {
sfree(map->key_data.dptr);
map->key_data.dptr = NULL;
map->key_data.dsize = 0;
}
if (NULL == data->dptr)
return;
map->key_data.dptr = (char *)am(myself, data->dsize);
if (NULL == map->key_data.dptr) {
logmsg(MSG_NOMEM, LOG_ERR, "Cannot alloc memory for key data");
} else {
memcpy(map->key_data.dptr, data->dptr, data->dsize);
map->key_data.dsize = data->dsize;
}
data->dptr = map->key_data.dptr;
return;
}
suc_code
open_yptol_files(map_ctrl *map)
{
map->entries = dbm_open(map->map_path, map->open_flags, map->open_mode);
if (NULL == map->entries) {
return (FAILURE);
}
if (yptol_mode) {
map->ttl = dbm_open(map->ttl_path, O_RDWR | O_CREAT, 0644);
if (NULL == map->ttl) {
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"Cannot open TTL file %s", map->ttl_path);
dbm_close(map->entries);
map->entries = NULL;
return (FAILURE);
}
}
return (SUCCESS);
}
suc_code
insert_map_in_list(char *map_name, int unique_value)
{
int index;
bool_t yptol_nl_sav = yptol_newlock;
map_id_elt_t *new_elt;
yptol_newlock = FALSE;
index = hash(map_name);
yptol_newlock = yptol_nl_sav;
new_elt = (map_id_elt_t *)calloc(1, sizeof (map_id_elt_t));
if (new_elt == NULL) {
return (FAILURE);
}
new_elt->map_name = strdup(map_name);
if (new_elt->map_name == NULL) {
sfree(new_elt);
return (FAILURE);
}
new_elt->map_id = unique_value;
if (map_id_list[index] == NULL) {
new_elt->next = NULL;
} else {
new_elt->next = map_id_list[index];
}
map_id_list[index] = new_elt;
return (SUCCESS);
}
#ifdef NISDB_LDAP_DEBUG
void
dump_map_id_list()
{
int i;
map_id_elt_t *cur_elt;
logmsg(MSG_NOTIMECHECK, LOG_DEBUG,
"dump_map_id_list: max_map is: %d, dumping map_idlist ...",
max_map);
for (i = 0; i < MAXHASH; i++) {
if (map_id_list[i] == NULL) {
logmsg(MSG_NOTIMECHECK, LOG_DEBUG,
"no map for index %d", i);
} else {
logmsg(MSG_NOTIMECHECK, LOG_DEBUG,
"index %d has the following maps", i);
cur_elt = map_id_list[i];
do {
logmsg(MSG_NOTIMECHECK, LOG_DEBUG,
"%s, unique id: %d",
cur_elt->map_name,
cur_elt->map_id);
cur_elt = cur_elt->next;
} while (cur_elt != NULL);
}
}
}
#endif
void
free_map_id_list()
{
int i;
map_id_elt_t *cur_elt, *next_elt;
for (i = 0; i < MAXHASH; i++) {
if (map_id_list[i] != NULL) {
cur_elt = map_id_list[i];
do {
next_elt = cur_elt->next;
if (cur_elt->map_name)
sfree(cur_elt->map_name);
sfree(cur_elt);
cur_elt = next_elt;
} while (cur_elt != NULL);
map_id_list[i] = NULL;
}
}
max_map = 0;
}
int
map_id_list_init()
{
char **domain_list, **map_list = NULL;
int domain_num;
int i, j;
char *myself = "map_id_list_init";
char mapbuf[MAXPATHLEN];
int mapbuf_len = sizeof (mapbuf);
int map_name_len;
int seqnum = 0;
int rc = 0;
for (i = 0; i < MAXHASH; i++) {
map_id_list[i] = NULL;
}
domain_num = get_mapping_domain_list(&domain_list);
for (i = 0; i < domain_num; i++) {
if (map_list) {
free_map_list(map_list);
map_list = NULL;
}
map_list = get_mapping_map_list(domain_list[i]);
if (map_list == NULL) {
logmsg(MSG_NOTIMECHECK, LOG_DEBUG,
"%s: get_mapping_map_list()"
" found no map for domain %s",
myself, domain_list[i]);
}
if (add_map_domain_to_list(domain_list[i], &map_list) ==
FALSE) {
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"%s: add_map_domain_to_list() failed", myself);
free_map_id_list();
if (map_list) free_map_list(map_list);
return (-1);
}
if (map_list == NULL || map_list[0] == NULL) {
logmsg(MSG_NOTIMECHECK, LOG_DEBUG,
"%s: no map in domain %s",
myself, domain_list[i]);
continue;
}
for (j = 0; map_list[j] != NULL; j++) {
map_name_len = ypdbpath_sz + 1 +
strlen(domain_list[i]) + 1 +
strlen(NTOL_PREFIX) +
strlen(map_list[j]) + 1;
if (map_name_len > mapbuf_len) {
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"%s: map name too long for %s",
" in domain %s", myself, map_list[j],
domain_list[i]);
free_map_id_list();
if (map_list) free_map_list(map_list);
return (-1);
}
(void) memset(mapbuf, 0, mapbuf_len);
(void) snprintf(mapbuf, map_name_len, "%s%c%s%c%s%s",
ypdbpath, SEP_CHAR, domain_list[i], SEP_CHAR,
NTOL_PREFIX, map_list[j]);
if (insert_map_in_list(mapbuf, seqnum)
== FAILURE) {
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"%s: failed to insert map %s",
" in domain %s", myself, map_list[j]);
free_map_id_list();
if (map_list) free_map_list(map_list);
return (-1);
}
seqnum++;
}
}
max_map = seqnum;
#ifdef NISDB_LDAP_DEBUG
dump_map_id_list();
#endif
if (max_map > MAXHASH) {
rc = -1;
logmsg(MSG_NOTIMECHECK, LOG_ERR,
"%s: too many maps (%d)",
myself, max_map);
free_map_id_list();
}
if (map_list) free_map_list(map_list);
return (rc);
}
void
get_list_max(map_id_elt_t ***list, int *max)
{
*list = map_id_list;
*max = max_map;
}