Print this page
NEX-17589 Get "too high" smbd error when copy big file to cifs share
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-17795 SMB logon should tolerate idmap problems
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-4083 Upstream changes from illumos 5917 and 5995
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-2460 libfksmbd should not link with libsmb
@@ -18,29 +18,30 @@
*
* CDDL HEADER END
*/
/*
* 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.
*/
/*
* 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.
*
* This one differs from the others in that it:
* 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>
#include <sys/types.h>
@@ -146,12 +147,11 @@
idmap_stat
smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
{
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);
if (stat != IDMAP_SUCCESS) {
@@ -173,23 +173,21 @@
* Frees the batch ID mapping context.
*/
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);
sib->sib_idmaph = NULL;
}
- if (sib->sib_maps == NULL)
- return;
-
if (sib->sib_flags & SMB_IDMAP_ID2SID) {
/*
* SIDs are allocated only when mapping
* UID/GID to SIDs
*/
@@ -196,11 +194,21 @@
for (i = 0; i < sib->sib_nmap; i++) {
smb_sid_free(sib->sib_maps[i].sim_sid);
/* 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) {
kmem_free(sib->sib_maps, sib->sib_size);
sib->sib_maps = NULL;
}
@@ -223,17 +231,19 @@
{
char sidstr[SMB_SID_STRSZ];
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) {
case SMB_IDMAP_USER:
stat = idmap_get_uidbysid(idmaph, sim->sim_domsid,
@@ -257,13 +267,10 @@
default:
stat = IDMAP_ERR_ARG;
break;
}
- /* This was copied by idmap_get_Xbysid. */
- sim->sim_domsid = NULL;
-
return (stat);
}
/*
* smb_idmap_batch_getsid
@@ -270,10 +277,12 @@
*
* Queue a request to map the given UID/GID to a SID.
*
* 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
smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
uid_t id, int idtype)
@@ -282,10 +291,11 @@
int flag = 0;
if (!idmaph || !sim)
return (IDMAP_ERR_ARG);
+ sim->sim_idtype = idtype;
switch (idtype) {
case SMB_IDMAP_USER:
stat = idmap_get_sidbyuid(idmaph, id, flag,
&sim->sim_domsid, &sim->sim_rid, &sim->sim_stat);
smb_idmap_check("idmap_get_sidbyuid", stat);
@@ -320,16 +330,39 @@
sim->sim_stat = IDMAP_SUCCESS;
stat = IDMAP_SUCCESS;
break;
default:
+ ASSERT(0);
return (IDMAP_ERR_ARG);
}
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
*
* trigger ID mapping service to get the mappings for queued
* requests.
@@ -351,19 +384,16 @@
/*
* Check the status for all the queued requests
*/
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);
}
}
+ }
if (smb_idmap_batch_binsid(sib) != 0)
stat = IDMAP_ERR_OTHER;
return (stat);
@@ -387,10 +417,11 @@
/* This operation is not required */
return (0);
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);
sid = smb_sid_fromstr(sim->sim_domsid);
if (sid == NULL)