summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2020-06-09 16:19:50 +0200
committerVolker Lendecke <vl@samba.org>2020-07-08 09:42:39 +0000
commitc25fb103ea8b1a822005afbc791610329fd0295a (patch)
tree6636330a9819282357e04dd6e05705fd3bccef79 /lib
parentcd5a2d015bfe62b2ff334c1ebf34e371e7cf1238 (diff)
downloadsamba-c25fb103ea8b1a822005afbc791610329fd0295a.tar.gz
lib/util: add generate_unique_u64() helper function
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/util/genrand_util.c23
-rw-r--r--lib/util/samba_util.h29
2 files changed, 51 insertions, 1 deletions
diff --git a/lib/util/genrand_util.c b/lib/util/genrand_util.c
index 05d1f3ef6e5..26b52a1c814 100644
--- a/lib/util/genrand_util.c
+++ b/lib/util/genrand_util.c
@@ -47,7 +47,30 @@ _PUBLIC_ uint64_t generate_random_u64(void)
return BVAL(v, 0);
}
+static struct generate_unique_u64_state {
+ uint64_t next_value;
+ int pid;
+} generate_unique_u64_state;
+_PUBLIC_ uint64_t generate_unique_u64(uint64_t veto_value)
+{
+ int pid = getpid();
+
+ if (unlikely(pid != generate_unique_u64_state.pid)) {
+ generate_unique_u64_state = (struct generate_unique_u64_state) {
+ .pid = pid,
+ .next_value = veto_value,
+ };
+ }
+
+ while (unlikely(generate_unique_u64_state.next_value == veto_value)) {
+ generate_nonce_buffer(
+ (void *)&generate_unique_u64_state.next_value,
+ sizeof(generate_unique_u64_state.next_value));
+ }
+
+ return generate_unique_u64_state.next_value++;
+}
/**
Microsoft composed the following rules (among others) for quality
diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h
index f0aa42e7271..5a81baa80b6 100644
--- a/lib/util/samba_util.h
+++ b/lib/util/samba_util.h
@@ -94,11 +94,38 @@ _PUBLIC_ int sys_getnameinfo(const struct sockaddr *psa,
_PUBLIC_ uint32_t generate_random(void);
/**
- generate a single random uint64_t
+ * generate a single random uint64_t
+ * @see generate_unique_u64
**/
_PUBLIC_ uint64_t generate_random_u64(void);
/**
+ * @brief Generate random nonces usable for re-use detection.
+ *
+ * We have a lot of places which require a unique id that can
+ * be used as a unique identitier for caching states.
+ *
+ * Always using generate_nonce_buffer() has it's performance costs,
+ * it's typically much better than generate_random_buffer(), but
+ * still it's overhead we want to avoid in performance critical
+ * workloads.
+ *
+ * We call generate_nonce_buffer() just once per given state
+ * and process.
+ *
+ * This is much lighter than generate_random_u64() and it's
+ * designed for performance critical code paths.
+ *
+ * @veto_value It is garanteed that the return value if different from
+ * the veto_value.
+ *
+ * @return a unique value per given state and process
+ *
+ * @see generate_random_u64
+ */
+uint64_t generate_unique_u64(uint64_t veto_value);
+
+/**
very basic password quality checker
**/
_PUBLIC_ bool check_password_quality(const char *s);