--- old/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c	Mon Aug  5 17:17:06 2019
+++ new/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c	Mon Aug  5 17:17:06 2019
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -27,10 +27,10 @@
  * SMB server interface to idmap
  * (smb_idmap_get..., smb_idmap_batch_...)
  *
- * There are three implementations of this interface:
- *	uts/common/fs/smbsrv/smb_idmap.c (smbsrv kmod)
- *	lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c (libfksmbsrv)
- *	lib/smbsrv/libsmb/common/smb_idmap.c (libsmb)
+ * There are three implementations of this interface.
+ * This is the "fake kernel" version of these routines.  See also:
+ * $SRC/lib/smbsrv/libsmb/common/smb_idmap.c
+ * $SRC/uts/common/fs/smbsrv/smb_idmap.c
  *
  * There are enough differences (relative to the code size)
  * that it's more trouble than it's worth to merge them.
@@ -39,6 +39,7 @@
  *	calls idmap interfaces (libidmap)
  *	uses kmem_... interfaces (libfakekernel)
  *	uses cmn_err instead of syslog, etc.
+ * The code in this variant looks a lot like the one in libsmb.
  */
 
 #include <sys/param.h>
@@ -148,8 +149,7 @@
 {
 	idmap_stat	stat;
 
-	if (!sib)
-		return (IDMAP_ERR_ARG);
+	ASSERT(sib != NULL);
 
 	bzero(sib, sizeof (smb_idmap_batch_t));
 	stat = idmap_get_create(&sib->sib_idmaph);
@@ -175,10 +175,11 @@
 void
 smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
 {
+	char *domsid;
 	int i;
 
-	if (sib == NULL)
-		return;
+	ASSERT(sib != NULL);
+	ASSERT(sib->sib_maps != NULL);
 
 	if (sib->sib_idmaph) {
 		idmap_get_destroy(sib->sib_idmaph);
@@ -185,9 +186,6 @@
 		sib->sib_idmaph = NULL;
 	}
 
-	if (sib->sib_maps == NULL)
-		return;
-
 	if (sib->sib_flags & SMB_IDMAP_ID2SID) {
 		/*
 		 * SIDs are allocated only when mapping
@@ -198,6 +196,16 @@
 			/* from strdup() in libidmap */
 			free(sib->sib_maps[i].sim_domsid);
 		}
+	} else if (sib->sib_flags & SMB_IDMAP_SID2ID) {
+		/*
+		 * SID prefixes are allocated only when mapping
+		 * SIDs to UID/GID
+		 */
+		for (i = 0; i < sib->sib_nmap; i++) {
+			domsid = sib->sib_maps[i].sim_domsid;
+			if (domsid)
+				smb_mem_free(domsid);
+		}
 	}
 
 	if (sib->sib_size && sib->sib_maps) {
@@ -225,13 +233,15 @@
 	idmap_stat stat;
 	int flag = 0;
 
-	if (idmaph == NULL || sim == NULL || sid == NULL)
-		return (IDMAP_ERR_ARG);
+	ASSERT(idmaph != NULL);
+	ASSERT(sim != NULL);
+	ASSERT(sid != NULL);
 
 	smb_sid_tostr(sid, sidstr);
 	if (smb_sid_splitstr(sidstr, &sim->sim_rid) != 0)
 		return (IDMAP_ERR_SID);
-	sim->sim_domsid = sidstr;
+	/* Note: Free sim_domsid in smb_idmap_batch_destroy */
+	sim->sim_domsid = smb_mem_strdup(sidstr);
 	sim->sim_idtype = idtype;
 
 	switch (idtype) {
@@ -259,9 +269,6 @@
 		break;
 	}
 
-	/* This was copied by idmap_get_Xbysid. */
-	sim->sim_domsid = NULL;
-
 	return (stat);
 }
 
@@ -272,6 +279,8 @@
  *
  * sim->sim_domsid and sim->sim_rid will contain the mapping
  * result upon successful process of the batched request.
+ * Stash the type for error reporting (caller saves the ID).
+ *
  * NB: sim_domsid allocated by strdup, here or in libidmap
  */
 idmap_stat
@@ -284,6 +293,7 @@
 	if (!idmaph || !sim)
 		return (IDMAP_ERR_ARG);
 
+	sim->sim_idtype = idtype;
 	switch (idtype) {
 	case SMB_IDMAP_USER:
 		stat = idmap_get_sidbyuid(idmaph, id, flag,
@@ -322,6 +332,7 @@
 		break;
 
 	default:
+		ASSERT(0);
 		return (IDMAP_ERR_ARG);
 	}
 
@@ -328,6 +339,28 @@
 	return (stat);
 }
 
+static void
+smb_idmap_bgm_report(smb_idmap_batch_t *sib, smb_idmap_t *sim)
+{
+
+	if ((sib->sib_flags & SMB_IDMAP_ID2SID) != 0) {
+		/*
+		 * Note: The ID and type we asked idmap to map
+		 * were saved in *sim_id and sim_idtype.
+		 */
+		uint_t id = (sim->sim_id == NULL) ?
+		    0 : (uint_t)*sim->sim_id;
+		cmn_err(CE_WARN, "Can't get SID for "
+		    "ID=%u type=%d, status=%d",
+		    id, sim->sim_idtype, sim->sim_stat);
+	}
+
+	if ((sib->sib_flags & SMB_IDMAP_SID2ID) != 0) {
+		cmn_err(CE_WARN, "Can't get ID for SID %s-%u, status=%d",
+		    sim->sim_domsid, sim->sim_rid, sim->sim_stat);
+	}
+}
+
 /*
  * smb_idmap_batch_getmappings
  *
@@ -353,13 +386,10 @@
 	 */
 	for (i = 0, sim = sib->sib_maps; i < sib->sib_nmap; i++, sim++) {
 		if (sim->sim_stat != IDMAP_SUCCESS) {
-			if (sib->sib_flags == SMB_IDMAP_SID2ID) {
-				cmn_err(CE_NOTE, "[%d] %d (%d)",
-				    sim->sim_idtype,
-				    sim->sim_rid,
-				    sim->sim_stat);
+			smb_idmap_bgm_report(sib, sim);
+			if ((sib->sib_flags & SMB_IDMAP_SKIP_ERRS) == 0) {
+				return (sim->sim_stat);
 			}
-			return (sim->sim_stat);
 		}
 	}
 
@@ -389,6 +419,7 @@
 
 	sim = sib->sib_maps;
 	for (i = 0; i < sib->sib_nmap; sim++, i++) {
+		ASSERT(sim->sim_domsid != NULL);
 		if (sim->sim_domsid == NULL)
 			return (-1);
 
