[SCM] Samba Shared Repository - branch master updated
Ralph Böhme
slow at samba.org
Sat Mar 5 11:54:03 UTC 2016
The branch, master has been updated
via 937d60f smbd: Clean up the logic inside vfs_chown_fsp() to prevent future security issues.
via 8b4a38b VFS: Modify lchown to take a const struct smb_filename * instead of const char *
via d1f26bc VFS: Modify chown to take a const struct smb_filename * instead of const char *
via 9678611 VFS: vfs_netatalk. Fix wrong VFS call used inside atalk_lchown()
from 9ee4678 vfs_glusterfs: Fix use after free in AIO callback.
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 937d60f2e24fa27dca562306022de1f4855f047c
Author: Jeremy Allison <jra at samba.org>
Date: Thu Mar 3 15:29:10 2016 -0800
smbd: Clean up the logic inside vfs_chown_fsp() to prevent future security issues.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
Autobuild-User(master): Ralph Böhme <slow at samba.org>
Autobuild-Date(master): Sat Mar 5 12:53:11 CET 2016 on sn-devel-144
commit 8b4a38b4c94bb3617d0b6444125d9e24f41891cf
Author: Jeremy Allison <jra at samba.org>
Date: Thu Mar 3 14:34:57 2016 -0800
VFS: Modify lchown to take a const struct smb_filename * instead of const char *
Preparing to reduce use of lp_posix_pathnames().
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit d1f26bc43228843f57b1ee23c1690306d6440865
Author: Jeremy Allison <jra at samba.org>
Date: Thu Mar 3 11:54:23 2016 -0800
VFS: Modify chown to take a const struct smb_filename * instead of const char *
Preparing to reduce use of lp_posix_pathnames().
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit 9678611d82d518bb16402a827cbf13769a5f0333
Author: Jeremy Allison <jra at samba.org>
Date: Thu Mar 3 11:53:39 2016 -0800
VFS: vfs_netatalk. Fix wrong VFS call used inside atalk_lchown()
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
-----------------------------------------------------------------------
Summary of changes:
examples/VFS/skel_opaque.c | 12 ++++--
examples/VFS/skel_transparent.c | 16 +++++---
source3/include/vfs.h | 26 ++++++++++---
source3/include/vfs_macros.h | 16 ++++----
source3/modules/vfs_cap.c | 56 ++++++++++++++++++++++++---
source3/modules/vfs_catia.c | 50 +++++++++++++++++++-----
source3/modules/vfs_ceph.c | 27 +++++++++----
source3/modules/vfs_default.c | 14 +++++--
source3/modules/vfs_fake_acls.c | 38 ++++++++++++++++---
source3/modules/vfs_fruit.c | 24 +++++++++---
source3/modules/vfs_full_audit.c | 16 +++++---
source3/modules/vfs_glusterfs.c | 12 ++++--
source3/modules/vfs_media_harmony.c | 50 +++++++++++-------------
source3/modules/vfs_netatalk.c | 22 ++++++-----
source3/modules/vfs_shadow_copy2.c | 30 +++++++++++----
source3/modules/vfs_snapper.c | 33 ++++++++++++----
source3/modules/vfs_time_audit.c | 20 +++++++---
source3/modules/vfs_unityed_media.c | 44 +++++++++++----------
source3/smbd/open.c | 6 ++-
source3/smbd/pysmbd.c | 14 ++++++-
source3/smbd/trans2.c | 4 +-
source3/smbd/vfs.c | 76 +++++++++++++++++++++++--------------
source3/torture/cmd_vfs.c | 12 +++++-
23 files changed, 431 insertions(+), 187 deletions(-)
Changeset truncated at 500 lines:
diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index e7bb645..457881d 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -382,8 +382,10 @@ static int skel_fchmod(vfs_handle_struct *handle, files_struct *fsp,
return -1;
}
-static int skel_chown(vfs_handle_struct *handle, const char *path,
- uid_t uid, gid_t gid)
+static int skel_chown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
errno = ENOSYS;
return -1;
@@ -396,8 +398,10 @@ static int skel_fchown(vfs_handle_struct *handle, files_struct *fsp,
return -1;
}
-static int skel_lchown(vfs_handle_struct *handle, const char *path,
- uid_t uid, gid_t gid)
+static int skel_lchown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
errno = ENOSYS;
return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index fe2356a..55b1ed6 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -488,10 +488,12 @@ static int skel_fchmod(vfs_handle_struct *handle, files_struct *fsp,
return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
}
-static int skel_chown(vfs_handle_struct *handle, const char *path, uid_t uid,
- gid_t gid)
+static int skel_chown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
- return SMB_VFS_NEXT_CHOWN(handle, path, uid, gid);
+ return SMB_VFS_NEXT_CHOWN(handle, smb_fname, uid, gid);
}
static int skel_fchown(vfs_handle_struct *handle, files_struct *fsp,
@@ -500,10 +502,12 @@ static int skel_fchown(vfs_handle_struct *handle, files_struct *fsp,
return SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
}
-static int skel_lchown(vfs_handle_struct *handle, const char *path, uid_t uid,
- gid_t gid)
+static int skel_lchown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
- return SMB_VFS_NEXT_LCHOWN(handle, path, uid, gid);
+ return SMB_VFS_NEXT_LCHOWN(handle, smb_fname, uid, gid);
}
static int skel_chdir(vfs_handle_struct *handle, const char *path)
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index c8e0494..e77d702 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -184,6 +184,10 @@
const struct smb_filename * */
/* Version 35 - Change chmod_acl from const char *, to
const struct smb_filename * */
+/* Version 35 - Change chown from const char *, to
+ const struct smb_filename * */
+/* Version 35 - Change lchown from const char *, to
+ const struct smb_filename * */
#define SMB_VFS_INTERFACE_VERSION 35
@@ -646,9 +650,15 @@ struct vfs_fn_pointers {
const struct smb_filename *smb_fname,
mode_t mode);
int (*fchmod_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, mode_t mode);
- int (*chown_fn)(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid);
+ int (*chown_fn)(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid);
int (*fchown_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, uid_t uid, gid_t gid);
- int (*lchown_fn)(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid);
+ int (*lchown_fn)(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid);
int (*chdir_fn)(struct vfs_handle_struct *handle, const char *path);
char *(*getwd_fn)(struct vfs_handle_struct *handle);
int (*ntimes_fn)(struct vfs_handle_struct *handle,
@@ -1095,12 +1105,16 @@ int smb_vfs_call_chmod(struct vfs_handle_struct *handle,
mode_t mode);
int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
struct files_struct *fsp, mode_t mode);
-int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
- uid_t uid, gid_t gid);
+int smb_vfs_call_chown(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid);
int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
struct files_struct *fsp, uid_t uid, gid_t gid);
-int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
- uid_t uid, gid_t gid);
+int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid);
int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path);
char *smb_vfs_call_getwd(struct vfs_handle_struct *handle);
int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index e5e3c99..ae2ba1b 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -251,20 +251,20 @@
#define SMB_VFS_NEXT_FCHMOD(handle, fsp, mode) \
smb_vfs_call_fchmod((handle)->next, (fsp), (mode))
-#define SMB_VFS_CHOWN(conn, path, uid, gid) \
- smb_vfs_call_chown((conn)->vfs_handles, (path), (uid), (gid))
-#define SMB_VFS_NEXT_CHOWN(handle, path, uid, gid) \
- smb_vfs_call_chown((handle)->next, (path), (uid), (gid))
+#define SMB_VFS_CHOWN(conn, smb_fname, uid, gid) \
+ smb_vfs_call_chown((conn)->vfs_handles, (smb_fname), (uid), (gid))
+#define SMB_VFS_NEXT_CHOWN(handle, smb_fname, uid, gid) \
+ smb_vfs_call_chown((handle)->next, (smb_fname), (uid), (gid))
#define SMB_VFS_FCHOWN(fsp, uid, gid) \
smb_vfs_call_fchown((fsp)->conn->vfs_handles, (fsp), (uid), (gid))
#define SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid) \
smb_vfs_call_fchown((handle)->next, (fsp), (uid), (gid))
-#define SMB_VFS_LCHOWN(conn, path, uid, gid) \
- smb_vfs_call_lchown((conn)->vfs_handles, (path), (uid), (gid))
-#define SMB_VFS_NEXT_LCHOWN(handle, path, uid, gid) \
- smb_vfs_call_lchown((handle)->next, (path), (uid), (gid))
+#define SMB_VFS_LCHOWN(conn, smb_fname, uid, gid) \
+ smb_vfs_call_lchown((conn)->vfs_handles, (smb_fname), (uid), (gid))
+#define SMB_VFS_NEXT_LCHOWN(handle, smb_fname, uid, gid) \
+ smb_vfs_call_lchown((handle)->next, (smb_fname), (uid), (gid))
#define SMB_VFS_CHDIR(conn, path) \
smb_vfs_call_chdir((conn)->vfs_handles, (path))
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 0bb943d..42b4b8d 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -336,26 +336,70 @@ static int cap_chmod(vfs_handle_struct *handle,
return ret;
}
-static int cap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int cap_chown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ int ret;
+ int saved_errno;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_CHOWN(handle, cappath, uid, gid);
+
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_CHOWN(handle, cap_smb_fname, uid, gid);
+ saved_errno = errno;
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ errno = saved_errno;
+ return ret;
}
-static int cap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int cap_lchown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ int ret;
+ int saved_errno;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_LCHOWN(handle, cappath, uid, gid);
+
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_LCHOWN(handle, cap_smb_fname, uid, gid);
+ saved_errno = errno;
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ errno = saved_errno;
+ return ret;
}
static int cap_chdir(vfs_handle_struct *handle, const char *path)
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index e142cce..4a988b9 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -522,46 +522,76 @@ static int catia_unlink(vfs_handle_struct *handle,
}
static int catia_chown(vfs_handle_struct *handle,
- const char *path,
+ const struct smb_filename *smb_fname,
uid_t uid,
gid_t gid)
{
char *name = NULL;
NTSTATUS status;
int ret;
+ int saved_errno;
+ struct smb_filename *catia_smb_fname = NULL;
- status = catia_string_replace_allocate(handle->conn, path,
- &name, vfs_translate_to_unix);
+ status = catia_string_replace_allocate(handle->conn,
+ smb_fname->base_name,
+ &name,
+ vfs_translate_to_unix);
if (!NT_STATUS_IS_OK(status)) {
errno = map_errno_from_nt_status(status);
return -1;
}
+ catia_smb_fname = synthetic_smb_fname(talloc_tos(),
+ name,
+ NULL,
+ NULL);
+ if (catia_smb_fname == NULL) {
+ TALLOC_FREE(name);
+ errno = ENOMEM;
+ return -1;
+ }
- ret = SMB_VFS_NEXT_CHOWN(handle, name, uid, gid);
+ ret = SMB_VFS_NEXT_CHOWN(handle, catia_smb_fname, uid, gid);
+ saved_errno = errno;
TALLOC_FREE(name);
-
+ TALLOC_FREE(catia_smb_fname);
+ errno = saved_errno;
return ret;
}
static int catia_lchown(vfs_handle_struct *handle,
- const char *path,
+ const struct smb_filename *smb_fname,
uid_t uid,
gid_t gid)
{
char *name = NULL;
NTSTATUS status;
int ret;
+ int saved_errno;
+ struct smb_filename *catia_smb_fname = NULL;
- status = catia_string_replace_allocate(handle->conn, path,
- &name, vfs_translate_to_unix);
+ status = catia_string_replace_allocate(handle->conn,
+ smb_fname->base_name,
+ &name,
+ vfs_translate_to_unix);
if (!NT_STATUS_IS_OK(status)) {
errno = map_errno_from_nt_status(status);
return -1;
}
+ catia_smb_fname = synthetic_smb_fname(talloc_tos(),
+ name,
+ NULL,
+ NULL);
+ if (catia_smb_fname == NULL) {
+ TALLOC_FREE(name);
+ errno = ENOMEM;
+ return -1;
+ }
- ret = SMB_VFS_NEXT_LCHOWN(handle, name, uid, gid);
+ ret = SMB_VFS_NEXT_LCHOWN(handle, catia_smb_fname, uid, gid);
+ saved_errno = errno;
TALLOC_FREE(name);
-
+ TALLOC_FREE(catia_smb_fname);
+ errno = saved_errno;
return ret;
}
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 82e15c8..b609d72 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -697,11 +697,18 @@ static int cephwrap_fchmod(struct vfs_handle_struct *handle, files_struct *fsp,
return -1;
}
-static int cephwrap_chown(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int cephwrap_chown(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
int result;
- DEBUG(10, ("[CEPH] chown(%p, %s, %d, %d)\n", handle, path, uid, gid));
- result = ceph_chown(handle->data, path, uid, gid);
+ DEBUG(10, ("[CEPH] chown(%p, %s, %d, %d)\n",
+ handle,
+ smb_fname->base_name,
+ uid,
+ gid));
+ result = ceph_chown(handle->data, smb_fname->base_name, uid, gid);
DEBUG(10, ("[CEPH] chown(...) = %d\n", result));
WRAP_RETURN(result);
}
@@ -722,12 +729,18 @@ static int cephwrap_fchown(struct vfs_handle_struct *handle, files_struct *fsp,
return result;
}
-static int cephwrap_lchown(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int cephwrap_lchown(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
int result;
-
- DEBUG(10, ("[CEPH] lchown(%p, %s, %d, %d)\n", handle, path, uid, gid));
- result = ceph_lchown(handle->data, path, uid, gid);
+ DEBUG(10, ("[CEPH] lchown(%p, %s, %d, %d)\n",
+ handle,
+ smb_fname->base_name,
+ uid,
+ gid));
+ result = ceph_lchown(handle->data, smb_fname->base_name, uid, gid);
DEBUG(10, ("[CEPH] lchown(...) = %d\n", result));
WRAP_RETURN(result);
}
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index bb55fac..4de965e 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1744,12 +1744,15 @@ static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t m
return result;
}
-static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int vfswrap_chown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
int result;
START_PROFILE(syscall_chown);
- result = chown(path, uid, gid);
+ result = chown(smb_fname->base_name, uid, gid);
END_PROFILE(syscall_chown);
return result;
}
@@ -1769,12 +1772,15 @@ static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t ui
#endif
}
-static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int vfswrap_lchown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
int result;
START_PROFILE(syscall_lchown);
- result = lchown(path, uid, gid);
+ result = lchown(smb_fname->base_name, uid, gid);
END_PROFILE(syscall_lchown);
return result;
}
diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c
index 3887e86..491e1ac 100644
--- a/source3/modules/vfs_fake_acls.c
+++ b/source3/modules/vfs_fake_acls.c
@@ -393,20 +393,33 @@ static int fake_acls_sys_acl_delete_def_file(vfs_handle_struct *handle, const ch
return ret;
}
-static int fake_acls_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int fake_acls_chown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
int ret;
uint8_t id_buf[4];
if (uid != -1) {
SIVAL(id_buf, 0, uid);
- ret = SMB_VFS_NEXT_SETXATTR(handle, path, FAKE_UID, id_buf, sizeof(id_buf), 0);
+ ret = SMB_VFS_NEXT_SETXATTR(handle,
+ smb_fname->base_name,
+ FAKE_UID,
+ id_buf,
+ sizeof(id_buf),
+ 0);
if (ret != 0) {
return ret;
}
}
if (gid != -1) {
SIVAL(id_buf, 0, gid);
- ret = SMB_VFS_NEXT_SETXATTR(handle, path, FAKE_GID, id_buf, sizeof(id_buf), 0);
+ ret = SMB_VFS_NEXT_SETXATTR(handle,
+ smb_fname->base_name,
+ FAKE_GID,
+ id_buf,
+ sizeof(id_buf),
+ 0);
if (ret != 0) {
return ret;
}
@@ -414,7 +427,10 @@ static int fake_acls_chown(vfs_handle_struct *handle, const char *path, uid_t ui
return 0;
}
-static int fake_acls_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int fake_acls_lchown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
int ret;
uint8_t id_buf[4];
@@ -428,14 +444,24 @@ static int fake_acls_lchown(vfs_handle_struct *handle, const char *path, uid_t u
* to.
*/
SIVAL(id_buf, 0, uid);
- ret = SMB_VFS_NEXT_SETXATTR(handle, path, FAKE_UID, id_buf, sizeof(id_buf), 0);
+ ret = SMB_VFS_NEXT_SETXATTR(handle,
+ smb_fname->base_name,
+ FAKE_UID,
+ id_buf,
+ sizeof(id_buf),
+ 0);
if (ret != 0) {
return ret;
}
}
if (gid != -1) {
SIVAL(id_buf, 0, gid);
- ret = SMB_VFS_NEXT_SETXATTR(handle, path, FAKE_GID, id_buf, sizeof(id_buf), 0);
+ ret = SMB_VFS_NEXT_SETXATTR(handle,
+ smb_fname->base_name,
+ FAKE_GID,
+ id_buf,
+ sizeof(id_buf),
+ 0);
if (ret != 0) {
return ret;
}
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 49cfa0c..73b5f3a 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -2545,16 +2545,17 @@ static int fruit_chmod(vfs_handle_struct *handle,
}
--
Samba Shared Repository
More information about the samba-cvs
mailing list