I'm using Exim4 with SpamAssassin installed.
I have a problem of internal spam being sent to a large number of mailing lists, coming from a few users which we cannot just educate or block for multiple reasons.
Is there a way to block emails to which an unreasonable amount of messages are sent to the same domain to force these users to BCC?
Yes, you can do this in SpamAssassin. For example, you can add the following rules to your local.cf file located at /etc/mail/spamassassin/local.cf
header TEN_TOCC_IN_SAME_DOM ToCc =~ /(\@[^,>;]{3,99}[a-z]\b)(?:[^\@.-][^\@]{0,99}\1){10}(?![.-])/
describe TEN_TOCC_IN_SAME_DOM Ten consecutive recipients have the same domain
The above example only catches ten consecutive recipients with the same domain, which must all be in the same header (ToCc means either To xor Cc; it does not merge the headers). If you change the third character class from [^\@]{0,99} to .{0,999} to match any character over a longer period of time, the rule will be good for more than just consecutively listed addresses, but note that this would make the regex far more expensive to compute.
You also have to make sure that SpamAssassin is looking at your internal and outbound mail, which is nonstandard.
Finally, you'll have to score the rule. Please test copiously before you do that. Especially since this is not a spam rule (it will hit more non-spam than spam).
You will not, however, be able to tell users why the message was rejected. An SMTP reject (e.g. from Exim) can have a custom "why this was rejected" prompt, which is highly useful for policing attachment sizes or even informing users that they're sending too much mail (perhaps they are infected). You can configure Exim to run SA at SMTP time (e.g. sa-exim), but then every spam rejection would have the same message to the end user.