]> git.proxmox.com Git - pmg-api.git/blob - src/PMG/RuleDB/LDAPUser.pm
fix #2071: RuleDB: ignore duplicate entries for Who objects
[pmg-api.git] / src / PMG / RuleDB / LDAPUser.pm
1 package PMG::RuleDB::LDAPUser;
2
3 use strict;
4 use warnings;
5 use DBI;
6 use Digest::SHA;
7
8 use PVE::INotify;
9
10 use PMG::Utils;
11 use PMG::RuleDB::Object;
12 use PMG::LDAPCache;
13 use PMG::LDAPConfig;
14 use PMG::LDAPSet;
15
16 use base qw(PMG::RuleDB::Object);
17
18 sub otype {
19 return 1006;
20 }
21
22 sub oclass {
23 return 'who';
24 }
25
26 sub otype_text {
27 return 'LDAP User';
28 }
29
30 sub new {
31 my ($type, $ldapuser, $profile, $ogroup) = @_;
32
33 my $class = ref($type) || $type;
34
35 my $self = $class->SUPER::new($class->otype(), $ogroup);
36
37 $self->{ldapuser} = $ldapuser // '';
38 $self->{profile} = $profile // '';
39
40 return $self;
41 }
42
43 sub load_attr {
44 my ($type, $ruledb, $id, $ogroup, $value) = @_;
45
46 my $class = ref($type) || $type;
47
48 defined($value) || die "undefined value: ERROR";
49
50 my $obj;
51 if ($value =~ m/^([^:]*):(.*)$/) {
52 $obj = $class->new($2, $1, $ogroup);
53 $obj->{digest} = Digest::SHA::sha1_hex($id, $2, $1, $ogroup);
54 } else {
55 $obj = $class->new($value, '', $ogroup);
56 $obj->{digest} = Digest::SHA::sha1_hex ($id, $value, '#', $ogroup);
57 }
58
59 $obj->{id} = $id;
60
61 return $obj;
62 }
63
64 sub save {
65 my ($self, $ruledb) = @_;
66
67 defined($self->{ogroup}) || die "undefined ogroup: ERROR";
68 defined($self->{ldapuser}) || die "undefined ldap user: ERROR";
69 defined($self->{profile}) || die "undefined ldap profile: ERROR";
70
71 my $user = $self->{ldapuser};
72 my $profile = $self->{profile};
73
74 my $confdata = "$profile:$user";
75
76 if (defined($self->{id})) {
77 # update
78
79 $ruledb->{dbh}->do(
80 "UPDATE Object SET Value = ? WHERE ID = ?",
81 undef, $confdata, $self->{id});
82
83 } else {
84 # insert
85
86 # check if it exists first
87 if (my $id = PMG::Utils::get_existing_object_id(
88 $ruledb->{dbh},
89 $self->{ogroup},
90 $self->otype(),
91 $confdata
92 )) {
93 return $id;
94 }
95
96 my $sth = $ruledb->{dbh}->prepare(
97 "INSERT INTO Object (Objectgroup_ID, ObjectType, Value) " .
98 "VALUES (?, ?, ?);");
99
100 $sth->execute($self->{ogroup}, $self->otype, $confdata);
101
102 $self->{id} = PMG::Utils::lastid($ruledb->{dbh}, 'object_id_seq');
103 }
104
105 return $self->{id};
106 }
107
108 sub test_ldap {
109 my ($ldap, $addr, $user, $profile) = @_;
110
111 return $ldap->account_has_address($user, $addr, $profile);
112 }
113
114 sub who_match {
115 my ($self, $addr, $ip, $ldap) = @_;
116
117 return 0 if !$ldap;
118
119 return test_ldap($ldap, $addr, $self->{ldapuser}, $self->{profile});
120 }
121
122 sub short_desc {
123 my ($self) = @_;
124
125 my $user = $self->{ldapuser};
126 my $profile = $self->{profile};
127
128 my $desc;
129
130 if ($profile) {
131 $desc = "LDAP user '$user', profile '$profile'";
132 } else {
133 $desc = "LDAP user without profile - fail always";
134 }
135
136 return $desc;
137 }
138
139 sub properties {
140 my ($class) = @_;
141
142 return {
143 profile => {
144 description => "Profile ID.",
145 type => 'string', format => 'pve-configid',
146 },
147 account => {
148 description => "LDAP user account name.",
149 type => 'string',
150 maxLength => 1024,
151 minLength => 1,
152 },
153 };
154 }
155
156 sub get {
157 my ($self) = @_;
158
159 return {
160 account => $self->{ldapuser},
161 profile => $self->{profile},
162 };
163 }
164
165 sub update {
166 my ($self, $param) = @_;
167
168 my $profile = $param->{profile};
169 my $cfg = PVE::INotify::read_file("pmg-ldap.conf");
170 my $config = $cfg->{ids}->{$profile};
171 die "LDAP profile '$profile' does not exist\n" if !$config;
172
173 my $account = $param->{account};
174 my $ldapcache = PMG::LDAPCache->new(
175 id => $profile, syncmode => 1, %$config);
176
177 die "LDAP acoount '$account' does not exist\n"
178 if !$ldapcache->account_exists($account);
179
180 $self->{ldapuser} = $account;
181 $self->{profile} = $profile;
182 }
183
184 1;
185
186 __END__
187
188 =head1 PMG::RuleDB::LDAPUser
189
190 A WHO object to check LDAP users
191
192 =head2 Attributes
193
194 =head3 ldapuser
195
196 An LDAP user account (ignore case).
197
198 =head3 profile
199
200 The LDAP profile name
201
202 =head2 Examples
203
204 $obj = PMG::RuleDB::LDAPUser>new('username', 'profile_name');
205