--- old/usr/src/uts/common/fs/smbsrv/smb_idmap.c	Mon Aug  5 17:26:31 2019
+++ new/usr/src/uts/common/fs/smbsrv/smb_idmap.c	Mon Aug  5 17:26:31 2019
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 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 kernel version of these routines.  See also:
+ * $SRC/lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c
+ * $SRC/lib/smbsrv/libsmb/common/smb_idmap.c
  *
  * There are enough differences (relative to the code size)
  * that it's more trouble than it's worth to merge them.
@@ -37,7 +37,7 @@
  *
  * This one differs from the others in that it:
  *	calls kernel (kidmap_...) interfaces
- *	domain SIDs are shared, not strdup'ed
+ *	returned domain SIDs are shared, not strdup'ed
  */
 
 /*
@@ -104,6 +104,14 @@
 		return (IDMAP_ERR_ARG);
 	}
 
+	/*
+	 * IDMAP_ERR_NOTFOUND is an advisory error
+	 * and idmap will generate a local sid.
+	 */
+	if (sim.sim_stat == IDMAP_ERR_NOTFOUND &&
+	    sim.sim_domsid != NULL)
+		sim.sim_stat = IDMAP_SUCCESS;
+
 	if (sim.sim_stat != IDMAP_SUCCESS)
 		return (sim.sim_stat);
 
@@ -174,7 +182,7 @@
 idmap_stat
 smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
 {
-	ASSERT(sib);
+	ASSERT(sib != NULL);
 
 	bzero(sib, sizeof (smb_idmap_batch_t));
 
@@ -201,11 +209,13 @@
 	char *domsid;
 	int i;
 
-	ASSERT(sib);
-	ASSERT(sib->sib_maps);
+	ASSERT(sib != NULL);
+	ASSERT(sib->sib_maps != NULL);
 
-	if (sib->sib_idmaph)
+	if (sib->sib_idmaph) {
 		kidmap_get_destroy(sib->sib_idmaph);
+		sib->sib_idmaph = NULL;
+	}
 
 	if (sib->sib_flags & SMB_IDMAP_ID2SID) {
 		/*
@@ -226,8 +236,10 @@
 		}
 	}
 
-	if (sib->sib_size && sib->sib_maps)
+	if (sib->sib_size && sib->sib_maps) {
 		kmem_free(sib->sib_maps, sib->sib_size);
+		sib->sib_maps = NULL;
+	}
 }
 
 /*
@@ -249,14 +261,16 @@
 	char strsid[SMB_SID_STRSZ];
 	idmap_stat idm_stat;
 
-	ASSERT(idmaph);
-	ASSERT(sim);
-	ASSERT(sid);
+	ASSERT(idmaph != NULL);
+	ASSERT(sim != NULL);
+	ASSERT(sid != NULL);
 
 	smb_sid_tostr(sid, strsid);
 	if (smb_sid_splitstr(strsid, &sim->sim_rid) != 0)
 		return (IDMAP_ERR_SID);
+	/* Note: Free sim_domsid in smb_idmap_batch_destroy */
 	sim->sim_domsid = smb_mem_strdup(strsid);
+	sim->sim_idtype = idtype;
 
 	switch (idtype) {
 	case SMB_IDMAP_USER:
@@ -290,6 +304,7 @@
  *
  * 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).
  */
 idmap_stat
 smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
@@ -297,6 +312,7 @@
 {
 	idmap_stat idm_stat;
 
+	sim->sim_idtype = idtype;
 	switch (idtype) {
 	case SMB_IDMAP_USER:
 		idm_stat = kidmap_batch_getsidbyuid(idmaph, id,
@@ -342,6 +358,28 @@
 	return (idm_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
  *
@@ -356,6 +394,7 @@
 smb_idmap_batch_getmappings(smb_idmap_batch_t *sib)
 {
 	idmap_stat idm_stat = IDMAP_SUCCESS;
+	smb_idmap_t *sim;
 	int i;
 
 	idm_stat = kidmap_get_mappings(sib->sib_idmaph);
@@ -365,9 +404,13 @@
 	/*
 	 * Check the status for all the queued requests
 	 */
-	for (i = 0; i < sib->sib_nmap; i++) {
-		if (sib->sib_maps[i].sim_stat != IDMAP_SUCCESS)
-			return (sib->sib_maps[i].sim_stat);
+	for (i = 0, sim = sib->sib_maps; i < sib->sib_nmap; i++, sim++) {
+		if (sim->sim_stat != IDMAP_SUCCESS) {
+			smb_idmap_bgm_report(sib, sim);
+			if ((sib->sib_flags & SMB_IDMAP_SKIP_ERRS) == 0) {
+				return (sim->sim_stat);
+			}
+		}
 	}
 
 	if (smb_idmap_batch_binsid(sib) != 0)
@@ -396,7 +439,7 @@
 
 	sim = sib->sib_maps;
 	for (i = 0; i < sib->sib_nmap; sim++, i++) {
-		ASSERT(sim->sim_domsid);
+		ASSERT(sim->sim_domsid != NULL);
 		if (sim->sim_domsid == NULL)
 			return (1);
 
