]> git.proxmox.com Git - pmg-api.git/blame - PMG/RuleDB/LDAP.pm
fix bug #1625 - change default rule priorities
[pmg-api.git] / PMG / RuleDB / LDAP.pm
CommitLineData
10621236
DM
1package PMG::RuleDB::LDAP;
2
3use strict;
4use warnings;
5use DBI;
6
2aeda4ac
DM
7use PVE::Exception qw(raise_param_exc);
8
10621236
DM
9use PMG::Utils;
10use PMG::RuleDB::Object;
11use PMG::LDAPCache;
12use PMG::LDAPSet;
13
14use base qw(PMG::RuleDB::Object);
15
16sub otype {
17 return 1005;
18}
19
20sub oclass {
21 return 'who';
22}
23
24sub otype_text {
25 return 'LDAP Group';
26}
27
10621236
DM
28sub new {
29 my ($type, $ldapgroup, $profile, $ogroup) = @_;
30
31 my $class = ref($type) || $type;
32
33 my $self = $class->SUPER::new($class->otype(), $ogroup);
34
35 $self->{ldapgroup} = $ldapgroup // '';
36 $self->{profile} = $profile // '';
37
38 return $self;
39}
40
41sub load_attr {
42 my ($type, $ruledb, $id, $ogroup, $value) = @_;
43
44 my $class = ref($type) || $type;
45
46 defined($value) || die "undefined value: ERROR";
47
48 my $obj;
49 if ($value =~ m/^([^:]*):(.*)$/) {
50 $obj = $class->new($2, $1, $ogroup);
2aeda4ac 51 $obj->{digest} = Digest::SHA::sha1_hex($id, $2, $1, $ogroup);
10621236 52 } else {
2aeda4ac
DM
53 $obj = $class->new($value, '', $ogroup);
54 $obj->{digest} = Digest::SHA::sha1_hex($id, $value, '#', $ogroup);
10621236
DM
55 }
56
57 $obj->{id} = $id;
58
59 return $obj;
60}
61
62sub save {
63 my ($self, $ruledb) = @_;
64
65 defined($self->{ogroup}) || die "undefined ogroup: ERROR";
66 defined($self->{ldapgroup}) || die "undefined ldap group: ERROR";
67 defined($self->{profile}) || die "undefined ldap profile: ERROR";
68
69 my $grp = $self->{ldapgroup};
70 my $profile = $self->{profile};
71
72 my $confdata = "$profile:$grp";
73
74 if (defined ($self->{id})) {
75 # update
76
77 $ruledb->{dbh}->do(
78 "UPDATE Object SET Value = ? WHERE ID = ?",
79 undef, $confdata, $self->{id});
80
81 } else {
82 # insert
83
84 my $sth = $ruledb->{dbh}->prepare(
85 "INSERT INTO Object (Objectgroup_ID, ObjectType, Value) " .
86 "VALUES (?, ?, ?);");
87
88 $sth->execute($self->{ogroup}, $self->otype, $confdata);
89
90 $self->{id} = PMG::Utils::lastid($ruledb->{dbh}, 'object_id_seq');
91 }
92
93 return $self->{id};
94}
95
96sub test_ldap {
97 my ($ldap, $addr, $group, $profile) = @_;
98
99 if ($group eq '') {
100 return $ldap->mail_exists($addr, $profile);
101 } elsif ($group eq '-') {
102 return !$ldap->mail_exists($addr, $profile);
2aeda4ac 103 } elsif ($profile) {
10621236 104 return $ldap->user_in_group ($addr, $group, $profile);
2aeda4ac
DM
105 } else {
106 # fail if we have a real $group without $profile
107 return 0;
10621236
DM
108 }
109}
110
111sub who_match {
112 my ($self, $addr, $ip, $ldap) = @_;
113
114 return 0 if !$ldap;
115
116 return test_ldap($ldap, $addr, $self->{ldapgroup}, $self->{profile});
117}
118
2aeda4ac
DM
119sub short_desc {
120 my ($self) = @_;
121
122 my $desc;
123
124 my $profile = $self->{profile};
125 my $group = $self->{ldapgroup};
126
127 if ($group eq '') {
128 $desc = "Existing LDAP address";
687306ad
DM
129 if ($profile) {
130 $desc .= ", profile '$profile'";
131 } else {
132 $desc .= ", any profile";
133 }
2aeda4ac
DM
134 } elsif ($group eq '-') {
135 $desc = "Unknown LDAP address";
687306ad
DM
136 if ($profile) {
137 $desc .= ", profile '$profile'";
138 } else {
139 $desc .= ", any profile";
140 }
2aeda4ac 141 } elsif ($profile) {
f76f331a 142 $desc = "LDAP group '$group', profile '$profile'";
2aeda4ac
DM
143 } else {
144 $desc = "LDAP group without profile - fail always";
145 }
146
147 return $desc;
148}
149
150sub properties {
151 my ($class) = @_;
152
153 return {
154 mode => {
155 description => "Operational mode. You can either match 'any' user, match when no such user exists with 'none', or match when the user is member of a specific group.",
156 type => 'string',
157 enum => ['any', 'none', 'group'],
158 },
159 profile => {
160 description => "Profile ID.",
161 type => 'string', format => 'pve-configid',
162 optional => 1,
163 },
164 group => {
165 description => "LDAP Group DN",
166 type => 'string',
167 maxLength => 1024,
168 minLength => 1,
169 optional => 1,
170 },
171 };
172}
173
174sub get {
175 my ($self) = @_;
176
177 my $group = $self->{ldapgroup};
178 my $profile = $self->{profile},
179
180 my $data = {};
181
182 if ($group eq '') {
183 $data->{mode} = 'any';
184 } elsif ($group eq '-') {
185 $data->{mode} = 'none';
186 } else {
187 $data->{mode} = 'group';
188 $data->{group} = $group;
189 }
190
191 $data->{profile} = $profile if $profile ne '';
192
193 return $data;
194 }
195
196sub update {
197 my ($self, $param) = @_;
198
199 my $mode = $param->{mode};
200
d974ca19
DM
201 if (defined(my $profile = $param->{profile})) {
202 my $cfg = PVE::INotify::read_file("pmg-ldap.conf");
203 my $config = $cfg->{ids}->{$profile};
204 die "LDAP profile '$profile' does not exist\n" if !$config;
205
206 if (defined(my $group = $param->{group})) {
207 my $ldapcache = PMG::LDAPCache->new(
208 id => $profile, syncmode => 1, %$config);
209
210 die "LDAP group '$group' does not exist\n"
211 if !$ldapcache->group_exists($group);
212 }
213 }
214
2aeda4ac 215 if ($mode eq 'any') {
5182cea0 216 raise_param_exc({ group => "parameter not allwed with mode '$mode'"})
2aeda4ac
DM
217 if defined($param->{group});
218 $self->{ldapgroup} = '';
219 $self->{profile} = $param->{profile} // '';
220 } elsif ($mode eq 'none') {
5182cea0 221 raise_param_exc({ group => "parameter not allwed with mode '$mode'"})
2aeda4ac
DM
222 if defined($param->{group});
223 $self->{ldapgroup} = '-';
224 $self->{profile} = $param->{profile} // '';
225 } elsif ($mode eq 'group') {
5182cea0 226 raise_param_exc({ group => "parameter is required with mode '$mode'"})
2aeda4ac
DM
227 if !defined($param->{group});
228 $self->{ldapgroup} = $param->{group};
5182cea0 229 raise_param_exc({ profile => "parameter is required with mode '$mode'"})
2aeda4ac
DM
230 if !defined($param->{profile});
231 $self->{profile} = $param->{profile};
232 } else {
233 die "internal error"; # just to me sure
234 }
235}
236
10621236
DM
2371;
238
239__END__
240
241=head1 PMG::RuleDB::LDAP
242
243A WHO object to check LDAP groups
244
245=head2 Attribues
246
247=head3 ldapgroup
248
249An LDAP group (ignore case).
250
251=head3 profile
252
253The LDAP profile name
254
255=head2 Examples
256
257 $obj = PMG::RuleDB::LDAP>new ('groupname', 'profile_name');