VYPR
Moderate severityNVD Advisory· Published Nov 15, 2024· Updated Nov 15, 2024

Improper Authorization in dolibarr/dolibarr

CVE-2021-3991

Description

An Improper Authorization vulnerability exists in Dolibarr versions prior to the 'develop' branch. A user with restricted permissions in the 'Reception' section is able to access specific reception details via direct URL access, bypassing the intended permission restrictions.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Dolibarr ERP/CRM prior to the develop branch contains an improper authorization vulnerability allowing restricted users to access reception details via direct URL.

CVE-2021-3991 is an improper authorization vulnerability in Dolibarr ERP/CRM, an open-source business management suite [1]. The flaw resides in the Reception module: a user with restricted permissions (e.g., lacking 'lire' or 'read' rights) can bypass intended access controls by directly navigating to reception detail URLs [2][3]. The root cause is missing permission checks in the receptioncard.php script, which fails to enforce the restrictedArea() function for all access paths [2].

Exploitation requires an authenticated session with a role that has limited Reception permissions. No special network position is needed; the attacker simply crafts a direct URL to a reception record (e.g., /reception/card.php?id=X). The vulnerability was introduced because the permission check was only applied when the origin was 'reception', leaving other entry points unguarded [2].

A successful attacker can view sensitive reception details, such as supplier order information, stock movements, and associated documents, that should be hidden from their role [3][4]. This could lead to information disclosure and potential business intelligence leakage, though no data modification or privilege escalation is reported.

The issue was fixed in the 'develop' branch via commit 63cd063, which restructures the permission logic to always verify reception rights when the module is enabled [2]. Users are advised to update to the latest develop version or apply the patch manually. No official workaround is documented, and the vulnerability is not listed on CISA's Known Exploited Vulnerabilities catalog.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
dolibarr/dolibarrPackagist
< 15.0.015.0.0

Affected products

3

Patches

1
63cd06394f39

Debug permission on supplier order.

https://github.com/dolibarr/dolibarrLaurent DestailleurNov 20, 2021via ghsa
8 files changed · +101 47
  • htdocs/core/menus/standard/eldy.lib.php+2 1 modified
    @@ -2149,7 +2149,8 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM
     					// Not enabled but visible (so greyed), except if parent was not enabled.
     					print '<div class="menu_contenu'.$cssmenu.'">';
     					print $tabstring;
    -					print '<span class="vsmenudisabled vsmenudisabledmargin">'.$menu_array[$i]['titre'].'</span><br></div>'."\n";
    +					print '<span class="vsmenudisabled vsmenudisabledmargin">'.$menu_array[$i]['titre'].'</span><br>';
    +					print '</div>'."\n";
     				}
     			}
     
    
  • htdocs/fourn/class/fournisseur.commande.class.php+8 1 modified
    @@ -2295,7 +2295,14 @@ public function Livraison($user, $date, $type, $comment)
     
     		dol_syslog(get_class($this)."::Livraison");
     
    -		if ($user->rights->fournisseur->commande->receptionner) {
    +		$usercanreceive = 0;
    +		if (empty($conf->reception->enabled)) {
    +			$usercanreceive = $user->rights->fournisseur->commande->receptionner;
    +		} else {
    +			$usercanreceive = $user->rights->reception->creer;
    +		}
    +
    +		if ($usercanreceive) {
     			// Define the new status
     			if ($type == 'par') {
     				$statut = self::STATUS_RECEIVED_PARTIALLY;
    
  • htdocs/fourn/commande/card.php+7 2 modified
    @@ -90,7 +90,6 @@
     if ($user->socid) {
     	$socid = $user->socid;
     }
    -$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande');
     
     // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
     $hookmanager->initHooks(array('ordersuppliercard', 'globalcard'));
    @@ -124,6 +123,8 @@
     	}
     }
     
    +$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande');
    +
     // Common permissions
     $usercanread	= ($user->rights->fournisseur->commande->lire || $user->rights->supplier_order->lire);
     $usercancreate	= ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer);
    @@ -136,7 +137,11 @@
     $usercanapprove			= $user->rights->fournisseur->commande->approuver;
     $usercanapprovesecond	= $user->rights->fournisseur->commande->approve2;
     $usercanorder			= $user->rights->fournisseur->commande->commander;
    -$usercanreceived		= $user->rights->fournisseur->commande->receptionner;
    +if (empty($conf->reception->enabled)) {
    +	$usercanreceive = $user->rights->fournisseur->commande->receptionner;
    +} else {
    +	$usercanreceive = $user->rights->reception->creer;
    +}
     
     // Permissions for includes
     $permissionnote		= $usercancreate; // Used by the include of actions_setnotes.inc.php
    
  • htdocs/fourn/commande/dispatch.php+34 15 modified
    @@ -62,11 +62,6 @@
     if ($user->socid) {
     	$socid = $user->socid;
     }
    -$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande');
    -
    -if (empty($conf->stock->enabled)) {
    -	accessforbidden();
    -}
     
     $hookmanager->initHooks(array('ordersupplierdispatch'));
     
    @@ -89,6 +84,21 @@
     	}
     }
     
    +if (empty($conf->reception->enabled)) {
    +	$permissiontoreceive = $user->rights->fournisseur->commande->receptionner;
    +	$permissiontocontrol = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->commande_advance->check)));
    +} else {
    +	$permissiontoreceive = $user->rights->reception->creer;
    +	$permissiontocontrol = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->creer)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->reception_advance->validate)));
    +}
    +
    +// $id is id of a purchase order.
    +$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande');
    +
    +if (empty($conf->stock->enabled)) {
    +	accessforbidden();
    +}
    +
     
     /*
      * Actions
    @@ -100,7 +110,7 @@
     	setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
     }
     
    -if ($action == 'checkdispatchline' && !((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) {
    +if ($action == 'checkdispatchline' && $permissiontocontrol) {
     	$error = 0;
     	$supplierorderdispatch = new CommandeFournisseurDispatch($db);
     
    @@ -137,7 +147,7 @@
     	}
     }
     
    -if ($action == 'uncheckdispatchline' && !((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) {
    +if ($action == 'uncheckdispatchline' && $permissiontocontrol) {
     	$error = 0;
     	$supplierorderdispatch = new CommandeFournisseurDispatch($db);
     
    @@ -173,7 +183,7 @@
     	}
     }
     
    -if ($action == 'denydispatchline' && !((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) {
    +if ($action == 'denydispatchline' && $permissiontocontrol) {
     	$error = 0;
     	$supplierorderdispatch = new CommandeFournisseurDispatch($db);
     
    @@ -209,7 +219,7 @@
     	}
     }
     
    -if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner) {
    +if ($action == 'dispatch' && $permissiontoreceive) {
     	$error = 0;
     
     	$db->begin();
    @@ -387,7 +397,7 @@
     }
     
     // Remove a dispatched line
    -if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->fournisseur->commande->receptionner) {
    +if ($action == 'confirm_deleteline' && $confirm == 'yes' && $permissiontoreceive) {
     	$db->begin();
     
     	$supplierorderdispatch = new CommandeFournisseurDispatch($db);
    @@ -430,7 +440,7 @@
     }
     
     // Update a dispatched line
    -if ($action == 'updateline' && $user->rights->fournisseur->commande->receptionner) {
    +if ($action == 'updateline' && $permissiontoreceive) {
     	$db->begin();
     	$error = 0;
     
    @@ -751,9 +761,9 @@
     
     				// Select warehouse to force it everywhere
     				if (count($listwarehouses) > 1) {
    -					print '<br>'.$langs->trans("ForceTo").' '.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 1, 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1);
    +					print '<br><span class="opacitymedium">'.$langs->trans("ForceTo").'</span> '.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 1, 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1);
     				} elseif (count($listwarehouses) == 1) {
    -					print '<br>'.$langs->trans("ForceTo").' '.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 0, 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1);
    +					print '<br><span class="opacitymedium">'.$langs->trans("ForceTo").'</span> '.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 0, 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1);
     				}
     
     				print '</td>';
    @@ -1055,10 +1065,19 @@
     
     				$dispatchBt = empty($conf->reception->enabled) ? $langs->trans("Receive") : $langs->trans("CreateReception");
     
    -				print '<br><input type="submit" class="button" name="dispatch" value="'.dol_escape_htmltag($dispatchBt).'"';
    +				print '<br>';
    +				print '<input type="submit" class="button" name="dispatch" value="'.dol_escape_htmltag($dispatchBt).'"';
    +				$disabled = 0;
    +				if (!$permissiontoreceive) {
    +					$disabled = 1;
    +				}
     				if (count($listwarehouses) <= 0) {
    +					$disabled = 1;
    +				}
    +				if ($disabled) {
     					print ' disabled';
     				}
    +
     				print '>';
     			}
     			print '</div>';
    @@ -1257,7 +1276,7 @@
     
     					// Add button to check/uncheck disaptching
     					print '<td class="center">';
    -					if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check))) {
    +					if (!$permissiontocontrol) {
     						if (empty($objp->status)) {
     							print '<a class="button buttonRefused" href="#">'.$langs->trans("Approve").'</a>';
     							print '<a class="button buttonRefused" href="#">'.$langs->trans("Deny").'</a>';
    
  • htdocs/reception/card.php+33 24 modified
    @@ -112,9 +112,6 @@
     // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
     $hookmanager->initHooks(array('receptioncard', 'globalcard'));
     
    -$permissiondellink = $user->rights->reception->creer; // Used by the include of actions_dellink.inc.php
    -//var_dump($object->lines[0]->detail_batch);
    -
     $date_delivery = dol_mktime(GETPOST('date_deliveryhour', 'int'), GETPOST('date_deliverymin', 'int'), 0, GETPOST('date_deliverymonth', 'int'), GETPOST('date_deliveryday', 'int'), GETPOST('date_deliveryyear', 'int'));
     
     if ($id > 0 || !empty($ref)) {
    @@ -142,16 +139,31 @@
     	$socid = $user->socid;
     }
     
    -if ($origin == 'reception') {
    +if (!empty($conf->reception->enabled) || $origin == 'reception' || empty($origin)) {
     	$result = restrictedArea($user, 'reception', $id);
     } else {
    +	// We do not use the reception module, so we test permission on the supplier orders
     	if ($origin == 'supplierorder' || $origin == 'order_supplier') {
     		$result = restrictedArea($user, 'fournisseur', $origin_id, 'commande_fournisseur', 'commande');
     	} elseif (empty($user->rights->{$origin}->lire) && empty($user->rights->{$origin}->read)) {
     		accessforbidden();
     	}
     }
     
    +if (!empty($conf->reception->enabled)) {
    +	$permissiontoread = $user->rights->reception->lire;
    +	$permissiontoadd = $user->rights->reception->creer;
    +	$permissiondellink = $user->rights->reception->creer; // Used by the include of actions_dellink.inc.php
    +	$permissiontovalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->creer)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->reception_advance->validate)));
    +	$permissiontodelete = $user->rights->reception->supprimer;
    +} else {
    +	$permissiontoread = $user->rights->fournisseur->commande->receptionner;
    +	$permissiontoadd = $user->rights->fournisseur->commande->receptionner;
    +	$permissiondellink = $user->rights->fournisseur->commande->receptionner; // Used by the include of actions_dellink.inc.php
    +	$permissiontovalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->commande_advance->check)));
    +	$permissiontodelete = $user->rights->fournisseur->commande->receptionner;
    +}
    +
     
     /*
      * Actions
    @@ -171,12 +183,12 @@
     	include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
     
     	// Reopen
    -	if ($action == 'reopen' && $user->rights->reception->creer) {
    +	if ($action == 'reopen' && $permissiontoadd) {
     		$result = $object->reOpen();
     	}
     
     	// Confirm back to draft status
    -	if ($action == 'modif' && $user->rights->reception->creer) {
    +	if ($action == 'modif' && $permissiontoadd) {
     		$result = $object->setDraft($user);
     		if ($result >= 0) {
     			// Define output language
    @@ -201,11 +213,11 @@
     	}
     
     	// Set incoterm
    -	if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled)) {
    +	if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled) && $permissiontoadd) {
     		$result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha'));
     	}
     
    -	if ($action == 'setref_supplier') {
    +	if ($action == 'setref_supplier' && $permissiontoadd) {
     		if ($result < 0) {
     			setEventMessages($object->error, $object->errors, 'errors');
     		}
    @@ -220,7 +232,7 @@
     		}
     	}
     
    -	if ($action == 'update_extras') {
    +	if ($action == 'update_extras' && $permissiontoadd) {
     		$object->oldcopy = dol_clone($object);
     
     		// Fill array 'array_options' with data from update form
    @@ -244,7 +256,7 @@
     	}
     
     	// Create reception
    -	if ($action == 'add' && $user->rights->reception->creer) {
    +	if ($action == 'add' && $permissiontoadd) {
     		$error = 0;
     		$predef = '';
     
    @@ -405,10 +417,7 @@
     			$_GET["commande_id"] = GETPOST('commande_id', 'int');
     			$action = 'create';
     		}
    -	} elseif ($action == 'confirm_valid' && $confirm == 'yes' &&
    -		((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->creer))
    -		|| (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->reception_advance->validate)))
    -	) {
    +	} elseif ($action == 'confirm_valid' && $confirm == 'yes' && $permissiontovalidate) {
     		$object->fetch_thirdparty();
     
     		$result = $object->valid($user);
    @@ -440,7 +449,7 @@
     				}
     			}
     		}
    -	} elseif ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->reception->supprimer) {
    +	} elseif ($action == 'confirm_delete' && $confirm == 'yes' && $permissiontodelete) {
     		$result = $object->delete($user);
     		if ($result > 0) {
     			header("Location: ".DOL_URL_ROOT.'/reception/index.php');
    @@ -455,7 +464,7 @@
     			if ($result < 0) {
     				setEventMessages($object->error, $object->errors, 'errors');
     		}*/
    -	} elseif ($action == 'setdate_livraison' && $user->rights->reception->creer) {
    +	} elseif ($action == 'setdate_livraison' && $permissiontoadd) {
     		//print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year'];
     		$datedelivery = dol_mktime(GETPOST('liv_hour', 'int'), GETPOST('liv_min', 'int'), 0, GETPOST('liv_month', 'int'), GETPOST('liv_day', 'int'), GETPOST('liv_year', 'int'));
     
    @@ -506,7 +515,7 @@
     		}
     
     		$action = "";
    -	} elseif ($action == 'builddoc') {
    +	} elseif ($action == 'builddoc' && $permissiontoread) {
     		// Build document
     		// En get ou en post
     		// Save last template used to generate document
    @@ -532,7 +541,7 @@
     			setEventMessages($object->error, $object->errors, 'errors');
     			$action = '';
     		}
    -	} elseif ($action == 'remove_file') {
    +	} elseif ($action == 'remove_file' && $permissiontoadd) {
     		// Delete file in doc form
     		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
    @@ -550,13 +559,13 @@
     			header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
     			exit();
     		}
    -	} elseif ($action == 'classifyclosed') {
    +	} elseif ($action == 'classifyclosed' && $permissiontoread) {
     		$result = $object->setClosed();
     		if ($result >= 0) {
     			header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
     			exit();
     		}
    -	} elseif ($action == 'deleteline' && !empty($line_id)) {
    +	} elseif ($action == 'deleteline' && !empty($line_id) && $permissiontoread) {
     		// delete a line
     		$lines = $object->lines;
     		$line = new CommandeFournisseurDispatch($db);
    @@ -579,7 +588,7 @@
     		} else {
     			setEventMessages($line->error, $line->errors, 'errors');
     		}
    -	} elseif ($action == 'updateline' && $user->rights->reception->creer && GETPOST('save')) {
    +	} elseif ($action == 'updateline' && GETPOST('save') && $permissiontoadd) {
     		// Update a line
     		// Clean parameters
     		$qty = 0;
    @@ -666,11 +675,11 @@
     				$object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
     			}
     		} else {
    -			header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // Pour reaffichage de la fiche en cours d'edition
    +			header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To reshow the record we edit
     			exit();
     		}
    -	} elseif ($action == 'updateline' && $user->rights->reception->creer && GETPOST('cancel', 'alpha') == $langs->trans("Cancel")) {
    -		header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // Pour reaffichage de la fiche en cours d'edition
    +	} elseif ($action == 'updateline' && $permissiontoadd && GETPOST('cancel', 'alpha') == $langs->trans("Cancel")) {
    +		header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To reshow the record we edit
     		exit();
     	}
     
    
  • htdocs/theme/eldy/global.inc.php+2 2 modified
    @@ -2881,12 +2881,12 @@
     	color: #202020;
     	margin: 1px 1px 1px 6px;
     }
    -font.vsmenudisabled { font-family: <?php print $fontlist ?>; text-align: <?php print $left; ?>; color: #aaa; }
    +span.vsmenudisabled, font.vsmenudisabled { font-family: <?php print $fontlist ?>; text-align: <?php print $left; ?>; color: #aaa; }
     a.vsmenu:link, a.vsmenu:visited {
     	color: var(--colortextbackvmenu);
     	white-space: nowrap;
     }
    -font.vsmenudisabledmargin { margin: 1px 1px 1px 6px; }
    +span.vsmenudisabledmargin, font.vsmenudisabledmargin { margin: 1px 1px 1px 6px; }
     li a.vsmenudisabled, li.vsmenudisabled { color: #aaa !important; }
     
     a.help:link, a.help:visited, a.help:hover, a.help:active, span.help { text-align: <?php print $left; ?>; color: #aaa; text-decoration: none; }
    
  • htdocs/theme/md/style.css.php+2 2 modified
    @@ -2928,9 +2928,9 @@
     a.vmenu:link, a.vmenu:visited { color: #<?php echo $colortextbackvmenu; ?>; }
     
     a.vsmenu:link, a.vsmenu:visited, a.vsmenu:hover, a.vsmenu:active, span.vsmenu { font-size:<?php print $fontsize ?>px; font-family: <?php print $fontlist ?>; text-align: <?php print $left; ?>; font-weight: normal; color: #202020; margin: 1px 1px 1px 8px; }
    -font.vsmenudisabled { font-size:<?php print $fontsize ?>px; font-family: <?php print $fontlist ?>; text-align: <?php print $left; ?>; font-weight: normal; color: #aaa; }
    +span.vsmenudisabled, font.vsmenudisabled { font-size:<?php print $fontsize ?>px; font-family: <?php print $fontlist ?>; text-align: <?php print $left; ?>; font-weight: normal; color: #aaa; }
     a.vsmenu:link, a.vsmenu:visited { color: #<?php echo $colortextbackvmenu; ?>; white-space: nowrap; }
    -font.vsmenudisabledmargin { margin: 1px 1px 1px 8px; }
    +span.vsmenudisabledmargin, font.vsmenudisabledmargin { margin: 1px 1px 1px 8px; }
     
     a.help:link, a.help:visited, a.help:hover, a.help:active, span.help { text-align: <?php print $left; ?>; font-weight: normal; color: #999; text-decoration: none; }
     
    
  • htdocs/user/perms.php+13 0 modified
    @@ -317,6 +317,19 @@
     			continue;
     		}
     
    +		// Special cases
    +		if (!empty($conf->reception->enabled)) {
    +			// The 2 permission in fournisseur modules has been replaced by permissions into reception module
    +			if ($obj->module == 'fournisseur' && $obj->perms == 'commande' && $obj->subperms == 'receptionner') {
    +				$i++;
    +				continue;
    +			}
    +			if ($obj->module == 'fournisseur' && $obj->perms == 'commande_advance' && $obj->subperms == 'check') {
    +				$i++;
    +				continue;
    +			}
    +		}
    +
     		$objMod = $modules[$obj->module];
     
     		// Save field module_position in database if value is wrong
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.