summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorbaban <none@none>2007-07-12 11:41:36 -0700
committerbaban <none@none>2007-07-12 11:41:36 -0700
commit651c0131ccc65381cbda174bee44a4fd7a518d6b (patch)
treee5612dfc36d4b61454a9c258599a558b22ac92e0 /usr/src
parent85025c032d701094e5f35de4f42ce66082924fc1 (diff)
downloadillumos-joyent-651c0131ccc65381cbda174bee44a4fd7a518d6b.tar.gz
6570027 memory leak in idmapd for idmap show -c winname:... code path
6573151 libidmap API should be more specific about RPC failures 6573159 idmap_config.c should use idmapdlog() to log messages instead of its own routines 6573415 Segmentation Fault in "idmap show unixname:unknownuser winname" 6573634 idmapd fails to start the reaper thread to close idle AD connections 6573752 idmapd still has syslog messages that should not be localized 6574136 libidmap should clear its handles after use for possible reuse 6575859 idmap add -u/g winname:...@* ... should be treated as an error -- @* rules must be directional 6576387 libidmap should provide macro for mapping direction
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/idmap/idmapd/adutils.c2
-rw-r--r--usr/src/cmd/idmap/idmapd/dbutils.c142
-rw-r--r--usr/src/cmd/idmap/idmapd/idmap_config.c109
-rw-r--r--usr/src/cmd/idmap/idmapd/idmap_config.h1
-rw-r--r--usr/src/cmd/idmap/idmapd/idmapd.c3
-rw-r--r--usr/src/cmd/idmap/idmapd/init.c6
-rw-r--r--usr/src/cmd/idmap/idmapd/server.c24
-rw-r--r--usr/src/lib/libidmap/common/idmap_api.c112
-rw-r--r--usr/src/lib/libidmap/common/idmap_impl.h16
-rw-r--r--usr/src/lib/libidmap/common/idmap_priv.h6
-rw-r--r--usr/src/lib/libidmap/common/utils.c32
11 files changed, 231 insertions, 222 deletions
diff --git a/usr/src/cmd/idmap/idmapd/adutils.c b/usr/src/cmd/idmap/idmapd/adutils.c
index 544eba857a..5f550a4f7c 100644
--- a/usr/src/cmd/idmap/idmapd/adutils.c
+++ b/usr/src/cmd/idmap/idmapd/adutils.c
@@ -159,7 +159,7 @@ static pthread_mutex_t qstatelock = PTHREAD_MUTEX_INITIALIZER;
* List of DSs, needed by the idle connection reaper thread
*/
static ad_host_t *host_head = NULL;
-static pthread_t reaperid = (pthread_t)-1;
+static pthread_t reaperid = 0;
static pthread_mutex_t adhostlock = PTHREAD_MUTEX_INITIALIZER;
/*ARGSUSED*/
diff --git a/usr/src/cmd/idmap/idmapd/dbutils.c b/usr/src/cmd/idmap/idmapd/dbutils.c
index 05786f4e35..446462109c 100644
--- a/usr/src/cmd/idmap/idmapd/dbutils.c
+++ b/usr/src/cmd/idmap/idmapd/dbutils.c
@@ -481,7 +481,8 @@ get_namerule_order(char *winname, char *windomain, char *unixname,
* Note that "" has priority over specific names because "" inhibits
* mappings and traditionally deny rules always had higher priority.
*/
- if (direction == 0 || direction == 1) {
+ if (direction != IDMAP_DIRECTION_U2W) {
+ /* bi-directional or from windows to unix */
if (winname == NULL)
return (IDMAP_ERR_W2U_NAMERULE);
else if (unixname == NULL)
@@ -528,11 +529,14 @@ get_namerule_order(char *winname, char *windomain, char *unixname,
* 4. * to ""
* 5. * to winname@domain (or winname)
*/
- if (direction == 0 || direction == 2) {
+ if (direction != IDMAP_DIRECTION_W2U) {
+ /* bi-directional or from unix to windows */
if (unixname == NULL || EMPTY_NAME(unixname))
return (IDMAP_ERR_U2W_NAMERULE);
else if (winname == NULL)
return (IDMAP_ERR_U2W_NAMERULE);
+ else if (windomain && *windomain == '*')
+ return (IDMAP_ERR_U2W_NAMERULE);
else if (*unixname == '*') {
if (*winname == '*')
*u2w_order = 3;
@@ -669,13 +673,13 @@ rm_namerule(sqlite *db, idmap_namerule *rule) {
if (rule->direction < 0) {
buf[0] = 0;
- } else if (rule->direction == 0) {
+ } else if (rule->direction == IDMAP_DIRECTION_BI) {
(void) snprintf(buf, sizeof (buf), "AND w2u_order > 0"
" AND u2w_order > 0");
- } else if (rule->direction == 1) {
+ } else if (rule->direction == IDMAP_DIRECTION_W2U) {
(void) snprintf(buf, sizeof (buf), "AND w2u_order > 0"
" AND (u2w_order = 0 OR u2w_order ISNULL)");
- } else if (rule->direction == 2) {
+ } else if (rule->direction == IDMAP_DIRECTION_U2W) {
(void) snprintf(buf, sizeof (buf), "AND u2w_order > 0"
" AND (w2u_order = 0 OR w2u_order ISNULL)");
}
@@ -810,10 +814,9 @@ lookup_wksids_sid2pid(idmap_mapping *req, idmap_id_res *res) {
int i;
for (i = 0; wksidstable[i].sidprefix; i++) {
if ((strcasecmp(wksidstable[i].sidprefix,
- req->id1.idmap_id_u.sid.prefix) == 0) &&
- req->id1.idmap_id_u.sid.rid ==
- wksidstable[i].rid &&
- wksidstable[i].direction != 2) {
+ req->id1.idmap_id_u.sid.prefix) == 0) &&
+ req->id1.idmap_id_u.sid.rid == wksidstable[i].rid &&
+ wksidstable[i].direction != IDMAP_DIRECTION_U2W) {
switch (req->id2.idtype) {
case IDMAP_UID:
if (wksidstable[i].is_user == 0)
@@ -846,9 +849,9 @@ lookup_wksids_pid2sid(idmap_mapping *req, idmap_id_res *res, int is_user) {
int i;
for (i = 0; wksidstable[i].sidprefix; i++) {
if (req->id1.idmap_id_u.uid == wksidstable[i].pid &&
- wksidstable[i].direction != 1 &&
- (wksidstable[i].is_user < 0 ||
- is_user == wksidstable[i].is_user)) {
+ wksidstable[i].direction != IDMAP_DIRECTION_W2U &&
+ (wksidstable[i].is_user < 0 ||
+ is_user == wksidstable[i].is_user)) {
switch (req->id2.idtype) {
case IDMAP_SID:
res->id.idmap_id_u.sid.rid =
@@ -939,7 +942,7 @@ lookup_cache_sid2pid(sqlite *cache, idmap_mapping *req, idmap_id_res *res) {
res->id.idmap_id_u.uid = pid;
res->id.idtype = is_user?
IDMAP_UID:IDMAP_GID;
- res->direction = 0;
+ res->direction = IDMAP_DIRECTION_BI;
req->direction |= is_user?
_IDMAP_F_EXP_EPH_UID:
_IDMAP_F_EXP_EPH_GID;
@@ -976,9 +979,10 @@ out:
if (retcode == IDMAP_SUCCESS) {
if (values[4])
res->direction =
- (strtol(values[4], &end, 10) == 0)?1:0;
+ (strtol(values[4], &end, 10) == 0)?
+ IDMAP_DIRECTION_W2U:IDMAP_DIRECTION_BI;
else
- res->direction = 1;
+ res->direction = IDMAP_DIRECTION_W2U;
if (values[3]) {
str = &req->id2name;
@@ -1306,7 +1310,7 @@ generate_localsid(idmap_mapping *req, idmap_id_res *res, int is_user) {
res->id.idmap_id_u.sid.rid =
(is_user)?req->id1.idmap_id_u.uid + LOCALRID_MIN:
req->id1.idmap_id_u.gid + INT32_MAX + 1;
- res->direction = 0;
+ res->direction = IDMAP_DIRECTION_BI;
/*
* Don't update name_cache because local sids don't have
@@ -1558,9 +1562,10 @@ out:
if (retcode == IDMAP_SUCCESS) {
if (values[1])
res->direction =
- (strtol(values[1], &end, 10) == 0)?1:0;
+ (strtol(values[1], &end, 10) == 0)?
+ IDMAP_DIRECTION_W2U:IDMAP_DIRECTION_BI;
else
- res->direction = 1;
+ res->direction = IDMAP_DIRECTION_W2U;
str = &req->id2name;
retcode = idmap_str2utf8(&str, unixname, 0);
}
@@ -1623,19 +1628,19 @@ dynamic_ephemeral_mapping(sqlite *cache, idmap_mapping *req,
uid_t next_pid;
if (IS_EPHEMERAL(res->id.idmap_id_u.uid)) {
- res->direction = 0;
+ res->direction = IDMAP_DIRECTION_BI;
} else if (res->id.idtype == IDMAP_UID) {
if (get_next_eph_uid(&next_pid) != 0)
return (IDMAP_ERR_INTERNAL);
res->id.idmap_id_u.uid = next_pid;
res->id.idtype = IDMAP_UID;
- res->direction = 0;
+ res->direction = IDMAP_DIRECTION_BI;
} else {
if (get_next_eph_gid(&next_pid) != 0)
return (IDMAP_ERR_INTERNAL);
res->id.idmap_id_u.gid = next_pid;
res->id.idtype = IDMAP_GID;
- res->direction = 0;
+ res->direction = IDMAP_DIRECTION_BI;
}
return (IDMAP_SUCCESS);
@@ -1950,9 +1955,10 @@ lookup_cache_pid2sid(sqlite *cache, idmap_mapping *req, idmap_id_res *res,
if (values[4])
res->direction =
- (strtol(values[4], &end, 10) == 0)?2:0;
+ (strtol(values[4], &end, 10) == 0)?
+ IDMAP_DIRECTION_U2W:IDMAP_DIRECTION_BI;
else
- res->direction = 2;
+ res->direction = IDMAP_DIRECTION_U2W;
if (getname == 0 || values[2] == NULL)
break;
@@ -2259,9 +2265,10 @@ out:
if (retcode == IDMAP_SUCCESS) {
if (values[2])
res->direction =
- (strtol(values[2], &end, 10) == 0)?2:0;
+ (strtol(values[2], &end, 10) == 0)?
+ IDMAP_DIRECTION_U2W:IDMAP_DIRECTION_BI;
else
- res->direction = 2;
+ res->direction = IDMAP_DIRECTION_U2W;
str = &req->id2name;
retcode = idmap_str2utf8(&str, winname, 0);
if (retcode == IDMAP_SUCCESS) {
@@ -2419,69 +2426,70 @@ out:
return (retcode);
}
-static void
-copy_id_mapping(idmap_mapping *mapping, idmap_mapping *request)
+static int
+copy_mapping_request(idmap_mapping *mapping, idmap_mapping *request)
{
+ (void) memset(mapping, 0, sizeof (*mapping));
+
mapping->flag = request->flag;
mapping->direction = request->direction;
+ mapping->id2.idtype = request->id2.idtype;
mapping->id1.idtype = request->id1.idtype;
if (request->id1.idtype == IDMAP_SID) {
mapping->id1.idmap_id_u.sid.rid =
request->id1.idmap_id_u.sid.rid;
- if (request->id1.idmap_id_u.sid.prefix)
+ if (!EMPTY_STRING(request->id1.idmap_id_u.sid.prefix)) {
mapping->id1.idmap_id_u.sid.prefix =
strdup(request->id1.idmap_id_u.sid.prefix);
- else
- mapping->id1.idmap_id_u.sid.prefix = NULL;
+ if (mapping->id1.idmap_id_u.sid.prefix == NULL)
+ return (-1);
+ }
} else {
mapping->id1.idmap_id_u.uid = request->id1.idmap_id_u.uid;
}
mapping->id1domain.idmap_utf8str_len =
request->id1domain.idmap_utf8str_len;
- if (mapping->id1domain.idmap_utf8str_len)
+ if (mapping->id1domain.idmap_utf8str_len) {
mapping->id1domain.idmap_utf8str_val =
strdup(request->id1domain.idmap_utf8str_val);
- else
- mapping->id1domain.idmap_utf8str_val = NULL;
+ if (mapping->id1domain.idmap_utf8str_val == NULL)
+ return (-1);
+ }
mapping->id1name.idmap_utf8str_len =
request->id1name.idmap_utf8str_len;
- if (mapping->id1name.idmap_utf8str_len)
+ if (mapping->id1name.idmap_utf8str_len) {
mapping->id1name.idmap_utf8str_val =
strdup(request->id1name.idmap_utf8str_val);
- else
- mapping->id1name.idmap_utf8str_val = NULL;
+ if (mapping->id1name.idmap_utf8str_val == NULL)
+ return (-1);
+ }
- mapping->id2.idtype = request->id2.idtype;
- if (request->id2.idtype == IDMAP_SID) {
- mapping->id2.idmap_id_u.sid.rid =
- request->id2.idmap_id_u.sid.rid;
- if (request->id2.idmap_id_u.sid.prefix)
- mapping->id2.idmap_id_u.sid.prefix =
- strdup(request->id2.idmap_id_u.sid.prefix);
- else
- mapping->id2.idmap_id_u.sid.prefix = NULL;
- } else {
- mapping->id2.idmap_id_u.uid = request->id2.idmap_id_u.uid;
+ /* We don't need the rest of the request i.e request->id2 */
+ return (0);
+
+errout:
+ if (mapping->id1.idmap_id_u.sid.prefix) {
+ free(mapping->id1.idmap_id_u.sid.prefix);
+ mapping->id1.idmap_id_u.sid.prefix = NULL;
}
- mapping->id2domain.idmap_utf8str_len =
- request->id2domain.idmap_utf8str_len;
- if (mapping->id2domain.idmap_utf8str_len)
- mapping->id2domain.idmap_utf8str_val =
- strdup(request->id2domain.idmap_utf8str_val);
- else
- mapping->id2domain.idmap_utf8str_val = NULL;
+ if (mapping->id1domain.idmap_utf8str_val) {
+ free(mapping->id1domain.idmap_utf8str_val);
+ mapping->id1domain.idmap_utf8str_val = NULL;
+ mapping->id1domain.idmap_utf8str_len = 0;
+ }
- mapping->id2name.idmap_utf8str_len =
- request->id2name.idmap_utf8str_len;
- if (mapping->id2name.idmap_utf8str_len)
- mapping->id2name.idmap_utf8str_val =
- strdup(request->id2name.idmap_utf8str_val);
- else
- mapping->id2name.idmap_utf8str_val = NULL;
+ if (mapping->id1name.idmap_utf8str_val) {
+ free(mapping->id1name.idmap_utf8str_val);
+ mapping->id1name.idmap_utf8str_val = NULL;
+ mapping->id1name.idmap_utf8str_len = 0;
+ }
+
+ (void) memset(mapping, 0, sizeof (*mapping));
+ return (-1);
}
@@ -2510,7 +2518,10 @@ get_w2u_mapping(sqlite *cache, sqlite *db, idmap_mapping *request,
}
/* Copy data from request to result */
- copy_id_mapping(mapping, request);
+ if (copy_mapping_request(mapping, request) < 0) {
+ retcode = IDMAP_ERR_MEMORY;
+ goto out;
+ }
winname = mapping->id1name.idmap_utf8str_val;
windomain = mapping->id1domain.idmap_utf8str_val;
@@ -2537,7 +2548,7 @@ get_w2u_mapping(sqlite *cache, sqlite *db, idmap_mapping *request,
windomain = mapping->id1domain.idmap_utf8str_val;
}
- if (winname && EMPTY_STRING(mapping->id1.idmap_id_u.sid.prefix)) {
+ if (winname && mapping->id1.idmap_id_u.sid.prefix == NULL) {
retcode = lookup_name2sid(cache, winname, windomain,
&is_user, &mapping->id1.idmap_id_u.sid.prefix,
&mapping->id1.idmap_id_u.sid.rid, mapping);
@@ -2605,7 +2616,10 @@ get_u2w_mapping(sqlite *cache, sqlite *db, idmap_mapping *request,
(void) memset(&state, 0, sizeof (state));
/* Copy data from request to result */
- copy_id_mapping(mapping, request);
+ if (copy_mapping_request(mapping, request) < 0) {
+ retcode = IDMAP_ERR_MEMORY;
+ goto out;
+ }
unixname = mapping->id1name.idmap_utf8str_val;
diff --git a/usr/src/cmd/idmap/idmapd/idmap_config.c b/usr/src/cmd/idmap/idmapd/idmap_config.c
index f6a951971f..74f5a0d9ba 100644
--- a/usr/src/cmd/idmap/idmapd/idmap_config.c
+++ b/usr/src/cmd/idmap/idmapd/idmap_config.c
@@ -38,7 +38,7 @@
#include <libintl.h>
#include <ctype.h>
#include <errno.h>
-#include "idmap_config.h"
+#include "idmapd.h"
#include <stdio.h>
#include <stdarg.h>
@@ -47,65 +47,10 @@
#define CONFIG_PG "config"
#define GENERAL_PG "general"
-#define IDMAP_CFG_DEBUG 0
-
/* initial length of the array for policy options/attributes: */
#define DEF_ARRAY_LENGTH 16
-static char errmess_buf [1000] =
- "Internal error: idmap configuration has not been initialized";
-
-static void
-errmess(char *format, va_list ap)
-{
-/*LINTED: E_SEC_PRINTF_VAR_FMT*/
- (void) vsnprintf(errmess_buf, sizeof (errmess_buf), format, ap);
- (void) strlcat(errmess_buf, "\n", sizeof (errmess_buf));
-
-#if IDMAP_CFG_DEBUG
- (void) fprintf(stderr, errmess_buf);
- fflush(stderr);
-#endif
-}
-
-
-static void
-idmap_error(char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- errmess(format, ap);
- va_end(ap);
-}
-
-static void
-idmap_scf_error(char *format, ...)
-{
- const char *scf_message;
- char *new_format;
- char *sep = ": ";
- va_list ap;
-
- va_start(ap, format);
-
- scf_message = scf_strerror(scf_error());
- new_format = (char *) malloc(sizeof (char) *
- (strlen(format) + strlen(scf_message) + strlen(sep) + 1));
-
- (void) strcpy(new_format, format);
- (void) strcat(new_format, sep);
- (void) strcat(new_format, scf_message);
-
- errmess(new_format, ap);
-
- va_end(ap);
- free(new_format);
-}
-
-char *
-idmap_cfg_error() {
- return (errmess_buf);
-}
+static const char *me = "idmapd";
/* Check if in the case of failure the original value of *val is preserved */
static int
@@ -137,8 +82,8 @@ get_val_int(idmap_cfg_t *cfg, char *name, void *val, scf_type_t type)
rc = scf_value_get_integer(value, val);
break;
default:
- idmap_scf_error(gettext("Internal error: invalid int type %d"),
- type);
+ idmapdlog(LOG_ERR, "%s: Invalid scf integer type (%d)",
+ me, type);
rc = -1;
break;
}
@@ -170,8 +115,7 @@ scf_value2string(scf_value_t *value) {
buf_size *= 2;
buf = (char *)realloc(buf, buf_size * sizeof (char));
if (!buf) {
- idmap_scf_error(
- gettext("Not enough memory"));
+ idmapdlog(LOG_ERR, "%s: Out of memory", me);
rc = -1;
goto destruction;
}
@@ -206,15 +150,18 @@ get_val_astring(idmap_cfg_t *cfg, char *name, char **val)
goto destruction;
if (0 > scf_property_get_value(scf_prop, value)) {
- idmap_scf_error(gettext("Cannot get the astring %s"), name);
+ idmapdlog(LOG_ERR,
+ "%s: scf_property_get_value(%s) failed: %s",
+ me, name, scf_strerror(scf_error()));
rc = -1;
goto destruction;
}
if (!(*val = scf_value2string(value))) {
rc = -1;
- idmap_scf_error(gettext("Cannot retrieve the astring %s"),
- name);
+ idmapdlog(LOG_ERR,
+ "%s: scf_value2string(%s) failed: %s",
+ me, name, scf_strerror(scf_error()));
}
destruction:
@@ -242,12 +189,14 @@ idmap_cfg_load(idmap_cfg_t *cfg)
cfg->pgcfg.global_catalog = NULL;
if (0 > scf_pg_update(cfg->handles.config_pg)) {
- idmap_scf_error(gettext("Error updating config pg"));
+ idmapdlog(LOG_ERR, "%s: scf_pg_update() failed: %s",
+ me, scf_strerror(scf_error()));
return (-1);
}
if (0 > scf_pg_update(cfg->handles.general_pg)) {
- idmap_scf_error(gettext("Error updating general pg"));
+ idmapdlog(LOG_ERR, "%s: scf_pg_update() failed: %s",
+ me, scf_strerror(scf_error()));
return (-1);
}
@@ -262,7 +211,6 @@ idmap_cfg_load(idmap_cfg_t *cfg)
return (-1);
/*
- * TBD:
* If there is no mapping_domain in idmap's smf config then
* set it to the joined domain.
* Till domain join is implemented, temporarily set it to
@@ -278,8 +226,8 @@ idmap_cfg_load(idmap_cfg_t *cfg)
cfg->pgcfg.mapping_domain, dname_size);
}
if (dname_size <= 0) {
- idmap_scf_error(
- gettext("Error obtaining the default domain"));
+ idmapdlog(LOG_ERR,
+ "%s: unable to get name service domain", me);
if (cfg->pgcfg.mapping_domain)
free(cfg->pgcfg.mapping_domain);
cfg->pgcfg.mapping_domain = NULL;
@@ -302,26 +250,28 @@ idmap_cfg_load(idmap_cfg_t *cfg)
return (rc);
}
+/*
+ * Initialize 'cfg'.
+ */
idmap_cfg_t *
idmap_cfg_init() {
- /*
- * The following initializes 'cfg'.
- */
/* First the smf repository handles: */
idmap_cfg_t *cfg = calloc(1, sizeof (idmap_cfg_t));
if (!cfg) {
- idmap_error(gettext("Not enough memory"));
+ idmapdlog(LOG_ERR, "%s: Out of memory", me);
return (NULL);
}
if (!(cfg->handles.main = scf_handle_create(SCF_VERSION))) {
- idmap_scf_error(gettext("SCF handle not created"));
+ idmapdlog(LOG_ERR, "%s: scf_handle_create() failed: %s",
+ me, scf_strerror(scf_error()));
goto error;
}
if (0 > scf_handle_bind(cfg->handles.main)) {
- idmap_scf_error(gettext("SCF connection failed"));
+ idmapdlog(LOG_ERR, "%s: scf_handle_bind() failed: %s",
+ me, scf_strerror(scf_error()));
goto error;
}
@@ -329,7 +279,8 @@ idmap_cfg_init() {
!(cfg->handles.instance = scf_instance_create(cfg->handles.main)) ||
!(cfg->handles.config_pg = scf_pg_create(cfg->handles.main)) ||
!(cfg->handles.general_pg = scf_pg_create(cfg->handles.main))) {
- idmap_scf_error(gettext("SCF handle creation failed"));
+ idmapdlog(LOG_ERR, "%s: scf handle creation failed: %s",
+ me, scf_strerror(scf_error()));
goto error;
}
@@ -341,14 +292,16 @@ idmap_cfg_init() {
cfg->handles.config_pg, /* pg */
NULL, /* prop */
SCF_DECODE_FMRI_EXACT)) {
- idmap_scf_error(gettext("SCF fmri decoding failed"));
+ idmapdlog(LOG_ERR, "%s: scf_handle_decode_fmri() failed: %s",
+ me, scf_strerror(scf_error()));
goto error;
}
if (0 > scf_service_get_pg(cfg->handles.service,
GENERAL_PG, cfg->handles.general_pg)) {
- idmap_scf_error(gettext("SCF general pg not obtained"));
+ idmapdlog(LOG_ERR, "%s: scf_service_get_pg() failed: %s",
+ me, scf_strerror(scf_error()));
goto error;
}
diff --git a/usr/src/cmd/idmap/idmapd/idmap_config.h b/usr/src/cmd/idmap/idmapd/idmap_config.h
index 77bf513001..c454175e84 100644
--- a/usr/src/cmd/idmap/idmapd/idmap_config.h
+++ b/usr/src/cmd/idmap/idmapd/idmap_config.h
@@ -63,7 +63,6 @@ typedef struct idmap_cfg {
extern idmap_cfg_t *idmap_cfg_init();
extern int idmap_cfg_fini(idmap_cfg_t *);
extern int idmap_cfg_load(idmap_cfg_t *);
-extern char *idmap_cfg_error();
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/idmap/idmapd/idmapd.c b/usr/src/cmd/idmap/idmapd/idmapd.c
index 3f17c060e8..e71afc4dbd 100644
--- a/usr/src/cmd/idmap/idmapd/idmapd.c
+++ b/usr/src/cmd/idmap/idmapd/idmapd.c
@@ -249,8 +249,7 @@ main(int argc, char **argv)
DAEMON_UID, DAEMON_GID,
PRIV_PROC_AUDIT, PRIV_FILE_DAC_READ,
(char *)NULL) == -1) {
- (void) idmapdlog(LOG_ERR,
- gettext("idmapd: unable to drop privileges"));
+ (void) idmapdlog(LOG_ERR, "idmapd: unable to drop privileges");
exit(1);
}
diff --git a/usr/src/cmd/idmap/idmapd/init.c b/usr/src/cmd/idmap/idmapd/init.c
index f07256058c..bd78c65dc6 100644
--- a/usr/src/cmd/idmap/idmapd/init.c
+++ b/usr/src/cmd/idmap/idmapd/init.c
@@ -62,15 +62,13 @@ fini_mapping_system() {
int
load_config() {
if ((_idmapdstate.cfg = idmap_cfg_init()) == NULL) {
- idmapdlog(LOG_ERR, "%s: config init failed - %s",
- me, CHECK_NULL(idmap_cfg_error()));
+ idmapdlog(LOG_ERR, "%s: failed to initialize config", me);
return (-1);
}
if (_idmapdstate.ad != NULL)
idmap_ad_free(&_idmapdstate.ad);
if (idmap_cfg_load(_idmapdstate.cfg) < 0) {
- idmapdlog(LOG_ERR, "%s: config load failed - %s",
- me, CHECK_NULL(idmap_cfg_error()));
+ idmapdlog(LOG_ERR, "%s: failed to load config", me);
return (-1);
}
if (_idmapdstate.cfg->pgcfg.mapping_domain == NULL ||
diff --git a/usr/src/cmd/idmap/idmapd/server.c b/usr/src/cmd/idmap/idmapd/server.c
index a79c6e2f5a..ab084756b3 100644
--- a/usr/src/cmd/idmap/idmapd/server.c
+++ b/usr/src/cmd/idmap/idmapd/server.c
@@ -280,11 +280,14 @@ list_mappings_cb(void *parg, int argc, char **argv, char **colnames) {
u2w = argv[5]?strtol(argv[5], &end, 10):0;
if (w2u > 0 && u2w == 0)
- result->mappings.mappings_val[cb_data->next].direction = 1;
+ result->mappings.mappings_val[cb_data->next].direction =
+ IDMAP_DIRECTION_W2U;
else if (w2u == 0 && u2w > 0)
- result->mappings.mappings_val[cb_data->next].direction = 2;
+ result->mappings.mappings_val[cb_data->next].direction =
+ IDMAP_DIRECTION_U2W;
else
- result->mappings.mappings_val[cb_data->next].direction = 0;
+ result->mappings.mappings_val[cb_data->next].direction =
+ IDMAP_DIRECTION_BI;
ptr = &result->mappings.mappings_val[cb_data->next].id1domain;
if (idmap_str2utf8(&ptr, argv[6], 0) != IDMAP_SUCCESS)
@@ -409,11 +412,14 @@ list_namerules_cb(void *parg, int argc, char **argv, char **colnames) {
u2w_order = argv[7]?strtol(argv[7], &end, 10):0;
if (w2u_order > 0 && u2w_order == 0)
- result->rules.rules_val[cb_data->next].direction = 1;
+ result->rules.rules_val[cb_data->next].direction =
+ IDMAP_DIRECTION_W2U;
else if (w2u_order == 0 && u2w_order > 0)
- result->rules.rules_val[cb_data->next].direction = 2;
+ result->rules.rules_val[cb_data->next].direction =
+ IDMAP_DIRECTION_U2W;
else
- result->rules.rules_val[cb_data->next].direction = 0;
+ result->rules.rules_val[cb_data->next].direction =
+ IDMAP_DIRECTION_BI;
result->lastrowid = strtoll(argv[0], &end, 10);
cb_data->next++;
@@ -453,14 +459,14 @@ idmap_list_namerules_1_svc(idmap_namerule rule, uint64_t lastrowid,
if (rule.direction < 0) {
w2ubuf[0] = u2wbuf[0] = 0;
- } else if (rule.direction == 0) {
+ } else if (rule.direction == IDMAP_DIRECTION_BI) {
(void) snprintf(w2ubuf, sizeof (w2ubuf), "AND w2u_order > 0");
(void) snprintf(u2wbuf, sizeof (u2wbuf), "AND u2w_order > 0");
- } else if (rule.direction == 1) {
+ } else if (rule.direction == IDMAP_DIRECTION_W2U) {
(void) snprintf(w2ubuf, sizeof (w2ubuf), "AND w2u_order > 0");
(void) snprintf(u2wbuf, sizeof (u2wbuf),
"AND (u2w_order = 0 OR u2w_order ISNULL)");
- } else if (rule.direction == 2) {
+ } else if (rule.direction == IDMAP_DIRECTION_U2W) {
(void) snprintf(w2ubuf, sizeof (w2ubuf),
"AND (w2u_order = 0 OR w2u_order ISNULL)");
(void) snprintf(u2wbuf, sizeof (u2wbuf), "AND u2w_order > 0");
diff --git a/usr/src/lib/libidmap/common/idmap_api.c b/usr/src/lib/libidmap/common/idmap_api.c
index ff0d6fe64f..3b2e538dd1 100644
--- a/usr/src/lib/libidmap/common/idmap_api.c
+++ b/usr/src/lib/libidmap/common/idmap_api.c
@@ -213,9 +213,12 @@ idmap_udt_commit(idmap_udt_handle_t *udthandle) {
(xdrproc_t)xdr_idmap_update_batch, (caddr_t)&udthandle->batch,
(xdrproc_t)xdr_idmap_retcode, (caddr_t)&retcode,
TIMEOUT);
- if (clntstat != RPC_SUCCESS) {
- return (IDMAP_ERR_RPC);
- }
+
+ /* reset handle so that it can be used again */
+ _IDMAP_RESET_UDT_HANDLE(udthandle);
+
+ if (clntstat != RPC_SUCCESS)
+ return (_idmap_rpc2stat(clnt));
if (retcode != IDMAP_SUCCESS)
errno = idmap_stat2errno(retcode);
return (retcode);
@@ -239,10 +242,10 @@ idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain,
boolean_t is_user, const char *winname, const char *unixname,
boolean_t is_nt4, int direction) {
idmap_retcode retcode;
- idmap_namerule *rule;
+ idmap_namerule *rule = NULL;
idmap_utf8str *str;
- retcode = _udt_extend_batch(udthandle, OP_ADD_NAMERULE);
+ retcode = _udt_extend_batch(udthandle);
if (retcode != IDMAP_SUCCESS)
goto errout;
@@ -270,11 +273,16 @@ idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain,
if (retcode != IDMAP_SUCCESS)
goto errout;
}
+
+ udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
+ OP_ADD_NAMERULE;
udthandle->next++;
return (IDMAP_SUCCESS);
errout:
- (void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch);
+ /* The batch should still be usable */
+ if (rule)
+ (void) xdr_free(xdr_idmap_namerule, (caddr_t)rule);
errno = idmap_stat2errno(retcode);
return (retcode);
}
@@ -286,10 +294,10 @@ idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user,
const char *windomain, const char *winname,
const char *unixname, int direction) {
idmap_retcode retcode;
- idmap_namerule *rule;
+ idmap_namerule *rule = NULL;
idmap_utf8str *str;
- retcode = _udt_extend_batch(udthandle, OP_RM_NAMERULE);
+ retcode = _udt_extend_batch(udthandle);
if (retcode != IDMAP_SUCCESS)
goto errout;
@@ -316,11 +324,14 @@ idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user,
if (retcode != IDMAP_SUCCESS)
goto errout;
}
+ udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
+ OP_RM_NAMERULE;
udthandle->next++;
return (IDMAP_SUCCESS);
errout:
- (void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch);
+ if (rule)
+ (void) xdr_free(xdr_idmap_namerule, (caddr_t)rule);
errno = idmap_stat2errno(retcode);
return (retcode);
}
@@ -331,18 +342,19 @@ idmap_stat
idmap_udt_flush_namerules(idmap_udt_handle_t *udthandle, boolean_t is_user) {
idmap_retcode retcode;
- retcode = _udt_extend_batch(udthandle, OP_FLUSH_NAMERULES);
+ retcode = _udt_extend_batch(udthandle);
if (retcode != IDMAP_SUCCESS)
goto errout;
udthandle->batch.idmap_update_batch_val[udthandle->next].
idmap_update_op_u.is_user = is_user;
+ udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
+ OP_FLUSH_NAMERULES;
udthandle->next++;
return (IDMAP_SUCCESS);
errout:
- (void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch);
errno = idmap_stat2errno(retcode);
return (retcode);
}
@@ -393,7 +405,7 @@ idmap_iter_namerules(idmap_handle_t *handle, const char *windomain,
rule = &arg->rule;
rule->is_user = is_user;
- rule->direction = -1;
+ rule->direction = IDMAP_DIRECTION_UNDEF;
if (windomain) {
str = &rule->windomain;
retcode = idmap_str2utf8(&str, windomain, 0);
@@ -463,7 +475,7 @@ idmap_iter_next_namerule(idmap_iter_t *iter, char **windomain,
if (is_nt4)
*is_nt4 = 0;
if (direction)
- *direction = -1;
+ *direction = IDMAP_DIRECTION_UNDEF;
__ITER_CHECK(iter, IDMAP_LIST_NAMERULES);
@@ -603,7 +615,7 @@ idmap_iter_next_mapping(idmap_iter_t *iter, char **sidprefix,
if (pid)
*pid = UINT32_MAX;
if (direction)
- *direction = -1;
+ *direction = IDMAP_DIRECTION_UNDEF;
__ITER_CHECK(iter, IDMAP_LIST_MAPPINGS);
@@ -784,7 +796,7 @@ idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
int flag, uid_t *uid, idmap_stat *stat) {
idmap_retcode retcode;
- idmap_mapping *mapping;
+ idmap_mapping *mapping = NULL;
/* sanity checks */
if (gh == NULL)
@@ -816,10 +828,9 @@ idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
return (IDMAP_SUCCESS);
errout:
- (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
- free(gh->retlist);
- gh->retlist = NULL;
- gh->next = 0;
+ /* Batch created so far should still be usable */
+ if (mapping)
+ (void) memset(mapping, 0, sizeof (*mapping));
errno = idmap_stat2errno(retcode);
return (retcode);
}
@@ -844,7 +855,7 @@ idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
int flag, gid_t *gid, idmap_stat *stat) {
idmap_retcode retcode;
- idmap_mapping *mapping;
+ idmap_mapping *mapping = NULL;
/* sanity checks */
if (gh == NULL)
@@ -876,10 +887,8 @@ idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
return (IDMAP_SUCCESS);
errout:
- (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
- free(gh->retlist);
- gh->retlist = NULL;
- gh->next = 0;
+ if (mapping)
+ (void) memset(mapping, 0, sizeof (*mapping));
errno = idmap_stat2errno(retcode);
return (retcode);
}
@@ -905,7 +914,7 @@ idmap_stat
idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
int flag, uid_t *pid, int *is_user, idmap_stat *stat) {
idmap_retcode retcode;
- idmap_mapping *mapping;
+ idmap_mapping *mapping = NULL;
/* sanity checks */
if (gh == NULL)
@@ -939,10 +948,8 @@ idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
return (IDMAP_SUCCESS);
errout:
- (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
- free(gh->retlist);
- gh->retlist = NULL;
- gh->next = 0;
+ if (mapping)
+ (void) memset(mapping, 0, sizeof (*mapping));
errno = idmap_stat2errno(retcode);
return (retcode);
}
@@ -967,7 +974,7 @@ idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) {
idmap_retcode retcode;
- idmap_mapping *mapping;
+ idmap_mapping *mapping = NULL;
/* sanity checks */
if (gh == NULL)
@@ -996,10 +1003,8 @@ idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
return (IDMAP_SUCCESS);
errout:
- (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
- free(gh->retlist);
- gh->retlist = NULL;
- gh->next = 0;
+ if (mapping)
+ (void) memset(mapping, 0, sizeof (*mapping));
errno = idmap_stat2errno(retcode);
return (retcode);
}
@@ -1024,7 +1029,7 @@ idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) {
idmap_retcode retcode;
- idmap_mapping *mapping;
+ idmap_mapping *mapping = NULL;
/* sanity checks */
if (gh == NULL)
@@ -1053,10 +1058,8 @@ idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
return (IDMAP_SUCCESS);
errout:
- (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
- free(gh->retlist);
- gh->retlist = NULL;
- gh->next = 0;
+ if (mapping)
+ (void) memset(mapping, 0, sizeof (*mapping));
errno = idmap_stat2errno(retcode);
return (retcode);
}
@@ -1090,7 +1093,7 @@ idmap_get_mappings(idmap_get_handle_t *gh) {
(caddr_t)&res,
TIMEOUT);
if (clntstat != RPC_SUCCESS) {
- retcode = IDMAP_ERR_RPC;
+ retcode = _idmap_rpc2stat(clnt);
goto out;
}
if (res.retcode != IDMAP_SUCCESS) {
@@ -1142,10 +1145,7 @@ idmap_get_mappings(idmap_get_handle_t *gh) {
retcode = IDMAP_SUCCESS;
out:
- (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
- free(gh->retlist);
- gh->retlist = NULL;
- gh->next = 0;
+ _IDMAP_RESET_GET_HANDLE(gh);
(void) xdr_free(xdr_idmap_ids_res, (caddr_t)&res);
errno = idmap_stat2errno(retcode);
return (retcode);
@@ -1197,7 +1197,7 @@ idmap_get_w2u_mapping(idmap_handle_t *handle,
if (unixname)
*unixname = NULL;
if (direction)
- *direction = -1;
+ *direction = IDMAP_DIRECTION_UNDEF;
request.flag = flag;
request.id1.idtype = IDMAP_SID;
@@ -1235,9 +1235,8 @@ idmap_get_w2u_mapping(idmap_handle_t *handle,
(xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
TIMEOUT);
- if (clntstat != RPC_SUCCESS) {
- return (IDMAP_ERR_RPC);
- }
+ if (clntstat != RPC_SUCCESS)
+ return (_idmap_rpc2stat(clnt));
retcode = result.retcode;
@@ -1300,7 +1299,7 @@ idmap_get_u2w_mapping(idmap_handle_t *handle,
if (rid)
*rid = UINT32_MAX;
if (direction)
- *direction = -1;
+ *direction = IDMAP_DIRECTION_UNDEF;
(void) memset(&request, 0, sizeof (request));
(void) memset(&result, 0, sizeof (result));
@@ -1328,9 +1327,8 @@ idmap_get_u2w_mapping(idmap_handle_t *handle,
(xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
TIMEOUT);
- if (clntstat != RPC_SUCCESS) {
- return (IDMAP_ERR_RPC);
- }
+ if (clntstat != RPC_SUCCESS)
+ return (_idmap_rpc2stat(clnt));
retcode = result.retcode;
@@ -1342,7 +1340,7 @@ idmap_get_u2w_mapping(idmap_handle_t *handle,
if (direction)
*direction = mapping->direction;
- if (sidprefix) {
+ if (sidprefix && mapping->id2.idmap_id_u.sid.prefix) {
*sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix);
if (*sidprefix == NULL) {
retcode = IDMAP_ERR_MEMORY;
@@ -1489,7 +1487,7 @@ static stat_table_t stattable[] = {
{IDMAP_ERR_NORESULT, gettext("No results available"), EINVAL},
{IDMAP_ERR_NOTUSER, gettext("Not a user"), EINVAL},
{IDMAP_ERR_NOTGROUP, gettext("Not a group"), EINVAL},
- {IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), EINVAL},
+ {IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), ENOTSUP},
{IDMAP_ERR_W2U_NAMERULE,
gettext("Invalid Windows to UNIX name-based rule"), EINVAL},
{IDMAP_ERR_U2W_NAMERULE,
@@ -1499,11 +1497,11 @@ static stat_table_t stattable[] = {
{IDMAP_ERR_ARG, gettext("Invalid argument"), EINVAL},
{IDMAP_ERR_SID, gettext("Invalid SID"), EINVAL},
{IDMAP_ERR_IDTYPE, gettext("Invalid identity type"), EINVAL},
- {IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EINVAL},
+ {IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EBADF},
{IDMAP_ERR_RPC, gettext("RPC error"), EINVAL},
{IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL},
- {IDMAP_ERR_BUSY, gettext("Server is busy"), EINVAL},
- {IDMAP_ERR_PERMISSION_DENIED, gettext("Permisssion denied"), EINVAL},
+ {IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY},
+ {IDMAP_ERR_PERMISSION_DENIED, gettext("Permisssion denied"), EACCES},
{IDMAP_ERR_NOMAPPING,
gettext("Mapping not found or inhibited"), EINVAL},
{IDMAP_ERR_NEW_ID_ALLOC_REQD,
diff --git a/usr/src/lib/libidmap/common/idmap_impl.h b/usr/src/lib/libidmap/common/idmap_impl.h
index 858654957d..584e42a993 100644
--- a/usr/src/lib/libidmap/common/idmap_impl.h
+++ b/usr/src/lib/libidmap/common/idmap_impl.h
@@ -61,9 +61,12 @@ struct idmap_udt_handle {
struct idmap_handle *ih;
idmap_update_batch batch;
uint64_t next;
- char *lastmsg;
};
+#define _IDMAP_RESET_UDT_HANDLE(uh) \
+ (void) xdr_free(xdr_idmap_update_batch, (caddr_t)&uh->batch);\
+ uh->next = 0;
+
typedef struct idmap_get_res {
idmap_id_type idtype;
uid_t *uid;
@@ -79,9 +82,15 @@ struct idmap_get_handle {
idmap_mapping_batch batch;
idmap_get_res_t *retlist;
uint64_t next;
- char *lastmsg;
};
+#define _IDMAP_RESET_GET_HANDLE(gh) \
+ (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);\
+ if (gh->retlist) \
+ free(gh->retlist);\
+ gh->retlist = NULL;\
+ gh->next = 0;
+
struct idmap_iter {
struct idmap_handle *ih;
int type;
@@ -101,10 +110,11 @@ typedef struct stat_table {
typedef idmap_retcode _idmap_stat;
-extern idmap_retcode _udt_extend_batch(idmap_udt_handle_t *, int);
+extern idmap_retcode _udt_extend_batch(idmap_udt_handle_t *);
extern idmap_retcode _get_ids_extend_batch(idmap_get_handle_t *);
extern idmap_stat _iter_get_next_list(int, idmap_iter_t *, void *,
uchar_t **, size_t, xdrproc_t, xdrproc_t);
+extern idmap_stat _idmap_rpc2stat(CLIENT *);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libidmap/common/idmap_priv.h b/usr/src/lib/libidmap/common/idmap_priv.h
index d5a54b5387..42de37b785 100644
--- a/usr/src/lib/libidmap/common/idmap_priv.h
+++ b/usr/src/lib/libidmap/common/idmap_priv.h
@@ -45,6 +45,12 @@ extern "C" {
#define IDMAP_FATAL_ERROR(rc) rc == IDMAP_ERR_MEMORY ||\
rc == IDMAP_ERR_DB
+/* Direction in which mapping is valid */
+#define IDMAP_DIRECTION_UNDEF -1 /* not defined */
+#define IDMAP_DIRECTION_BI 0 /* bi-directional */
+#define IDMAP_DIRECTION_W2U 1 /* windows to unix only */
+#define IDMAP_DIRECTION_U2W 2 /* unix to windows only */
+
/* Opaque handle to batch config add/remove operations */
typedef struct idmap_udt_handle idmap_udt_handle_t;
diff --git a/usr/src/lib/libidmap/common/utils.c b/usr/src/lib/libidmap/common/utils.c
index c9d9c69001..80b9141c47 100644
--- a/usr/src/lib/libidmap/common/utils.c
+++ b/usr/src/lib/libidmap/common/utils.c
@@ -42,7 +42,7 @@
static struct timeval TIMEOUT = { 25, 0 };
idmap_retcode
-_udt_extend_batch(idmap_udt_handle_t *udthandle, int opnum) {
+_udt_extend_batch(idmap_udt_handle_t *udthandle) {
idmap_update_op *tmplist;
size_t nsize;
@@ -61,7 +61,7 @@ _udt_extend_batch(idmap_udt_handle_t *udthandle, int opnum) {
udthandle->batch.idmap_update_batch_len += _UDT_SIZE_INCR;
}
udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
- opnum;
+ OP_NONE;
return (IDMAP_SUCCESS);
}
@@ -125,8 +125,34 @@ _iter_get_next_list(int type, idmap_iter_t *iter,
TIMEOUT);
if (clntstat != RPC_SUCCESS) {
free(*list);
- return (IDMAP_ERR_RPC);
+ return (_idmap_rpc2stat(clnt));
}
iter->retlist = *list;
return (IDMAP_SUCCESS);
}
+
+idmap_stat
+_idmap_rpc2stat(CLIENT *clnt) {
+ /*
+ * We only deal with door_call(3C) errors here. We look at
+ * r_err.re_errno instead of r_err.re_status because we need
+ * to differentiate between RPC failures caused by bad door fd
+ * and others.
+ */
+ struct rpc_err r_err;
+ if (clnt) {
+ clnt_geterr(clnt, &r_err);
+ errno = r_err.re_errno;
+ switch (r_err.re_errno) {
+ case ENOMEM:
+ return (IDMAP_ERR_MEMORY);
+ case EBADF:
+ return (IDMAP_ERR_RPC_HANDLE);
+ default:
+ return (IDMAP_ERR_RPC);
+ }
+ }
+
+ /* null handle */
+ return (IDMAP_ERR_RPC_HANDLE);
+}