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-9190 Files with owners not in /etc/passwd and not having inherited ACL's are prevented from seeing ownership/permissions via SMB
Reviewed by: Gordon Ross <gordon.ross@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>
SMB-50 User-mode SMB server
Includes work by these authors:
Thomas Keiser <thomas.keiser@nexenta.com>
Albert Lee <trisk@nexenta.com>
*** 18,45 ****
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2013 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 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 kernel (kidmap_...) interfaces
! * domain SIDs are shared, not strdup'ed
*/
/*
* SMB ID mapping
*
--- 18,45 ----
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. 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.
! * 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.
*
* This one differs from the others in that it:
* calls kernel (kidmap_...) interfaces
! * returned domain SIDs are shared, not strdup'ed
*/
/*
* SMB ID mapping
*
*** 102,111 ****
--- 102,119 ----
default:
ASSERT(0);
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);
if (sim.sim_domsid == NULL)
return (IDMAP_ERR_NOMAPPING);
*** 172,182 ****
* Creates and initializes the context for batch ID mapping.
*/
idmap_stat
smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
{
! ASSERT(sib);
bzero(sib, sizeof (smb_idmap_batch_t));
sib->sib_idmaph = kidmap_get_create(global_zone);
--- 180,190 ----
* Creates and initializes the context for batch ID mapping.
*/
idmap_stat
smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
{
! ASSERT(sib != NULL);
bzero(sib, sizeof (smb_idmap_batch_t));
sib->sib_idmaph = kidmap_get_create(global_zone);
*** 199,213 ****
smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
{
char *domsid;
int i;
! ASSERT(sib);
! ASSERT(sib->sib_maps);
! if (sib->sib_idmaph)
kidmap_get_destroy(sib->sib_idmaph);
if (sib->sib_flags & SMB_IDMAP_ID2SID) {
/*
* SIDs are allocated only when mapping
* UID/GID to SIDs
--- 207,223 ----
smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
{
char *domsid;
int i;
! ASSERT(sib != NULL);
! ASSERT(sib->sib_maps != NULL);
! if (sib->sib_idmaph) {
kidmap_get_destroy(sib->sib_idmaph);
+ sib->sib_idmaph = NULL;
+ }
if (sib->sib_flags & SMB_IDMAP_ID2SID) {
/*
* SIDs are allocated only when mapping
* UID/GID to SIDs
*** 224,235 ****
if (domsid)
smb_mem_free(domsid);
}
}
! if (sib->sib_size && sib->sib_maps)
kmem_free(sib->sib_maps, sib->sib_size);
}
/*
* smb_idmap_batch_getid
*
--- 234,247 ----
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;
+ }
}
/*
* smb_idmap_batch_getid
*
*** 247,264 ****
smb_sid_t *sid, int idtype)
{
char strsid[SMB_SID_STRSZ];
idmap_stat idm_stat;
! ASSERT(idmaph);
! ASSERT(sim);
! ASSERT(sid);
smb_sid_tostr(sid, strsid);
if (smb_sid_splitstr(strsid, &sim->sim_rid) != 0)
return (IDMAP_ERR_SID);
sim->sim_domsid = smb_mem_strdup(strsid);
switch (idtype) {
case SMB_IDMAP_USER:
idm_stat = kidmap_batch_getuidbysid(idmaph, sim->sim_domsid,
sim->sim_rid, sim->sim_id, &sim->sim_stat);
--- 259,278 ----
smb_sid_t *sid, int idtype)
{
char strsid[SMB_SID_STRSZ];
idmap_stat idm_stat;
! 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:
idm_stat = kidmap_batch_getuidbysid(idmaph, sim->sim_domsid,
sim->sim_rid, sim->sim_id, &sim->sim_stat);
*** 288,304 ****
--- 302,320 ----
*
* 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).
*/
idmap_stat
smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
uid_t id, int idtype)
{
idmap_stat idm_stat;
+ sim->sim_idtype = idtype;
switch (idtype) {
case SMB_IDMAP_USER:
idm_stat = kidmap_batch_getsidbyuid(idmaph, id,
(const char **)&sim->sim_domsid, &sim->sim_rid,
&sim->sim_stat);
*** 340,349 ****
--- 356,387 ----
}
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
*
* trigger ID mapping service to get the mappings for queued
* requests.
*** 354,376 ****
*/
idmap_stat
smb_idmap_batch_getmappings(smb_idmap_batch_t *sib)
{
idmap_stat idm_stat = IDMAP_SUCCESS;
int i;
idm_stat = kidmap_get_mappings(sib->sib_idmaph);
if (idm_stat != IDMAP_SUCCESS)
return (idm_stat);
/*
* 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);
}
if (smb_idmap_batch_binsid(sib) != 0)
idm_stat = IDMAP_ERR_OTHER;
return (idm_stat);
--- 392,419 ----
*/
idmap_stat
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);
if (idm_stat != IDMAP_SUCCESS)
return (idm_stat);
/*
* 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) {
! 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)
idm_stat = IDMAP_ERR_OTHER;
return (idm_stat);
*** 394,404 ****
/* This operation is not required */
return (0);
sim = sib->sib_maps;
for (i = 0; i < sib->sib_nmap; sim++, i++) {
! ASSERT(sim->sim_domsid);
if (sim->sim_domsid == NULL)
return (1);
if ((sid = smb_sid_fromstr(sim->sim_domsid)) == NULL)
return (1);
--- 437,447 ----
/* 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);
if ((sid = smb_sid_fromstr(sim->sim_domsid)) == NULL)
return (1);