Forum Moderators: phranque

Message Too Old, No Replies

How best to accomplish this? LDAP, Perl, and header

Retrieve LDAP group membership and convert string

         

coreyva

6:02 pm on Mar 15, 2011 (gmt 0)

10+ Year Member



We have a webserver that forwards all requests to a central site for various states to communicate with each other. We are required to set several headers with each request. Username, time, state, ... and now a new one, userrole. Since our authentication is through LDAP, I'm able to query the users group membership for this information. However the information returned is the full LDAP string.

I've written a small perl script to take extract the CN and return a comma separated value as required. I've tried to solve this with a RewriteMap prg but have not been successful, so I think I may need to try mod_perl. The rewrite log never shows data being sent to the map ur. I added logging to the up as well but no data has been sent there.

This is uncharted water for me, so I'd like to know if this is possible with mod_perl or if there is a better way of accomplishing this that I'm unaware of. Any input on this would be greatly appreciated.


##############################
# my config snip
<VirtualHost *:81>
ProxyVia On
RewriteEngine On
RewriteMap ur prg:/etc/apache2/urmap.pl
RewriteLog /etc/apache2/rewrite.log
RewriteLogLevel 9
<LocationMatch "^/" >
AuthType Basic
AuthBasicProvider ldap
AuthzLDAPAuthoritative Off
AuthName "foo"
AuthLDAPUrl "ldap://eaxmaple.com:389/OU=User,DC=example,DC=com?sAMAccountName,memberOf?sub?(objectcategory=user)"
AuthLDAPBindDN "CN=PAM,OU=Service Accounts,DC=example,DC=com"
AuthLDAPBindPassword foobar
Require valid-user

RewriteEngine On
#RewriteOptions inherit

RewriteCond %{ENV:AUTHENTICATE_SAMACCOUNTNAME} (.*)
RewriteRule .* - [E=uid:%1]
RewriteCond %{ENV:AUTHENTICATE_MEMBEROF} (.*)
# A few examples I've tried
#RewriteCond ${ur:%1} (.*)
#RewriteRule (.*) ${ur:%1} [C]
#RewriteRule (.*) - [E=u_r:%1]
#RewriteRule (.*) ${ur:%1} [E=u_r:%1]
RewriteRule (.*) - [E=u_r:%1]

RequestHeader set UserId %{uid}e
RequestHeader set StateRequestorIdentifier 16000
RequestHeader set StateGeneratedIdentifier %t
RequestHeader set RequestServer 10.10.10.65
RequestHeader set StateIdentifier "Example"
RequestHeader set Date %t
RequestHeader set UserRole %{u_r}e

</LocationMatch>
CustomLog /var/log/apache2/testproxyserver.log combined
ErrorLog /var/log/apache2/testproxyserver_error.log
LogLevel info

# This is where the request will be forwarded to, commented out for testing
# ProxyPass / https://www.foo.gov/
# ProxyPassReverse / https://www.foo.gov/

</VirtualHost>

##############################
#/etc/apache2/urmap.pl

#!/usr/bin/perl -073 -w
$| = 1;
while (<STDIN>) {
$data=$_;
$data=~ s/CN=//;
$data=~ s/,.*$//;
$data=~ s/^ //;
push (@UR,$data);
};
if ($data ne "") {
$user_role=join(",",@UR);
$user_role="$user_role\n";
print $user_role;
} else {
print "NULL";
};

##############################
# example AUTHENTICATE_MEMBEROF
CN=AA,OU=Security Groups,DC=foo,DC=example,DC=com; CN=AB,OU=Security Groups,DC=foo,DC=example,DC=com; CN=AC,OU=Distribution Groups,DC=foo,DC=example,DC=com; CN=AD,OU=Distribution Groups,DC=foo,DC=example,DC=com; CN=AE,OU=Security Groups,DC=foo,DC=example,DC=com

##############################
# an example of my current header
Host: foo:81
Connection: keep-alive
Cache-Control: max-age=0
Authorization: Basic dmF...........MjM=
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
UserId: me
StateRequestorIdentifier: 16000
StateGeneratedIdentifier: t=1300211268173673
RequestServer: 10.10.10.10
StateIdentifier: Foo
Date: t=1300211268173673
UserRole: CN=AA,OU=Security Groups,DC=foo,DC=example,DC=com; CN=AB,OU=Security Groups,DC=foo,DC=example,DC=com; CN=AC,OU=Distribution Groups,DC=foo,DC=example,DC=com; CN=AD,OU=Distribution Groups,DC=foo,DC=example,DC=com; CN=AE,OU=Security Groups,DC=foo,DC=example,DC=com

##############################
# what they now expect my header to look like
<snip>
StateRequestorIdentifier: 16000
StateGeneratedIdentifier: t=1300211268173673
RequestServer: 10.10.10.10
StateIdentifier: Foo
Date: t=1300211268173673
UserRole: AA,AB,AC,AD,AD

jdMorgan

12:56 am on Mar 18, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Start simple:

RewriteRule ^test_ur1$ http://example.com/test_ur2?ur_returned=${ur:testvalue} [R=301,L]

A request for URL-path "/test_ur1" will call your ur map script, then redirect to /test_ur2 after putting the returned value into the query string so you can see it in your address bar. Put some valid value where I typed "testval".

Be aware that your script must *never* be allowed to "die" -- It must run forever after Apache starts up, waiting for input from STDIN. Be very careful to handle all possible errors within the script itself, returning a specific value if an error occurs, which you can test for in the mod_rewrite code with a RewriteCond.

Jim

coreyva

6:38 pm on Mar 21, 2011 (gmt 0)

10+ Year Member



First, thanks for the reply. Unfortunately for me, I'm not actually accessing any local URLs as Apache is setup to be a forwarding proxy. I've been looking at mod_perl, but haven't really found a starting point for what I'm trying to accomplish. When the clients are forwarded to the destination site, we add a few headers for authentication and user roles. This all work fine, except for the fact that returned user role from AUTHENTICATE_MEMBEROF (Groups in Active Directory) is in the wrong format. So I need some way to manipulate the variable before inserting the header in the request. While it seems to be a trivial task, I've not found a way to accomplish it.