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