crpb

unfortuanetly, this only seems to work for Outlook and iOS. Neither Apple Mail or Thunderbird do seem to care about these. I know that Thunderbird looks for something called Autoconfig and Apple Mail's autodiscover mechanism seems to be even more opaque. It's such a downer, that everyone seems to cook up their own solution for this.

  • crpb replied to this.

    sbudach

    My Claws-Mail at least is happy with those imaps and submission-references.

    EDIT: Did a bit of reading on Thunderbird...
    https://wiki.mozilla.org/Thunderbird:Autoconfiguration
    https://wiki.mozilla.org/Thunderbird:Autoconfiguration:DNSBasedLookup

    Maybe there already is such an app or i think i will write my own little bottle-app to provide a backend for "TXT mailconf=uri.to.app/emaildomain.tld" which then does an SRV-Lookup and generate a config.xml with the corresponding fields...

    OR SOMETHING LIKE THAT o_0..
    Still need to test if those config.xml with "TXT mailconf=" entries even work now. Most references in the mozilla-wiki are dead...

      crpb

      Yeah… I read something about such an app. I wasn't aware, that you can invoke it as a result of a TXT DNS lookup…

      Well, each domain would just have an DNS TXT Entry Pointing to "mailconf=https://uri.to.app/dnsdomain.tld" to make it possible.
      For clarification an example with dig

      # dig +short TXT domainA.tld
      "v=spf1 mx -all"
      "mailconf=https://ac.my.app/mail/domainA.tld/config.xml"
      # dig +short TXT domainB.tld
      "v=spf1 mx -all"
      "mailconf=https://ac.my.app/mail/domainB.tld/config.xml"

      EDIT:
      And internally it should query all those SRV-Entries on "domainA|B|X.tld" and generate a config with the respective DNS-Priorities. So basically as default something like: incomingserver imap+ssl, outgoingserver submission+tls if you use that template from above.

      Nothing really test so far! Just a thought of how this could be done without all those other "A" subdomains (autoconfig|autodiscover.domain.tld) and no extra configuration needed at company-domain.tld.

      And after a bit of searching i at least found a few references. But not exactly what i was thinking about.
      https://rseichter.github.io/automx2/
      https://github.com/Monogramm/autodiscover-email-settings

      cheers!

      a month later

      BTRFS MAINTENANCE

      To not have to care so much about doing recommended regularly Maintenance-Tasks on the BTRFS Volumes you can install the Package btrfsmaintenance.

      There is also an article about disabling btrfsmaintenance but the note "Disabling automatic drive maintenance, in favor of manual maintenance, is desired." without any explanation is nor helpful at all.

      zypper refresh
      zypper install -y btrfsmaintenance
      # Let the script do most of the work on all (sub)volumes
      sed '/^BTRFS/s/\//auto/g' /etc/sysconfig/btrfsmaintenance -i
      systemctl restart btrfsmaintenance-refresh.service

      By default the Systemd-Timers btrfs.scrub and btrfs-balance are now active. I guess this enough for now.

      25 days later

      crpb To find the users and their mail directories, there is a single line command:
      echo "select maildir,username from users where maildir<>'';" | mysql -N grommunio | sort

      Hey Walter,

      that is certainly another Option. Currently i use the following in my scripts.

      _grom_query_maildir(){
        grommunio-admin user query --filter username="${1}" maildir
      }
      2 months later

      Learn Ham - Update 2024.04.28 2024.06.26

      As i was bothered by the Spam-Handling on some Mails from an Mailinglist which always landed in my Junk-Folder i finally got around to create this little Function script.

      Both scripts can be configured to wait at least N Days before the Mail will be processed by the script.
      And aswell as in the original you can configure if it should delete the Mail after learning it.

      The HAM-Runner will mark messages as READ after indexing them if they aren't deleted.

      Additionally you can now provide optional parameters to rspamc to be able to use another RSPAMD Installation.

      grommunio-ham-run.sh

      .service, .timer & installscript in the folder

      grommunio-spam-run.sh

      Create HAM-LEARN-FOLDER for all users

      USERS=$(grommunio-admin user query username status maildir |awk '$2=="0/active" && $3 ~ /\/var\/lib\/gromox/ {print$1}')
      # this might say it failed but then the folder just exists already
      for USER in $USERS; do 
      grommunio-admin exmdb $USER folder create -t IPF.Note --comment "HAM-Training" TRAIN-HAM 9; 
      done

      PS: HowTo Moving mails automatically to Junk-Folder via Inbox-Rule https://community.grommunio.com/d/572-spam-handling/12

      Autodiscover

      GPO Copy/Paste

      <?xml version="1.0" encoding="utf-8"?>
      <RegistrySettings clsid="{A3CCFC41-DFDB-43a5-8D26-0FE8B954DA51}">
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeExplicitO365Endpoint" status="ExcludeExplicitO365Endpoint" image="11" changed="2023-01-06 06:48:06" uid="{3607AC9F-C086-4FF5-AD5E-DC8A2A8EC815}" bypassErrors="1"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeExplicitO365Endpoint" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeLastKnownGoodURL" status="ExcludeLastKnownGoodURL" image="11" changed="2023-01-06 06:47:24" uid="{A4BDDC22-D8C2-40E3-ABA8-2E4C4CE47558}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeLastKnownGoodURL" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpsRootDomain" status="ExcludeHttpsRootDomain" image="11" changed="2023-01-06 06:47:28" uid="{A9023706-376D-4FB9-8E30-4BBBB0FA6981}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpsRootDomain" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpsAutoDiscoverDomain" status="ExcludeHttpsAutoDiscoverDomain" image="11" changed="2023-01-06 06:47:31" uid="{36E47622-6C23-4D1E-8ECB-07A350DFCFD0}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpsAutoDiscoverDomain" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpRedirect" status="ExcludeHttpRedirect" image="11" changed="2023-01-06 06:47:35" uid="{105A60A9-BBAC-40AF-88FC-7AF986D6A568}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpRedirect" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeScpLookup" status="ExcludeScpLookup" image="11" changed="2023-01-06 06:47:39" uid="{699006E9-FB8F-492F-81F4-80472FFE8972}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeScpLookup" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeSrvRecord" status="ExcludeSrvRecord" image="11" changed="2023-01-06 06:47:45" uid="{5B7B8077-42E9-4671-A6B5-FBA0F0B277A7}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeSrvRecord" type="REG_DWORD" value="00000000"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="EnableOffice365ConfigService" status="EnableOffice365ConfigService" image="11" changed="2023-01-06 06:47:51" uid="{194041B7-4A42-49AD-9AB1-BFC997765D6F}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="EnableOffice365ConfigService" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeExplicitO365Endpoint" status="ExcludeExplicitO365Endpoint" image="11" changed="2023-01-06 06:44:28" uid="{5F314DA6-E185-477E-985C-06B23414101E}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeExplicitO365Endpoint" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeLastKnownGoodURL" status="ExcludeLastKnownGoodURL" image="11" changed="2023-01-06 06:44:52" uid="{4E4FA923-0695-44F2-A4C1-8026615BA571}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeLastKnownGoodURL" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpsRootDomain" status="ExcludeHttpsRootDomain" image="11" changed="2023-01-06 06:45:05" uid="{A9B1A99D-16F2-4421-BD93-B8850A6B62C1}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpsRootDomain" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpsAutoDiscoverDomain" status="ExcludeHttpsAutoDiscoverDomain" image="11" changed="2023-01-06 06:45:31" uid="{85F10106-1B5D-49A6-8782-D69355A0719C}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpsAutoDiscoverDomain" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpRedirect" status="ExcludeHttpRedirect" image="11" changed="2023-01-06 06:45:36" uid="{DD799D8D-A86C-4EB4-B0DB-D31A7E0B5E7D}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpRedirect" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeScpLookup" status="ExcludeScpLookup" image="11" changed="2023-01-06 06:45:42" uid="{DC5FA5D9-0ADC-4A87-9525-7A6D436D9957}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeScpLookup" type="REG_DWORD" value="00000001"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeSrvRecord" status="ExcludeSrvRecord" image="11" changed="2023-01-06 06:45:50" uid="{7232EDBC-B500-4BB7-BB54-87F674C5A5F5}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeSrvRecord" type="REG_DWORD" value="00000000"/></Registry>
        <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="EnableOffice365ConfigService" status="EnableOffice365ConfigService" image="11" changed="2023-01-06 06:45:57" uid="{E08FC552-3554-4909-84FE-8D04FF60F921}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="EnableOffice365ConfigService" type="REG_DWORD" value="00000001"/></Registry>
      </RegistrySettings>

      user.reg

      Windows Registry Editor Version 5.00
      [HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Outlook\AutoDiscover]
      "ExcludeExplicitO365Endpoint"=dword:00000001
      "ExcludeLastKnownGoodURL"=dword:00000001
      "ExcludeHttpsRootDomain"=dword:00000001
      "ExcludeHttpsAutoDiscoverDomain"=dword:00000001
      "ExcludeHttpRedirect"=dword:00000001
      "ExcludeScpLookup"=dword:00000001
      "ExcludeSrvRecord"=dword:00000000
      "EnableOffice365ConfigService"=dword:00000000
      
      [HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover]
      "ExcludeExplicitO365Endpoint"=dword:00000001
      "ExcludeLastKnownGoodURL"=dword:00000001
      "ExcludeHttpsRootDomain"=dword:00000001
      "ExcludeHttpsAutoDiscoverDomain"=dword:00000001
      "ExcludeHttpRedirect"=dword:00000001
      "ExcludeScpLookup"=dword:00000001
      "ExcludeSrvRecord"=dword:00000000
      "EnableOffice365ConfigService"=dword:00000000

      I don't like anything other than DNS Records 😛

      3 months later

      Get Folder-Permissions a bit quicker than before...

      exmdb_get_permissions_hr() {
        local OWNER FID PFLDS FOLDER EXMDB SQLQUERY RET
        if [[ "$#" -ne 1 ]]; then
          echo "Usage: ${FUNCNAME[0]} username@domain.tld"
          return 1
        fi
        _grom_users="${_grom_users:=$(grommunio-admin user query username |sed 1d)}"
        # Check for correct Username
        if [[ "$_grom_users" =~ $1 ]]; then
          OWNER="${1}"
          EXMDB="$(grommunio-admin user query maildir --filter username="$OWNER")/exmdb/exchange.sqlite3"
          # grommunio-admin taginfo 805371935
          # 0x3001001f (805371935): DISPLAYNAME, type WSTRING
          SQLQUERY="
      -- THIS IS A COMMENT!
      -- SELECT DISTINCT(printf('0x%x', p.folder_id)) as hexfid, f1.propval FROM permissions p
      -- INNER JOIN folder_properties f1 on f1.folder_id = p.folder_id and f1.proptag = 805371935
      SELECT DISTINCT(printf('0x%x', p.folder_id)) as hexfid FROM permissions p
      WHERE p.username != 'default';
      "
            # True if FILE exists and is readable.
            if [ -r "$EXMDB" ]; then
              PFLDS="$(echo "$SQLQUERY" |sqlite3 --readonly --noheader "$EXMDB")"
              if [ "${#PFLDS}" -eq 0 ]; then 
                echo "No special permissions in MBX: $OWNER"
                return 0
              fi
              grommunio-admin exmdb "$OWNER" folder list -r | while read -r FOLDER; do
                # Leading '\' in front of grep to make sure no aliases are used.
                FID="$(echo "$FOLDER" |\grep -Po '0x(?<=\ \(0x).*(?=\)$)')"
                echo -e "\033[1m${FOLDER}\033[0m"
                if [[ "$PFLDS" =~ $FID ]]; then
                  grommunio-admin exmdb "$OWNER" folder permissions "$FID"
                fi
              done
            fi
        fi
      }
      complete -F _comp_grom_users exmdb_get_permissions_hr

      Because iterating over a thousand folders with grommunio-admin exmdb user@domain.tld permissions $FOLDERID takes bit too long if nothing is configured anyway..

      There are some folders which are not listed with grommunio-admin exmdb user@domain.tld folder list -r, so it might print the List in those cases.

      a month later

      crpb Automated version with Configs from RPMs and other sutff

      The script to build and configure traffic-status and brotli now removes all temporary dependencies to keep a small footprint on the Server.

      alien8.sh

      a year later

      /tmp as tmpfs on appliance

      ref: https://en.opensuse.org/openSUSE:Tmp_on_tmpfs

      BTRFS SYSTEM OLD

      btrfs subvolume delete -i $(btrfs subvolume list /  |awk '/@\/tmp/ {print $2}') /
      systemctl link /usr/share/systemd/tmp.mount
      rm -Rf /tmp
      reboot

      XFS SYSTEM CURRENT

      rm -Rf /tmp/*
      systemctl link /usr/share/systemd/tmp.mount
      reboot
      crpb changed the title to scripting / snippets / notepad .

      grommunio-spam-run.sh

      only learn and optional delete with a minimum age of n days

      #!/bin/bash
      # vim:ts=2 sts=2 sw=2 et
      
      if ! [ -e /etc/gromox/spamrun.cfg ]; then
        cat << EOF > /etc/gromox/spamrun.cfg
      # Only scan messages which are older than n days.
      # Default: SPAMRUN_DAYS=7
      SPAMRUN_DAYS=7
      # To delete the message after the scan set to 'true' 
      # Default: SPAMRUN_DELETE=false
      SPAMRUN_DELETE=false
      EOF
      fi
      
      
      # source config file
      if [ -r /etc/gromox/spamrun.cfg ]; then
        . /etc/gromox/spamrun.cfg
      fi
      if [ -z ${SPAMRUN_DAYS+x} ]; then
        SQLITE_QUERY='select message_id,mid_string from messages where parent_fid=0x17;'
      else
        SQLITE_QUERY="""
        SELECT m.message_id,m.mid_string
        FROM messages m
        INNER JOIN message_properties mp1
        ON mp1.message_id = m.message_id
        AND mp1.proptag = 235274304
        AND (mp1.propval/10000000-11644473600) < unixepoch('now','-$SPAMRUN_DAYS days')
        WHERE m.parent_fid = 0x17;
        """
      fi
      DO_DEL="${SPAMRUN_DELETE:-"false"}"
      # add "-d" to delete junk emails after they have been learned
      if [ "$1" = "-d" ]
      then
        DO_DEL=true
      fi
      
      MYSQL_CFG="/etc/gromox/mysql_adaptor.cfg"
      
      if [ ! -e "${MYSQL_CFG}" ] ; then
        echo "MySQL configuration not found. (${MYSQL_CFG})"
        exit 1
      fi
      
      MYSQL_PARAMS="--skip-column-names --skip-line-numbers"
      MYSQL_USERNAME=$(sed -ne 's/mysql_username\s*=\s*\(.*\)\s*/-u\1/pI' ${MYSQL_CFG})
      MYSQL_PASSWORD=$(sed -ne 's/mysql_password\s*=\s*\(.*\)\s*/-p\1/pI' ${MYSQL_CFG})
      MYSQL_DBNAME=$(sed -ne 's/mysql_dbname\s*=\s*\(.*\)\s*/\1/pI' ${MYSQL_CFG})
      MYSQL_HOST=$(sed -ne 's/mysql_host\s*=\s*\(.*\)\s*/-h\1/pI' ${MYSQL_CFG})
      MYSQL_QUERY="SELECT username,maildir from users where id <> 0 and maildir <> \"\";"
      MYSQL_CMD=("mysql" "${MYSQL_PARAMS}" "${MYSQL_USERNAME:=-uroot}" "${MYSQL_PASSWORD:=}" "${MYSQL_HOST:=-hlocalhost}" "${MYSQL_DBNAME:=grommunio}")
      # shellcheck disable=SC2068
      if ${MYSQL_CMD[@]}<<<"exit"&>/dev/null; then
        echo "${MYSQL_QUERY}" | ${MYSQL_CMD[@]} | while read -r USERNAME MAILDIR ; do
        sqlite3 -readonly -tabs -noheader "${MAILDIR}/exmdb/exchange.sqlite3" "$SQLITE_QUERY" |
          while read -r MESSAGEID MIDSTRING; do
            echo "Learning spam for user ${USERNAME}" | systemd-cat -t grommunio-spam-run
            MSGFILE="$MAILDIR/eml/$MIDSTRING"
            if [[ ! -f "$MSGFILE" ]]; then
              gromox-exm2eml -u "${USERNAME}" "${MESSAGEID}" 2>/dev/null | rspamc learn_spam | systemd-cat -t grommunio-spam-run
            else
              rspamc learn_spam --header 'Learn-Type: bulk' "$MSGFILE" | systemd-cat -t grommunio-spam-run
            fi
            if [ ${DO_DEL} == "true" ]; then
              /usr/sbin/gromox-mbop -u "${USERNAME}" delmsg -f 0x17 "${MESSAGEID}" | systemd-cat -t grommunio-spam-run
            fi
          done
          rm -f "${SPAMLIST}"
        done
      else
        echo "MySQL-Connection couldn't be established, please check your configuration." | systemd-cat -t grommunio-spam-run -p err
      fi

      appliance - xfs - dedicated /var/lib/gromox

      DISK=/dev/sdb
      parted -s $DISK mklabel gpt
      parted -s $DISK mkpart primary 0GB 100%
      pvcreate ${DISK}1
      vgcreate gromox ${DISK}1
      # use only 80% so we can make use of lvm snapshots for backups
      lvcreate gromox -n maildir -l80%VG
      # enable bigtime=1 to remove silly messages about 2038
      mkfs.xfs -m bigtime=1 /dev/gromox/maildir
      #lsblk -f /dev/gromox/maildir --output UUID --noheadings
      echo "UUID=$(lsblk -f /dev/gromox/maildir --noheadings --output UUID) /var/lib/gromox xfs defaults 0 0" |tee -a /etc/fstab
      mv /var/lib/gromox{,.bak}
      mkdir /var/lib/gromox
      mount /var/lib/gromox
      #cp -a /var/lib/gromox.bak/* /var/lib/gromox/
      rsync -av /var/lib/gromox.bak/ /var/lib/gromox
      find /var/lib/gromox -ls
      #chown gromox:gromox /var/lib/gromox
      #chmod 770 /var/lib/gromox
      rm -Rf /var/lib/gromox.bak

      LVM Snapshot for backups - example

      ##  STOP SERVICES TO CLEANUP midb's
      /usr/bin/systemctl stop gromox-midb.service gromox-imap.service gromox-pop3.service
      # DO SOME CLEANUP ON THE MAILBOXES
      for d in /var/lib/gromox/user/*/*; do
        /usr/sbin/gromox-mbop -d $d vacuum;
        /usr/sbin/gromox-mbop -d $d purge-datafiles;
      done
      ## CREATE LVM SNAPSHOT
      /sbin/lvcreate -l10%FREE --snapshot --name s_maildir /dev/gromox/maildir
          Logical volume "s_maildir" created.
      ## START SERVICES AGAIN (we have a snapshot!)
      /usr/bin/systemctl start gromox-midb.service gromox-imap.service gromox-pop3.service
      ## SHOW THAT WE HAVE A SNAP
      /sbin/lvs
        LV        VG        Attr       LSize  Pool Origin  Data%  Meta%  Move Log Cpy%Sync Convert
        LVRoot    grommunio -wi-ao---- 19.68g
        maildir   gromox    owi-aos--- 40.00g
        s_maildir gromox    swi-a-s---  1.00g      maildir 0.00
      ## TEMPORARY MOUNT POINT
      SNAP=$(mktemp --suffix=lvmsnap --directory)
      ## MOUNT XFS ( we need -o nouuid as xfs doesn't like duplicates of UUIDs )
      /usr/bin/mount -o nouuid /dev/gromox/s_maildir $SNAP
      ## SHOW THE CONTENTS
      /usr/bin/find $SNAP -ls
            128      0 drwxrwx---   5 gromox   gromox         45 Apr  1 16:41 /tmp/tmp.xa5jeBj8Rylvmsnap
            131      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/domain
       33554560      0 drwxrwx---   6 gromox   gromox         56 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/queue
       67149888      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/queue/mess
      100663424      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/queue/save
            132      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/queue/timer
       33554561      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/queue/cache
       67149889      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/user
      ## RUN BACKUP / RSYNC / WHATEVER
      
      ## AND AFTER WE ARE FINISHED
      /usr/bin/umount $SNAP
      /sbin/lvremove /dev/gromox/s_maildir --yes

      APT Pinning Supported/Community/Devel

      Whomever might need it. Now you can 🙂

      v=supported will also be available in a few days.

      % apt policy
      Package files:
       100 /var/lib/dpkg/status
           release a=now
        50 https://download.grommunio.com/devel/Debian_12 Debian_12/main amd64 Packages
           release v=devel,o=grommunio,n=Debian_12,l=grommunio,c=main,b=amd64
           origin download.grommunio.com
       450 https://download.grommunio.com/community/Debian_12 Debian_12/main amd64 Packages
           release v=community,o=grommunio,n=Debian_12,l=grommunio,c=main,b=amd64
           origin download.grommunio.com
       500 https://download.grommunio.com/supported/Debian_12 Debian_12/main amd64 Packages
           release o=grommunio,n=Debian_12,l=grommunio,c=main,b=amd64
           origin download.grommunio.com
       500 http://ftp2.de.debian.org/debian bookworm-updates/main amd64 Packages
           release v=12-updates,o=Debian,a=stable-updates,n=bookworm-updates,l=Debian,c=main,b=amd64
           origin ftp2.de.debian.org
       500 http://security.debian.org/debian-security bookworm-security/main amd64 Packages
           release v=12,o=Debian,a=stable-security,n=bookworm-security,l=Debian-Security,c=main,b=amd64
           origin security.debian.org
       500 http://ftp2.de.debian.org/debian bookworm/main amd64 Packages
           release v=12.5,o=Debian,a=stable,n=bookworm,l=Debian,c=main,b=amd64
           origin ftp2.de.debian.org
      Pinned packages:
           libapache2-mod-php -> 2:8.2+93 with priority -1
           apache2-bin -> 2.4.57-2 with priority -1
           apache2 -> 2.4.57-2 with priority -1
      
      
      % cat /etc/apt/preferences.d/80-grommunio
      Package: *
      Pin: release o=grommunio, v=devel
      Pin-Priority: 50
      
      Package: *
      Pin: release o=grommunio, v=community
      Pin-Priority: 450
      
      
      % cat /etc/apt/sources.list.d/grommunio.sources
      # Supported
      Types: deb
      URIs: https://download.grommunio.com/supported/Debian_12/
      Suites: Debian_12
      Components: main
      Enabled: yes
      Signed-By: /usr/share/keyrings/download.grommunio.com.gpg
      Signed-By:
       -----BEGIN PGP PUBLIC KEY BLOCK-----
       .
       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
       mGJfShvIgpqehgKMDoUzZkpIov34ef7O6RxVVA==
       =D9oD
       -----END PGP PUBLIC KEY BLOCK-----
      
      # Community
      Types: deb
      URIs: https://download.grommunio.com/community/Debian_12/
      Suites: Debian_12
      Components: main
      Enabled: yes
      #Signed-By: /usr/share/keyrings/download.grommunio.com.gpg
      Signed-By:
       -----BEGIN PGP PUBLIC KEY BLOCK-----
       .
       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
       mGJfShvIgpqehgKMDoUzZkpIov34ef7O6RxVVA==
       =D9oD
       -----END PGP PUBLIC KEY BLOCK-----
      
      # Devel
      Types: deb
      URIs: https://download.grommunio.com/devel/Debian_12/
      Suites: Debian_12
      Components: main
      Enabled: yes
      #Signed-By: /etc/apt/keyrings/download.grommunio.com.gpg
      Signed-By:
       -----BEGIN PGP PUBLIC KEY BLOCK-----
       .
       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
       mGJfShvIgpqehgKMDoUzZkpIov34ef7O6RxVVA==
       =D9oD
       -----END PGP PUBLIC KEY BLOCK-----
      a month later

      Activate ZRAM Swap

      *vroom* *vroom*

      OpenSuSe

      zypper in -y zram-generator
      mkdir -p /etc/systemd/zram-generator.conf.d
      printf '[zram0]\nzram-size = int(ram)\n' >> /etc/systemd/zram-generator.conf.d/0.conf

      Debian

      apt-get install -y systemd-zram-generator
      echo 'zram-size = int(ram)' |tee -a /etc/systemd/zram-generator.conf

      This will end up with 100% zramswap of the original ramsize.
      That isn't the double of ram just out of the blue tho :-).

      https://www.kernel.org/doc/html/next/admin-guide/blockdev/zram.html

      a month later

      Passwordless IMAP for archive purposes

      No more relying on users to update their passwords for external mail archiving over imap or worse storing their passwords /o\.

      References:
      https://community.grommunio.com/d/349-geloschte-objekte-wiederherstellen/9
      https://community.grommunio.com/d/836-seperate-authmgrcfg/6

      Upstream: https://github.com/crpb/grommunio/blob/main/tools/enable-pwless-imapd

      Changed a few things, look at the upstream url..

      Caveats: as i use an additional firewall-cmd zone the rules for like 443,8443,.. will not work and you might have to add them if you need or you might change the script to use the public zone.

      2 months later

      Appliance Basic Setup - Ansible

      Here is my freshly revised Playbook to prepare the Appliance.

      And no, i haven't had the need for complex roles so it's just a play.

      Requirements on Appliance

      • root password set (for access via ssh)
      • Network configured (The MachineID fix might lead to a new ip with dhcp)

      Requirements on Workstation

      mkdir -p group_vars
      echo pubkey_url: https://what.ever/some/pubkey.pub >> ~/group_vars/all
      cat << EOF > inventory.yaml
      grommunio:
        hosts:
          grommunio-test-1.your.network.local:
      EOF

      Tasks

      • - Fixes Systemd-Machine-ID (fixed in 2025.01)
      • Enable Systemd-Networkd instead of wicked
      • Auto-accept Repo-Keys and apply latest Updates
      • Set Timezone
      • Install various Software-Packages
      • Install virtualizing agent depending on the Hardware (QEMU, VMware or Hyper-V)
      • Activate ZRAM (100%)
      • Enable etckeeper
      • Enable automatic installation of security updates / daily
      • Enable group wheel and allow sudo for them (no user creation included)
      • Grub timeout 2 seconds instead of 10
      • Install SSH pubkey for root via http link
      • Disable Password Auth for SSH (pubkey only!)
      • Enable tmpfs for /tmp

      prepare-appliance.json

      [
      	{
      		"name": "Python311",
      		"hosts": "doesntexist",
      		"become": false,
      		"tags": "python",
      		"tasks": [
      			{
      				"name": "Install Python311",
      				"ansible.builtin.shell": "zypper --quiet --non-interactive install -y --no-recommends --force python311",
      				"ignore_errors": true
      			},
      	{
      		"name": "Reset ssh connection to allow user changes to affect 'current login user'",
      		"ansible.builtin.meta": "reset_connection"
      	}
      		]
      	},
      	{
      		"name": "NetworkD",
      		"hosts": "all",
      		"become": false,
      		"tags": "systemd",
      		"tasks": [
      			{
      				"name": "Disable wicked",
      				"ansible.builtin.systemd_service": {
      					"name": "wicked",
      					"enabled": false,
      				}
      			},
      			{
      				"name": "Enable NetworkD and Resolved",
      				"ansible.builtin.systemd_service": {
      					"name": "{{ item }}",
      					"state": "started",
      					"enabled": true
      				},
      				"with_items": [
      					"systemd-networkd",
      					"systemd-resolved"
      				]
      			},
      			{
      				"name": "resolv.conf",
      				"ansible.builtin.file": {
      					"src": "/run/systemd/resolve/resolv.conf",
      					"dest": "/etc/resolv.conf",
      					"state": "link",
      					"force": true
      				},
      				"register": "resolvconf",
      				"changed_when": "resolvconf.changed"
      			}
      		]
      	},
      	{
      		"name": "SystemD",
      		"hosts": "grommunio",
      		"become": false,
      		"tags": "systemd",
      		"tasks": [
      			{
      				"name": "JournalDPersistent",
      				"ansible.builtin.blockinfile": {
      					"path": "/etc/systemd/journald.conf.d/persistent.conf",
      					"create": true,
      					"owner": "root",
      					"group": "root",
      					"mode": "0660",
      					"block": "[Journal]\nStorage=persistent\nCompress=no\nSplitMode=no\n"
      				},
      				"tags": "systemd, journald"
      			}
      		]
      	},
      
      	{
      		"name": "Install Updates",
      		"hosts": "grommunio",
      		"become": false,
      		"tags": "updates",
      		"tasks": [
      			{
      				"name": "Activate-Grommunio-Repo",
      				"ansible.builtin.command": "grommunio-repo community",
      				"register": "grommuniorepo",
      				"ignore_errors": true,
      				"changed_when": "grommuniorepo"
      			},
      			{
      				"name": "Grommunio-Update Check",
      				"ansible.builtin.command": "grommunio-update check",
      				"register": "grommuniorepo",
      				"ignore_errors": true,
      				"changed_when": "grommuniorepo"
      			},
      			{
      				"name": "TestRepo",
      				"ansible.builtin.shell": "zypper --quiet repos --name grommunio >/dev/null 2>&1",
      				"register": "grommuniorepo",
      				"ignore_errors": true,
      				"changed_when": "grommuniorepo"
      			},
      			{
      				"name": "Refresh-Repos-Accept-Keys",
      				"ansible.builtin.command": "zypper --quiet --gpg-auto-import-keys ref",
      				"when": "grommuniorepo.rc != 0",
      				"ignore_errors": true,
      				"register": "refret",
      				"changed_when": "refret"
      			},
      			{
      				"name": "Activate-Grommunio-Repo-And-Upgrade",
      				"ansible.builtin.command": "grommunio-update upgrade community --noreboot",
      				"when": "grommuniorepo.rc != 0",
      				"ignore_errors": true,
      				"register": "ignoreerrors",
      				"changed_when": "ignoreerrors"
      			}
      		]
      	},
      	{
      		"name": "Virtualization",
      		"hosts": "grommunio",
      		"become": false,
      		"tags": "virtualization",
      		"gather_facts": true,
      		"tasks": [
      			{
      				"name": "Install QemuGuestAgent",
      				"community.general.zypper": {
      					"name": [
      						"qemu-guest-agent"
      					],
      					"state": "installed",
      					"disable_recommends": true,
      					"clean_deps": true
      				},
      				"tags": "hypervisor",
      				"when": "ansible_system_vendor == \"QEMU\""
      			},
      			{
      				"name": "Enable qemu-guest-agent",
      				"ansible.builtin.systemd_service": {
      					"name": "qemu-guest-agent",
      					"state": "started",
      					"enabled": true
      				},
      				"tags": "hypervisor",
      				"when": "ansible_system_vendor == \"QEMU\""
      			},
      			{
      				"name": "Install HyperV agent",
      				"community.general.zypper": {
      					"name": [
      						"hyper-v"
      					],
      					"state": "installed",
      					"disable_recommends": true,
      					"clean_deps": true
      				},
      				"tags": "hypervisor",
      				"when": "ansible_system_vendor == \"Microsoft Corporation\""
      			},
      			{
      				"name": "Enable HyperV agent",
      				"ansible.builtin.systemd_service": {
      					"name": "{{ item }}",
      					"state": "started",
      					"enabled": true
      				},
      				"with_items": [
      					"hv_fcopy_daemon",
      					"hv_kvp_daemon",
      					"hv_vss_daemon"
      				],
      				"tags": "hypervisor",
      				"when": "ansible_system_vendor == \"Microsoft Corporation\""
      			},
      			{
      				"name": "Install OpenVMTools",
      				"community.general.zypper": {
      					"name": [
      						"open-vm-tools"
      					],
      					"state": "installed",
      					"disable_recommends": true,
      					"clean_deps": true
      				},
      				"tags": "hypervisor",
      				"when": "ansible_system_vendor == \"VMware, Inc.\""
      			},
      			{
      				"name": "Enable OpenVMTools",
      				"ansible.builtin.systemd_service": {
      					"name": "{{ item }}",
      					"state": "started",
      					"enabled": true
      				},
      				"with_items": [
      					"vgauthd",
      					"vmtoolsd"
      				],
      				"tags": "hypervisor",
      				"when": "ansible_system_vendor == \"VMware, Inc.\""
      			}
      		]
      	},
      	{
      		"name": "TmpFS_Enable",
      		"hosts": "grommunio",
      		"tags": "tmpfs",
      		"become": false,
      		"tasks": [
      			{
      				"name": "FindMntTmp",
      				"ansible.builtin.command": "findmnt --types=tmpfs --target=/tmp --noheadings",
      				"ignore_errors": true,
      				"register": "notmpfs"
      			},
      			{
      				"name": "DeleteTmp",
      				"ansible.builtin.file": {
      					"path": "/tmp",
      					"state": "absent"
      				},
      				"when": "notmpfs.rc != 0",
      				"register": "tmpfsdeleted"
      			},
      			{
      				"name": "CreateTmp",
      				"ansible.builtin.file": {
      					"path": "/tmp",
      					"state": "directory",
      					"mode": "0755"
      				},
      				"when": "notmpfs != 0",
      				"register": "tmpfsempty"
      			},
      			{
      				"name": "TmpfsEnable",
      				"ansible.builtin.file": {
      					"src": "/usr/share/systemd/tmp.mount",
      					"dest": "/etc/systemd/system/tmp.mount",
      					"state": "link"
      				},
      				"register": "tmpfsenabled",
      				"when": "tmpfsempty",
      				"changed_when": "tmpfsenabled.changed"
      			},
      			{
      				"name": "Reboot",
      				"ansible.builtin.reboot": {
      					"msg": "Reboot initiated by Ansible for TmpFS",
      					"connect_timeout": 5,
      					"reboot_timeout": 300,
      					"pre_reboot_delay": 0,
      					"post_reboot_delay": 30,
      					"test_command": "uptime"
      				},
      				"when": "tmpfsenabled.changed"
      			}
      		]
      	},
      	{
      		"name": "Basics",
      		"hosts": "grommunio",
      		"become": false,
      		"gather_facts": true,
      		"handlers": [
      			{
      				"name": "Restart ssh",
      				"ansible.builtin.systemd_service": {
      					"name": "sshd",
      					"daemon_reload": true
      				}
      			},
      			{
      				"name": "Grub2MkConfig",
      				"ansible.builtin.command": "grub2-mkconfig -o /boot/grub2/grub.cfg"
      			}
      		],
      		"tasks": [
      			{
      				"name": "Timezone",
      				"community.general.timezone": {
      					"name": "UTC"
      				}
      			},
      			{
      				"name": "Required-software",
      				"community.general.zypper": {
      					"name": [
      						"ShellCheck",
      						"aaa_base-extras",
      						"acl",
      						"bzip2",
      						"git",
      						"growpart",
      						"gron",
      						"htop",
      						"jq",
      						"man",
      						"man-pages",
      						"coreutils-doc",
      						"php8-APCu",
      						"purge-kernels-service",
      						"python3-argcomplete",
      						"bash-completion",
      						"firewalld-bash-completion",
      						"sshfs",
      						"system-group-wheel",
      						"zram-generator",
      						"vim-data"
      					],
      					"state": "present",
      					"disable_recommends": false,
      					"force_resolution": true
      				},
      				"tags": "software"
      			},
      			{
      				"name": "Uninstall replaced thingies",
      				"community.general.zypper": {
      					"name": [
      						"systemd-zram",
      						"yast2-online-update-configuration"
      					],
      					"state": "absent"
      				},
      				"tags": [ "software", "uninstall", "deprecated" ]
      			},
      			{
      				"name": "Cleanup yast2-online-update-configuration",
      				"ansible.builtin.file": {
      					"path": "{{ item }}",
      					"state": "absent"
      				},
      				"with_items": [
      					"/etc/cron.daily/automatic_online_update",
      					"/etc/cron.daily/opensuse.org-online_update"
      				]
      			},
      			{
      				"name": "Install os-update + rebootmgr",
      				"community.general.zypper": {
      					"name": [
      						"os-update",
      						"rebootmgr"
      					],
      					"state": "present",
      					"disable_recommends": true
      				},
      				"tags": [ "software", "os-update", "updates", "rebootmgr" ]
      			},
      			{
      				"name": "os-update only do security-updates",
      				"ansible.builtin.lineinfile": {
      					"dest": "/etc/os-update.conf",
      					"regexp": "^UPDATE_CMD=.*",
      					"line": "UPDATE_CMD=\"security\"",
      					"state": "present"
      				},
      				"tags": [ "os-update", "updates" ]
      			},
      			{
      				"name": "Enable os-update.timer",
      				"ansible.builtin.systemd_service": {
      					"name": "os-update.timer",
      					"enabled": true
      				},
      				"tags": "software"
      			},
      			{
      				"name": "Etckeeper install",
      				"community.general.zypper": {
      					"name": [
      						"etckeeper",
      						"etckeeper-bash-completion",
      						"etckeeper-zsh-completion",
      						"etckeeper-zypp-plugin"
      					],
      					"state": "present",
      					"disable_recommends": true
      				},
      				"tags": [ "software", "etckeeper" ]
      			},
      			{
      				"name": "Enable etckeeper.timer",
      				"ansible.builtin.systemd_service": {
      					"name": "etckeeper.timer",
      					"enabled": true
      				},
      				"tags": "software"
      			},
      			{
      				"name": "Check if Etckeeper is already initialized",
      				"ansible.builtin.stat": {
      					"path": "/etc/.git/"
      				},
      				"register": "etckeeperinit"
      			},
      			{
      				"name": "Etckeeper init",
      				"ansible.builtin.command": "etckeeper init",
      				"when": "not etckeeperinit.stat.exists",
      				"tags": [ "software", "etckeeper" ]
      			},
      			{
      				"name": "Etckeeper Commit",
      				"ansible.builtin.command": "etckeeper commit -m 'init'",
      				"when": "not etckeeperinit.stat.exists",
      				"tags": [ "software", "etckeeper" ]
      			},
      			{
      				"name": "Enable purgekernels",
      				"ansible.builtin.systemd_service": {
      					"name": "purge-kernels",
      					"enabled": true
      				},
      				"tags": "software"
      			},
      			{
      				"name": "Enable Zram0",
      				"ansible.builtin.blockinfile": {
      					"path": "/etc/systemd/zram-generator.conf.d/0.conf",
      					"create": true,
      					"owner": "root",
      					"group": "root",
      					"mode": "0660",
      					"block": "[zram0]\nzram-size = int(ram)\n"
      				},
      				"tags": "zram"
      			},
      			{
      				"name": "Sudoers g=wheel",
      				"ansible.builtin.blockinfile": {
      					"path": "/etc/sudoers.d/wheel",
      					"create": true,
      					"owner": "root",
      					"group": "root",
      					"mode": "0440",
      					"block": "%wheel ALL=(ALL:ALL) ALL\n"
      				},
      				"tags": "sudo"
      			},
      			{
      				"name": "Grub2Timeout 2sec",
      				"ansible.builtin.lineinfile": {
      					"dest": "/etc/default/grub",
      					"regexp": "^GRUB_TIMEOUT=10",
      					"line": "GRUB_TIMEOUT=2",
      					"state": "present"
      				},
      				"tags": "grub",
      				"notify": [
      					"Grub2MkConfig"
      				]
      			},
      			{
      				"name": "Sudoers use userpass",
      				"ansible.builtin.replace": {
      					"path": "/etc/sudoers",
      					"regexp": "'^Defaults targetpw'",
      					"replace": "'#Defaults targetpw'"
      				},
      				"tags": "sudo"
      			},
      			{
      				"name": "Set authorized_keys for root",
      				"tags": "ssh",
      				"ansible.posix.authorized_key": {
      					"user": "root",
      					"state": "present",
      					"key": "{{ lookup('url', pubkey_url, split_lines=False) }}"
      				}
      			},
      			{
      				"name": "SSHD No PasswordAuthentication",
      				"ansible.builtin.lineinfile": {
      					"dest": "/etc/ssh/sshd_config",
      					"regexp": "^#PasswordAuthe.*$",
      					"line": "PasswordAuthentication no",
      					"state": "present",
      					"backup": true
      				},
      				"tags": "ssh"
      			},
      			{
      				"name": "SSHD No ChallengeResponseAuthentication",
      				"ansible.builtin.lineinfile": {
      					"dest": "/etc/ssh/sshd_config",
      					"regexp": "^#ChallengeResponse.*$",
      					"line": "ChallengeResponseAuthentication no",
      					"state": "present",
      					"backup": true
      				},
      				"tags": "ssh"
      			},
      			{
      				"name": "SSHD PermitRootlogin without-password",
      				"ansible.builtin.lineinfile": {
      					"dest": "/etc/ssh/sshd_config",
      					"regexp": "^PermitRootLogin",
      					"line": "PermitRootLogin without-password",
      					"state": "present",
      					"backup": true
      				},
      				"notify": [
      					"Restart ssh"
      				],
      				"tags": "ssh"
      			}
      		]
      	}
      ]

      First run with ask-pass

      ansible-playbook prepare-appliance.json -l grommunio-test-1.your.network.local -k

      If everything worked out you will need to ommit the -k as that is only for password auth.

      From here i usually configure an additional mount for /var/lib/gromox but that i do manually followed by grommunio-setup.

      11 days later

      Lookup Folder Permissions in seconds

      and make them easily exportable aswell

      exmdb-perms.sql

      -- FOLDER PERMISSIONS LOOKUP TABLE
      CREATE TABLE IF NOT EXISTS "temp"."perms" (
        "perm"  INTEGER UNIQUE,
        "name"  TEXT
      );
      INSERT OR REPLACE INTO perms("perm","name") VALUES
      ( 1,'redany'),
      ( 2,'create'),
      ( 4,'sendas'),
      ( 8,'editowned'),
      ( 16,'deleteowned'),
      ( 32,'editany'),
      ( 64,'deleteany'),
      ( 128,'createsubfolder'),
      ( 256,'folderowner'),
      ( 512,'foldercontact'),
      ( 1024,'foldervisible'),
      ( 2048,'freebusysimple'),
      ( 4096,'freebusydetailed'),
      ( 8192,'storeowner')
      ;
      -- FOLDER LOOKUP VIEW VIA FOLDERS INCLUDING PARENT
      CREATE VIEW IF NOT EXISTS temp.folderlist
      AS SELECT distinct(p.folder_id),
                p.parent_id,
                f1.propval
           FROM folders p
           JOIN folder_properties f1
             ON f1.folder_id = p.folder_id
            AND f1.proptag = 805371935
          ORDER BY p.folder_id
      ;
      -- FOLDER LOOKUP VIEW VIA PERMISSIONS
      CREATE VIEW IF NOT EXISTS temp.folderlist_p
      AS SELECT distinct(p.folder_id),
                f1.propval
        FROM    permissions p
       INNER    JOIN folder_properties f1
          ON    f1.folder_id = p.folder_id
         AND    f1.proptag = 805371935
       ORDER    BY p.folder_id
      ;
      -- LOOKUP PERMISSIONS
      CREATE VIEW IF NOT EXISTS temp.folderpermissions
      AS SELECT p.folder_id as folder_int,
                f.parent_id,
                (SELECT printf('0x%x',p.folder_id)) AS folder_hex,
                (SELECT printf('0x%x',f.parent_id)) AS parent_hex,
                f.propval AS folder_name,
                p.username,
                x.name as permission,
                (SELECT printf('0x%x',p.permission)) AS permission_hex
          FROM  permissions p
          JOIN  folderlist f
            ON  p.folder_id = f.folder_id
          LEFT  JOIN temp.perms x
            ON  x.perm = p.permission
      ORDER BY  p.folder_id ASC,
                f.parent_id ASC,
                p.username ASC
      ;
      -- QUERY OUR VIEW
      SELECT * FROM folderpermissions
      ;

      Usage

      sqlite3 -readonly -columns /var/lib/gromox/user/X/Y/exmdb/exchange.sqlite3 < exmdb-perms.sql
      for exmdb in /var/lib/gromox/user/*/*/exmdb/exchange.sqlite3; do
         echo $exmdb
         sqlite3 -readonly -csv $exmdb < sql/exmdb-perms.sql
      done

      © 2020-2024 grommunio GmbH. All rights reserved. | https://grommunio.com | Data Protection | Legal notice