Most important thing to do is to set auth_debug=yes, and preferrably also auth_debug_passwords=yes. After that you'll see exactly what dovecot-auth is doing in the logs.
In addition, it might be useful to know how to construct and to decode a PLAIN mechanism string. printf(1) and mmencode(1) should be available on most Unix or GNU/Linux systems. (If not, check with your distribution. GNU coreutils includes printf(1), and metamail includes mmencode(1). In Debian, mmencode is called mimencode(1).)
Example authentication string encoding
$ printf 'username\0username\0password' | mmencode dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmQ=
This string is what a client would use to attempt PLAIN authentication as user "username" with password "password." With 'auth_debug_passwords=yes, it would appear in your logs.
Alternate Approach with perl
Unfortunately, mmencode on FreeBSD chokes on "\0". As an alternate, if you have MIME::Base64 on your system, you can use a perl statement to do the same thing:
perl -MMIME::Base64 -e 'print encode_base64("myusername\@domain.tld\0myusername\@domain.tld\0mypassword");'
As mmencode -u doesn't encounter any "\0" you can also do:
perl -MMIME::Base64 -e 'print encode_base64("myusername\@domain.tld\0myusername\@domain.tld\0mypassword");' | mmencode -u
to check that you have encoded correctly.
Example authentication string decoding
You can use mmencode -u to interpret the encoded string pasted into stdin as follows:
# mmencode -u bXl1c2VybmFtZUBkb21haW4udGxkAG15dXNlcm5hbWVAZG9tYWluLnRsZABteXBhc3N3b3Jk<CR> firstname.lastname@example.org@domain.tldmypassword<CTRL-D> #
You should see the correct user address (twice) and password. The null bytes won't display.