diff --git a/CHANGELOG.md b/CHANGELOG.md
index 83f1c3ffc682b71e1e67d74e713f1997dfb255d7..f8a6a7dc4323fe3643fc13c0c1227ba90f6a40bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,15 +9,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
+* Configurable requirements for user names and passwords. The default is the old hard-coded configuration.
+
 ### Changed
 
+* Minimal changes to the error messages for invalid user names and passwords.
+
 ### Deprecated
 
 ### Removed
 
 ### Fixed
 
-* [caosdb-server#145](https://gitlab.com/caosdb/caosdb-server/-/issues/145) Searching for large numbers results in wrong results if integer values are
+* [caosdb-server#148](https://gitlab.com/caosdb/caosdb-server/-/issues/148)
+  Cannot delete file entities containing unescaped space characters
+* [caosdb-server#145](https://gitlab.com/caosdb/caosdb-server/-/issues/145)
+  Searching for large numbers results in wrong results if integer values are
   used.
 
 ### Security
@@ -34,6 +41,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Fixed
 
+* [caosdb-server#142](https://gitlab.com/caosdb/caosdb-server/-/issues/142)
+  Can't create users with dots in their user names
 * `ldap_authentication.sh <username>` failed on every attempt when used in
   combination with OpenLDAP with default configuration.
 * `ldap_authentication.sh` allowed empty and even wrong passwords when used in
diff --git a/conf/core/server.conf b/conf/core/server.conf
index 246be9aa9285e4434803d3a71d18c24412922bf4..57744250a7ef88285b343aa5c037de9cbbf97097 100644
--- a/conf/core/server.conf
+++ b/conf/core/server.conf
@@ -199,6 +199,18 @@ CHECK_ENTITY_ACL_ROLES_MODE=MUST
 # part of any Entity ACL.
 GLOBAL_ENTITY_PERMISSIONS_FILE=./conf/core/global_entity_permissions.xml
 
+# --------------------------------------------------
+# User Account Settings
+# --------------------------------------------------
+
+# Requirements for user names. The default is POSIX compliant, see
+# https://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_426
+USER_NAME_VALID_REGEX=^[\\w\\.][\\w\\.-]*{1,32}$
+USER_NAME_INVALID_MESSAGE=User names must have a length from 1 to 32 characters. They must contain only latin letters a-z (upper case or lower case), number 0-9, dots (.), underscores (_), or hyphens (-). They must no start with a hyphen.
+
+PASSWORD_VALID_REGEX=^((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\\p{Punct}]).{8,128})$
+PASSWORD_INVALID_MESSAGE=Passwords must have a length from 8 to 128 characters. THe must contain at least one [A-Z], one [a-z], one [0-9] and a special character e.g. [!ยง$%&/()=?.;,:#+*+~].
+
 # --------------------------------------------------
 # Extensions
 # --------------------------------------------------
diff --git a/src/main/java/org/caosdb/server/ServerProperties.java b/src/main/java/org/caosdb/server/ServerProperties.java
index 34899f7551ccc8ac99e6f2246eeb154c37171e53..aa8fc43ead96dad56e739950f12ad7638e550bef 100644
--- a/src/main/java/org/caosdb/server/ServerProperties.java
+++ b/src/main/java/org/caosdb/server/ServerProperties.java
@@ -108,8 +108,6 @@ public class ServerProperties extends Properties {
 
   public static final String KEY_NEW_USER_DEFAULT_ACTIVITY = "NEW_USER_DEFAULT_ACTIVITY";
 
-  public static final String KEY_PASSWORD_STRENGTH_REGEX = "PASSWORD_STRENGTH_REGEX";
-
   public static final String KEY_QUERY_FILTER_ENTITIES_WITHOUT_RETRIEVE_PERMISSIONS =
       "QUERY_FILTER_ENTITIES_WITHOUT_RETRIEVE_PERMISSIONS";
 
@@ -141,6 +139,12 @@ public class ServerProperties extends Properties {
   public static final String KEY_PROJECT_REVISTION = "project.revision";
   public static final String KEY_BUILD_TIMESTAMP = "build.timestamp";
 
+  public static final String KEY_USER_NAME_VALID_REGEX = "USER_NAME_VALID_REGEX";
+  public static final String KEY_USER_NAME_INVALID_MESSAGE = "USER_NAME_INVALID_MESSAGE";
+
+  public static final String KEY_PASSWORD_STRENGTH_REGEX = "PASSWORD_VALID_REGEX";
+  public static final String KEY_PASSWORD_WEAK_MESSAGE = "PASSWORD_INVALID_MESSAGE";
+
   /**
    * Read the config files and initialize the server properties.
    *
diff --git a/src/main/java/org/caosdb/server/resource/UserResource.java b/src/main/java/org/caosdb/server/resource/UserResource.java
index 2c463e0e4bf7a640adc2a8368f74d798f69d0fd5..de07331e9637549285d71ca2fd910916cd13316a 100644
--- a/src/main/java/org/caosdb/server/resource/UserResource.java
+++ b/src/main/java/org/caosdb/server/resource/UserResource.java
@@ -128,10 +128,9 @@ public class UserResource extends AbstractCaosDBServerResource {
         return error(m, Status.CLIENT_ERROR_NOT_FOUND);
       } else if (m == ServerMessages.ENTITY_DOES_NOT_EXIST) {
         return error(m, Status.CLIENT_ERROR_CONFLICT);
-      } else if (m == ServerMessages.PASSWORD_TOO_WEAK) {
-        return error(m, Status.CLIENT_ERROR_UNPROCESSABLE_ENTITY);
+      } else {
+        return error(m, Status.CLIENT_ERROR_BAD_REQUEST);
       }
-      throw m;
     } catch (final NumberFormatException e) {
       return error(ServerMessages.CANNOT_PARSE_INT_VALUE, Status.CLIENT_ERROR_BAD_REQUEST);
     }
@@ -163,10 +162,9 @@ public class UserResource extends AbstractCaosDBServerResource {
     } catch (final Message m) {
       if (m == ServerMessages.ACCOUNT_NAME_NOT_UNIQUE) {
         return error(m, Status.CLIENT_ERROR_CONFLICT);
-      } else if (m == ServerMessages.PASSWORD_TOO_WEAK) {
-        return error(m, Status.CLIENT_ERROR_UNPROCESSABLE_ENTITY);
+      } else {
+        return error(m, Status.CLIENT_ERROR_BAD_REQUEST);
       }
-      throw m;
     }
 
     final Document doc = new Document();
diff --git a/src/main/java/org/caosdb/server/transaction/InsertUserTransaction.java b/src/main/java/org/caosdb/server/transaction/InsertUserTransaction.java
index 09d59e8d84659037da66e11f7b4c0da556d8aa50..8abc2ede52375158c006d0108e9fea2523526006 100644
--- a/src/main/java/org/caosdb/server/transaction/InsertUserTransaction.java
+++ b/src/main/java/org/caosdb/server/transaction/InsertUserTransaction.java
@@ -24,6 +24,8 @@
 package org.caosdb.server.transaction;
 
 import org.apache.shiro.SecurityUtils;
+import org.caosdb.server.CaosDBServer;
+import org.caosdb.server.ServerProperties;
 import org.caosdb.server.accessControl.ACMPermissions;
 import org.caosdb.server.accessControl.Principal;
 import org.caosdb.server.accessControl.UserSources;
@@ -86,18 +88,13 @@ public class InsertUserTransaction extends AccessControlTransaction {
   }
 
   /*
-   * Names should have at least a length of 1, a maximum length of 32 and match
-   * ^[a-zA-Z_][a-zA-Z0-9_-]*$.
+   * Check requirements for user names (length, character set). Default config is POSIX compliant.
    */
   private void checkUserName(String name) throws Message {
-    // Make this configurable?
-    final boolean length = name.length() >= 1 && name.length() <= 32;
-    final boolean match =
-        name.matches("^[\\p{Lower}\\p{Upper}_][\\p{Lower}\\p{Upper}\\p{Digit}_-]*$");
-
-    if (!(length && match)) {
+    String regex = CaosDBServer.getServerProperty(ServerProperties.KEY_USER_NAME_VALID_REGEX);
+    if (!name.matches(regex)) {
       throw ServerMessages.INVALID_USER_NAME(
-          "User names must have a length from 1 to 32 characters, begin with a latin letter a-z (upper case or lower case) or an underscore (_), and all other characters must be latin letters, arabic numbers, hyphens (-) or undescores (_).");
+          CaosDBServer.getServerProperty(ServerProperties.KEY_USER_NAME_INVALID_MESSAGE));
     }
 
     if (UserSources.isUserExisting(new Principal(this.user.realm, this.user.name))) {
diff --git a/src/main/java/org/caosdb/server/utils/FileUtils.java b/src/main/java/org/caosdb/server/utils/FileUtils.java
index 70ba003018e3ccc7831bf9f536e827552445ec6a..eb4270f8d33abf933dbe24001bfa9b02ce45639b 100644
--- a/src/main/java/org/caosdb/server/utils/FileUtils.java
+++ b/src/main/java/org/caosdb/server/utils/FileUtils.java
@@ -525,7 +525,7 @@ public class FileUtils {
   }
 
   private static void callPosixUnlink(File file) throws IOException, InterruptedException {
-    final Process cmd = Runtime.getRuntime().exec("unlink " + file.getAbsolutePath());
+    final Process cmd = Runtime.getRuntime().exec(new String[] {"unlink", file.getAbsolutePath()});
     if (cmd.waitFor() != 0) {
       throw new CaosDBException("could not unlink " + file.getAbsolutePath());
     }
diff --git a/src/main/java/org/caosdb/server/utils/ServerMessages.java b/src/main/java/org/caosdb/server/utils/ServerMessages.java
index 151f55face7edbfab793606474f183a65f0468be..835087ce8825de6c136dabd746534bc42f3240d5 100644
--- a/src/main/java/org/caosdb/server/utils/ServerMessages.java
+++ b/src/main/java/org/caosdb/server/utils/ServerMessages.java
@@ -337,7 +337,7 @@ public class ServerMessages {
       new Message(
           MessageType.Error,
           MessageCode.MESSAGE_CODE_UNKNOWN,
-          "This user name is yet in use. Please choose another one.");
+          "This user name is already in use. Please choose another one.");
 
   public static final Message ACCOUNT_HAS_BEEN_DELETED =
       new Message(
@@ -399,11 +399,12 @@ public class ServerMessages {
           MessageCode.MESSAGE_CODE_UNKNOWN,
           "This email address is not RFC822 compliant.");
 
-  public static final Message PASSWORD_TOO_WEAK =
-      new Message(
-          MessageType.Error,
-          MessageCode.MESSAGE_CODE_UNKNOWN,
-          "This password is too weak. It should be longer than 8 characters and sufficiently random.");
+  public static final Message PASSWORD_TOO_WEAK(String policy) {
+    return new Message(
+        MessageType.Error,
+        MessageCode.MESSAGE_CODE_UNKNOWN,
+        "The password does not comply with the current policies for passwords: " + policy);
+  }
 
   public static final Message AFFILIATION_ERROR =
       new Message(
@@ -609,7 +610,7 @@ public class ServerMessages {
     return new Message(
         MessageType.Error,
         MessageCode.MESSAGE_CODE_UNKNOWN,
-        "The user name does not comply with the policies for user names: " + policy);
+        "The user name does not comply with the current policies for user names: " + policy);
   }
 
   public static final Message CANNOT_DELETE_YOURSELF() {
diff --git a/src/main/java/org/caosdb/server/utils/Utils.java b/src/main/java/org/caosdb/server/utils/Utils.java
index b21ba0f550e1f855ca21e26c1cfd04bb75107223..07a7e9618aa5b9e45f0086e837acfe1bf427173f 100644
--- a/src/main/java/org/caosdb/server/utils/Utils.java
+++ b/src/main/java/org/caosdb/server/utils/Utils.java
@@ -35,6 +35,8 @@ import java.text.DecimalFormat;
 import java.util.Scanner;
 import java.util.regex.Pattern;
 import org.apache.commons.codec.binary.Base32;
+import org.caosdb.server.CaosDBServer;
+import org.caosdb.server.ServerProperties;
 import org.caosdb.server.entity.Message;
 import org.jdom2.Document;
 import org.jdom2.Element;
@@ -304,18 +306,15 @@ public class Utils {
    * @param password The password to be checked.
    */
   public static void checkPasswordStrength(final String password) throws Message {
-    final boolean length = password.length() >= 8;
-    final boolean uppercase = password.matches(".*\\p{Upper}.*");
-    final boolean lowercase = password.matches(".*\\p{Lower}.*");
-    final boolean number = password.matches(".*\\p{Digit}.*");
-    final boolean punct = password.matches(".*\\p{Punct}.*");
+    String regex = CaosDBServer.getServerProperty(ServerProperties.KEY_PASSWORD_STRENGTH_REGEX);
 
-    if (!(length && uppercase && lowercase && number && punct)) {
-      throw ServerMessages.PASSWORD_TOO_WEAK;
+    if (password.equals("correcthorsebatterystaple")) {
+      throw ServerMessages.PASSWORD_TOO_WEAK("PWNED!");
     }
 
-    if (password.equals("correcthorsebatterystaple")) {
-      throw ServerMessages.PASSWORD_TOO_WEAK;
+    if (!password.matches(regex)) {
+      throw ServerMessages.PASSWORD_TOO_WEAK(
+          CaosDBServer.getServerProperty(ServerProperties.KEY_PASSWORD_WEAK_MESSAGE));
     }
   }
 }