/usr/share/perl5/Apache/Ocsinventory/Server/Duplicate.pm is in ocsinventory-server 2.0.5-1.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | ###############################################################################
## OCSINVENTORY-NG
## Copyleft Pascal DANEK 2005
## Web : http://www.ocsinventory-ng.org
##
## This code is open source and may be copied and modified as long as the source
## code is always made freely available.
## Please refer to the General Public Licence http://www.gnu.org/ or Licence.txt
################################################################################
package Apache::Ocsinventory::Server::Duplicate;
use strict;
BEGIN{
if($ENV{'OCS_MODPERL_VERSION'} == 1){
require Apache::Ocsinventory::Server::Modperl1;
Apache::Ocsinventory::Server::Modperl1->import();
}elsif($ENV{'OCS_MODPERL_VERSION'} == 2){
require Apache::Ocsinventory::Server::Modperl2;
Apache::Ocsinventory::Server::Modperl2->import();
}
}
require Exporter;
our @ISA = qw /Exporter/;
our @EXPORT = qw / _duplicate_main /;
use Apache::Ocsinventory::Server::Constants;
use Apache::Ocsinventory::Server::System qw /:server _modules_get_duplicate_handlers/;
use Apache::Ocsinventory::Map;
# Subroutine called at the end of database inventory insertions
sub _duplicate_main{
my %exist;
my $red;
my $result = $Apache::Ocsinventory::CURRENT_CONTEXT{'XML_ENTRY'};
my $dbh = $Apache::Ocsinventory::CURRENT_CONTEXT{'DBI_HANDLE'};
my $DeviceID = $Apache::Ocsinventory::CURRENT_CONTEXT{'DATABASE_ID'};
# If the duplicate is specified
if($result->{CONTENT}->{OLD_DEVICEID} and $result->{CONTENT}->{OLD_DEVICEID} ne $Apache::Ocsinventory::CURRENT_CONTEXT{'DEVICEID'}){
&_log(326,'duplicate',$result->{CONTENT}->{OLD_DEVICEID}) if $ENV{'OCS_OPT_LOGLEVEL'};
# Looking for database id of old deviceid
my $request = $dbh->prepare('SELECT ID FROM hardware WHERE DEVICEID=?');
$request->execute($result->{CONTENT}->{OLD_DEVICEID});
if(my $row = $request->fetchrow_hashref){
if(&_duplicate_replace($row->{'ID'})){
# If there is an invalid old deviceid
&_log(513,'duplicate','old deviceid') if $ENV{'OCS_OPT_LOGLEVEL'};
$dbh->rollback;
}else{
$dbh->commit;
$red = 1;
}
}
}
# Handle duplicates if $ENV{'OCS_OPT_AUTO_DUPLICATE_LVL'} is set
if($ENV{'OCS_OPT_AUTO_DUPLICATE_LVL'}){
# Trying to find some duplicate evidences
&_duplicate_detect(\%exist);
# For each result, we are trying to know if it is a true duplicate (according to AUTO_DUPLICATE_LVL
for(sort keys(%exist)){
if(&_duplicate_evaluate(\%exist, $_)){
if(&_duplicate_replace($_)){
&_log(517,'duplicate','replacing_error') if $ENV{'OCS_OPT_LOGLEVEL'};
$dbh->rollback;
}else{
$dbh->commit;
$red = 1;
}
}
}
}
return $red;
}
sub _already_in_array {
my $lookfor = shift;
my $ref = shift;
foreach (@$ref){
return 1 if($lookfor eq $_);
}
return 0;
}
sub _duplicate_evaluate{
my $exist = shift;
my $key = shift;
# Check duplicate , according to AUTO_DUPLICATE_LVL
$exist->{$key}->{'MASK'} = 0;
$exist->{$key}->{'MASK'}|=DUP_HOSTNAME_FL if $exist->{$key}->{'HOSTNAME'};
$exist->{$key}->{'MASK'}|=DUP_SERIAL_FL if $exist->{$key}->{'SSN'};
$exist->{$key}->{'MASK'}|=DUP_MACADDR_FL if $exist->{$key}->{'MACADDRESS'};
$exist->{$key}->{'MASK'}|=DUP_SMODEL_FL if $exist->{$key}->{'SMODEL'};
$exist->{$key}->{'MASK'}|=DUP_UUID_FL if $exist->{$key}->{'UUID'};
$exist->{$key}->{'MASK'}|=DUP_ASSETTAG_FL if $exist->{$key}->{'ASSETTAG'};
if((($ENV{'OCS_OPT_AUTO_DUPLICATE_LVL'} & $exist->{$key}->{'MASK'})) == $ENV{'OCS_OPT_AUTO_DUPLICATE_LVL'}){
return(1);
}else{
return(0);
}
}
sub _duplicate_detect{
my $exist = shift;
my $result = $Apache::Ocsinventory::CURRENT_CONTEXT{'XML_ENTRY'};
my $dbh = $Apache::Ocsinventory::CURRENT_CONTEXT{'DBI_HANDLE'};
my $DeviceID = $Apache::Ocsinventory::CURRENT_CONTEXT{'DATABASE_ID'};
my $request;
my $row;
my(@bad_serial, @bad_mac);
# Retrieve generic mac addresses
$request = $dbh->prepare('SELECT MACADDRESS FROM blacklist_macaddresses');
$request->execute();
push @bad_mac, $row->{MACADDRESS} while($row = $request->fetchrow_hashref());
# Retrieve generic serials
$request = $dbh->prepare('SELECT SERIAL FROM blacklist_serials');
$request->execute();
push @bad_serial, $row->{SERIAL} while($row = $request->fetchrow_hashref());
# Do we already have the hostname
$request = $dbh->prepare('SELECT ID, NAME FROM hardware WHERE NAME=? AND ID<>? ORDER BY ID');
$request->execute($result->{CONTENT}->{HARDWARE}->{NAME}, $DeviceID);
while($row = $request->fetchrow_hashref()){
if(!($row->{'NAME'} eq '')){
$exist->{$row->{'ID'}}->{'HOSTNAME'}=1;
}
}
# Do we already have the assettag ?
$request = $dbh->prepare('SELECT HARDWARE_ID, ASSETTAG FROM bios WHERE ASSETTAG=? AND HARDWARE_ID<>? ORDER BY HARDWARE_ID');
$request->execute($result->{CONTENT}->{BIOS}->{ASSETTAG}, $DeviceID);
while($row = $request->fetchrow_hashref()){
if(!($row->{'ASSETTAG'} eq '')){
$exist->{$row->{'ID'}}->{'ASSETTAG'}=1;
}
}
# Do we already have the uuid ?
$request = $dbh->prepare('SELECT ID, UUID FROM hardware WHERE UUID=? AND ID<>? ORDER BY ID');
$request->execute($result->{CONTENT}->{HARDWARE}->{UUID}, $DeviceID);
while($row = $request->fetchrow_hashref()){
if(!($row->{'UUID'} eq '')){
$exist->{$row->{'ID'}}->{'UUID'}=1;
}
}
# ...and one MAC of this machine
for(@{$result->{CONTENT}->{NETWORKS}}){
$request = $dbh->prepare('SELECT HARDWARE_ID,DESCRIPTION,MACADDR FROM networks WHERE MACADDR=? AND HARDWARE_ID<>?');
$request->execute($_->{MACADDR}, $DeviceID);
while($row = $request->fetchrow_hashref()){
if(!&_already_in_array($row->{'MACADDR'}, \@bad_mac)){
$exist->{$row->{'HARDWARE_ID'}}->{'MACADDRESS'}++;
}
}
}
# ...or its serial
if($result->{CONTENT}->{BIOS}->{SSN}){
$request = $dbh->prepare('SELECT HARDWARE_ID, SSN FROM bios WHERE SSN=? AND HARDWARE_ID<>?');
$request->execute($result->{CONTENT}->{BIOS}->{SSN}, $DeviceID);
while($row = $request->fetchrow_hashref()){
if(!&_already_in_array($row->{'SSN'}, \@bad_serial)){
$exist->{$row->{'HARDWARE_ID'}}->{'SSN'}=1;
}
}
}
# ...or its serial model
if($result->{CONTENT}->{BIOS}->{SMODEL}){
$request = $dbh->prepare('SELECT HARDWARE_ID, SMODEL FROM bios WHERE SMODEL=? AND HARDWARE_ID<>?');
$request->execute($result->{CONTENT}->{BIOS}->{SMODEL}, $DeviceID);
while($row = $request->fetchrow_hashref()){
$exist->{$row->{'HARDWARE_ID'}}->{'SMODEL'}=1;
}
}
$request->finish;
}
sub _duplicate_replace{
my $device = shift;
#Locks the device
if( &_lock($device) ){
&_log( 516, 'duplicate', 'device locked');
return 1;
}
my $DeviceID = $Apache::Ocsinventory::CURRENT_CONTEXT{'DATABASE_ID'};
my $dbh = $Apache::Ocsinventory::CURRENT_CONTEXT{'DBI_HANDLE'};
my $result = $Apache::Ocsinventory::CURRENT_CONTEXT{'XML_ENTRY'};
# We keep the old quality and fidelity
my $request=$dbh->prepare('SELECT QUALITY,FIDELITY,CHECKSUM,USERID FROM hardware WHERE ID=?');
$request->execute($device);
# If it does not exist
unless($request->rows){
&_unlock($device);
return(1);
}
my $row = $request->fetchrow_hashref;
my $quality = $row->{'QUALITY'}?$row->{'QUALITY'}:0;
my $fidelity = $row->{'FIDELITY'};
my $checksum = $row->{'CHECKSUM'};
my $userid = $row->{'USERID'};
$request->finish;
# Current userid or previous one ?
if( $result->{CONTENT}->{HARDWARE}->{USERID}!~/system|localsystem/i ){
$userid = $result->{CONTENT}->{HARDWARE}->{USERID};
}
# TODO: catch the queries return code
# Keeping few informations from hardware
$dbh->do(" UPDATE hardware SET QUALITY=".$dbh->quote($quality).",
FIDELITY=".$dbh->quote($fidelity).",
CHECKSUM=(".(defined($checksum)?$checksum:CHECKSUM_MAX_VALUE)."|".(defined($result->{CONTENT}->{HARDWARE}->{CHECKSUM})?$result->{CONTENT}->{HARDWARE}->{CHECKSUM}:CHECKSUM_MAX_VALUE)."),
USERID=".$dbh->quote($userid)."
WHERE ID=".$DeviceID
) ;
$dbh->do("DELETE FROM hardware WHERE ID=?", {}, $device) ;
# We keep the informations of the following tables: devices, accountinfo, itmgmt_comments
$dbh->do('DELETE FROM accountinfo WHERE HARDWARE_ID=?', {}, $DeviceID) ;
$dbh->do('UPDATE accountinfo SET HARDWARE_ID=? WHERE HARDWARE_ID=?', {}, $DeviceID, $device) ;
$dbh->do('DELETE FROM devices WHERE HARDWARE_ID=?', {}, $DeviceID) ;
$dbh->do('UPDATE devices SET HARDWARE_ID=? WHERE HARDWARE_ID=?', {}, $DeviceID, $device) ;
$dbh->do('UPDATE itmgmt_comments SET HARDWARE_ID=? WHERE HARDWARE_ID=?', {}, $DeviceID, $device) ;
# We keep the static inclusions/exclusions (STATIC=1|2)
$dbh->do('UPDATE groups_cache SET HARDWARE_ID=? WHERE HARDWARE_ID=? AND (STATIC=1 OR STATIC=2)', {}, $DeviceID, $device) ;
# The computer may not correspond to the previous dynamic groups, as its inventory could potentially change
$dbh->do('DELETE FROM groups_cache WHERE HARDWARE_ID=?', {}, $device) ;
# Drop old computer from "auto" tables in Map
# TODO: is it possible to manage the not auto section => not auto for import but auto for deletion ?
for (keys(%DATA_MAP)){
next if !$DATA_MAP{$_}->{delOnReplace} || !$DATA_MAP{$_}->{auto} || $DATA_MAP{$_}->{capacities};
unless($dbh->do("DELETE FROM $_ WHERE HARDWARE_ID=?", {}, $device)){
&_unlock($device);
return(1);
}
}
# Trace duplicate if needed
if($ENV{'OCS_OPT_TRACE_DELETED'}){
unless( $dbh->do('INSERT INTO deleted_equiv(DATE,DELETED,EQUIVALENT) VALUES(NULL,?,?)', {} , $device,$DeviceID)){
&_unlock($device);
return(1);
}
}
# To enable option managing duplicates
for(&_modules_get_duplicate_handlers()){
last if $_==0;
# Returning 1 will abort replacement
unless(&$_(\%Apache::Ocsinventory::CURRENT_CONTEXT, $device)){
&_unlock($device);
return(1);
}
}
&_log(300,'duplicate',"$device => $DeviceID") if $ENV{'OCS_OPT_LOGLEVEL'};
#Remove lock
&_unlock($device);
0;
}
1;
|