Yes, there is logic for being able to skip over arbitrary numbers of lines. There are no "grouping brackets" or anything of the sort, but if you combine the logic that you just mentioned with the ability to skip over lines, you can selectively exclude behavior.
Here's an example from my personal server:
# Skip Google authenticator check if they're coming from a local IP.
auth [success=1 default=ignore] pam_access.so accessfile=/etc/security/access/nogoogle.conf noaudit
auth required pam_google_authenticator.so nullok
I don't really need two-factor authentication if the source IP is coming from my local network, so I'm using the outcome of the
pam_access.so check to skip exactly one line on success. If the check fails, nothing happens and the next line is checked.
You can find more about this in the
pam.conf manpage. Search for "value1". The section starts off like so:
For the more complicated syntax valid control values have the following form:
[value1=action1 value2=action2 ...]
Where valueN corresponds to the return code from the function invoked in the
module for which the line is defined.
Keep in mind that this logic is much more complex, and if people edit your PAM configurations without noting the presence of line skipping they can cause all kinds of chaos by adding or removing lines in the wrong places.