| 1 | #!/usr/local/bin/perl -w |
| 2 | |
| 3 | # This is a sample authentication module for authpipe. It uses the same |
| 4 | # protocol that pop3d/imapd/webmail use to communicate with authdaemon. |
| 5 | # |
| 6 | # If you want to indicate a temporary failure (e.g. database unavailable) |
| 7 | # then simply exit without sending any response. This will be indicated as |
| 8 | # a tempfail response, and a new child process will be started for the |
| 9 | # next authentication request, therefore ensuring that it is reinitialized. |
| 10 | # |
| 11 | # You can run this from the command line to test it. Example requests: |
| 12 | # |
| 13 | # PRE . imap fred@example.com -- display data for this account |
| 14 | # |
| 15 | # AUTH 35 -- 35 is length of |
| 16 | # imap -- "imap\nlogin\nfred@example.com\nfoobar\n" |
| 17 | # login |
| 18 | # fred@example.com |
| 19 | # foobar |
| 20 | # |
| 21 | # PASSWD imap<tab>fred@example.com<tab>foobar<tab>newpass |
| 22 | # |
| 23 | # ENUMERATE |
| 24 | |
| 25 | my %authdata = ( |
| 26 | 'fred@example.com' => ['foobar', 81, 81, '/home/fred', 'Maildir', 'disablepop3=0', '10000000S'], |
| 27 | 'wilma@example.com' => ['bazbaz', 81, 81, '/home/wilma'], |
| 28 | ); |
| 29 | |
| 30 | $|=1; |
| 31 | |
| 32 | sub sendres($$) |
| 33 | { |
| 34 | my $uid = shift; |
| 35 | my $ref = shift; |
| 36 | # see authdamond.c for full list of possible fields |
| 37 | print "ADDRESS=$uid\n"; |
| 38 | print "PASSWD2=$ref->[0]\n"; |
| 39 | print "UID=$ref->[1]\n"; |
| 40 | print "GID=$ref->[2]\n"; |
| 41 | print "HOME=$ref->[3]\n"; |
| 42 | print "MAILDIR=$ref->[4]\n" if $ref->[4]; |
| 43 | print "OPTIONS=$ref->[5]\n" if $ref->[5]; |
| 44 | print "QUOTA=$ref->[6]\n" if $ref->[6]; |
| 45 | print ".\n"; |
| 46 | } |
| 47 | |
| 48 | print STDERR "Sample module starting\n"; |
| 49 | |
| 50 | while (<>) |
| 51 | { |
| 52 | if (/^PRE (\S+) (\S+) (.*)$/) |
| 53 | { |
| 54 | # $1=. $2=service $3=uid |
| 55 | if ($authdata{$3}) |
| 56 | { |
| 57 | sendres($3, $authdata{$3}); |
| 58 | next; |
| 59 | } |
| 60 | } |
| 61 | elsif (/^AUTH (\d+)$/ && read(STDIN,$buf,$1) == $1 && |
| 62 | $buf =~ /^(.*)\n(login)\n(.*)\n(.*)$/) |
| 63 | { |
| 64 | # $1=service, $2=authtype, $3=user, $4=password |
| 65 | if ($authdata{$3} && $authdata{$3}->[0] eq $4) |
| 66 | { |
| 67 | sendres($3, $authdata{$3}); |
| 68 | next; |
| 69 | } |
| 70 | } |
| 71 | elsif (/^PASSWD (.*?)\t(.*?)\t(.*?)\t(.*?)$/) |
| 72 | { |
| 73 | # $1=service, $2=user, $3=oldpasswd, $4=newpasswd |
| 74 | if ($authdata{$2} && $authdata{$2}->[0] eq $3) |
| 75 | { |
| 76 | # not a useful example unless you have set MAXDAEMONS=1 |
| 77 | $authdata{$2}->[0] = $4; |
| 78 | print "OK\n"; |
| 79 | next; |
| 80 | } |
| 81 | } |
| 82 | elsif (/^ENUMERATE$/) { |
| 83 | foreach $k (keys %authdata) { |
| 84 | $d = $authdata{$k}; |
| 85 | print "$k\t$d->[1]\t$d->[2]\t$d->[3]\t$d->[4]\t$d->[5]\n"; |
| 86 | } |
| 87 | print ".\n"; |
| 88 | next; |
| 89 | } |
| 90 | print "FAIL\n"; |
| 91 | } |