nur-sery/nur_src/ldap/ldap.php

161 lines
4.9 KiB
PHP
Raw Permalink Normal View History

2024-04-04 22:21:20 +04:00
<?php
namespace nur\ldap;
use nur\A;
use nur\data\types\md_utils;
use nur\data\types\Metadata;
class ldap {
#############################################################################
const ADD_SCHEMA = [
"controls" => ["array", []],
];
/** @var Metadata */
private static $add_md;
static function add_md(): Metadata {
return md_utils::ensure_md(self::$add_md, self::ADD_SCHEMA);
}
static function add($conn, string $dn, array $attrs, $params=null): void {
self::add_md()->ensureSchema($params);
$r = LdapException::check("add", $conn
, @ldap_add_ext($conn, $dn, $attrs, $params["controls"]));
LdapException::check_result("add", $conn, $r);
}
#############################################################################
const MODIFY_SCHEMA = [
"controls" => ["array", []],
];
/** @var Metadata */
private static $modify_md;
static function modify_md(): Metadata {
return md_utils::ensure_md(self::$modify_md, self::MODIFY_SCHEMA);
}
static function prepare_modify(array $modattrs): array {
$modifs = [];
foreach ($modattrs as $modattr) {
$modtype = false;
$first = true;
$index = 0;
foreach ($modattr as $name => $value) {
if ($first && $name === $index) {
$first = false;
$index++;
switch ($value) {
case "add":
$modtype = LDAP_MODIFY_BATCH_ADD;
break;
case "delete":
$modtype = LDAP_MODIFY_BATCH_REMOVE;
break;
case "replace":
$modtype = LDAP_MODIFY_BATCH_REPLACE;
break;
}
continue;
}
if ($name === $index) {
$index++;
$modifs[] = [
"modtype" => LDAP_MODIFY_BATCH_REMOVE_ALL,
"attrib" => $value,
];
} else {
$modifs[] = [
"modtype" => $modtype,
"attrib" => $name,
"values" => $value
];
}
}
}
return $modifs;
}
static function modify($conn, string $dn, array $modattrs, $params=null): void {
self::modify_md()->ensureSchema($params);
$modifs = self::prepare_modify($modattrs);
LdapException::check("modify", $conn
, @ldap_modify_batch($conn, $dn, $modifs, $params["controls"]));
}
#############################################################################
const RENAME_SCHEMA = [
"new_parent" => ["?string", null],
"delete_old_rdn" => ["bool", true],
"controls" => ["array", []],
];
/** @var Metadata */
private static $rename_md;
static function rename_md(): Metadata {
return md_utils::ensure_md(self::$rename_md, self::RENAME_SCHEMA);
}
/**
* préparer les paramètres pour le renommage
*
* si $newRdn n'est pas vide:
* - si $params["new_parent"] n'est pas spécifié ou null, alors on ne fait
* qu'un renommage: prendre le suffixe de $dn
* - sinon, le nouveau DN est "$newRdn,$params[new_parent]"
*
* si $newRdn est vide:
* - il s'agit d'un déplacement de branche. $params["new_parent"] ne doit pas
* être vide et c'est la nouvelle destination. le RDN n'est pas modifié
*/
static function prepare_rename(string $dn, string &$newRdn, &$params = null): bool {
self::rename_md()->ensureSchema($params);
names::split_dn($dn, $origRdn, $origParent);
$newParent = $params["new_parent"];
if ($newRdn != "") {
# renommage et éventuellement déplacement
if (strpos($newRdn, "=") === false) {
# si le rdn ne comporte que la valeur, alors prendre le nom de
# l'attribut depuis origRdn
$name = A::first_key(names::split_rdn($origRdn));
$newRdn = names::build_rdn($name, $newRdn);
}
if ($newParent === null) $newParent = $origParent;
} else {
# déplacement avec le même RDN
$newRdn = $origRdn;
}
$newDn = names::join($newRdn, $newParent);
names::split_dn($newDn, $newRdn, $newParent);
$params["new_parent"] = $newParent;
return $newDn !== $dn;
}
static function rename($conn, string $dn, string $newRdn, array $params): string {
$newParent = $params["new_parent"];
$r = LdapException::check("rename", $conn
, @ldap_rename_ext($conn, $dn, $newRdn, $newParent
, $params["delete_old_rdn"], $params["controls"]));
LdapException::check_result("rename", $conn, $r);
return names::join($newRdn, $newParent);
}
#############################################################################
const DELETE_SCHEMA = [
"controls" => ["array", []],
];
/** @var Metadata */
private static $delete_md;
static function delete_md(): Metadata {
return md_utils::ensure_md(self::$delete_md, self::DELETE_SCHEMA);
}
static function delete($conn, string $dn, $params=null): void {
self::delete_md()->ensureSchema($params);
$r = LdapException::check("delete", $conn
, @ldap_delete_ext($conn, $dn, $params["controls"]));
LdapException::check_result("delete", $conn, $r);
}
}