diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c2de130bd802f9bd3be3d9f0e91a53a74401225b..609009d00a4eb24fdeb45059b0e6b72b0ee4092c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,8 +3,10 @@
 #
 # Copyright (C) 2018 Research Group Biomedical Physics,
 # Max-Planck-Institute for Dynamics and Self-Organization Göttingen
+# Copyright (C) 2019-2022 Indiscale GmbH <info@indiscale.com>
 # Copyright (C) 2019 Henrik tom Wörden
 # Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
+# Copyright (C) 2020-2022 Daniel Hornung <d.hornung@indiscale.com>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as
@@ -25,8 +27,6 @@ variables:
   CI_REGISTRY_IMAGE: $CI_REGISTRY/caosdb/src/caosdb-server/caosdb-server-testenv:latest
   GIT_SUBMODULE_STRATEGY: normal
 
-  DEPLOY_PIPELINE: https://gitlab.indiscale.com/api/v4/projects/14/trigger/pipeline
-
   ## FOR DEBUGGING
   TRIGGERED_BY_REPO: SERVER
   TRIGGERED_BY_REF: $CI_COMMIT_REF_NAME
@@ -39,16 +39,13 @@ stages:
   - test
   - deploy
 
-.env: &env
-  - F_BRANCH="${CI_COMMIT_REF_NAME}"
-
 info:
   tags: [cached-dind]
   image: docker:20.10
   stage: info
   needs: []
   script:
-    - *env
+    - F_BRANCH="${CI_COMMIT_REF_NAME}"
     - echo "Pipeline triggered by $TRIGGERED_BY_REPO@$TRIGGERED_BY_REF ($TRIGGERED_BY_HASH)"
     - echo "Pipeline will trigger DEPLOY with branch $DEPLOY_REF"
     - echo "F_BRANCH = $F_BRANCH"
@@ -83,25 +80,26 @@ test:
     - mvn compile
     - mvn test
 
-
-
 # Deploy: Trigger building of server image and integration tests
-trigger_build:
-  tags: [ docker ]
+trigger_inttest:
   stage: deploy
   needs: [ test ]
-  script:
-    - *env
-
-    - echo "Triggering pipeline ${DEPLOY_PIPELINE}@${DEPLOY_REF} with F_BRANCH=${F_BRANCH}"
-    - /usr/bin/curl -X POST
-      -F token=$CI_JOB_TOKEN
-      -F "variables[SERVER]=$CI_COMMIT_REF_NAME"
-      -F "variables[F_BRANCH]=$F_BRANCH"
-      -F "variables[TRIGGERED_BY_REPO]=$TRIGGERED_BY_REPO"
-      -F "variables[TRIGGERED_BY_REF]=$TRIGGERED_BY_REF"
-      -F "variables[TRIGGERED_BY_HASH]=$TRIGGERED_BY_HASH"
-      -F ref=$DEPLOY_REF $DEPLOY_PIPELINE
+  inherit:
+    variables:
+      # List the variables that shall be inherited, which also means they will override any equally
+      # named varibles in child pipelines.
+      - DEPLOY_REF
+      - TRIGGERED_BY_REPO
+      - TRIGGERED_BY_REF
+      - TRIGGERED_BY_HASH
+  variables:
+    # Renaming variables.
+    F_BRANCH: $CI_COMMIT_REF_NAME
+    SERVER: $CI_COMMIT_REF_NAME
+  trigger:
+    project: caosdb/src/caosdb-deploy
+    branch: $DEPLOY_REF
+    strategy: depend
 
 # Build the sphinx documentation and make it ready for deployment by Gitlab Pages
 # Special job for serving a static website. See https://docs.gitlab.com/ee/ci/yaml/README.html#pages
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0777d7740fbf2b5e2ac0c71142405377dfa9af1e..f8a6a7dc4323fe3643fc13c0c1227ba90f6a40bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,16 +9,52 @@ 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#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
+
+## [0.7.3] - 2022-05-03
+(Daniel Hornung)
+
+### Changed
+
+* `misc/pam_authentication/ldap.conf` is not used for configuring the
+  `ldap_authentication.sh` script anymore.
+  Use `misc/pam_authentication/ldap.env` instead and view the documentation
+  inside the file itself for more information.
+
+### 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
+  combination with MS Active Directory when AD is configured to allow binding
+  with an empty password.
+
 ### Security
 
+* `ldap_authentication.sh` allowed empty and even wrong passwords when used in
+  combination with MS Active Directory when AD is configured to allow binding
+  with an empty password. This is only relevant for non-default configurations
+  of the `PAM.pam_script` option in the `usersources.ini`.
 
 ## [0.7.2] - 2022-03-25
 (Timm Fitschen)
diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md
index 3a388c541301c55ef32dd2e25e22c8ca750348b2..ba9de363576a963eb9696baf3244c06559279bce 100644
--- a/DEPENDENCIES.md
+++ b/DEPENDENCIES.md
@@ -12,7 +12,7 @@
 
 ## For Deploying a Web User Interface (optional)
 
-* `>=caosdb-webui 0.5.0`
+* `>=caosdb-webui 0.6.0`
 
 ## For Building the Documentation (optional)
 
diff --git a/FEATURES.md b/FEATURES.md
index ac273ca11876636a8e688ddc4458ecb48bf98e3d..9cad165e562bcb55bb1b18f14ee3c5b55d328ba8 100644
--- a/FEATURES.md
+++ b/FEATURES.md
@@ -18,4 +18,4 @@
 * CaosDB FileSystem
 * User Management, Authentication and Authorization
   * Internal authentication service
-  * Authentication via an external service.
+  * Authentication via an external service (PAM, LDAP)
diff --git a/README_SETUP.md b/README_SETUP.md
index 77106e5aa931ebb064610959fe2efbff043eb04d..6bbbd71167a9243966f88b29c82184600bcaa25a 100644
--- a/README_SETUP.md
+++ b/README_SETUP.md
@@ -1,7 +1,8 @@
 # Getting Started with the CaosDB Server
 
 Here, you find information on requirements, the installation, configuration and
-more.
+more. Note, that building the CaosDB Server from the sources and maintaining
+the server requires the knowledge/skill of an experienced Linux administrator.
 
 ## Requirements
 
@@ -83,8 +84,8 @@ server:
    `caosdb-mysqlbackend` repository
 5. Create an authtoken config (e.g. copy `conf/core/authtoken.example.yaml` to
    `conf/ext/authtoken.yml` and change it)
-6. Copy `conf/core/server.conf` to `conf/ext/server.conf` and change it
-   appropriately:
+6. If any of the settings in `conf/core/server.conf` do not fit your needs, create
+   `conf/ext/server.conf` and add settings as required:
     * Setup for MySQL back-end:
       specify the fields `MYSQL_USER_NAME`, `MYSQL_USER_PASSWORD`,
       `MYSQL_DATABASE_NAME`, and `MYSQL_HOST`.
diff --git a/RELEASE_GUIDELINES.md b/RELEASE_GUIDELINES.md
index 4b9185323d3b6fdafbd049e7c68273c909de5a05..fff7dac583213ca4d1b79c68dbd66cdee83ed78b 100644
--- a/RELEASE_GUIDELINES.md
+++ b/RELEASE_GUIDELINES.md
@@ -1,6 +1,6 @@
-# Release Guidelines for the CaosDB MySQL Backend
+# Release Guidelines for the CaosDB Server
 
-This document specifies release guidelines in addition to the generel release
+This document specifies release guidelines in addition to the general release
 guidelines of the CaosDB Project
 ([RELEASE_GUIDELINES.md](https://gitlab.com/caosdb/caosdb/blob/dev/RELEASE_GUIDELINES.md))
 
@@ -18,18 +18,30 @@ guidelines of the CaosDB Project
 
 2. Check all general prerequisites.
 
-3. Update the version property in [pom.xml](./pom.xml) (probably this means to
-   remove the `-SNAPSHOT`) and in `src/doc/conf.py`.
+3. Update the versions in:
+  * [pom.xml](./pom.xml) (probably this means to remove the `-SNAPSHOT`)
+  * `src/doc/conf.py`
+  * `CHANGELOG.md`
 
-4. Merge the release branch into the main branch.
+5. Merge the release branch into the main branch.
 
-5. Tag the latest commit of the main branch with `v<VERSION>`.
+6. Tag the latest commit of the main branch with `v<VERSION>`.
 
-6. Delete the release branch.
+7. Delete the release branch.
 
-7. Merge the main branch back into the dev branch.
+8. Merge the main branch back into the dev branch.
 
-8. Update the version property in [pom.xml](./pom.xml) for the next
-   developlement round (with a `-SNAPSHOT` suffix).
+9. Update the versions for the next developement round:
+  *  [pom.xml](./pom.xml) with a `-SNAPSHOT` suffix
+  * `src/doc/conf.py`
+  * `CHANGELOG.md`: Re-add the `[Unreleased]` section.
 
-9. Add a gitlab release in the respective repository.
+10. Add a gitlab release in the respective repository:
+    https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/releases
+
+    Add a description, which can be a copy&paste from the CHANGELOG, possibly prepended by:
+    ```md
+# Changelog
+
+[See full changelog](https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/blob/v0.7.3/CHANGELOG.md)
+    ```
diff --git a/caosdb-webui b/caosdb-webui
index e6788d0380bdaf02d43498347616e6f3c4195663..86dc30e3526f2eab97de5dcd53c8eaa12c0e42e6 160000
--- a/caosdb-webui
+++ b/caosdb-webui
@@ -1 +1 @@
-Subproject commit e6788d0380bdaf02d43498347616e6f3c4195663
+Subproject commit 86dc30e3526f2eab97de5dcd53c8eaa12c0e42e6
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/conf/core/usersources.ini.template b/conf/core/usersources.ini.template
index 2e0fe2490a65b53022d8d0edff6495f3b92ec10a..fb3285723f0721da3280e5ef33461ff4b684e89f 100644
--- a/conf/core/usersources.ini.template
+++ b/conf/core/usersources.ini.template
@@ -42,7 +42,8 @@ defaultRealm = PAM
 # Options for authentication against Linux' PAM.
 [PAM]
 class = org.caosdb.server.accessControl.Pam
-# The script which does the actual checking.
+# The script which does the actual checking. It is possible to put custom
+# scripts or the misc/pam_authentication/ldap_authentication.sh script here.
 ; pam_script = ./misc/pam_authentication/pam_authentication.sh
 default_status = ACTIVE
 # Only users which fulfill these criteria are accepted.
diff --git a/doc/devel/Benchmarking.md b/doc/devel/Benchmarking.md
index 5fc3f75fe01114558f325662048cde904480c910..8a3eff2addb927eab425f7e755e3a181a53b9d18 100644
--- a/doc/devel/Benchmarking.md
+++ b/doc/devel/Benchmarking.md
@@ -59,7 +59,10 @@ enabled on start up.
 This script expects the MariaDB server to be accessible on 127.0.0.1 with the default caosdb user
 and password (caosdb;random1234).
 
-
+You might consider to increase `performance_schema_events_transactions_history_long_size`.
+```
+performance_schema_events_transactions_history_long_size=1000000
+```
 The performance schema must be enabled (see below).
 
 ### MariaDB General Query Log ###
diff --git a/misc/pam_authentication/ldap.conf b/misc/pam_authentication/ldap.conf
deleted file mode 100644
index 664dd7c97524242fdb1ea7015bbc0e26c087b062..0000000000000000000000000000000000000000
--- a/misc/pam_authentication/ldap.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-# This file is sourced by the LDAP authentication script
-
-# Set the ldap server here.
-# LDAP_SERVER="example.com"
-
-# Set the ldap domain here. This is used to generate a fully qualified
-# user name: <USER>@$LDAP_DOMAIN
-# LDAP_DOMAIN="example.com"
diff --git a/misc/pam_authentication/ldap.env b/misc/pam_authentication/ldap.env
new file mode 100644
index 0000000000000000000000000000000000000000..6067400cb2f0d965b2b85a7ac08f3b35117864c5
--- /dev/null
+++ b/misc/pam_authentication/ldap.env
@@ -0,0 +1,50 @@
+# ldap.env - This file is sourced by the LDAP authentication script.
+#
+# Please see https://linux.die.net/man/5/ldap.conf for more client
+# configuration variables.
+
+# REQUIRED - Set the ldap server here,
+export LDAPURI="ldap[s]://<ldap-service>[:<port>]"
+
+# REQUIRED - Set the base domain here. This is used to generate a fully
+# qualified user name, a Distinguished Name (DN), with the BIND_DN_PATTERN:
+export USER_BASE="dc=example,dc=org" # for actual LDAP servers
+#export USER_BASE="example.org" # for MS Active Directory
+
+# The BIND_DN_PATTERN is used to construct the DN from the USER_NAME and the
+# USER_BASE. Be sure to surround it with single quotation marks "'" because the
+# variables inside are to be expanded by the script. Defaults to the first
+#export BIND_DN_PATTERN='cn=${USER_NAME},${USER_BASE}' # for actual LDAP servers.
+#export BIND_DN_PATTERN='${USER_NAME}@${USER_BASE}' # for MS Active Directory
+
+# The WHO_AM_I_PATTERN is used to construct the expected representation of the
+# bound user account. Normal LDAP servers return "dn:<dn>" but MS Active
+# Directory chooses to return "u:<domain>\<user_name>" instead. Be sure to
+# surround it with single quotation marks "'" because the variables inside are
+# to be expanded by the script. Defaults to the first.
+#export WHO_AM_I_PATTERN='dn:cn=${USER_NAME},${USER_BASE}' # for actual LDAP
+                                                           # servers.
+#export WHO_AM_I_PATTERN='u:<domain>\\${USER_NAME}' # for MS Active Directory.
+                                                    # Mind the double back-slash.
+
+# TLS SETTINGS
+
+# Specifies what checks to perform on server certificates in a TLS session, if
+# any. Defaults to "hard" which means that a successful TLS-certificate check
+# is necessary.
+#export LDAPTLS_REQCERT=never
+#export LDAPTLS_REQCERT=allow
+#export LDAPTLS_REQCERT=try
+#export LDAPTLS_REQCERT=hard
+
+# In some cases there is no need for specifying the TLS certificates here, e.g.
+# when they are installed system-wide. If that does not work, use these
+# variables:
+
+# Specifies the file that contains certificates for all of the Certificate
+# Authorities the client will recognize.
+#export LDAPTLS_CACERT="<filename>"
+
+# Specifies the path of a directory that contains Certificate Authority
+# certificates in separate individual files.
+#export LDAPTLS_CACERTDIR="<path>"
diff --git a/misc/pam_authentication/ldap_authentication.sh b/misc/pam_authentication/ldap_authentication.sh
index 1b86b8e1783399e2c43b92981a43789accb21e7d..e58b5caa3e518a386169b37d1723b76418570162 100755
--- a/misc/pam_authentication/ldap_authentication.sh
+++ b/misc/pam_authentication/ldap_authentication.sh
@@ -24,37 +24,44 @@
 # Try to authenticate a user ($1) via LDAP, either via stdin or a password file ($2, if given).
 
 [[ "$#" == "1" || "$#" == "2" ]] || {
-    echo "Call this script as: $0 <user> [<password file>]"
+    echo "Call this script as: $0 <user> [-|<password file>]"
     exit 1
 }
 
-# set LDAP_SERVER here
-# e.g. `LDAP_SERVER=example.com`
-exe_dir=$(dirname $0)
-. "$exe_dir/"ldap.conf
+# Load all LDAP client settings
+exe_dir=$(dirname "$0")
+. "$exe_dir/ldap.env"
+LDAPTLS_REQCERT="${LDAP_TLS_REQCERT:-hard}"
+BIND_DN_PATTERN="${BIND_DN_PATTERN:-"cn=\${USER_NAME},\${USER_BASE}"}"
+WHO_AM_I_PATTERN="${WHO_AM_I_PATTERN:-"dn:cn=\${USER_NAME},\${USER_BASE}"}"
 
 # If the second argument is empty or "-", take password from stdin, else use the argument as a file.
 testpw() {
-    username="${1}@${LDAP_DOMAIN}"
+    local USER_NAME bind_dn who_am_i pwfile pwargs result
+
+    # cn is case-insensitive https://ldapwiki.com/wiki/Distinguished%20Name%20Case%20Sensitivity
+    USER_NAME="$(echo "$1" | tr '[:upper:]' '[:lower:]')"
+
+    bind_dn="$(eval "echo \"$BIND_DN_PATTERN\"")"
+    who_am_i="$(eval "echo \"$WHO_AM_I_PATTERN\"")"
+
     pwfile="$2"
-    pwargs=("-w" "$pwfile")
-    if [[ $pwfile == "-" ]] ; then
+    pwargs=("-y" "$pwfile")
+    if [ "$pwfile" = "-" ] ; then
+        pwargs=("-W")
+    elif [ -z "$pwfile" ] ; then
         pwargs=("-W")
     fi
 
-    export LDAPTLS_REQCERT=ALLOW
-    if timeout 5s ldapwhoami -x -H "ldaps://$LDAP_SERVER" -D "$username" "${pwargs[@]}"; then
+    result="$(ldapwhoami -o "nettimeout=10" -x -D "$bind_dn" "${pwargs[@]}")"
+    if [ "$?" -ne "0" ] ; then
+        return 1
+    elif [ "$result" = "$who_am_i" ] ; then
         return 0
-    else
-        ret_code="$?"
     fi
-
-    # Possibly try a second time
-    if [[ "$ret_code" != "124" ]] ; then
-        return "$ret_code"
-    fi
-
-    ldapwhoami -x -H "ldaps://$LDAP_SERVER" -D "$username" "${pwargs[@]}"
+    echo "result : $result"
+    echo "pattern: $who_am_i"
+    return 1
 
 }
 
diff --git a/src/doc/conf.py b/src/doc/conf.py
index 079eec42b21b3532e30c21ceaf8afe5a8ea7f35b..ba98f7e554816f858f5664c084c20bc1b33167de 100644
--- a/src/doc/conf.py
+++ b/src/doc/conf.py
@@ -21,7 +21,7 @@ import sphinx_rtd_theme
 # -- Project information -----------------------------------------------------
 
 project = 'caosdb-server'
-copyright = '2020, IndiScale GmbH'
+copyright = '2022, IndiScale GmbH'
 author = 'Daniel Hornung'
 
 # The short X.Y version
diff --git a/src/doc/permissions.rst b/src/doc/permissions.rst
index e61ee49a948e905f1800ee5fdb2f0efb6a4ab207..c0f30a0ee05d6cc8cac237b305e63b2c83ec7dce 100644
--- a/src/doc/permissions.rst
+++ b/src/doc/permissions.rst
@@ -5,9 +5,7 @@ CaosDB has a fine grained role based permission system. Each interaction
 with the server is governed by the current rules of the user, by default
 this is the ``anonymous`` role. The permissions for an action which
 involves one or more objects are set either manually or via default
-permissions which can be configured. For more detailed information,
-there is separate
-:doc:``documentation of the permission system<permissions>``.
+permissions which can be configured.
 
 Permissions are needed to perform particular elementary *actions* during
 any interaction with the the server. E.g. retrieving an Entity requires
@@ -87,11 +85,11 @@ How to set permissions
    various files which use the permission API:
 
    -  The `example
-      file <https://gitlab.com/caosdb/caosdb-pylib/blob/HEAD/examples/set_permissions.py>`__
+      file <https://gitlab.com/caosdb/caosdb-pylib/-/blob/main/examples/set_permissions.py>`__
    -  The ```caosdb_admin.py`` utility
-      script <https://gitlab.com/caosdb/caosdb-pylib/blob/HEAD/src/caosdb/utils/caosdb_admin.py>`__
+      script <https://gitlab.com/caosdb/caosdb-pylib/-/blob/main/src/caosdb/utils/caosdb_admin.py>`__
    -  The `integration
-      tests <https://gitlab.com/caosdb/caosdb-pyinttest/blob/HEAD/tests/test_permissions.py>`__
+      tests <https://gitlab.com/caosdb/caosdb-pyinttest/-/blob/main/tests/test_permissions.py>`__
       also cover quite a bit of the permission API.
 
 -  WebUI :: Not implemented (or documented?) yet.
diff --git a/src/doc/roles.md b/src/doc/roles.md
index 2d1d36c47c34658a306384e39033f7ea4e5eb040..138c75d37df7b883d1e494a438283f1a610f07c3 100644
--- a/src/doc/roles.md
+++ b/src/doc/roles.md
@@ -10,7 +10,7 @@ users may have the same role, and there may be roles without any users.
 
 The user and their roles are always returned by the server in answers to requests
 and can thus be interpreted and used by clients.  The most important use though
-is [permission](doc:`permissions`) checking in the server: Access and
+is [permission](permissions.rst) checking in the server: Access and
 modification of
 entities can be controlled via roles, so that users of a given role are allowed
 or denied certain actions.  Incidentally, the permission to edit the permissions
@@ -32,4 +32,4 @@ There are some special roles, which are automatically assigned to users:
 
 Except for the `anonymous` role, these special roles are not returned by the
 server, but can nevertheless be used to define
-[permissions](doc:`permissions`).
+[permissions](permissions.rst).
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/query/POV.java b/src/main/java/org/caosdb/server/query/POV.java
index b1a457529a0199edcc5061110ee97e416a264fff..89ea9ad46e6205dfe0583e8f54551effd82a2658 100644
--- a/src/main/java/org/caosdb/server/query/POV.java
+++ b/src/main/java/org/caosdb/server/query/POV.java
@@ -63,6 +63,7 @@ public class POV implements EntityFilterInterface {
   private DateTimeInterface vDatetime;
   private final String aggregate;
   private String targetSet = null;
+  private String unitStr = null;
   private Unit unit = null;
   private Long stdUnitSig = null;
   private Double vDoubleConvertedToStdUnit = null;
@@ -112,7 +113,6 @@ public class POV implements EntityFilterInterface {
 
     // parse value to int/double/datetime
     if (this.value != null) {
-      String unitStr = null;
 
       // try and parse as integer
       try {
@@ -122,44 +122,41 @@ public class POV implements EntityFilterInterface {
           throw new NumberFormatException();
         }
         final String vIntStr = m.group(1);
-        unitStr = m.group(2);
+        this.unitStr = m.group(2);
         this.vInt = Integer.parseInt(vIntStr);
       } catch (final NumberFormatException e) {
         this.vInt = null;
       }
 
-      // try and parse as double
-      if (this.vInt != null) {
-        this.vDouble = (double) this.vInt;
-      } else {
+      // Try and parse as double, if integer parsing was unsuccessful.
+      if (this.vInt == null) {
         try {
-          final Pattern dp = Pattern.compile("^(-?[0-9]+(?:\\.[0-9]+))\\s*([^-]*)$");
+          // Doubles are allowed without dots, for example when the integer overflows.
+          final Pattern dp = Pattern.compile("^(-?[0-9]+(?:\\.)?(?:[0-9]+))\\s*([^-]*)$");
           final Matcher m = dp.matcher(value);
           if (!m.matches()) {
             throw new NumberFormatException();
           }
           final String vDoubleStr = m.group(1);
-          unitStr = m.group(2);
+          this.unitStr = m.group(2);
 
           this.vDouble = Double.parseDouble(vDoubleStr);
-          if (this.vDouble % 1 == 0) {
-            this.vInt = (int) Math.floor(this.vDouble);
-          }
         } catch (final NumberFormatException e) {
           this.vDouble = null;
         }
       }
 
-      if (this.vDouble != null && unitStr != null && unitStr.length() > 0) {
+      if ((this.vDouble != null || this.vInt != null)
+          && this.unitStr != null
+          && this.unitStr.length() > 0) {
         try {
-          this.unit = getUnit(unitStr);
+          this.unit = getUnit(this.unitStr);
         } catch (final ParserException e) {
           e.printStackTrace();
           throw new UnsupportedOperationException("Could not parse the unit.");
         }
 
         this.stdUnitSig = this.unit.normalize().getSignature();
-        this.vDoubleConvertedToStdUnit = this.unit.convert(this.vDouble);
       }
       // try and parse as datetime
       try {
@@ -219,6 +216,11 @@ public class POV implements EntityFilterInterface {
           "Versioned queries are not supported for subqueries yet. Please file a feature request.");
     }
     final long t1 = System.currentTimeMillis();
+    // Add type-converted substitutes for ints/doubles.
+    final Integer vIntSubst =
+        (this.vDouble != null && this.vDouble % 1 == 0) ? (int) Math.rint(this.vDouble) : null;
+    final Double vDoubleSubst = (this.vInt != null) ? (double) this.vInt : null;
+
     try {
       this.connection = query.getConnection();
       this.targetSet = query.getTargetSet();
@@ -272,14 +274,25 @@ public class POV implements EntityFilterInterface {
       } else {
         callPOV.setNull(6, VARCHAR);
       }
-      if (this.vInt != null) { // vInt
-        callPOV.setInt(7, this.vInt);
+      if (this.vInt != null || this.vDouble != null) { // Some numeric
+        if (this.vInt != null) {
+          callPOV.setInt(7, this.vInt);
+          callPOV.setDouble(8, vDoubleSubst);
+        } else {
+          if (vIntSubst == null) {
+            callPOV.setNull(7, INTEGER);
+          } else {
+            callPOV.setInt(7, vIntSubst);
+          }
+          callPOV.setDouble(8, this.vDouble);
+        }
+        // finally: do unit conversion
+        if (this.unitStr != null && this.unitStr.length() > 0) {
+          this.vDoubleConvertedToStdUnit =
+              this.unit.convert(this.vDouble != null ? this.vDouble : vDoubleSubst);
+        }
       } else {
         callPOV.setNull(7, INTEGER);
-      }
-      if (this.vDouble != null) { // vDouble
-        callPOV.setDouble(8, this.vDouble);
-      } else {
         callPOV.setNull(8, DOUBLE);
       }
       if (this.unit != null) {
@@ -505,6 +518,27 @@ public class POV implements EntityFilterInterface {
     return ret;
   }
 
+  /** Return the Int value, which may be null. */
+  public Integer getVInt() {
+    if (this.vInt != null) {
+      return Integer.valueOf(vInt);
+    }
+    return null;
+  }
+
+  /** Return the Double value, which may be null. */
+  public Double getVDouble() {
+    if (this.vDouble != null) {
+      return Double.valueOf(vDouble);
+    }
+    return null;
+  }
+
+  /** Return the Datetime value, which may be null. */
+  public DateTimeInterface getVDatetime() {
+    return this.vDatetime;
+  }
+
   public String getAggregate() {
     return this.aggregate;
   }
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));
     }
   }
 }
diff --git a/src/test/java/org/caosdb/server/query/TestCQL.java b/src/test/java/org/caosdb/server/query/TestCQL.java
index ff1be776b041490aac7c434acdee73c96a9e88f9..3a151fc3b7b908936aa5087b5b7509be73abc278 100644
--- a/src/test/java/org/caosdb/server/query/TestCQL.java
+++ b/src/test/java/org/caosdb/server/query/TestCQL.java
@@ -240,6 +240,7 @@ public class TestCQL {
   String queryIssue132b = "FIND ENTITY WHICH HAS BEEN CREATED TODAY BY ME";
   String queryIssue134 = "SELECT pname FROM  ename";
   String queryIssue131 = "FIND ENTITY WITH pname = 13 €";
+  String queryIssue145 = "FIND ENTITY WITH pname145 = 10000000000";
 
   // File paths ///////////////////////////////////////////////////////////////
   String filepath_verb01 = "/foo/";
@@ -3781,6 +3782,7 @@ public class TestCQL {
 
     System.out.println(sfq.toStringTree(parser));
     assertEquals("POV(pname,=,1.02m)", sfq.filter.toString());
+    assertEquals(1.02, ((POV) sfq.filter).getVDouble(), 0.0);
 
     // 5 children: FIND, entity, WHITE_SPACE, filter, EOF
     assertEquals(5, sfq.getChildCount());
@@ -6906,4 +6908,31 @@ public class TestCQL {
     assertEquals("POV(pname2,>,30)", pov1.getSubProperty().getFilter().toString());
     assertEquals("POV(pname2,<,40)", pov2.getSubProperty().getFilter().toString());
   }
+
+  /**
+   * Integer values which are too large for Int32
+   *
+   * <p>String queryIssue145= "FIND ENTITY WITH pname145 = 10000000000";
+   */
+  @Test
+  public void testIssue145() {
+    // must yield a valid value
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.queryIssue145));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+    assertEquals("POV(pname145,=,10000000000)", sfq.filter.toString());
+
+    // assert value
+    POV pov = ((POV) sfq.filter);
+    System.out.println(pov.getValue());
+    assertEquals("10000000000", pov.getValue());
+    assertNotNull(pov.getVDouble());
+    assertNull(pov.getVInt());
+    assertEquals(1e10, pov.getVDouble().doubleValue(), 0.0);
+  }
 }