Bläddra i källkod

[Multi] Fixes #1058 by including a 'force password update' option and also introduces a attributes json object to be used for further mailbox configurations in the future

André Peters 7 år sedan
förälder
incheckning
2865c892a6

+ 1 - 1
data/Dockerfiles/dovecot/docker-entrypoint.sh

@@ -82,7 +82,7 @@ cat <<EOF > /usr/local/etc/dovecot/sql/dovecot-dict-sql-passdb.conf
 driver = mysql
 connect = "host=mysql dbname=${DBNAME} user=${DBUSER} password=${DBPASS}"
 default_pass_scheme = SSHA256
-password_query = SELECT password FROM mailbox WHERE username = '%u' AND domain IN (SELECT domain FROM domain WHERE domain='%d' AND active='1')
+password_query = SELECT password FROM mailbox WHERE username = '%u' AND domain IN (SELECT domain FROM domain WHERE domain='%d' AND active='1') AND JSON_EXTRACT(attributes, "$.force_pw_update") != 1
 user_query = SELECT CONCAT('maildir:/var/vmail/',maildir) AS mail, 5000 AS uid, 5000 AS gid, concat('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active = '1'
 iterate_query = SELECT username FROM mailbox WHERE active='1';
 EOF

+ 1 - 2
data/Dockerfiles/sogo/bootstrap-sogo.sh

@@ -19,14 +19,13 @@ mysql --host mysql -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "DROP VIEW IF EXISTS so
 
 mysql --host mysql -u ${DBUSER} -p${DBPASS} ${DBNAME} << EOF
 CREATE VIEW sogo_view (c_uid, domain, c_name, c_password, c_cn, mail, aliases, ad_aliases, home, kind, multiple_bookings) AS
-SELECT mailbox.username, mailbox.domain, mailbox.username, mailbox.password, mailbox.name, mailbox.username, IFNULL(GROUP_CONCAT(ga.aliases SEPARATOR ' '), ''), IFNULL(gda.ad_alias, ''), CONCAT('/var/vmail/', maildir), mailbox.kind, mailbox.multiple_bookings FROM mailbox
+SELECT mailbox.username, mailbox.domain, mailbox.username, if(json_extract(attributes, '$.force_pw_update') = '0', password, 'invalid'), mailbox.name, mailbox.username, IFNULL(GROUP_CONCAT(ga.aliases SEPARATOR ' '), ''), IFNULL(gda.ad_alias, ''), CONCAT('/var/vmail/', maildir), mailbox.kind, mailbox.multiple_bookings FROM mailbox
 LEFT OUTER JOIN grouped_mail_aliases ga ON ga.username REGEXP CONCAT('(^|,)', mailbox.username, '($|,)')
 LEFT OUTER JOIN grouped_domain_alias_address gda ON gda.username = mailbox.username
 WHERE mailbox.active = '1'
 GROUP BY mailbox.username;
 EOF
 
-
 mkdir -p /var/lib/sogo/GNUstep/Defaults/
 
 # Generate plist header with timezone data

+ 8 - 0
data/web/edit.php

@@ -390,6 +390,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
         <form class="form-horizontal" data-id="editmailbox" role="form" method="post">
           <input type="hidden" value="0" name="sender_acl">
           <input type="hidden" value="0" name="active">
+          <input type="hidden" value="0" name="force_pw_update">
           <div class="form-group">
             <label class="control-label col-sm-2" for="name"><?=$lang['edit']['full_name'];?>:</label>
             <div class="col-sm-10">
@@ -476,6 +477,13 @@ if (isset($_SESSION['mailcow_cc_role'])) {
               </div>
             </div>
           </div>
+          <div class="form-group">
+            <div class="col-sm-offset-2 col-sm-10">
+              <div class="checkbox">
+              <label><input type="checkbox" value="1" name="force_pw_update" <?=($result['attributes']['force_pw_update']=="1") ? "checked" : null;?>> <?=$lang['edit']['force_pw_update'];?></label>
+              </div>
+            </div>
+          </div>
           <div class="form-group">
             <div class="col-sm-offset-2 col-sm-10">
               <button class="btn btn-success" id="edit_selected" data-id="editmailbox" data-item="<?=htmlspecialchars($result['username']);?>" data-api-url='edit/mailbox' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>

+ 1 - 1
data/web/inc/functions.inc.php

@@ -414,7 +414,7 @@ function edit_user_account($postarray) {
 			}
 			$password_hashed = hash_password($password_new);
 			try {
-				$stmt = $pdo->prepare("UPDATE `mailbox` SET `password` = :password_hashed WHERE `username` = :username");
+				$stmt = $pdo->prepare("UPDATE `mailbox` SET `password` = :password_hashed, `attributes` = JSON_SET(`attributes`, '$.force_pw_update', '0') WHERE `username` = :username");
 				$stmt->execute(array(
 					':password_hashed' => $password_hashed,
 					':username' => $username

+ 6 - 14
data/web/inc/functions.mailbox.inc.php

@@ -1954,6 +1954,7 @@ function mailbox($_action, $_type, $_data = null, $attr = null) {
             $is_now = mailbox('get', 'mailbox_details', $username);
             if (!empty($is_now)) {
               $active     = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
+              (int)$force_pw_update = (isset($_data['force_pw_update'])) ? intval($_data['force_pw_update']) : intval($is_now['attributes']['force_pw_update']);
               $name       = (!empty($_data['name'])) ? $_data['name'] : $is_now['name'];
               $domain     = $is_now['domain'];
               $quota_m    = (!empty($_data['quota'])) ? $_data['quota'] : ($is_now['quota'] / 1048576);
@@ -2113,24 +2114,11 @@ function mailbox($_action, $_type, $_data = null, $attr = null) {
               }
               $password_hashed = hash_password($password);
               try {
-                $stmt = $pdo->prepare("UPDATE `alias` SET
-                    `active` = :active
-                      WHERE `address` = :address");
-                $stmt->execute(array(
-                  ':address' => $username,
-                  ':active' => $active
-                ));
                 $stmt = $pdo->prepare("UPDATE `mailbox` SET
-                    `active` = :active,
                     `password` = :password_hashed,
-                    `name`= :name,
-                    `quota` = :quota_b
                       WHERE `username` = :username");
                 $stmt->execute(array(
                   ':password_hashed' => $password_hashed,
-                  ':active' => $active,
-                  ':name' => $name,
-                  ':quota_b' => $quota_b,
                   ':username' => $username
                 ));
               }
@@ -2153,12 +2141,14 @@ function mailbox($_action, $_type, $_data = null, $attr = null) {
               $stmt = $pdo->prepare("UPDATE `mailbox` SET
                   `active` = :active,
                   `name`= :name,
-                  `quota` = :quota_b
+                  `quota` = :quota_b,
+                  `attributes` = JSON_SET(`attributes`, '$.force_pw_update', :force_pw_update)
                     WHERE `username` = :username");
               $stmt->execute(array(
                 ':active' => $active,
                 ':name' => $name,
                 ':quota_b' => $quota_b,
+                ':force_pw_update' => $force_pw_update,
                 ':username' => $username
               ));
             }
@@ -3070,6 +3060,7 @@ function mailbox($_action, $_type, $_data = null, $attr = null) {
                 `mailbox`.`domain`,
                 `mailbox`.`quota`,
                 `quota2`.`bytes`,
+                `attributes`,
                 `quota2`.`messages`
                   FROM `mailbox`, `quota2`, `domain`
                     WHERE `mailbox`.`kind` NOT REGEXP 'location|thing|group' AND `mailbox`.`username` = `quota2`.`username` AND `domain`.`domain` = `mailbox`.`domain` AND `mailbox`.`username` = :mailbox");
@@ -3097,6 +3088,7 @@ function mailbox($_action, $_type, $_data = null, $attr = null) {
             $mailboxdata['active_int'] = $row['active_int'];
             $mailboxdata['domain'] = $row['domain'];
             $mailboxdata['quota'] = $row['quota'];
+            $mailboxdata['attributes'] = json_decode($row['attributes'], true);
             $mailboxdata['quota_used'] = intval($row['bytes']);
             $mailboxdata['percent_in_use'] = round((intval($row['bytes']) / intval($row['quota'])) * 100);
             $mailboxdata['messages'] = $row['messages'];

+ 2 - 2
data/web/inc/init_db.inc.php

@@ -3,7 +3,7 @@ function init_db_schema() {
   try {
     global $pdo;
 
-    $db_version = "08022018_1219";
+    $db_version = "16022018_1419";
 
     $stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
     $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
@@ -191,9 +191,9 @@ function init_db_schema() {
           "domain" => "VARCHAR(255) NOT NULL",
           "tls_enforce_in" => "TINYINT(1) NOT NULL DEFAULT '0'",
           "tls_enforce_out" => "TINYINT(1) NOT NULL DEFAULT '0'",
+          "attributes" => "JSON DEFAULT '{}'",
           "kind" => "VARCHAR(100) NOT NULL DEFAULT ''",
           "multiple_bookings" => "TINYINT(1) NOT NULL DEFAULT '0'",
-          "wants_tagged_subject" => "TINYINT(1) NOT NULL DEFAULT '0'",
           "created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
           "modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
           "active" => "TINYINT(1) NOT NULL DEFAULT '1'"

+ 3 - 0
data/web/lang/lang.de.php

@@ -100,6 +100,7 @@ $lang['warning']['spam_alias_temp_error'] = 'Kann zur Zeit keinen Spam-Alias ers
 $lang['danger']['spam_alias_max_exceeded'] = 'Maximale Anzahl an Spam-Alias-Adressen erreicht';
 $lang['danger']['validity_missing'] = 'Bitte geben Sie eine Gültigkeitsdauer an';
 $lang['user']['loading'] = "Lade...";
+$lang['user']['force_pw_update'] = 'Das Passwort für diesen Benutzer <b>muss</b> geändert werden, damit die Zugriffssperre auf die Groupwarekomponenten wieder freigeschaltet wird.';
 $lang['user']['active_sieve'] = "Aktiver Filter";
 $lang['user']['show_sieve_filters'] = "Zeige aktiven Filter des Benutzers";
 $lang['user']['no_active_filter'] = "Kein aktiver Filter vorhanden";
@@ -320,6 +321,8 @@ $lang['edit']['max_mailboxes'] = 'Max. Mailboxanzahl:';
 $lang['edit']['title'] = 'Objekt bearbeiten';
 $lang['edit']['target_address'] = 'Ziel-Adresse(n) <small>(getrennt durch Komma)</small>:';
 $lang['edit']['active'] = 'Aktiv';
+$lang['edit']['force_pw_update'] = 'Erzwinge Passwortänderung bei nächstem Login';
+$lang['edit']['force_pw_update_info'] = 'Dem Benutzer wird lediglich der Zugang zur mailcow UI ermöglicht.';
 $lang['edit']['target_domain'] = 'Ziel-Domain:';
 $lang['edit']['password'] = 'Passwort:';
 $lang['edit']['ratelimit'] = 'Limit ausgehender Nachrichten/Stunde:';

+ 3 - 0
data/web/lang/lang.en.php

@@ -100,6 +100,7 @@ $lang['warning']['spam_alias_temp_error'] = "Temporary error: Cannot add spam al
 $lang['danger']['spam_alias_max_exceeded'] = "Max. allowed spam alias addresses exceeded";
 $lang['danger']['validity_missing'] = 'Please assign a period of validity';
 $lang['user']['loading'] = "Loading...";
+$lang['user']['force_pw_update'] = 'You <b>must</b> set a new password to be able to access groupware related services.';
 $lang['user']['active_sieve'] = "Active filter";
 $lang['user']['show_sieve_filters'] = "Show active user sieve filter";
 $lang['user']['no_active_filter'] = "No active filter available";
@@ -321,6 +322,8 @@ $lang['edit']['max_mailboxes'] = 'Max. possible mailboxes';
 $lang['edit']['title'] = 'Edit object';
 $lang['edit']['target_address'] = 'Goto address/es <small>(comma-separated)</small>';
 $lang['edit']['active'] = 'Active';
+$lang['edit']['force_pw_update'] = 'Force password update at next login';
+$lang['edit']['force_pw_update_info'] = 'This user will only be able to login to mailcow UI.';
 $lang['edit']['target_domain'] = 'Target domain';
 $lang['edit']['password'] = 'Password';
 $lang['edit']['ratelimit'] = 'Outgoing rate limit/h';

+ 3 - 0
data/web/user.php

@@ -89,6 +89,9 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
 <div class="panel-body">
   <div class="row">
     <div class="col-sm-offset-3 col-sm-9">
+      <?php if ($mailboxdata['attributes']['force_pw_update'] == "1"): ?>
+      <div class="alert alert-danger"><?=$lang['user']['force_pw_update'];?></div>
+      <?php endif; ?>
       <p><a href="#pwChangeModal" data-toggle="modal">[<?=$lang['user']['change_password'];?>]</a></p>
       <p><a target="_blank" href="https://mailcow.github.io/mailcow-dockerized-docs/client/#<?=$clientconfigstr;?>">[<?=$lang['user']['client_configuration'];?>]</a></p>
     </div>

+ 2 - 2
docker-compose.yml

@@ -128,7 +128,7 @@ services:
             - phpfpm
 
     sogo-mailcow:
-      image: mailcow/sogo:1.16
+      image: mailcow/sogo:1.17
       build: ./data/Dockerfiles/sogo
       environment:
         - DBNAME=${DBNAME}
@@ -149,7 +149,7 @@ services:
             - sogo
 
     dovecot-mailcow:
-      image: mailcow/dovecot:1.20
+      image: mailcow/dovecot:1.22
       build: ./data/Dockerfiles/dovecot
       cap_add:
         - NET_BIND_SERVICE