RT notifier: parse templates without header correctly
[openxpki.git] / tools / scripts / auth_MS-ADS_over_LDAP-SASL-v2.pl
blobe509dc7af2d683c921d119b33c574b58641c23aa
1 #!/usr/bin/perl
3 # Written 2008 by J Kunkel [jkunkel@aplusg.de] for the OpenXPKI project
4 # (C) Copyright 2008 by The OpenXPKI Project
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
18 # test:
19 # =====
20 # export LOGIN=jkunkel && export PASSWD=topsecret \
21 # && ./auth_MS-ADS_over_LDAP-SASL.pl
24 # use this handler in auth.xml:
25 # =============================
26 # <handler name="MS-ADS LDAP-SASL" type="External">
27 # <description>
28 # Login with your Microsoft ADS User-Account.
29 # </description>
30 # <command>auth_MS-ADS_over_LDAP-SASL.pl</command>
31 # <role></role>
32 # <pattern>x</pattern>
33 # <replacement>x</replacement>
34 # <env>
35 # <name>LOGIN</name>
36 # <value>__USER__</value>
37 # </env>
38 # <env>
39 # <name>PASSWD</name>
40 # <value>__PASSWD__</value>
41 # </env>
42 # </handler>
44 use warnings;
45 use strict;
46 use Net::LDAP;
47 use Authen::SASL;
48 use Carp;
49 use URI;
50 use Getopt::Std;
52 #########################
53 # configuration
54 #########################
55 # set to 1
56 my $DEBUG = 0;
58 my $HOST = 'ag-dom-003';
59 my $BASEDN = "dc=a-g,dc=de";
61 my $USER = $ENV{'LOGIN'};
62 my $PASSWD = $ENV{'PASSWD'};
64 print "==>" . $USER . "\n" if $DEBUG;
65 print "==>" . $PASSWD . "\n" if $DEBUG;
67 # AD groups how represent the OpenXPKI roles
68 my $GROUP_CA = "OpenXPKI_CA";
69 my $GROUP_RA = "OpenXPKI_RA";
70 my $GROUP_USER = "OpenXPKI_USER";
73 my @attrs = ["dn"];
74 my $ldap = 0;
75 my $count = 0;
77 #########################
78 #LDAP connect over SASL
79 #########################
80 until($ldap = Net::LDAP->new($HOST)) {
81 die "Can not connect to ldap://$HOST/" if ++$count > 10;
82 sleep 1;
85 my $sasl = Authen::SASL->new(
86 mechanism => 'DIGEST-MD5',
87 callback => {
88 user => $USER,
89 pass => $PASSWD
93 my $mesg = $ldap->bind($BASEDN, sasl => $sasl, version => 3);
94 exit $mesg->code if $mesg->code;
96 #########################
97 #get group DN's
98 #########################
99 my $group_ca_dn = &getGroupDN($GROUP_CA);
100 my $group_ra_dn = &getGroupDN($GROUP_RA);
101 my $group_user_dn = &getGroupDN($GROUP_USER);
103 #########################
104 #get user DN
105 #########################
106 my $userDN = &getUserDN($USER);
108 print "==>" . $group_user_dn . "\n" if $DEBUG;
109 print "==>" . $userDN . "\n" if $DEBUG;
111 #########################
112 #check IsMember
113 #print OpenXPKI role
114 #########################
116 &setRoleAndExit("CA Operator") if &getIsMember($group_ca_dn, $userDN);
117 &setRoleAndExit("RA Operator") if &getIsMember($group_ra_dn, $userDN);
118 &setRoleAndExit("User") if &getIsMember($group_user_dn, $userDN);
120 exit 1; # if not member of a group
122 #########################
123 #functions
124 #########################
126 sub setRoleAndExit
128 my ($role) = @_;
129 print $role;
130 $ldap->unbind();
131 exit 0;
136 # get DN of given group
137 sub getGroupDN
139 my ($group) = @_;
140 #get original group DN
141 $mesg = $ldap->search(
142 base => $BASEDN,
143 filter => "(&(cn=$group)(objectclass=group))",
144 attrs => @attrs
146 my $entry = $mesg->pop_entry();
147 print "==> group is ",$entry->dn(),"\n" if $DEBUG;
148 return $entry->dn();
151 # get DN of given user
152 sub getUserDN
154 my ($user) = @_;
155 $mesg = $ldap->search(
156 base => $BASEDN,
157 filter => "samaccountname=$user",
158 attrs => @attrs
160 my $entry = $mesg->pop_entry();
161 print "==> user is ",$entry->dn(),"\n" if $DEBUG;
162 return $entry->dn();
165 #function userdn is member of groudn
166 sub getIsMember
168 my ($groupDN,$userDN) = @_;
169 my $return = 0;
171 print "==> in getIsMember:$groupDN\n" if $DEBUG;
172 #if user is a member then return true
173 my $mesg = $ldap->compare(
174 $groupDN,
175 attr => "member",
176 value => $userDN
180 #0x06 == LDAP_COMPARE_TRUE
181 if ($mesg->code() == 0x06) {
182 return 1;
185 #is also a group and perhaps a member of that group
186 my @groupattrs = ["member","objectclass","memberurl"];
187 eval{
188 $mesg = $ldap->search(
189 base => $groupDN,
190 filter => "(|(objectclass=group)(objectclass=groupOfUrls))",
191 attrs => @groupattrs
193 my $entry = $mesg->pop_entry();
194 #check is a member then return true
195 my $urlvalues = $entry->get_value("memberurl", asref => 1);
196 foreach my $urlval (@{$urlvalues})
198 my $uri = new URI ($urlval);
199 my $filter = $uri->filter();
200 my @attrs = $uri->attributes();
201 eval {
202 $mesg = $ldap->search(
203 base => $userDN,
204 scope => "base",
205 filter => $filter,
206 attrs => \@attrs
208 #if we find an entry it returns true
209 #else keep searching
210 $entry = $mesg->pop_entry();
211 print "ldapurl",$entry->dn,"\n" if $DEBUG;
212 if ($entry->dn)
214 $return = 1 ;
215 return 1;
218 } #end foreach
220 my $membervalues = $entry->get_value("member", asref => 1);
221 foreach my $val (@{$membervalues})
223 #stop as soon as we have a match
224 if (&getIsMember($val,$userDN))
226 $return=1;
227 return 1;
231 die $mesg->error if $mesg->code;
232 #if make it this far then you must be a member
234 # retrun 0 if a fault
235 if ($@)
237 return 0;
239 else
241 return $return;