changeset 4695:42666b3425e5

6569573 idmapd could log better messages when AD LDAP bind fails 6579507 idmapd should generate and set a machine_sid when it's missing 6579919 Need Creator Authority domain string in idmap.h
author baban
date Fri, 20 Jul 2007 15:17:01 -0700
parents 73996a03bcc9
children 666103281afe
files usr/src/cmd/idmap/idmapd/Makefile usr/src/cmd/idmap/idmapd/adutils.c usr/src/cmd/idmap/idmapd/idmap_config.c usr/src/cmd/idmap/idmapd/idmapd.c usr/src/cmd/idmap/idmapd/init.c usr/src/lib/libidmap/common/idmap_api.c usr/src/uts/common/sys/idmap.h
diffstat 7 files changed, 168 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/idmap/idmapd/Makefile	Fri Jul 20 14:09:21 2007 -0700
+++ b/usr/src/cmd/idmap/idmapd/Makefile	Fri Jul 20 15:17:01 2007 -0700
@@ -60,7 +60,7 @@
 CLOBBERFILES += $(IDMAP_PROT_H)
 
 CFLAGS += -v
-LDLIBS += -lsecdb -lnsl -lidmap -lscf -lldap
+LDLIBS += -lsecdb -lnsl -lidmap -lscf -lldap -luuid
 
 $(PROG) := MAPFILES = $(MAPFILE.INT) $(MAPFILE.NGB)
 $(PROG) := LDFLAGS += $(MAPFILES:%=-M%)
--- a/usr/src/cmd/idmap/idmapd/adutils.c	Fri Jul 20 14:09:21 2007 -0700
+++ b/usr/src/cmd/idmap/idmapd/adutils.c	Fri Jul 20 15:17:01 2007 -0700
@@ -483,9 +483,9 @@
 		    &idmap_saslcallback, NULL /* defaults */);
 
 		if (rc != LDAP_SUCCESS) {
-			idmapdlog(LOG_ERR, "Could not authenticate to the "
-			    "LDAP server.  (Check that the host keys are "
-			    "correct?)");
+			idmapdlog(LOG_ERR, "ldap_sasl_interactive_bind_s() "
+			    "to server %s:%d failed. (%s)",
+			    adh->host, adh->port, ldap_err2string(rc));
 			return (rc);
 		}
 	}
--- a/usr/src/cmd/idmap/idmapd/idmap_config.c	Fri Jul 20 14:09:21 2007 -0700
+++ b/usr/src/cmd/idmap/idmapd/idmap_config.c	Fri Jul 20 15:17:01 2007 -0700
@@ -41,17 +41,55 @@
 #include "idmapd.h"
 #include <stdio.h>
 #include <stdarg.h>
+#include <uuid/uuid.h>
 
+#define	MACHINE_SID_LEN	(9 + UUID_LEN/4 * 11)
 #define	FMRI_BASE "svc:/system/idmap"
-
 #define	CONFIG_PG "config"
 #define	GENERAL_PG "general"
-
 /* initial length of the array for policy options/attributes: */
 #define	DEF_ARRAY_LENGTH 16
 
 static const char *me = "idmapd";
 
+static int
+generate_machine_sid(char **machine_sid) {
+	char *p;
+	uuid_t uu;
+	int i, j, len, rlen;
+	uint32_t rid;
+
+	/*
+	 * Generate and split 128-bit UUID into four 32-bit RIDs
+	 * The machine_sid will be of the form S-1-5-N1-N2-N3-N4
+	 * We depart from Windows here, which instead of 128
+	 * bits worth of random numbers uses 96 bits.
+	 */
+
+	*machine_sid = calloc(1, MACHINE_SID_LEN);
+	if (*machine_sid == NULL) {
+		idmapdlog(LOG_ERR, "%s: Out of memory", me);
+		return (-1);
+	}
+	(void) strcpy(*machine_sid, "S-1-5-21");
+	p = *machine_sid + strlen("S-1-5-21");
+	len = MACHINE_SID_LEN - strlen("S-1-5-21");
+
+	uuid_clear(uu);
+	uuid_generate_random(uu);
+
+	for (i = 0; i < UUID_LEN/4; i++) {
+		j = i * 4;
+		rid = (uu[j] << 24) | (uu[j + 1] << 16) |
+			(uu[j + 2] << 8) | (uu[j + 3]);
+		rlen = snprintf(p, len, "-%u", rid);
+		p += rlen;
+		len -= rlen;
+	}
+
+	return (0);
+}
+
 /* Check if in the case of failure the original value of *val is preserved */
 static int
 get_val_int(idmap_cfg_t *cfg, char *name, void *val, scf_type_t type)
@@ -177,6 +215,96 @@
 	return (rc);
 }
 
+static int
+set_val_astring(idmap_cfg_t *cfg, char *name, const char *val)
+{
+	int			rc = 0, i;
+	scf_property_t		*scf_prop = NULL;
+	scf_value_t		*value = NULL;
+	scf_transaction_t	*tx = NULL;
+	scf_transaction_entry_t	*ent = NULL;
+
+	if ((scf_prop = scf_property_create(cfg->handles.main)) == NULL ||
+	    (value = scf_value_create(cfg->handles.main)) == NULL ||
+	    (tx = scf_transaction_create(cfg->handles.main)) == NULL ||
+	    (ent = scf_entry_create(cfg->handles.main)) == NULL) {
+		idmapdlog(LOG_ERR, "%s: Unable to set property %s: %s",
+		    me, name, scf_strerror(scf_error()));
+		rc = -1;
+		goto destruction;
+	}
+
+	for (i = 0; i < MAX_TRIES && rc == 0; i++) {
+		if (scf_transaction_start(tx, cfg->handles.config_pg) == -1) {
+			idmapdlog(LOG_ERR,
+			    "%s: scf_transaction_start(%s) failed: %s",
+			    me, name, scf_strerror(scf_error()));
+			rc = -1;
+			goto destruction;
+		}
+
+		rc = scf_transaction_property_new(tx, ent, name,
+		    SCF_TYPE_ASTRING);
+		if (rc == -1) {
+			idmapdlog(LOG_ERR,
+			    "%s: scf_transaction_property_new() failed: %s",
+			    me, scf_strerror(scf_error()));
+			goto destruction;
+		}
+
+		if (scf_value_set_astring(value, val) == -1) {
+			idmapdlog(LOG_ERR,
+			    "%s: scf_value_set_astring() failed: %s",
+			    me, scf_strerror(scf_error()));
+			rc = -1;
+			goto destruction;
+		}
+
+		if (scf_entry_add_value(ent, value) == -1) {
+			idmapdlog(LOG_ERR,
+			    "%s: scf_entry_add_value() failed: %s",
+			    me, scf_strerror(scf_error()));
+			rc = -1;
+			goto destruction;
+		}
+
+		rc = scf_transaction_commit(tx);
+		if (rc == 0 && i < MAX_TRIES - 1) {
+			/*
+			 * Property group set in scf_transaction_start()
+			 * is not the most recent. Update pg, reset tx and
+			 * retry tx.
+			 */
+			idmapdlog(LOG_WARNING,
+			    "%s: scf_transaction_commit(%s) failed - Retry: %s",
+			    me, name, scf_strerror(scf_error()));
+			if (scf_pg_update(cfg->handles.config_pg) == -1) {
+				idmapdlog(LOG_ERR,
+				    "%s: scf_pg_update() failed: %s",
+				    me, scf_strerror(scf_error()));
+				rc = -1;
+				goto destruction;
+			}
+			scf_transaction_reset(tx);
+		}
+	}
+
+	/* Log failure message if all retries failed */
+	if (rc == 0) {
+		idmapdlog(LOG_ERR,
+		    "%s: scf_transaction_commit(%s) failed: %s",
+		    me, name, scf_strerror(scf_error()));
+		rc = -1;
+	}
+
+destruction:
+	scf_value_destroy(value);
+	scf_entry_destroy(ent);
+	scf_transaction_destroy(tx);
+	scf_property_destroy(scf_prop);
+	return (rc);
+}
+
 int
 idmap_cfg_load(idmap_cfg_t *cfg)
 {
@@ -237,6 +365,18 @@
 	rc = get_val_astring(cfg, "machine_sid", &cfg->pgcfg.machine_sid);
 	if (rc != 0)
 		return (-1);
+	if (cfg->pgcfg.machine_sid == NULL) {
+		/* If machine_sid not configured, generate one */
+		if (generate_machine_sid(&cfg->pgcfg.machine_sid) < 0)
+			return (-1);
+		rc = set_val_astring(cfg, "machine_sid",
+		    cfg->pgcfg.machine_sid);
+		if (rc < 0) {
+			free(cfg->pgcfg.machine_sid);
+			cfg->pgcfg.machine_sid = NULL;
+			return (-1);
+		}
+	}
 
 	rc = get_val_astring(cfg, "global_catalog", &cfg->pgcfg.global_catalog);
 	if (rc != 0)
--- a/usr/src/cmd/idmap/idmapd/idmapd.c	Fri Jul 20 14:09:21 2007 -0700
+++ b/usr/src/cmd/idmap/idmapd/idmapd.c	Fri Jul 20 15:17:01 2007 -0700
@@ -288,15 +288,11 @@
 		exit(1);
 	}
 
-	setegid(DAEMON_GID);
-	seteuid(DAEMON_UID);
 	if (init_mapping_system() < 0) {
 		idmapdlog(LOG_ERR,
 		"idmapd: unable to initialize mapping system");
 		exit(1);
 	}
-	seteuid(0);
-	setegid(0);
 
 	xprt = svc_door_create(idmap_prog_1, IDMAP_PROG, IDMAP_V1, 0);
 	if (xprt == NULL) {
--- a/usr/src/cmd/idmap/idmapd/init.c	Fri Jul 20 14:09:21 2007 -0700
+++ b/usr/src/cmd/idmap/idmapd/init.c	Fri Jul 20 15:17:01 2007 -0700
@@ -38,20 +38,29 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <rpcsvc/daemon_utils.h>
 
 static const char *me = "idmapd";
 
 int
 init_mapping_system() {
+	int rc = 0;
+
 	if (rwlock_init(&_idmapdstate.rwlk_cfg, USYNC_THREAD, NULL) != 0)
 		return (-1);
 	if (load_config() < 0)
 		return (-1);
+
+	(void) setegid(DAEMON_GID);
+	(void) seteuid(DAEMON_UID);
 	if (init_dbs() < 0) {
+		rc = -1;
 		fini_mapping_system();
-		return (-1);
 	}
-	return (0);
+	(void) seteuid(0);
+	(void) setegid(0);
+
+	return (rc);
 }
 
 void
--- a/usr/src/lib/libidmap/common/idmap_api.c	Fri Jul 20 14:09:21 2007 -0700
+++ b/usr/src/lib/libidmap/common/idmap_api.c	Fri Jul 20 15:17:01 2007 -0700
@@ -658,7 +658,7 @@
 	if (sidprefix) {
 		str = mappings->mappings.mappings_val[iter->next].id1.
 			idmap_id_u.sid.prefix;
-		if (str) {
+		if (str && *str != '\0') {
 			*sidprefix = strdup(str);
 			if (*sidprefix == NULL) {
 				retcode = IDMAP_ERR_MEMORY;
@@ -1124,7 +1124,8 @@
 			if (gh->retlist[i].rid)
 				*gh->retlist[i].rid = id->idmap_id_u.sid.rid;
 			if (gh->retlist[i].sidprefix) {
-				if (id->idmap_id_u.sid.prefix == NULL) {
+				if (id->idmap_id_u.sid.prefix == NULL ||
+				    *id->idmap_id_u.sid.prefix == '\0') {
 					*gh->retlist[i].sidprefix = NULL;
 					break;
 				}
@@ -1340,7 +1341,8 @@
 
 	if (direction)
 		*direction = mapping->direction;
-	if (sidprefix && mapping->id2.idmap_id_u.sid.prefix) {
+	if (sidprefix && mapping->id2.idmap_id_u.sid.prefix &&
+	    *mapping->id2.idmap_id_u.sid.prefix != '\0') {
 		*sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix);
 		if (*sidprefix == NULL) {
 			retcode = IDMAP_ERR_MEMORY;
@@ -1404,7 +1406,7 @@
 			return (IDMAP_SUCCESS);
 		if (in->idmap_utf8str_val == NULL)
 			return (IDMAP_ERR_ARG);
-		if (in->idmap_utf8str_val[len - 1] != 0)
+		if (in->idmap_utf8str_val[len - 1] != '\0')
 			len++;
 		*out = calloc(1, len);
 		if (*out == NULL)
@@ -1417,7 +1419,7 @@
 			return (IDMAP_SUCCESS);
 		if (in->idmap_utf8str_val == NULL)
 			return (IDMAP_ERR_ARG);
-		if (in->idmap_utf8str_val[len - 1] != 0)
+		if (in->idmap_utf8str_val[len - 1] != '\0')
 			len++;
 		if (outsize < len)
 			return (IDMAP_ERR_ARG);
@@ -1501,7 +1503,7 @@
 	{IDMAP_ERR_RPC, gettext("RPC error"), EINVAL},
 	{IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL},
 	{IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY},
-	{IDMAP_ERR_PERMISSION_DENIED, gettext("Permisssion denied"), EACCES},
+	{IDMAP_ERR_PERMISSION_DENIED, gettext("Permission denied"), EACCES},
 	{IDMAP_ERR_NOMAPPING,
 		gettext("Mapping not found or inhibited"), EINVAL},
 	{IDMAP_ERR_NEW_ID_ALLOC_REQD,
--- a/usr/src/uts/common/sys/idmap.h	Fri Jul 20 14:09:21 2007 -0700
+++ b/usr/src/uts/common/sys/idmap.h	Fri Jul 20 15:17:01 2007 -0700
@@ -71,4 +71,7 @@
 #define	IDMAP_WK_CREATOR_OWNER_UID	2147483648U
 #define	IDMAP_WK__MAX_UID		2147483648U
 
+/* Reserved SIDs */
+#define	IDMAP_WK_CREATOR_SID_AUTHORITY	"S-1-3"
+
 #endif /* _SYS_IDMAP_H */