SenderMustExistInExternalDatabase Broken in RT3?

Hi,

I sent this to the rt-users list last week and received no reply, so I
thought I would try this list:

I am using rt 3.0.1 on Redhat 7.3 with the following in RT_SiteConfig:

Set($LookupSenderInExternalDatabase, 1);
Set($SenderMustExistInExternalDatabase , 1);
Set($WebExternalAuth , 1);
Set($WebExternalGecos , 1);
Set($WebExternalAuto , 1);

I modified the LookupExternalUserInfo subroutine in lib\RT\EmailParser.pm
to work with my LDAP server. I can login through the web and everything
works fine (account created, can log in, etc).

I only want LDAP users to be able to create tickets via web or
email. Problem is, any address has an account created when I request a
ticket via email. I thought the point of SenderMustExistInExternalDatabase
was to prevent this from happening. I do NOT have CreateTicket privileges
set to everyone.

Does anyone else have this working in RT 3.0.1? Any suggestions for what I
am doing wrong?

Further investigation in lib\RT\EmailParser.pm shows the following
statement in the GetCurrentUser sub:

if ( $RT::SenderMustExistInExternalDatabase && 

!$UserFoundInExternalDatabase ) {

If changed to:

if ( $RT::SenderMustExistInExternalDatabase ) {

accounts are still being created.

Confused,
Jeff

OK, I see that the user is being created by CreateUser in
Interfaces/Email.pm. Can someone tell me where this gets called from so I
can see if it is checking $SenderMustExistInExternalDatabase?

Thanks in advance for any help!

– Jeff

At 02:46 PM 4/21/2003, Jeff Hoover wrote:

At 10:22 AM 4/22/2003, Jeff Hoover wrote:

OK, I see that the user is being created by CreateUser in
Interfaces/Email.pm. Can someone tell me where this gets called from so I
can see if it is checking $SenderMustExistInExternalDatabase?

Thanks in advance for any help!

– Jeff

Never mind. I guess when nobody will help you, you have to figure things
out on your own. I found where it was getting called from and fixed this
problem. I’m sure there is a better way, and it may not be bug proof, but
this way worked for me:

  1. Edit lib/RT/EmailParser.pm to allow

@EXPORT_OK = qw(&LookupExternalUserInfo);

  1. Edit lib/RT/Interface/Email/Auth/MailFrom.pm

25c25,27
< use RT::Interface::Email qw(ParseSenderAddressFromHead CreateUser);

use RT::Interface::Email qw(ParseSenderAddressFromHead CreateUser
MailError);
use RT::EmailParser qw(&LookupExternalUserInfo);
use MIME::Entity;
39a42
my $Username = undef;
40a44,80

# Now we need to check in external database if set
if ( $RT::LookupSenderInExternalDatabase ) {

  my $parser = RT::EmailParser->new();
  ( $UserFoundInExternalDatabase, %UserInfo ) = 

$parser->LookupExternalUserInfo( $Address, $Name );

  if ( $RT::SenderMustExistInExternalDatabase && 

!$UserFoundInExternalDatabase ) {

      my $Message = "Sender's email address was not found in the 

user database.";

        # {{{  This code useful only if you've defined an 

AutoRejectRequest template

        require RT::Template;
        my $template = new RT::Template($RT::Nobody);
        $template->Load('AutoRejectRequest');
        $Message = $template->Content || $Message;

        # }}}

        MailError(
             To      => $Address,
             Subject => "Ticket Creation failed: user could not be 

created",

             Explanation => $Message,
             MIMEObj     => $entity,
             LogLevel    => 'notice' );

        return ($CurrentUser);

  } else {
    $Address  = $UserInfo{'EmailAddress'};
    $Username = $UserInfo{'Name'};
  }
}

121c161
< $CurrentUser = CreateUser( undef, $Address, $Name, $args{‘Message’} );

$CurrentUser = CreateUser( $Username, $Address, $Name, 

$args{‘Message’} );

– Jeff

I am using rt 3.0.1 on Redhat 7.3 with the following in RT_SiteConfig:

Set($LookupSenderInExternalDatabase, 1);
Set($SenderMustExistInExternalDatabase , 1);
Set($WebExternalAuth , 1);
Set($WebExternalGecos , 1);
Set($WebExternalAuto , 1);

I modified the LookupExternalUserInfo subroutine in lib\RT\EmailParser.pm
to work with my LDAP server. I can login through the web and everything
works fine.

I only want LDAP users to be able to create tickets via web or
email. Problem is, any address has an account created when I request a
ticket via email. I thought the point of SenderMustExistInExternalDatabase
was to prevent this from happening. I do NOT have CreateTicket privileges
set to everyone.

Does anyone else have this working in RT 3.0.1? Any suggestions for what I
am doing wrong?

Further investigation in lib\RT\EmailParser.pm shows the following
statement in the GetCurrentUser sub:

if ( $RT::SenderMustExistInExternalDatabase && 

!$UserFoundInExternalDatabase ) {

If changed to:

if ( $RT::SenderMustExistInExternalDatabase ) {

accounts are still being created.

Confused,
Jeff

Karsten,

I am also new to RT3. I haven’t quite figured everything out yet, but I’ll
share with everyone what I have done so far incase someone else wants to
use this. To authenticate against LDAP you need to set RT’s
$WebExternalAuth settings (in RT_SiteConfig) and use Apache’s AuthLDAP module.

To autocreate accounts when logging in you have to modify the
LookupExternalUserInfo subroutine to your liking. I’ll paste mine
below. Maybe someone will improve it. I also edited
rt3/var/mason_data/obj/standard/autohandler to add:

  $UserObj->SetEmailAddress("$user\@mydomain.com") if defined $user;

under $UserObj->SetRealName($realname) if defined $realname;

Also, if you want users to have unprivileged accounts created automatically
instead of privileged, change line 75 to:

  $UserObj->SetPrivileged(0);

Hope that helps you get started.

– Jeff

ps - you WILL have to modify the subroutine for your LDAP setup. This
subroutine was based off either an old email posting or a file in the
contribs, I don’t remember.

sub LookupExternalUserInfo {
my $self = shift;
my $EmailAddress = shift;
my $RealName = shift;

my $FoundInExternalDatabase = 0;
my %params;

#Name is the RT username you want to use for this user.
$params{‘Name’} = $EmailAddress;
$params{‘EmailAddress’} = $EmailAddress;
$params{‘RealName’} = $RealName;

$RT::Logger->debug(“LookupExternalUserInfo: Entered with:\n”,
“\tName = $params{‘Name’}\n”,
“\tEmailAddress = $params{‘EmailAddress’}\n”,
“\tRealName = $params{‘RealName’}\n”,
“\tFound = $FoundInExternalDatabase\n”);

$params{‘RealName’} =~ s/"//g;

use Net::LDAP;
use Net::LDAP::Constant qw(LDAP_SUCCESS);

use constant LDAP => q(ldap.yourdomain.com);
use constant LDAP_PORT => q(389);
use constant LDAP_BASE => q(ou=People,dc=yourdomain,dc=com);
use constant LDAP_UID => q(uid);
use constant LDAP_EMAIL => q(mail);
use constant LDAP_ALT_EMAIL => q(mailAlternateAddress);
use constant LDAP_CN => q(cn);

my $ldap = new Net::LDAP(LDAP, port => LDAP_PORT)
or $RT::Logger->critical("LookupExternalUserInfo: Cannot connect to ",
“LDAP’\n”),
return ($FoundInExternalDatabase, %params);

my $mesg = $ldap->bind();
if ($mesg->code != LDAP_SUCCESS) {
$RT::Logger->critical("LookupExternalUserInfo: Cannot bind anonymously ",
“to LDAP:”, $mesg->code, “\n”);
$params{‘RealName’} = “"$params{‘RealName’}"”;
return ($FoundInExternalDatabase, %params);
}

my $filter = “@{[ LDAP_EMAIL ]}=$params{‘EmailAddress’}”;
$RT::Logger->debug("LookupExternalUserInfo: First search filter ",
“‘$filter’\n”);
$mesg = $ldap->search(base => LDAP_BASE,
filter => $filter,
attrs => [ LDAP_UID, LDAP_EMAIL, LDAP_CN ]);
if ($mesg->code != LDAP_SUCCESS) {
$RT::Logger->critical("LookupExternalUserInfo: Could not search for ",
"$filter: ", $mesg->code, “\n”);
$params{‘RealName’} = “"$params{‘RealName’}"”;
return ($FoundInExternalDatabase, %params);
}

$RT::Logger->debug("LookupExternalUserInfo: First search produced “,
$mesg->count, " results\n”);

E-mail search failed

unless ($mesg->count == 1) {
$filter = “@{[ LDAP_ALT_EMAIL ]}=$params{‘EmailAddress’}”;

 $RT::Logger->debug("LookupExternalUserInfo: Second search filter ",
                    "'$filter'\n");
 $mesg = $ldap->search(base   => LDAP_BASE,
                       filter => $filter,
                       attrs  => [ LDAP_UID, LDAP_EMAIL, LDAP_CN ]);
 if ($mesg->code != LDAP_SUCCESS)  {
   $RT::Logger->critical("LookupExternalUserInfo: Could not search for ",
                         "$filter: ", $mesg->code, "\n");
   $params{'RealName'} = "\"$params{'RealName'}\"";
   return ($FoundInExternalDatabase, %params);
 }

}

$RT::Logger->debug("LookupExternalUserInfo: Second search produced “,
$mesg->count, " results with filter $filter\n”);

One of the two searches succeeded with just one match

if ($mesg->count == 1) {
$params{‘Name’} = ($mesg->first_entry->get_value(LDAP_UID))[0];
$params{‘EmailAddress’} = ($mesg->first_entry->get_value(LDAP_EMAIL))[0];
$params{‘RealName’} = ($mesg->first_entry->get_value(LDAP_CN))[0];
$FoundInExternalDatabase = 1;
}

$mesg = $ldap->unbind();
if ($mesg->code != LDAP_SUCCESS) {
$RT::Logger->critical("LookupExternalUserInfo: Could not unbind from ",
"LDAP: ", $mesg->code, “\n”);
}
undef $ldap;
undef $mesg;

$params{‘RealName’} = “"$params{‘RealName’}"”;
$RT::Logger->debug("LookupExternalUserInfo: Leaving LDAP examination ",
“with:\n”,
“\tName = $params{‘Name’}\n”,
“\tEmailAddress = $params{‘EmailAddress’}\n”,
“\tRealName = $params{‘RealName’}\n”,
“\tFound = $FoundInExternalDatabase\n”);

return ($FoundInExternalDatabase, %params) if $FoundInExternalDatabase;
}

At 10:37 AM 4/22/2003, Karsten Konrad wrote: