]> granicus.if.org Git - ejabberd/commitdiff
Fix mod_privacy race condition
authorNathan Bruning <nathan@iperity.com>
Sat, 27 Oct 2018 13:26:37 +0000 (15:26 +0200)
committerNathan Bruning <nathan@iperity.com>
Mon, 10 Jun 2019 10:49:39 +0000 (12:49 +0200)
mod_privacy updates the c2s state in user_receive_packet, which
tracks the *result* of the IQ set for active privacy lists.

When a second stanza is sent directly after a privacy list request,
the second stanza will be processed using the old privacy list,
because the IQ result has not yet been routed.

src/mod_privacy.erl

index 0b534d272d184e091885e5d4bc61b41b0bd87488..0204e09177aed8e87581a245f3e8a1f639d7956a 100644 (file)
@@ -419,6 +419,27 @@ user_send_packet({#iq{type = Type,
                false -> IQ
            end,
     {NewIQ, State};
+
+user_send_packet({#iq{type = Type,
+          from = #jid{luser = U, lserver = S},
+          to = #jid{luser = U, lserver = S},
+          sub_els = [_]} = IQ,
+        State})
+  when Type == set ->
+    case xmpp:get_subtag(IQ, #privacy_query{}) of
+      #privacy_query{active = undefined} -> {IQ, State};
+      #privacy_query{default = undefined, active = Active} ->
+        case get_user_list(U, S, Active) of
+          {ok, _} ->
+            % Adjust the client's state directly, so the next to-be-processed
+            % packet will take the active list into account.
+            {IQ, State#{privacy_active_list => Active}};
+          true ->
+            {IQ, State}
+        end;
+      _ -> {IQ, State}
+    end;
+
 user_send_packet(Acc) ->
     Acc.