[PATCH] Always read from /dev/urandom

Volker Lendecke Volker.Lendecke at SerNet.DE
Mon Oct 12 18:25:41 UTC 2015


Hi!

When running smbd with open/close traffic, our md4 code starts to show
up pretty high in profiles. This was due to the random number generation
in smbXsrv_open.c and other places. Instead of tuning our random number
generator, I decided to try just removing it. It turned out to be pretty
successful.

I know this might be controversial, so try the test prog yourself!

Review&comments appreciated!

Thanks,

Volker

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From df3915e4c04fca64aac288ce65bb735013e0bdf4 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 12 Oct 2015 15:57:34 +0200
Subject: [PATCH 1/3] lib: Move sys_rw* to lib/util

genrand.c will require it soon
---
 lib/util/sys_rw.c                            | 101 +++++++++++++++++++++++
 lib/util/sys_rw.h                            |  36 +++++++++
 lib/util/sys_rw_data.c                       | 117 +++++++++++++++++++++++++++
 lib/util/sys_rw_data.h                       |  34 ++++++++
 lib/util/wscript_build                       |   6 ++
 source3/lib/ctdbd_conn.c                     |   2 +-
 source3/lib/recvfile.c                       |   2 +-
 source3/lib/sys_rw.c                         | 101 -----------------------
 source3/lib/sys_rw.h                         |  36 ---------
 source3/lib/sys_rw_data.c                    | 117 ---------------------------
 source3/lib/sys_rw_data.h                    |  34 --------
 source3/lib/util.c                           |   4 +-
 source3/lib/util_file.c                      |   2 +-
 source3/lib/util_sock.c                      |   4 +-
 source3/lib/util_transfer_file.c             |   2 +-
 source3/libsmb/unexpected.c                  |   2 +-
 source3/modules/vfs_aio_fork.c               |   4 +-
 source3/modules/vfs_aio_linux.c              |   2 +-
 source3/modules/vfs_aio_posix.c              |   2 +-
 source3/modules/vfs_cacheprime.c             |   2 +-
 source3/modules/vfs_default.c                |   2 +-
 source3/modules/vfs_fruit.c                  |   2 +-
 source3/modules/vfs_glusterfs.c              |   2 +-
 source3/modules/vfs_preopen.c                |   2 +-
 source3/modules/vfs_smb_traffic_analyzer.c   |   2 +-
 source3/nmbd/asyncdns.c                      |   2 +-
 source3/printing/print_cups.c                |   2 +-
 source3/printing/printing.c                  |   2 +-
 source3/rpc_server/samr/srv_samr_chgpasswd.c |   2 +-
 source3/smbd/notify_inotify.c                |   2 +-
 source3/smbd/process.c                       |   2 +-
 source3/smbd/reply.c                         |   2 +-
 source3/smbd/scavenger.c                     |   2 +-
 source3/smbd/smb2_read.c                     |   2 +-
 source3/torture/torture.c                    |   2 +-
 source3/utils/smbfilter.c                    |   2 +-
 source3/winbindd/winbindd_dual.c             |   4 +-
 source3/wscript_build                        |   5 --
 38 files changed, 326 insertions(+), 325 deletions(-)
 create mode 100644 lib/util/sys_rw.c
 create mode 100644 lib/util/sys_rw.h
 create mode 100644 lib/util/sys_rw_data.c
 create mode 100644 lib/util/sys_rw_data.h
 delete mode 100644 source3/lib/sys_rw.c
 delete mode 100644 source3/lib/sys_rw.h
 delete mode 100644 source3/lib/sys_rw_data.c
 delete mode 100644 source3/lib/sys_rw_data.h

diff --git a/lib/util/sys_rw.c b/lib/util/sys_rw.c
new file mode 100644
index 0000000..f625066
--- /dev/null
+++ b/lib/util/sys_rw.c
@@ -0,0 +1,101 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Jeremy Allison  1998-2005
+ * Copyright (C) Timur Bakeyev        2005
+ * Copyright (C) Bjoern Jacke    2006-2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "lib/util/sys_rw.h"
+
+/*******************************************************************
+A read wrapper that will deal with EINTR/EWOULDBLOCK
+********************************************************************/
+
+ssize_t sys_read(int fd, void *buf, size_t count)
+{
+	ssize_t ret;
+
+	do {
+		ret = read(fd, buf, count);
+	} while (ret == -1 && (errno == EINTR || errno == EAGAIN ||
+			       errno == EWOULDBLOCK));
+
+	return ret;
+}
+
+/*******************************************************************
+A write wrapper that will deal with EINTR/EWOULDBLOCK.
+********************************************************************/
+
+ssize_t sys_write(int fd, const void *buf, size_t count)
+{
+	ssize_t ret;
+
+	do {
+		ret = write(fd, buf, count);
+	} while (ret == -1 && (errno == EINTR || errno == EAGAIN ||
+			       errno == EWOULDBLOCK));
+
+	return ret;
+}
+
+/*******************************************************************
+A writev wrapper that will deal with EINTR.
+********************************************************************/
+
+ssize_t sys_writev(int fd, const struct iovec *iov, int iovcnt)
+{
+	ssize_t ret;
+
+	do {
+		ret = writev(fd, iov, iovcnt);
+	} while (ret == -1 && (errno == EINTR || errno == EAGAIN ||
+			       errno == EWOULDBLOCK));
+
+	return ret;
+}
+
+/*******************************************************************
+A pread wrapper that will deal with EINTR
+********************************************************************/
+
+ssize_t sys_pread(int fd, void *buf, size_t count, off_t off)
+{
+	ssize_t ret;
+
+	do {
+		ret = pread(fd, buf, count, off);
+	} while (ret == -1 && errno == EINTR);
+	return ret;
+}
+
+/*******************************************************************
+A write wrapper that will deal with EINTR
+********************************************************************/
+
+ssize_t sys_pwrite(int fd, const void *buf, size_t count, off_t off)
+{
+	ssize_t ret;
+
+	do {
+		ret = pwrite(fd, buf, count, off);
+	} while (ret == -1 && errno == EINTR);
+	return ret;
+}
diff --git a/lib/util/sys_rw.h b/lib/util/sys_rw.h
new file mode 100644
index 0000000..ee1584e
--- /dev/null
+++ b/lib/util/sys_rw.h
@@ -0,0 +1,36 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Jeremy Allison  1998-2005
+ * Copyright (C) Timur Bakeyev        2005
+ * Copyright (C) Bjoern Jacke    2006-2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIB_SYS_RW_H__
+#define __LIB_SYS_RW_H__
+
+#include <unistd.h>
+
+struct iovec;
+
+ssize_t sys_read(int fd, void *buf, size_t count);
+ssize_t sys_write(int fd, const void *buf, size_t count);
+ssize_t sys_writev(int fd, const struct iovec *iov, int iovcnt);
+ssize_t sys_pread(int fd, void *buf, size_t count, off_t off);
+ssize_t sys_pwrite(int fd, const void *buf, size_t count, off_t off);
+
+#endif
diff --git a/lib/util/sys_rw_data.c b/lib/util/sys_rw_data.c
new file mode 100644
index 0000000..de71716
--- /dev/null
+++ b/lib/util/sys_rw_data.c
@@ -0,0 +1,117 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Jeremy Allison  1998-2005
+ * Copyright (C) Timur Bakeyev        2005
+ * Copyright (C) Bjoern Jacke    2006-2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "lib/util/sys_rw_data.h"
+#include "lib/util/sys_rw.h"
+#include "lib/util/iov_buf.h"
+
+/****************************************************************************
+ Write all data from an iov array
+ NB. This can be called with a non-socket fd, don't add dependencies
+ on socket calls.
+****************************************************************************/
+
+ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
+{
+	ssize_t to_send;
+	ssize_t thistime;
+	size_t sent;
+	struct iovec iov_copy[iovcnt];
+	struct iovec *iov;
+
+	to_send = iov_buflen(orig_iov, iovcnt);
+	if (to_send == -1) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	thistime = sys_writev(fd, orig_iov, iovcnt);
+	if ((thistime <= 0) || (thistime == to_send)) {
+		return thistime;
+	}
+	sent = thistime;
+
+	/*
+	 * We could not send everything in one call. Make a copy of iov that
+	 * we can mess with.
+	 */
+
+	memcpy(iov_copy, orig_iov, sizeof(struct iovec) * iovcnt);
+	iov = iov_copy;
+
+	while (sent < to_send) {
+		bool ok;
+
+		ok = iov_advance(&iov, &iovcnt, thistime);
+		if (!ok) {
+			errno = EIO;
+			return -1;
+		}
+
+		thistime = sys_writev(fd, iov, iovcnt);
+		if (thistime <= 0) {
+			break;
+		}
+		sent += thistime;
+	}
+
+	return sent;
+}
+
+/****************************************************************************
+ Write data to a fd.
+ NB. This can be called with a non-socket fd, don't add dependencies
+ on socket calls.
+****************************************************************************/
+
+ssize_t write_data(int fd, const void *buffer, size_t n)
+{
+	struct iovec iov;
+
+	iov.iov_base = discard_const_p(void, buffer);
+	iov.iov_len = n;
+	return write_data_iov(fd, &iov, 1);
+}
+
+/*
+ * Blocking read n bytes from a fd
+ */
+
+ssize_t read_data(int fd, void *buffer, size_t n)
+{
+	ssize_t nread;
+
+	nread = 0;
+
+	while (nread < n) {
+		ssize_t ret;
+		ret = sys_read(fd, ((char *)buffer) + nread, n - nread);
+		if (ret <= 0) {
+			return ret;
+		}
+		nread += ret;
+	}
+
+	return nread;
+}
diff --git a/lib/util/sys_rw_data.h b/lib/util/sys_rw_data.h
new file mode 100644
index 0000000..bda3795
--- /dev/null
+++ b/lib/util/sys_rw_data.h
@@ -0,0 +1,34 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Jeremy Allison  1998-2005
+ * Copyright (C) Timur Bakeyev        2005
+ * Copyright (C) Bjoern Jacke    2006-2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIB_SYS_RW_DATA_H__
+#define __LIB_SYS_RW_DATA_H__
+
+#include <unistd.h>
+
+struct iovec;
+
+ssize_t write_data_iov(int fd, const struct iovec *iov, int iovcnt);
+ssize_t write_data(int fd, const void *buffer, size_t n);
+ssize_t read_data(int fd, void *buffer, size_t n);
+
+#endif
diff --git a/lib/util/wscript_build b/lib/util/wscript_build
index e3bf073..2b48685 100755
--- a/lib/util/wscript_build
+++ b/lib/util/wscript_build
@@ -181,3 +181,9 @@ if not bld.env.SAMBA_UTIL_CORE_ONLY:
                       source='iov_buf.c',
                       local_include=False,
                       private_library=True)
+
+    bld.SAMBA3_LIBRARY('sys_rw',
+                       source='sys_rw.c sys_rw_data.c',
+                       deps='replace iov_buf',
+                       local_include=False,
+                       private_library=True)
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index 9e598ac..c7c6356 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -23,7 +23,7 @@
 #include "serverid.h"
 #include "ctdbd_conn.h"
 #include "system/select.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw_data.h"
 #include "lib/util/iov_buf.h"
 
 #include "messages.h"
diff --git a/source3/lib/recvfile.c b/source3/lib/recvfile.c
index 403d5e8..e1eb241 100644
--- a/source3/lib/recvfile.c
+++ b/source3/lib/recvfile.c
@@ -25,7 +25,7 @@
 
 #include "includes.h"
 #include "system/filesys.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 
 /* Do this on our own in TRANSFER_BUF_SIZE chunks.
  * It's safe to make direct syscalls to lseek/write here
diff --git a/source3/lib/sys_rw.c b/source3/lib/sys_rw.c
deleted file mode 100644
index 6d8f149..0000000
--- a/source3/lib/sys_rw.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Samba system utilities
- * Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Jeremy Allison  1998-2005
- * Copyright (C) Timur Bakeyev        2005
- * Copyright (C) Bjoern Jacke    2006-2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "replace.h"
-#include "system/filesys.h"
-#include "lib/sys_rw.h"
-
-/*******************************************************************
-A read wrapper that will deal with EINTR/EWOULDBLOCK
-********************************************************************/
-
-ssize_t sys_read(int fd, void *buf, size_t count)
-{
-	ssize_t ret;
-
-	do {
-		ret = read(fd, buf, count);
-	} while (ret == -1 && (errno == EINTR || errno == EAGAIN ||
-			       errno == EWOULDBLOCK));
-
-	return ret;
-}
-
-/*******************************************************************
-A write wrapper that will deal with EINTR/EWOULDBLOCK.
-********************************************************************/
-
-ssize_t sys_write(int fd, const void *buf, size_t count)
-{
-	ssize_t ret;
-
-	do {
-		ret = write(fd, buf, count);
-	} while (ret == -1 && (errno == EINTR || errno == EAGAIN ||
-			       errno == EWOULDBLOCK));
-
-	return ret;
-}
-
-/*******************************************************************
-A writev wrapper that will deal with EINTR.
-********************************************************************/
-
-ssize_t sys_writev(int fd, const struct iovec *iov, int iovcnt)
-{
-	ssize_t ret;
-
-	do {
-		ret = writev(fd, iov, iovcnt);
-	} while (ret == -1 && (errno == EINTR || errno == EAGAIN ||
-			       errno == EWOULDBLOCK));
-
-	return ret;
-}
-
-/*******************************************************************
-A pread wrapper that will deal with EINTR
-********************************************************************/
-
-ssize_t sys_pread(int fd, void *buf, size_t count, off_t off)
-{
-	ssize_t ret;
-
-	do {
-		ret = pread(fd, buf, count, off);
-	} while (ret == -1 && errno == EINTR);
-	return ret;
-}
-
-/*******************************************************************
-A write wrapper that will deal with EINTR
-********************************************************************/
-
-ssize_t sys_pwrite(int fd, const void *buf, size_t count, off_t off)
-{
-	ssize_t ret;
-
-	do {
-		ret = pwrite(fd, buf, count, off);
-	} while (ret == -1 && errno == EINTR);
-	return ret;
-}
diff --git a/source3/lib/sys_rw.h b/source3/lib/sys_rw.h
deleted file mode 100644
index ee1584e..0000000
--- a/source3/lib/sys_rw.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Samba system utilities
- * Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Jeremy Allison  1998-2005
- * Copyright (C) Timur Bakeyev        2005
- * Copyright (C) Bjoern Jacke    2006-2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LIB_SYS_RW_H__
-#define __LIB_SYS_RW_H__
-
-#include <unistd.h>
-
-struct iovec;
-
-ssize_t sys_read(int fd, void *buf, size_t count);
-ssize_t sys_write(int fd, const void *buf, size_t count);
-ssize_t sys_writev(int fd, const struct iovec *iov, int iovcnt);
-ssize_t sys_pread(int fd, void *buf, size_t count, off_t off);
-ssize_t sys_pwrite(int fd, const void *buf, size_t count, off_t off);
-
-#endif
diff --git a/source3/lib/sys_rw_data.c b/source3/lib/sys_rw_data.c
deleted file mode 100644
index e3f934d..0000000
--- a/source3/lib/sys_rw_data.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Samba system utilities
- * Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Jeremy Allison  1998-2005
- * Copyright (C) Timur Bakeyev        2005
- * Copyright (C) Bjoern Jacke    2006-2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "replace.h"
-#include "system/filesys.h"
-#include "lib/sys_rw_data.h"
-#include "lib/sys_rw.h"
-#include "lib/util/iov_buf.h"
-
-/****************************************************************************
- Write all data from an iov array
- NB. This can be called with a non-socket fd, don't add dependencies
- on socket calls.
-****************************************************************************/
-
-ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
-{
-	ssize_t to_send;
-	ssize_t thistime;
-	size_t sent;
-	struct iovec iov_copy[iovcnt];
-	struct iovec *iov;
-
-	to_send = iov_buflen(orig_iov, iovcnt);
-	if (to_send == -1) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	thistime = sys_writev(fd, orig_iov, iovcnt);
-	if ((thistime <= 0) || (thistime == to_send)) {
-		return thistime;
-	}
-	sent = thistime;
-
-	/*
-	 * We could not send everything in one call. Make a copy of iov that
-	 * we can mess with.
-	 */
-
-	memcpy(iov_copy, orig_iov, sizeof(struct iovec) * iovcnt);
-	iov = iov_copy;
-
-	while (sent < to_send) {
-		bool ok;
-
-		ok = iov_advance(&iov, &iovcnt, thistime);
-		if (!ok) {
-			errno = EIO;
-			return -1;
-		}
-
-		thistime = sys_writev(fd, iov, iovcnt);
-		if (thistime <= 0) {
-			break;
-		}
-		sent += thistime;
-	}
-
-	return sent;
-}
-
-/****************************************************************************
- Write data to a fd.
- NB. This can be called with a non-socket fd, don't add dependencies
- on socket calls.
-****************************************************************************/
-
-ssize_t write_data(int fd, const void *buffer, size_t n)
-{
-	struct iovec iov;
-
-	iov.iov_base = discard_const_p(void, buffer);
-	iov.iov_len = n;
-	return write_data_iov(fd, &iov, 1);
-}
-
-/*
- * Blocking read n bytes from a fd
- */
-
-ssize_t read_data(int fd, void *buffer, size_t n)
-{
-	ssize_t nread;
-
-	nread = 0;
-
-	while (nread < n) {
-		ssize_t ret;
-		ret = sys_read(fd, ((char *)buffer) + nread, n - nread);
-		if (ret <= 0) {
-			return ret;
-		}
-		nread += ret;
-	}
-
-	return nread;
-}
diff --git a/source3/lib/sys_rw_data.h b/source3/lib/sys_rw_data.h
deleted file mode 100644
index bda3795..0000000
--- a/source3/lib/sys_rw_data.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Samba system utilities
- * Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Jeremy Allison  1998-2005
- * Copyright (C) Timur Bakeyev        2005
- * Copyright (C) Bjoern Jacke    2006-2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LIB_SYS_RW_DATA_H__
-#define __LIB_SYS_RW_DATA_H__
-
-#include <unistd.h>
-
-struct iovec;
-
-ssize_t write_data_iov(int fd, const struct iovec *iov, int iovcnt);
-ssize_t write_data(int fd, const void *buffer, size_t n);
-ssize_t read_data(int fd, void *buffer, size_t n);
-
-#endif
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 2ac4dbd..f633575 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -30,8 +30,8 @@
 #include "messages.h"
 #include "libcli/security/security.h"
 #include "serverid.h"
-#include "lib/sys_rw.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw.h"
+#include "lib/util/sys_rw_data.h"
 #include "lib/util/util_process.h"
 
 #ifdef HAVE_SYS_PRCTL_H
diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c
index a603f01..5584d91 100644
--- a/source3/lib/util_file.c
+++ b/source3/lib/util_file.c
@@ -18,7 +18,7 @@
  */
 
 #include "includes.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 
 /**
  Load from a pipe into memory.
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index cb57f84..2939b4f 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -28,8 +28,8 @@
 #include "../lib/util/tevent_unix.h"
 #include "../lib/util/tevent_ntstatus.h"
 #include "../lib/tsocket/tsocket.h"
-#include "lib/sys_rw.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw.h"
+#include "lib/util/sys_rw_data.h"
 
 const char *client_addr(int fd, char *addr, size_t addrlen)
 {
diff --git a/source3/lib/util_transfer_file.c b/source3/lib/util_transfer_file.c
index 91f4f6f..5653906 100644
--- a/source3/lib/util_transfer_file.c
+++ b/source3/lib/util_transfer_file.c
@@ -22,7 +22,7 @@
 
 #include <includes.h>
 #include "transfer_file.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 
 /****************************************************************************
  Transfer some data between two fd's.
diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c
index 013d798..27d21b6 100644
--- a/source3/libsmb/unexpected.c
+++ b/source3/libsmb/unexpected.c
@@ -22,7 +22,7 @@
 #include "../lib/util/tevent_ntstatus.h"
 #include "lib/tsocket/tsocket.h"
 #include "libsmb/nmblib.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 
 static const char *nmbd_socket_dir(void)
 {
diff --git a/source3/modules/vfs_aio_fork.c b/source3/modules/vfs_aio_fork.c
index 5b398b2e..7fca3d1 100644
--- a/source3/modules/vfs_aio_fork.c
+++ b/source3/modules/vfs_aio_fork.c
@@ -26,8 +26,8 @@
 #include "smbd/globals.h"
 #include "lib/async_req/async_sock.h"
 #include "lib/util/tevent_unix.h"
-#include "lib/sys_rw.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw.h"
+#include "lib/util/sys_rw_data.h"
 #include "lib/msghdr.h"
 
 #if !defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && !defined(HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS)
diff --git a/source3/modules/vfs_aio_linux.c b/source3/modules/vfs_aio_linux.c
index db5f075..74ebb3c 100644
--- a/source3/modules/vfs_aio_linux.c
+++ b/source3/modules/vfs_aio_linux.c
@@ -24,7 +24,7 @@
 #include "smbd/smbd.h"
 #include "smbd/globals.h"
 #include "lib/util/tevent_unix.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 #include <sys/eventfd.h>
 #include <libaio.h>
 
diff --git a/source3/modules/vfs_aio_posix.c b/source3/modules/vfs_aio_posix.c
index ef5f706..bca69b4 100644
--- a/source3/modules/vfs_aio_posix.c
+++ b/source3/modules/vfs_aio_posix.c
@@ -24,7 +24,7 @@
 #include "smbd/smbd.h"
 #include "smbd/globals.h"
 #include "lib/util/tevent_unix.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 #include <aio.h>
 
 /* The signal we'll use to signify aio done. */
diff --git a/source3/modules/vfs_cacheprime.c b/source3/modules/vfs_cacheprime.c
index e90e09a..cb8b328 100644
--- a/source3/modules/vfs_cacheprime.c
+++ b/source3/modules/vfs_cacheprime.c
@@ -17,7 +17,7 @@
 
 #include "includes.h"
 #include "smbd/smbd.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 
 /* Cache priming module.
  *
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 9ea630a..bbe8cca 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -32,7 +32,7 @@
 #include "lib/util/tevent_unix.h"
 #include "lib/asys/asys.h"
 #include "lib/util/tevent_ntstatus.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 8393366..25a86c1 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -29,7 +29,7 @@
 #include "messages.h"
 #include "libcli/security/security.h"
 #include "../libcli/smb/smb2_create_ctx.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 #include "lib/util/tevent_ntstatus.h"
 
 /*
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index a66887d..cf8066e 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -43,7 +43,7 @@
 #include "lib/util/tevent_unix.h"
 #include "lib/tevent/tevent_internal.h"
 #include "smbd/globals.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 
 #define DEFAULT_VOLFILE_SERVER "localhost"
 
diff --git a/source3/modules/vfs_preopen.c b/source3/modules/vfs_preopen.c
index c83d312..b67aad8 100644
--- a/source3/modules/vfs_preopen.c
+++ b/source3/modules/vfs_preopen.c
@@ -21,7 +21,7 @@
 #include "includes.h"
 #include "system/filesys.h"
 #include "smbd/smbd.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw_data.h"
 
 struct preopen_state;
 
diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c
index 0208cde..f5c39ad 100644
--- a/source3/modules/vfs_smb_traffic_analyzer.c
+++ b/source3/modules/vfs_smb_traffic_analyzer.c
@@ -29,7 +29,7 @@
 #include "../librpc/gen_ndr/ndr_netlogon.h"
 #include "auth.h"
 #include "../lib/tsocket/tsocket.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw_data.h"
 
 /* abstraction for the send_over_network function */
 enum sock_type {INTERNET_SOCKET = 0, UNIX_DOMAIN_SOCKET};
diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c
index 66e3674..b4532fa 100644
--- a/source3/nmbd/asyncdns.c
+++ b/source3/nmbd/asyncdns.c
@@ -19,7 +19,7 @@
 
 #include "includes.h"
 #include "nmbd/nmbd.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw_data.h"
 
 /***************************************************************************
   Add a DNS result to the name cache.
diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c
index 110711c..756d67a 100644
--- a/source3/printing/print_cups.c
+++ b/source3/printing/print_cups.c
@@ -26,7 +26,7 @@
 #include "printing.h"
 #include "printing/pcap.h"
 #include "librpc/gen_ndr/ndr_printcap.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 
 #ifdef HAVE_CUPS
 #include <cups/cups.h>
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 4a2ffd1..e7e6c6d 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -36,7 +36,7 @@
 #include "messages.h"
 #include "util_tdb.h"
 #include "lib/param/loadparm.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw_data.h"
 
 extern struct current_user current_user;
 extern userdom_struct current_user_info;
diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c
index ad710bb..bfb7af6 100644
--- a/source3/rpc_server/samr/srv_samr_chgpasswd.c
+++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c
@@ -54,7 +54,7 @@
 #include "rpc_server/samr/srv_samr_util.h"
 #include "passdb.h"
 #include "auth.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 
 #ifndef ALLOW_CHANGE_PASSWORD
 #if (defined(HAVE_TERMIOS_H) && defined(HAVE_DUP2) && defined(HAVE_SETSID))
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index 8f47124..78fb654 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -24,7 +24,7 @@
 #include "includes.h"
 #include "../librpc/gen_ndr/notify.h"
 #include "smbd/smbd.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw_data.h"
 
 #include <sys/inotify.h>
 
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index b491b31..c99c75e 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -39,7 +39,7 @@
 #include "../libcli/security/dom_sid.h"
 #include "../libcli/security/security_token.h"
 #include "lib/id_cache.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw_data.h"
 #include "serverid.h"
 #include "system/threads.h"
 
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index b1b91e1..bebb789 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -43,7 +43,7 @@
 #include "../lib/tsocket/tsocket.h"
 #include "lib/tevent_wait.h"
 #include "libcli/smb/smb_signing.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw_data.h"
 
 /****************************************************************************
  Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
diff --git a/source3/smbd/scavenger.c b/source3/smbd/scavenger.c
index baf71d8..ea0a894 100644
--- a/source3/smbd/scavenger.c
+++ b/source3/smbd/scavenger.c
@@ -26,7 +26,7 @@
 #include "smbd/scavenger.h"
 #include "locking/proto.h"
 #include "lib/util/util_process.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_SCAVENGER
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index 03cd54b..89527f3 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -26,7 +26,7 @@
 #include "libcli/security/security.h"
 #include "../lib/util/tevent_ntstatus.h"
 #include "rpc_server/srv_pipe_hnd.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw_data.h"
 
 static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
 					      struct tevent_context *ev,
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 914caf8..21d2dd2 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -41,7 +41,7 @@
 #include "util_tdb.h"
 #include "../libcli/smb/read_smb.h"
 #include "../libcli/smb/smbXcli_base.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw_data.h"
 
 extern char *optarg;
 extern int optind;
diff --git a/source3/utils/smbfilter.c b/source3/utils/smbfilter.c
index 9b871be..9068448 100644
--- a/source3/utils/smbfilter.c
+++ b/source3/utils/smbfilter.c
@@ -22,7 +22,7 @@
 #include "system/select.h"
 #include "../lib/util/select.h"
 #include "libsmb/nmblib.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw_data.h"
 
 #define SECURITY_MASK 0
 #define SECURITY_SET  0
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 213462e..17a89a7 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -38,8 +38,8 @@
 #include "messages.h"
 #include "../lib/util/tevent_unix.h"
 #include "lib/param/loadparm.h"
-#include "lib/sys_rw.h"
-#include "lib/sys_rw_data.h"
+#include "lib/util/sys_rw.h"
+#include "lib/util/sys_rw_data.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
diff --git a/source3/wscript_build b/source3/wscript_build
index 48fb144..dc26fb3 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -247,11 +247,6 @@ bld.SAMBA3_SUBSYSTEM('KRBCLIENT',
                      source='libads/kerberos.c libads/ads_status.c',
                      public_deps='krb5samba k5crypto gssapi LIBTSOCKET CLDAP LIBNMB')
 
-bld.SAMBA3_LIBRARY('sys_rw',
-                   source='lib/sys_rw.c lib/sys_rw_data.c',
-                   deps='replace iov_buf',
-                   private_library=True)
-
 bld.SAMBA3_SUBSYSTEM('samba3util',
                    source='''lib/system.c
                    lib/sendfile.c
-- 
1.9.1


From 9b80eca887bbc7e705568b307f4088d9986169c1 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 3 Oct 2015 00:27:22 +0200
Subject: [PATCH 2/3] lib: Add a little tool to perftest
 generate_random_buffer()

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 lib/util/tests/genrandperf.c | 39 +++++++++++++++++++++++++++++++++++++++
 lib/util/wscript_build       |  6 ++++++
 2 files changed, 45 insertions(+)
 create mode 100644 lib/util/tests/genrandperf.c

diff --git a/lib/util/tests/genrandperf.c b/lib/util/tests/genrandperf.c
new file mode 100644
index 0000000..143b3fe
--- /dev/null
+++ b/lib/util/tests/genrandperf.c
@@ -0,0 +1,39 @@
+/*
+   Unix SMB/CIFS implementation.
+   local testing of random data routines.
+   Copyright (C) Volker Lendecke <vl at samba.org> 2015
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "lib/util/genrand.h"
+
+int main(int argc, const char *argv[])
+{
+	int i, num;
+	uint64_t val;
+
+	if (argc != 2) {
+		fprintf(stderr, "genrandper <num>\n");
+		exit(1);
+	}
+	num = atoi(argv[1]);
+
+	for(i=0; i<num; i++) {
+		generate_random_buffer((uint8_t *)&val, sizeof(val));
+	}
+	printf("%"PRIu64"\n", val);
+	return 0;
+}
diff --git a/lib/util/wscript_build b/lib/util/wscript_build
index 2b48685..2c4d093 100755
--- a/lib/util/wscript_build
+++ b/lib/util/wscript_build
@@ -88,6 +88,12 @@ if not bld.env.SAMBA_UTIL_CORE_ONLY:
                       local_include=False,
                       private_library=True)
 
+    bld.SAMBA_BINARY('genrandperf',
+                     source='tests/genrandperf.c',
+                     deps='genrand replace',
+                     local_include=False,
+                     install=False)
+
     bld.SAMBA_LIBRARY('samba-util',
                   source='''talloc_stack.c smb_threads.c
                     rbtree.c rfc1738.c become_daemon.c system.c select.c getpass.c
-- 
1.9.1


From b9df1cb063d57df037200b9123fb7b5eca76573b Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 2 Oct 2015 00:27:22 +0200
Subject: [PATCH 3/3] Rely on /dev/urandom

This removes quite a bit of code. All reasonable systems have /dev/urandom
these days. Linux, Solaris and the BSDs do.  In case we find a system
without /dev/urandom, we will have to go hunting in other libraries.

The main reason for this is speed: On Ubuntu 14.04 doing direct reads from
/dev/urandom is 2-3 times faster than our md4 based code. On virtualized
FreeBSD 10 the difference is even larger.

My first approach was to use fopen/fread. It was even faster, but less
than twice as fast. So I thought we could save the additional complexity
when having to deal with throwing away buffers when forking and the
additional memory footprint per process.

With this simple generate_random_buffer it will be easier to adapt new
syscalls to get randomness.
---
 lib/util/genrand.c              | 259 +++-------------------------------------
 lib/util/genrand.h              |  11 --
 lib/util/tests/genrand.c        |  12 --
 lib/util/wscript_build          |   2 +-
 source3/lib/util.c              |   6 -
 source3/passdb/secrets.c        |  29 -----
 source4/param/secrets.c         |  53 --------
 source4/param/secrets.h         |   8 --
 source4/smbd/process_standard.c |   6 -
 source4/smbd/server.c           |   6 -
 10 files changed, 17 insertions(+), 375 deletions(-)

diff --git a/lib/util/genrand.c b/lib/util/genrand.c
index 4473433..a775535 100644
--- a/lib/util/genrand.c
+++ b/lib/util/genrand.c
@@ -21,268 +21,41 @@
 
 #include "replace.h"
 #include "system/filesys.h"
-#include "../lib/crypto/crypto.h"
 #include "lib/util/genrand.h"
+#include "sys_rw_data.h"
 #include "lib/util/blocking.h"
-#include "lib/util/time_basic.h"
-#include "lib/util/byteorder.h"
-
-/**
- * @file
- * @brief Random number generation
- */
-
-static unsigned char hash[258];
-static uint32_t counter;
-
-static bool done_reseed = false;
-static unsigned int bytes_since_reseed = 0;
 
 static int urand_fd = -1;
 
-static void (*reseed_callback)(void *userdata, int *newseed);
-static void *reseed_callback_userdata = NULL;
-
-/**
- Copy any user given reseed data.
-**/
-
-_PUBLIC_ void set_rand_reseed_callback(void (*fn)(void *, int *), void *userdata)
-{
-	reseed_callback = fn;
-	reseed_callback_userdata = userdata;
-	set_need_random_reseed();
-}
-
-/**
- * Tell the random number generator it needs to reseed.
- */
-_PUBLIC_ void set_need_random_reseed(void)
+static void open_urandom(void)
 {
-	done_reseed = false;
-	bytes_since_reseed = 0;
-}
-
-static void get_rand_reseed_data(int *reseed_data)
-{
-	if (reseed_callback) {
-		reseed_callback(reseed_callback_userdata, reseed_data);
-	} else {
-		*reseed_data = 0;
-	}
-}
-
-/****************************************************************
- Setup the seed.
-*****************************************************************/
-
-static void seed_random_stream(unsigned char *seedval, size_t seedlen)
-{
-	unsigned char j = 0;
-	size_t ind;
-
-	for (ind = 0; ind < 256; ind++)
-		hash[ind] = (unsigned char)ind;
-
-	for( ind = 0; ind < 256; ind++) {
-		unsigned char tc;
-
-		j += (hash[ind] + seedval[ind%seedlen]);
-
-		tc = hash[ind];
-		hash[ind] = hash[j];
-		hash[j] = tc;
-	}
-
-	hash[256] = 0;
-	hash[257] = 0;
-}
-
-/****************************************************************
- Get datasize bytes worth of random data.
-*****************************************************************/
-
-static void get_random_stream(unsigned char *data, size_t datasize)
-{
-	unsigned char index_i = hash[256];
-	unsigned char index_j = hash[257];
-	size_t ind;
-
-	for( ind = 0; ind < datasize; ind++) {
-		unsigned char tc;
-		unsigned char t;
-
-		index_i++;
-		index_j += hash[index_i];
-
-		tc = hash[index_i];
-		hash[index_i] = hash[index_j];
-		hash[index_j] = tc;
-
-		t = hash[index_i] + hash[index_j];
-		data[ind] = hash[t];
-	}
-
-	hash[256] = index_i;
-	hash[257] = index_j;
-}
-
-/****************************************************************
- Get a 16 byte hash from the contents of a file.
-
- Note that the hash is initialised, because the extra entropy is not
- worth the valgrind pain.
-*****************************************************************/
-
-static void do_filehash(const char *fname, unsigned char *the_hash)
-{
-	unsigned char buf[1011]; /* deliberate weird size */
-	unsigned char tmp_md4[16];
-	int fd, n;
-
-	ZERO_STRUCT(tmp_md4);
-
-	fd = open(fname,O_RDONLY,0);
-	if (fd == -1)
+	if (urand_fd != -1) {
 		return;
-
-	while ((n = read(fd, (char *)buf, sizeof(buf))) > 0) {
-		mdfour(tmp_md4, buf, n);
-		for (n=0;n<16;n++)
-			the_hash[n] ^= tmp_md4[n];
-	}
-	close(fd);
-}
-
-/**************************************************************
- Try and get a good random number seed. Try a number of
- different factors. Firstly, try /dev/urandom - use if exists.
-
- We use /dev/urandom as a read of /dev/random can block if
- the entropy pool dries up. This leads clients to timeout
- or be very slow on connect.
-
- If we can't use /dev/urandom then seed the stream random generator
- above...
-**************************************************************/
-
-static int do_reseed(int fd)
-{
-	unsigned char seed_inbuf[40];
-	uint32_t v1, v2; struct timeval tval; pid_t mypid;
-	int reseed_data = 0;
-
-	if (fd == -1) {
-		fd = open( "/dev/urandom", O_RDONLY,0);
-		if (fd != -1) {
-			smb_set_close_on_exec(fd);
-		}
-	}
-	if (fd != -1
-	    && (read(fd, seed_inbuf, sizeof(seed_inbuf)) == sizeof(seed_inbuf))) {
-		seed_random_stream(seed_inbuf, sizeof(seed_inbuf));
-		return fd;
 	}
-
-	/* Add in some secret file contents */
-
-	do_filehash("/etc/shadow", &seed_inbuf[0]);
-
-	/*
-	 * Add the counter, time of day, and pid.
-	 */
-
-	GetTimeOfDay(&tval);
-	mypid = getpid();
-	v1 = (counter++) + mypid + tval.tv_sec;
-	v2 = (counter++) * mypid + tval.tv_usec;
-
-	SIVAL(seed_inbuf, 32, v1 ^ IVAL(seed_inbuf, 32));
-	SIVAL(seed_inbuf, 36, v2 ^ IVAL(seed_inbuf, 36));
-
-	/*
-	 * Add any user-given reseed data.
-	 */
-
-	get_rand_reseed_data(&reseed_data);
-	if (reseed_data) {
-		size_t i;
-		for (i = 0; i < sizeof(seed_inbuf); i++)
-			seed_inbuf[i] ^= ((char *)(&reseed_data))[i % sizeof(reseed_data)];
+	urand_fd = open( "/dev/urandom", O_RDONLY,0);
+	if (urand_fd == -1) {
+		abort();
 	}
-
-	seed_random_stream(seed_inbuf, sizeof(seed_inbuf));
-
-	return -1;
+	smb_set_close_on_exec(urand_fd);
 }
 
-/**
- Interface to the (hopefully) good crypto random number generator.
- Will use our internal PRNG if more than 40 bytes of random generation
- has been requested, otherwise tries to read from /dev/random
-**/
 _PUBLIC_ void generate_random_buffer(uint8_t *out, int len)
 {
-	unsigned char md4_buf[64];
-	unsigned char tmp_buf[16];
-	unsigned char *p;
-
-	if(!done_reseed) {
-		bytes_since_reseed += len;
-
-		/* Magic constant to try and avoid reading 40 bytes
-		 * and setting up the PRNG if the app only ever wants
-		 * a few bytes */
-		if (bytes_since_reseed < 40) {
-			if (urand_fd == -1) {
-				urand_fd = open( "/dev/urandom", O_RDONLY,0);
-				if (urand_fd != -1) {
-					smb_set_close_on_exec(urand_fd);
-				}
-			}
-			if(urand_fd != -1 && (read(urand_fd, out, len) == len)) {
-				return;
-			}
-		}
-
-		urand_fd = do_reseed(urand_fd);
-		done_reseed = true;
-	}
-
-	/*
-	 * Generate random numbers in chunks of 64 bytes,
-	 * then md4 them & copy to the output buffer.
-	 * This way the raw state of the stream is never externally
-	 * seen.
-	 */
+	ssize_t rw_ret;
 
-	p = out;
-	while(len > 0) {
-		int copy_len = len > 16 ? 16 : len;
+	open_urandom();
 
-		get_random_stream(md4_buf, sizeof(md4_buf));
-		mdfour(tmp_buf, md4_buf, sizeof(md4_buf));
-		memcpy(p, tmp_buf, copy_len);
-		p += copy_len;
-		len -= copy_len;
+	rw_ret = read_data(urand_fd, out, len);
+	if (rw_ret != len) {
+		abort();
 	}
 }
 
-/**
- Interface to the (hopefully) good crypto random number generator.
- Will always use /dev/urandom if available.
-**/
+/*
+ * Keep generate_secret_buffer in case we ever want to do something
+ * different
+ */
 _PUBLIC_ void generate_secret_buffer(uint8_t *out, int len)
 {
-	if (urand_fd == -1) {
-		urand_fd = open( "/dev/urandom", O_RDONLY,0);
-		if (urand_fd != -1) {
-			smb_set_close_on_exec(urand_fd);
-		}
-	}
-	if(urand_fd != -1 && (read(urand_fd, out, len) == len)) {
-		return;
-	}
-
 	generate_random_buffer(out, len);
 }
diff --git a/lib/util/genrand.h b/lib/util/genrand.h
index 73ca601..ef6bbc6 100644
--- a/lib/util/genrand.h
+++ b/lib/util/genrand.h
@@ -20,17 +20,6 @@
 */
 
 /**
- Copy any user given reseed data.
-**/
-
-void set_rand_reseed_callback(void (*fn)(void *, int *), void *userdata);
-
-/**
- * Tell the random number generator it needs to reseed.
- */
-void set_need_random_reseed(void);
-
-/**
  Interface to the (hopefully) good crypto random number generator.
  Will use our internal PRNG if more than 40 bytes of random generation
  has been requested, otherwise tries to read from /dev/random
diff --git a/lib/util/tests/genrand.c b/lib/util/tests/genrand.c
index 3d48be0..81c20bc 100644
--- a/lib/util/tests/genrand.c
+++ b/lib/util/tests/genrand.c
@@ -23,17 +23,6 @@
 #include "torture/torture.h"
 #include "torture/local/proto.h"
 
-static void dummy_reseed(void *userdata, int *d)
-{
-	*d = 42;
-}
-
-static bool test_reseed_callback(struct torture_context *tctx)
-{
-	set_rand_reseed_callback(dummy_reseed, NULL);
-	return true;
-}
-
 static bool test_check_password_quality(struct torture_context *tctx)
 {
 	torture_assert(tctx, !check_password_quality(""), "empty password");
@@ -64,7 +53,6 @@ static bool test_generate_random_str(struct torture_context *tctx)
 struct torture_suite *torture_local_genrand(TALLOC_CTX *mem_ctx)
 {
 	struct torture_suite *suite = torture_suite_create(mem_ctx, "genrand");
-	torture_suite_add_simple_test(suite, "reseed_callback", test_reseed_callback);
 	torture_suite_add_simple_test(suite, "check_password_quality", test_check_password_quality);
 	torture_suite_add_simple_test(suite, "generate_random_str", test_generate_random_str);
 	return suite;
diff --git a/lib/util/wscript_build b/lib/util/wscript_build
index 2c4d093..81578a9 100755
--- a/lib/util/wscript_build
+++ b/lib/util/wscript_build
@@ -84,7 +84,7 @@ if not bld.env.SAMBA_UTIL_CORE_ONLY:
 
     bld.SAMBA_LIBRARY('genrand',
                       source='genrand.c',
-                      deps='time-basic socket-blocking LIBCRYPTO',
+                      deps='replace socket-blocking sys_rw',
                       local_include=False,
                       private_library=True)
 
diff --git a/source3/lib/util.c b/source3/lib/util.c
index f633575..a0da087 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -441,12 +441,6 @@ NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
 		reinit_after_fork_pipe[1] = -1;
 	}
 
-	/* Reset the state of the random
-	 * number generation system, so
-	 * children do not get the same random
-	 * numbers as each other */
-	set_need_random_reseed();
-
 	/* tdb needs special fork handling */
 	if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
 		DEBUG(0,("tdb_reopen_all failed.\n"));
diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c
index 7071fd9..4372c63 100644
--- a/source3/passdb/secrets.c
+++ b/source3/passdb/secrets.c
@@ -37,28 +37,10 @@
 
 static struct db_context *db_ctx;
 
-/**
- * Use a TDB to store an incrementing random seed.
- *
- * Initialised to the current pid, the very first time Samba starts,
- * and incremented by one each time it is needed.
- *
- * @note Not called by systems with a working /dev/urandom.
- */
-static void get_rand_seed(void *userdata, int *new_seed)
-{
-	*new_seed = getpid();
-	if (db_ctx) {
-		dbwrap_trans_change_int32_atomic_bystring(
-			db_ctx, "INFO/random_seed", new_seed, 1);
-	}
-}
-
 /* open up the secrets database with specified private_dir path */
 bool secrets_init_path(const char *private_dir)
 {
 	char *fname = NULL;
-	unsigned char dummy;
 	TALLOC_CTX *frame;
 
 	if (db_ctx != NULL) {
@@ -86,17 +68,6 @@ bool secrets_init_path(const char *private_dir)
 		return False;
 	}
 
-	/**
-	 * Set a reseed function for the crypto random generator
-	 *
-	 * This avoids a problem where systems without /dev/urandom
-	 * could send the same challenge to multiple clients
-	 */
-	set_rand_reseed_callback(get_rand_seed, NULL);
-
-	/* Ensure that the reseed is done now, while we are root, etc */
-	generate_random_buffer(&dummy, sizeof(dummy));
-
 	TALLOC_FREE(frame);
 	return True;
 }
diff --git a/source4/param/secrets.c b/source4/param/secrets.c
index 92e338a..9874088 100644
--- a/source4/param/secrets.c
+++ b/source4/param/secrets.c
@@ -33,59 +33,6 @@
 #include "dsdb/samdb/samdb.h"
 
 /**
- * Use a TDB to store an incrementing random seed.
- *
- * Initialised to the current pid, the very first time Samba starts,
- * and incremented by one each time it is needed.  
- * 
- * @note Not called by systems with a working /dev/urandom.
- */
-static void get_rand_seed(struct tdb_wrap *secretsdb, int *new_seed) 
-{
-	*new_seed = getpid();
-	if (secretsdb != NULL) {
-		tdb_change_int32_atomic(secretsdb->tdb, "INFO/random_seed", new_seed, 1);
-	}
-}
-
-/**
- * open up the randseed database and set the random number generator callback
- */
-bool randseed_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
-{
-	char *fname;
-	uint8_t dummy;
-	struct tdb_wrap *tdb;
-
-	fname = lpcfg_private_path(mem_ctx, lp_ctx, "randseed.tdb");
-
-	tdb = tdb_wrap_open(mem_ctx, fname,
-			    lpcfg_tdb_hash_size(lp_ctx, fname),
-			    lpcfg_tdb_flags(lp_ctx, TDB_DEFAULT),
-			    O_RDWR|O_CREAT, 0600);
-
-	if (!tdb) {
-		DEBUG(0,("Failed to open %s\n", fname));
-		talloc_free(fname);
-		return false;
-	}
-	talloc_free(fname);
-
-	/**
-	 * Set a reseed function for the crypto random generator 
-	 * 
-	 * This avoids a problem where systems without /dev/urandom
-	 * could send the same challenge to multiple clients
-	 */
-	set_rand_reseed_callback((void (*) (void *, int *))get_rand_seed, tdb);
-
-	/* Ensure that the reseed is done now, while we are root, etc */
-	generate_random_buffer(&dummy, sizeof(dummy));
-
-	return true;
-}
-
-/**
   connect to the secrets ldb
 */
 struct ldb_context *secrets_db_connect(TALLOC_CTX *mem_ctx,
diff --git a/source4/param/secrets.h b/source4/param/secrets.h
index 1e7849f..015ea12 100644
--- a/source4/param/secrets.h
+++ b/source4/param/secrets.h
@@ -28,14 +28,6 @@
 #define SECRETS_PRINCIPAL_SEARCH "(&(|(realm=%s)(flatname=%s))(servicePrincipalName=%s))"
 #define SECRETS_LDAP_FILTER "(&(objectclass=ldapSecret)(cn=SAMDB Credentials))"
 
-/**
- * Use a TDB to store an incrementing random seed.
- *
- * Initialised to the current pid, the very first time Samba starts,
- * and incremented by one each time it is needed.  
- * 
- * @note Not called by systems with a working /dev/urandom.
- */
 struct loadparm_context;
 struct tevent_context;
 struct ldb_message;
diff --git a/source4/smbd/process_standard.c b/source4/smbd/process_standard.c
index b55a1a7..d223776 100644
--- a/source4/smbd/process_standard.c
+++ b/source4/smbd/process_standard.c
@@ -277,9 +277,6 @@ static void standard_accept_connection(struct tevent_context *ev,
 		child_pipe[1] = -1;
 	}
 
-	/* Ensure that the forked children do not expose identical random streams */
-	set_need_random_reseed();
-
 	/* setup the process title */
 	c = socket_get_peer_addr(sock2, ev);
 	s = socket_get_my_addr(sock2, ev);
@@ -356,9 +353,6 @@ static void standard_new_task(struct tevent_context *ev,
 		child_pipe[1] = -1;
 	}
 
-	/* Ensure that the forked children do not expose identical random streams */
-	set_need_random_reseed();
-
 	setproctitle("task %s server_id[%d]", service_name, (int)pid);
 
 	/* setup this new task.  Cluster ID is PID based for this process model */
diff --git a/source4/smbd/server.c b/source4/smbd/server.c
index b0f67c9..cb1a20b 100644
--- a/source4/smbd/server.c
+++ b/source4/smbd/server.c
@@ -392,12 +392,6 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
 
 	pidfile_create(lpcfg_pid_directory(cmdline_lp_ctx), binary_name);
 
-	/* Set up a database to hold a random seed, in case we don't
-	 * have /dev/urandom */
-	if (!randseed_init(talloc_autofree_context(), cmdline_lp_ctx)) {
-		return 1;
-	}
-
 	if (lpcfg_server_role(cmdline_lp_ctx) == ROLE_ACTIVE_DIRECTORY_DC) {
 		if (!open_schannel_session_store(talloc_autofree_context(), cmdline_lp_ctx)) {
 			exit_daemon("Samba cannot open schannel store for secured NETLOGON operations.", EACCES);
-- 
1.9.1



More information about the samba-technical mailing list