<br>I didn&#39;t see many living examples of how to do this, so I thought<br>it might be useful to share.<br><br>In our system, we have an LDAP auth backend which can be broader<br>than the mailboxes on a system.  We didn&#39;t have any luck with<br>
using pam_groupdn in pam_ldap.conf, so it is useful to use the PAM<br>module listfile.  In pam.d/imap (same for pop or sieve) we would include:<br><br>auth        required      pam_listfile.so onerr=fail item=user sense=allow file=/cyrus/mailmgmt/mysystemlist<br>
<br>If you are not in this file list of users, but you have<br>authenticated against the backend OK, you won&#39;t get in.<br><br>Keeping that list of mailbox users updated is done by<br>a cron running the perl script following:<br>
<br><br>#!/usr/bin/perl -w<br><br># Maintain a list of valid mailboxes on mysystem for pam authentication purposes<br><br>use strict;<br>use Fcntl &#39;:flock&#39;;<br><br># Global variables for filenames, etc.<br>my( $basedir );<br>
$basedir = &quot;/cyrus/mailmgmt&quot;;<br><br>my( $PWD ) = $ENV{&#39;PWD&#39;};<br><br>chdir ( $basedir );<br><br># Other global variables<br>my( %mysystemboxes, $now);<br><br># Get the mailbox list from mysystem<br>%mysystemboxes = &amp;get_mysystem_mailboxes( );<br>
<br>chdir( $PWD ) if ( $PWD );<br><br>exit 0;<br><br>#<br># It&#39;s all subroutines from here on out<br>#<br>#<br>#<br># Subroutine to get the mailbox list from mysystem.<br>#<br><br>sub get_mysystem_mailboxes( ) {<br>   my( @mysystemboxes );<br>
   # Get the list of mailboxes from <a href="http://mysystem.example.com">mysystem.example.com</a><br>   @mysystemboxes = &amp;get_mailbox_list( &quot;localhost&quot;, &quot;cyrusadm&quot;, &quot;mypassword&quot; );<br>   if( grep { /^IMAP error:/ } @mysystemboxes ) {<br>
      die &quot;Error retrieving mailbox list from mysystem.\n@mysystemboxes\n&quot;;<br>   }<br>   # Dump the mailbox list to a file<br>   open( SYSTEMBOXES, &quot;&gt; $basedir/mysystemlist &quot; ) or die &quot;Couldn&#39;t open file: $!\n&quot;;<br>
   foreach( @mysystemboxes ) { print SYSTEMBOXES &quot;$_\n&quot;; }<br>   print SYSTEMBOXES &quot;cyrusadm\n&quot;;<br>   close( SYSTEMBOXES ) or die &quot;Couldn&#39;t close file: $!\n&quot;;<br>   return %{ { map { $_ =&gt; 1 } @mysystemboxes } };<br>
}<br>#<br>#<br># Subroutine for an IMAP connection to get a mailbox list from a server<br>#<br>sub get_mailbox_list( $$$ ) {<br>   use IMAP::Admin;<br><br>   my( $server, $uid, $pwd ) = @_;<br>   my( $client, $mailbox, @mailboxlist, @usernames, $username );<br>
<br>   $client = IMAP::Admin-&gt;new(     &#39;Server&#39;=&gt;      &quot;$server&quot;,<br>                                   &#39;Login&#39; =&gt;      &quot;$uid&quot;,<br>                                   &#39;Password&#39; =&gt;   &quot;$pwd&quot;,<br>
                                   &#39;CRAM&#39;  =&gt;      0<br>                                   ) or<br>        return &quot;Couldn&#39;t create IMAP connection: $!\n&quot;;<br><br>   @mailboxlist = $client-&gt;list( &quot;user.*&quot; ) or<br>
        return &quot;IMAP error: \n\t&quot; . $client-&gt;error . &quot;\n&quot;;<br><br>   $client-&gt;close;<br>  foreach $mailbox ( @mailboxlist ) {<br>      push @usernames, ${ [ split( /\./, $mailbox ) ] }[1];<br>   }<br>
<br>   @usernames = keys %{ { map { $_ =&gt; 1 } @usernames } };<br><br>   return( @usernames );<br>}<br><br><br>It would need some adjustment for different type of authentication or<br>separator.<br><br><br>