Ablakok.  Vírusok.  Jegyzetfüzetek.  Internet.  hivatal.  Segédprogramok.  Drivers

1

Egy egyszerű webhelyet fejlesztek PHP-ben, hogy néhány felhasználó elvégezhessen bizonyos feladatokat. Célom, hogy szerep alapú jogosultságot szerezzek a felhasználóknak, és az LDAP csoporttagságuk szerint különböző oldalakat lássanak. Én így próbálom megvalósítani az IT-t

1) használja a php-ldap könyvtár függvényeket az LDAP szerverhez való csatlakozáshoz 2) ldapsearch segítségével kinyerje ki a csoportnév és a felhasználónév dn-jét a felhasználói bázisból dn és csoportbázis dn 3) keresse meg a "memberOf" attribútumokat a felhasználói bejegyzésben, és párosítsa őket a dn csoporttal. Igaz értéket ad vissza, ha egyezik 4) Keresse meg a "member" attribútumokat a csoportbejegyzésben, és párosítsa őket a dn felhasználóval. Igazat ad vissza, ha egyezés van.

Eddig egy OpenLDAP szerveren teszteltem, és úgy tűnik, működik, de szeretném, ha a szkript más címtárszerverekkel is működne, mint például az ApacheDS, az Active Directory és a 389ds. Mivel nem férek hozzá több címtárszerverhez, szeretném tudatni Önnel, hogy ezek a lépések működnek-e más címtárszervereken vagy sem. Bármilyen segítséget ebben a tekintetben nagyra értékelnénk. Előre is köszönöm.

0

Itt van a "Felhasználói szűrő" szűrő (& (| (objectClass = személy) (objectClass = inetOrgPerson)) (| (uid = ($felhasználónév)) (cn = ($felhasználónév)) (sAMAccountname = ($felhasználónév)) ) ) "és csoportkereső szűrő" (| (objectClass = groupOfNames) (objectClass = posixGroup)) " - Anindya Mukherjee Szeptember 09 14 2014-09-09 14:37:05

  • 1 válasz
  • Válogatás:

    Tevékenység

0

Ezek a lépések többnyire más LDAP-kiszolgálókon működnek. Azonban meg kell tudnia változtatni a használt attribútumokat, mivel az ActiveDirectory például a samAccountName attribútumot használja, ahol az alapértelmezett LDAP-séma az uid-t használja.

Tekintse meg a https://github.com/heiglandreas/kimai/blob/feature/fixLDAPAuthentication/core/libraries/Kimai/Auth/Ldapadvanced.php webhelyet, amely hasznos részleteket tartalmazhat. Nem veszi figyelembe azt a problémát, ahol a csoporttagság a usernode-ban van definiálva!

0

Köszi az infót. A felhasználói keresési szűrőm az inetOrgPerson vagy "person" objektum attribútumokat és "uid" vagy "cn" vagy "sAMAccountname" attribútumokat keres, tehát működnie kell az AD-ben. Ami az AD csoportinformációkat a felhasználói bemeneti rekordban tárolja, megváltoztattam a folyamat menetét úgy, hogy először a felhasználói rekordot ellenőrizték a csoportinformációk tekintetében, és ha hamis értéket adnak vissza, akkor keressen a csoportban az ou csoportban. Az a gondom, hogy ha bármely más címtárszerver használ nem szabványos módonés egy másik attribútum és/vagy objektumosztály a csoporttal kapcsolatos információk tárolására. -

16 évvel ezelőtt

Próbálja ki ezt a szkriptet, ha nem tudja, hogyan kell felhasználót hozzáadni az AD Win2K-hoz.
Az attribútumokkal kapcsolatos további információkért nyissa meg az adsiedit konzolt a Win2K támogatási eszközeiben.

$adduserAD["cn"] =
$adduserAD["példánytípus"] =
$adduserAD["objectclass"] = "legfelső";
$adduserAD["objectclass"] = "személy";
$adduserAD["objectclass"] = "szervezeti személy";
$adduserAD["objectclass"] = "felhasználó";
$adduserAD["megjelenítési név"] =
$adduserAD["név"] =
$adduserAD["nevük"] =
$adduserAD["sn"] =
$adduserAD["vállalat"] =
$adduserAD["osztály"] =
$adduserAD["cím"] =
$adduserAD["leírás"] =
$adduserAD["mail"] =
$adduserAD["inicials"] =
$adduserAD["samaccountname"] =
$adduserAD["felhasználói alapnév"] =
$adduserAD["profilútvonal"] =
$adduserAD["manager"] = ***DistinguishedName használata***

if (!($ldap = ldap_connect("localhost"))) (
die("Nem sikerült csatlakozni az LDAP szerverhez");
}
if (!($res = @ldap_bind($ldap, " [e-mail védett]", $jelszó))) (
die("Nem sikerült kapcsolódni az LDAP fiókhoz");
}
if (!(ldap_add($ldap, "CN=Új felhasználó,OU=OU felhasználók,DC=pc,DC=com", $adduserAD)))(
echo "Hiba történt a fiók létrehozása során
echo "Kérjük a rendszergazdát!";
kijárat;
}
ldap_unbind($ldap);

12 évvel ezelőtt

Így adhat hozzá egy felhasználót kivonatolt MD5 jelszóval az OpenLDAP-hoz. Ezt a technikát használtam a Drupal-fiókok áttelepítésére az OpenLDAP-ba egy egyszeri bejelentkezési megoldáshoz.

A trükk az, hogy az OpenLDAP-nak meg kell adni a hash típusát (pl. (MD5)) a jelszó előtt, és a base64 kódolja a BINÁRIS hash eredményt. A PHP md5() vagy sha() hash függvényei által visszaadott értékeket nem lehet csak base64 kódolni, mert ezek hexadecimális karakterláncot adnak vissza. Először a pack("H*", $hash_result) parancsot kell használni, hogy bináris karakterláncot alakítsunk ki. , AKKOR tudsz base64 kódolja.

Itt található a teljes kód a kivonatolt jelszóval rendelkező felhasználó csatlakozásához és hozzáadásához. Nem kell (MD5) használnod, választhat egy másik hash-t is, ha ez van. A kivonatolt jelszavak egyikének kimenete így fog kinézni: (md5)bdwD04RS9xMDGVi1n/H36Q==

Végezetül néhány figyelmeztetés: Ez a technika nem fog működni, ha a jelszót só értékkel hashelte (de a Drupal nem). Ez a technika biztosan nem fog működni Active Directory, ahol a jelszavakat biztosan csak SSL-kapcsolaton keresztül lehet beállítani, és a hash valószínűleg másképp működik.

$ds = ldap_connect($szervercím);
ha ($ds) (
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); // különben a PHP alapértelmezés szerint az ldap v2-t használja, és szintaktikai hibát fog kapni!
$r = ldap_bind($ds, $managerDN, $managerPassword);
$ldaprecord["cn"] = $újfelhasználó_felhasználónév;
$ldaprecord["givenName"] = $újfelhasználó_utóneve;
$ldaprecord["sn"] = $újfelhasználói_vezetéknév;
// helyezze a felhasználót az objectClass inetOrgPerson-ba, hogy beállíthassuk a mail és telefonszám attribútumait
$ldaprecord["objectclass"] = "személy";
$ldaprecord["objectclass"] = "szervezeti személy";
$ldaprecord["objectclass"] = "inetOrgPerson";
$ldaprecord["mail"] = $újfelhasználói_e-mail_cím;
$ldaprecord["telefonszám"] = $újfelhasználói_telefonszám;
// és most a trükkös rész, a base64 kódolja a bináris hash eredményt:
$ldaprecord["userPassword"] = "(MD5)" . base64_encode(pack("H*",$újfelhasználó_md5kivonatos_jelszó));
// Ha helyette az egyszerű szöveges jelszót használja, használhatja a következőket:
// $ldaprecord["userPassword"] = "(MD5)" . base64_encode(pack("H*",md5($newuser_plaintext_password)));
$r = ldap_add($ds, $base_user_dn, $ldaprecord);
) else ( die "nem tud csatlakozni az LDAP szerverhez a $serverAddress címen."; )

11 évvel ezelőtt

Létrehoztam egy egyszerű függvényt, amely meghívható globális terjesztési csoportok létrehozására az Active Directoryban:

függvény ldap_createGroup ($object_name , $dn , $members , $ldap_conn )
{
$addgroup_ad [ "cn" ]= " $objektum_neve " ;
$addgroup_ad [ "objectClass" ][ 0 ] = "top" ;
$addgroup_ad [ "objectClass" ][ 1 ] = "csoport" ;
$addgroup_ad [ "groupType" ]= "2" ;
$addgroup_ad [ "tag" ]= $tagok ;
$addgroup_ad [ "sAMAccountName" ] = $objektum_neve ;

ldap_add ($ldap_conn , $dn , $addgroup_ad );

If(ldap_error ($ldap_conn ) == "Siker")
return true ;
más
return false ;
}
?>

Ezt a függvényt a következő kóddal hívhatja meg:

$ldap_conn = ldap_bind();
$object_name = "Tesztcsoport" ;
$dn = "CN=" . $objektum_neve . ",OU=PathToAddGroupTo,OU=Minden felhasználó,DC=YOURDOMAIN,DC=COM";
$tagok = "CN=User1,OU=PathToAddGroupTo,OU=Minden felhasználó,DC=YOURDOMAIN,DC=COM";
$tagok = "CN=User2,OU=PathToAddGroupTo,OU=Minden felhasználó,DC=YOURDOMAIN,DC=COM";

Ldap_createGroup ($object_name , $dn , $members , $ldap_conn );
?>

A másik általam létrehozott függvény az ldap_bind(), és ezzel lehet LDAP szerverhez kötni:

függvény ldap_bind()
{
$ldap_addr = "192.168.1.1" ; // Módosítsa ezt az LDAP szerver IP-címére
$ldap_conn = ldap_connect ($ldap_addr ) or die("Nem sikerült csatlakozni!" );
ldap_set_option ($ldap_conn , LDAP_OPT_PROTOCOL_VERSION , 3 );
$ldap_rdn = "tartománynév\\felhasználói_fiók" ;
$ldap_pass = "felhasználói_jelszó" ;

// A felhasználó hitelesítése a tartományvezérlővel szemben
$flag_ldap = ldap_bind($ldap_conn , $ldap_rdn , $ldap_pass );
return $ldap_conn ;
}
?>

13 évvel ezelőtt

Amikor attribútumokat ad hozzá/szerkeszt egy felhasználóhoz, ne feledje, hogy a "memberof" attribútum egy speciális eset. A memberOf attribútum a felhasználói séma nem elérhető attribútuma. Ha valakit szeretne hozzáadni egy csoporthoz, akkor a felhasználót kell hozzáadnia a csoporthoz, nem pedig a csoportot a felhasználóhoz. Ezt a "member" csoportattribútum elérésével teheti meg:

$csoport_neve = "CN=MyGroup,OU=Csoportok,DC=példa,DC=com";
$group_info [ "tag" ] = $dn ; // A felhasználó megkülönböztető neve hozzáadásra kerül a csoport "tag" tömbjéhez
ldap_mod_add ($csatlakozás , $csoportnév , $csoport_információ );

?>

11 évvel ezelőtt

Ez a megoldás nálunk működik.
A formában a CN és a pwdtxt véletlenszerűen jön létre szigorú szabályok alapján.
Ez a szkript 50-60 felhasználót hoz létre AD pr.day! és soha nem is volt hibája!

## Az űrlapból
$CN = $_POST["CN"];
$givenName = $_POST["givenName"];
$SN = $_POST[ "SN" ];
$mail = $_POST["mail"];
$Phone = $_POST["Telefon"];
$pwdtxt = $_POST [ "pwdtxt" ];

$AD_server = "localhost:390" ; // Local Stunnel --> http://www.stunnel.org/
$AD_Auth_User = "[e-mail védett]" ; //Adminisztratív felhasználó
$AD_Auth_PWD = "duppiduppdupp" ; //A jelszó

$dn = "CN=" . $CN . ",OU=Brukere,DC=diák,DC=valahol,DC=com";

## Hozzon létre Unicode jelszót
$newPassword = "\"" .$pwdtxt ."\"" ;
$len = strlen($newPassword);
$newPassw = "" ;

for($i = 0 ; $i< $len ; $i ++) {
$newPassw .= " ( $newPassword ( $i )) \000" ;
}

## KAPCSOLAT A HIRDETÉSHEZ
$ds = ldap_connect($AD_szerver);
if ($ds ) (
ldap_set_option($ds , LDAP_OPT_PROTOCOL_VERSION , 3 ); // FONTOS
$r = ldap_bind($ds , $AD_Auth_User , $AD_Auth_PWD ); //BIND

$ldaprecord [ "cn" ] = $CN ;
$ldaprecord [ "givenName" ] = $givenName ;
$ldaprecord [ "sn" ] = $SN ;
$ldaprecord [ "objectclass" ][ 0 ] = "top" ;
$ldaprecord [ "objectclass" ][ 1 ] = "személy" ;
$ldaprecord [ "objectclass" ][ 1 ] = "szervezeti személy" ;
$ldaprecord [ "objectclass" ][ 2 ] = "felhasználó" ;
$ldaprecord [ "mail" ] = $mail ;
$ldaprecord [ "telephoneNumber" ] = $Telefon ;
$ldaprecord [ "unicodepwd" ] = $newPassw ;
$ldaprecord [ "sAMAccountName" ] = $CN ;
$ldaprecord [ "UserAccountControl" ] = "512" ;
//Ez a felhasználó letiltásának megakadályozása. -->
http : //support.microsoft.com/default.aspx?scid=kb;en-us;305144

$r = ldap_add ($ds , $dn , $ldaprecord );

) más (
visszhang "nem tud csatlakozni az LDAP szerverhez a következő címen:$AD_szerver.";
}

?>

Ez a kódpélda létrehoz egy felhasználót i AD.
Ezt egy belső weboldalon használjuk a létrehozáshoz
ideiglenes felhasználók, akik hozzáférhetnek a vezeték nélküli hálózathoz.
Van egy .pl szkriptünk, amely 24 óra elteltével törli a felhasználókat.

11 évvel ezelőtt

Miután "problémáim vannak az attribútumok hozzáadásával logikai szintaxissal (1.3.6.1.4.1.1466.115.121.1.7)

$["boolean_attr"]=igaz; //adj egy figyelmeztetést, ldap_add(): Hozzáadás: Érvénytelen szintaxis

ezt úgy oldotta meg, hogy erre beállította az értéket:

$["boolean_attr"]="IGAZ";

remélem ez segíthet.

16 évvel ezelőtt

Válaszul jharnett kérdésére, amely az ldap_add-ből alapértelmezés szerint letiltott fiókokról szólt, találtunk egy megoldást.

A userAccountControl attribútum egy értéket tartalmaz, amely tartalmazza, hogy a fiók le van-e tiltva vagy engedélyezett. Az alapértelmezett számunkra 546; amikor ezt 544-re változtattuk, a fiók engedélyezve lett. Úgy tűnik, hogy a userAccountControl bármely értékének 2-vel történő módosítása engedélyezi vagy letiltja a fiókot.

A következő kóddal sikerült létrehoznunk egy új felhasználót egy engedélyezett fiókkal:

$adduserAD["userAccountControl"] = "544";

Ezt az elemet most hozzáadtuk a fenti példa tömbjéhez.

7 hónappal ezelőtt

Csoport létrehozása az Active Directoryban

$ds = ldap_connect("IP-szerver/localhost" );
$alap_dn = "CN=Csoportnév,OU=Szervezeti egység,DC=Domain-név,DC=com"; //megkülönböztetettA csoport neve

Ha ($ds ) (
// bind a megfelelő dn-nel, hogy frissítési hozzáférést biztosítson
ldap_bind($ds , , "some-password" );

//Tagok hozzáadása a csoporthoz
$tag_tömb = array();
$member_array [ 0 ] = "CN=Rendszergazda,OU=Szervezeti egység,DC=Domain-név,DC=com";
$member_array [ 1 ] = "CN=Felhasználó,OU=Szervezeti egység,DC=Domain-név,DC=com";

$entry[ "cn" ] = "Csoportteszt" ;
$entry [ "samaccountname" ] = "Csoportteszt" ;
$entry [ "objectClass" ] = "Csoport" ;
$entry [ "description" ] = "Csoport teszt!!" ;
$entry [ "tag" ] = $tag_tömb ;
$entry [ "groupType" ] = "2" ; //GroupType="2" a terjesztés / GroupType="1" a biztonság

ldap_add ($ds , $base_dn , $bejegyzés );

ldap_close($ds);
) más (
visszhang "Nem lehet csatlakozni az LDAP szerverhez";
}
?>

14 évvel ezelőtt

Egy másik szórakoztató dolog: az ldap_add() nem szereti az üres tagú tömböket: így
sor(
= "név"
= ""
= "érték"
szintaktikai hibát fog eredményezni!

oldja meg ezt egy egyszerű kódrészlettel:

foreach ($originalobject mint $kulcs => $érték)(
if ($érték != "")(
$objektum[$kulcs] = $érték;
}
}

ahol az $originalobject a nem bejelölt tömb, az $object pedig az üres tagok nélküli tömb.

19 évvel ezelőtt

Az Ldap_add() csak akkor veszi figyelembe az $entry["attribútum"][x]="érték" *ha több értéke is van az attribútumnak*. Ha csak egy attribútumérték van, akkor azt *KELL* beírni $entry["attribute"]="érték"-ként, vagy az ldap_add() az attribútum értékét "Tömb"-re állítja be az $entry[be tett érték helyett. "tulajdonság"].

Itt van egy kis rutin, amit felírtam, hogy ezt automatikusan megtegyem. a bemenet elemzésekor csak használja a multi_add():
függvény multi_add ($attribútum , $érték )
{
globális $bejegyzés ; // a hozzáadni kívánt LDAP bejegyzés

If(isset($bejegyzés [ $attribútum ]))
if(is_tömb ($bejegyzés [ $attribútum ]))
$bejegyzés [ $attribútum ][ count ($bejegyzés [ $attribútum ])] = $érték ;
más
{
$tmp = $bejegyzés [ $attribútum ];
unset($bejegyzés [ $attribútum ]);
$bejegyzés [ $attribútum ][ 0 ] = $tmp ;
$bejegyzés [ $attribútum ][ 1 ] = $érték ;
}
más
$bejegyzés [ $attribútum ] = $érték ;
}
?>
A multi_add() ellenőrzi, hogy van-e már érték az attribútumhoz. ha nem, akkor $entry[$attribute]=$értékként adja hozzá. Ha az attribútumnak már van értéke, akkor az attribútumot tömbbé alakítja, és helyesen adja hozzá a több értéket.

Hogyan kell használni:
switch($form_data_name )
{
case "phone" : multi_add ("telephoneNumber" , $form_data_value ); szünet;
case "fax" : multi_add ("faximileTelephoneNumber" , $form_data_value ); szünet;
case "email" : multi_add ("mail" , $form_data_value ); szünet;
...
}
?>
Az általam tervezett rendszerben az űrlapnak vannak ctype1, ctype2, ctype3 stb. nevű legördülő menüi. és az értékek "fax, mail, telefon...". A tényleges kapcsolati adatok (telefonszám, fax, e-mail stb.) a contact1, contact2, contact3 stb. A felhasználó lehúzza a kapcsolat típusát (telefon, e-mail), majd megadja az adatokat (szám, cím stb.)

Változóváltozókat használok a bejegyzés kitöltéséhez és az üres helyek kihagyásához. Nagyon tiszta űrlapbeviteli rendszert biztosít. írj e-mailt, ha érdekel, mert azt hiszem, túlnőttem az itt megengedett jegyzetméreten. :-)

6 évvel ezelőtt

Folyamatosan az "Object Class Violation" üzenetet kaptam, amikor megpróbáltam hozzáadni a posixAccount-ot és a shadowAccount-ot objektumosztályként. Kiderült, hogy ezekben az objektumosztályokban sok kötelező mező volt, amelyeket nem adtam hozzá. Előfordulhat, hogy exportálnia kell egy működő felhasználót (ha van phpLDAPadmin), és meg kell néznie, hogy pontosan milyen mezői vannak, majd próbálja meg pontosan bemásolni a szkriptbe. Az sem árt, ha először mindent tömbbé tesz, később javíthatja ezeket a mezőket.

A Drupal könnyen nevezhető univerzális eszköznek különféle feladatok végrehajtására, valamint a vállalati megoldások bizonyos összetettségére.
Történt ugyanis, hogy elsősorban Drupalt használok a cégnél, belül intranet hálózat, amely rendelkezik Active Directory. És annak érdekében, hogy teljesen
használja a hálózatunk infrastruktúráját, legalábbis a program Active Directory jogosultság az oldalakon és szolgáltatásokon, és itt a Drupal problémái vannak
nem, köszönhetően a Lightweight Directory Access Protocol (LDAP) modulnak.
Ebben a cikkben szeretném elmondani, hogyan van beállítva a környezetemben, és talán a cikk hasznos lesz valakinek.

Tehát, csak előre tekintve, azt mondom, hogy ennek a modulnak a segítségével a következőket nyújthatja:
1. LDAP hitelesítés a hálózaton (esetemben én használom Active Directory a Microsofttól)
2. Állítsa be az átjelentkezési jogosultságot (amikor a felhasználó automatikusan bejelentkezik az operációs rendszer fiókjával)
3. Korlátozza a hozzáférést azokra, akik beléphetnek az oldalra, és akik nem.
4. A fiókattribútumok szinkronizálása Active Directory felhasználói profil mezőkkel az oldalon, és fordítva.
5. A fiók frissítése az oldalon a bejelentkezési adatok megváltoztatása után Active Directory(általában a munkavállaló nevének megváltoztatása után fordul elő - a bejelentkezés ugyanúgy változik)
6. Szerepkör hozzárendelése egy felhasználóhoz a webhelyen, attól függően, hogy egy adott csoportban hol helyezkedik el Active Directory

Mert Továbbra is aktív felhasználó vagyok a Drupal 7-nek, majd az ő példája alapján adok minden instrukciót, de ismét, amikor az érdeklődés kedvéért elindítottam a Drupal 8-at,
aztán rájöttem, hogy a modul szinte teljesen megegyezik a Drupal 7. verziójával.

Másolja át nekünk a modul adatait, valamint azok függőségeit CtoolsÉs Entity API. A modulok oldalon aktiválja a következő modulokat:

  1. LDAP hitelesítés
  2. LDAP-engedélyezés (opcionális modul, ha korlátozni kell a webhelyhez való hozzáférést, vagy a webhely szerepköreit az alapján, hogy a felhasználó az Active Directory-csoportokban van)
  3. LDAP engedélyezés – Drupal szerepkörök (kiegészítés a fent leírt modulhoz)
  4. LDAP szerverek
  5. LDAP SSO (opcionális modul, ha nincs szüksége átjelentkezési jogosultságra, vagy ha a webszerver nincs erre konfigurálva, akkor nem telepítheti)
  6. LDAP felhasználói modul

Érdemes megjegyezni, hogy a modul nem lesz telepítve, ha a modul nincs telepítve a PHP beállításaiban. php_ldap. Ezért telepítse előre, és alkalmazkodjon környezete jellemzőihez.

A modul sikeres telepítése után lépjen a beállításaihoz, amelyek itt találhatók admin/config/people/ldap

A modul beállításai 4 lapra vannak osztva: Beállítások, Szerverek, felhasználó, Hitelesítés, Engedélyezés

Az első lapon a fiók jelszavas titkosítási módszere van konfigurálva. Active Directory a Drupalon belül.

A gyakorlatomban ezt nem használom, ezért azonnal a második fülre megyek Szerverek. És itt megállunk részletesebben.
A lapon megjelenik az oldalon használt összes létrehozott LDAP hitelesítési szerver, alapértelmezés szerint ez a lista üres és mi a gombot használjuk Adja hozzá az LDAP-kiszolgáló konfigurációját létrehozhat egy új szervert.
A szerver létrehozásának oldala több blokkra van felosztva, nézzük meg mindegyiket:

csatlakozási beállítások

Gépnév ehhez a szerverkonfigurációhoz. - a létrehozott szerver tényleges gépneve. szoktam hívni Active Directory
Név ** - a szerver más neve, én is hívom Active Directory
**Engedélyezve
- Pipát teszek, így beírom a létrehozott szerver konfigurációt
LDAP szerver típusa- az én esetemben választok Active Directory
LDAP szerver- tartománynév vagy IP-cím, ahol az Active Directory szerver található, esetemben ad.zv
LDAP port- alapértelmezés szerint hagyja el 389 , nálunk ugyanígy van
Használja a Start-TLS-t- Nem jelölöm be a négyzetet, mert ne használjon titkosítást
Kövesse az LDAP-hivatkozásokat- Én sem állítom be, bár nem teljesen értettem, mire való ez a beállítás

Kötési mód

Kötési módszer keresésekhez (például felhasználói objektumok vagy csoporttagságuk keresése)
Vagyis a kérdés az, hogy kinek a megbízásából hogyan történik a kapcsolat az Active Directory szerverrel, hogy egy felhasználót keressen a létezés tényére, olvassa be az attribútumait stb.
Csakúgy, mint az érték leírásában, az első lehetőséget használom Service Account Bind legjobb gyakorlatként.
Ugyanis a kapcsolat a szerverrel egy speciális, előre létrehozott fiókból jön létre az Active Directoryban, amely jogosult a címtárak és az Active Directory struktúra olvasására.
Az alábbi opció kiválasztásával a mezőkben meg kell adnia a szolgáltatási fiók bejelentkezési nevét és jelszavát DN a nem névtelen kereséshezÉs Jelszó a nem névtelen kereséshez

Törölje a meglévő jelszót az adatbázisból. Ellenőrizze ezt, amikor leállítja a szolgáltatásfiók-kötést- a tétel nem alkalmazható a fent leírt módszerünkre, ezért nem jelöljük be a négyzetet.

LDAP felhasználó és Drupal felhasználói kapcsolat

Alap DN-ek LDAP-felhasználók, csoportok és egyéb bejegyzések számára- alap DN, ahol az összes felhasználó az Active Directoryban található, esetemben én állítom be DC=ad,DC=zv. Ebben a beállításban jobb, ha konzultál az Active Directory-kiszolgáló rendszergazdáival
AuthName attribútumÉs AccountName attribútum- attribútum, amelyben a felhasználónév és a fióknév tárolva van, általában azonosnak kell lenniük, és a legtöbb esetben fel van tüntetve samaccountname, mert alapértelmezés szerint a bejelentkezés ott található az Active Directoryban
email attribútum- attribútum, amelyben a felhasználó postafiókja található, esetemben levél. Érdemes megjegyezni, hogy a Drupal esetében ez a mező kötelező, mert. A Drupalnak nem lehet postafiók nélküli felhasználója, így ha a környezetedben van lehetőség arra, hogy vannak postafiók nélküli felhasználók, akkor az alábbi mezőben kell kitölteni a postafiókot a sablon szerint, vagy később egy másik lapon visszatér ehhez a beállításhoz a másik oldalról.
email sablon- postafióksablon, amelyet akkor használunk, ha például a postafiókok megegyeznek a bejelentkezési adatokkal, vagy több felhasználói attribútumból állnak az Active Directoryban. Ezért egyszerűen összeállíthatja attribútumjelzőkből.
Bélyegkép attribútum- egy attribútum, amelyben a felhasználó képe található (binárisan) a felhasználói profil képeibe való későbbi betöltéshez a Drupalban, esetemben miniatűrPhoto
Állandó és egyedi felhasználói azonosító attribútum- Egy egyedi attribútum, amely soha nem változik az Active Directory-felhasználók számára. Olyan esetekben használatos, amikor például az Ön bejelentkezési neve a felhasználó vezetékneve és kezdőbetűi, és ha a felhasználó hirtelen megváltoztatta a vezetéknevét, majd a bejelentkezési neve megváltozott, akkor a következő alkalommal, amikor belép a Drupal oldalára, alapértelmezés szerint új felhasználóként, és a Drupal új fiókot hoz létre (persze, ha a postafiók is megváltozott, mert ha változatlan marad, akkor a Drupal postafiókütközést fog jelenteni, és nem hoz létre új bejegyzést). Éppen ezért ez a mező egyedi kulcsként szolgál, amelyet mindenekelőtt akkor kell megnézni, amikor a felhasználó belép az oldalra, még akkor is, ha megváltoztatta a bejelentkezési adatait, a Drupal először ezen attribútum alapján találja meg, majd kapcsolatot épít ki Az Active Directory felhasználója, és ennek eredményeként frissíti bejelentkezési adatait a Drupal webhelyen. Az én esetemben az objectsid
Az állandó és egyedi felhasználói azonosító attribútum rendelkezik bináris értékkel? - Azért tettem egy pipát, mert objectsid binárisan tárolva.

AD-vel dolgozni PHP-ben

Adatok olvasása. 1. rész: Csatlakozás AD-hez, adatok lekérdezése és feldolgozása

Tartalom sorozat:

Alapvető AD-műveletek elvégzéséhez, mint például felhasználó hozzáadása vagy eltávolítása, adat- vagy csoporttagság módosítása, és különösen tömeges műveleteknél (például az összes felhasználó listájának osztályonkénti létrehozása) egyáltalán nem szükséges a Visual Basic ill. PowerShell - ehhez elegendő a PHP ismerete (valamint a szükséges jogokkal rendelkező felhasználó jelenléte).

Gyakran használt rövidítések:

  • AD - Active Directory (címtárszolgáltatás);
  • LDAP - könnyű címtár-hozzáférési protokoll;
  • DN - megkülönböztetett név (megkülönböztetett név).

A júniusban (, , ) megjelent sorozat első részei arról szóltak, hogyan lehet kiolvasni az AD szerver adatait, normál LDAP szerverként elérni azt a szabványos ldapsearch program és a Bourne Shell nyelven írt script segítségével. Azt kell mondanom, hogy a Bourne Shell nem nagyon alkalmas az ilyen munkákra: még egy meglehetősen egyszerű művelethez is, amikor két oszlopból szövegfájlt készítünk, nagyon nem triviális mozdulatokat kell végezni. Tehát teljesen természetes, hogy megpróbálja átírni egy magas szintű nyelven, mint például a PHP.

Konfigurációs fájl

A szkript majdnem ugyanazt a konfigurációs fájlt használja. Tartalma az 1. listán látható.

Lista 1. phpldapread.php script konfigurációs fájl
#LDAP szerver a kapcsolathoz ldap_server=10.54.200.1 #Alap DN a kapcsolathoz ldap_basedn="dc=shelton,dc=int" #Bind DN a kapcsolathoz [e-mail védett]#Annak a felhasználónak a jelszava, akinek nevében a kapcsolat létrejön ldap_password="cXdlcnR5YXNkZgo 1" #Rekordválasztó szűrő. Ez azt jelenti: válassza ki azokat a User típusú objektumokat, amelyek # nem rendelkeznek a "Fiók zárolása" tulajdonsággal: ldap_common_filter="(&(!(userAccountControl:1.2.840.113556.1.4.803:=2)) (sAMAccountType=805306368))" #A listázott felhasználók figyelmen kívül hagyása rendszerobjektumok ignore_list="SQLAgentCmdExec,SMSService,SMSServer_001, wsus" #A fájl mentési könyvtára etcdir=/tmp #Fájlnév listával sarglist=sargusers

Függőségek, segítő funkciók

A szkripthez szükség van a további pear-Config és pear-Console_Getopt összetevőkre, valamint a php-ldap nyelvi kiterjesztésre. A Pear-Config szükséges a konfigurációs fájl olvasásához, a pear-Console_Getopt a parancssori paraméterek elemzéséhez. El kell mondanunk, hogy nem a teljes szkriptet fedik le: az olyan kérdések, mint a konfigurációs fájl olvasása, a súgó megjelenítése vagy a parancssor elemzése, már elég jól leírtak, így a vonatkozó funkciók kimaradnak, a szkript teljes verziója letölthető. letöltve innen: . Csak azokat vesszük figyelembe, amelyek közvetlenül kapcsolódnak az AD-ből, mint LDAP-kiszolgálóból származó adatok olvasásához, és néhány nem szabványos kiegészítő funkciót.

A fordított jelszókonverziós funkció a 2. listában látható. Az úgynevezett "védelem" teljes szerepe a véletlen szivárgás megakadályozása (az úgynevezett pipetta), semmi több.

Lista 2. Fordított jelszó konvertáló funkció.
/* * Fordított jelszókonverzió * @param string $konvertált konvertált jelszó * @return string $passwd jelszó szöveges formában */ function demux_passwd($converted) ( $_conved = explode(" ", $converted); $_passwd = "" ; if ($_conved != 0) for (;$_conved != 0; $_conved--) ( $_conved = $_conved . "="; ) $_passwd = base64_decode($_conved); return rtrim($_passwd) ;)

Itt persze nincs semmi különösebb érdekesség: ahogy az előző részekben már szó volt róla, a jelszót a base64-re konvertált konfigurációs fájl tárolja, a helyőrzőket eldobjuk, helyette egy szám kerül. Ez a függvény az inverz transzformációt hajtja végre.

Az UTF-8-ról KOI8-R-re konvertáló függvény a 3. listában látható. Erre a funkcióra azért van szükség, mert a FreeBSD konzol nem használ UTF-8-at.

3. lista. Funkció a karakterlánc UTF-8-ról KOI8-R-re konvertálására
/* * Karakterlánc konvertálása UTF-8-ról KOI8-R-re * @param string $source UTF-8 kódolt karakterlánc * @return string $dest KOI8-R kódolt karakterlánc */ függvény _from_utf8($source) ( $converted = iconv (" UTF-8", "KOI8-R", $forrás); return($konvertált); )

Ezen kívül egy teljesen érdektelen safe_logger függvényt használnak, aminek az a feladata, hogy üzeneteket küldjön ki a naplóba vagy a konzolba a script befejezésével vagy anélkül. Mindezek a funkciók az utils.php fájlban vannak tárolva.

Csatlakozás az AD-hez

Az AD-hez való csatlakozáshoz használja a 4. listában látható ldap_server_connect függvényt. A függvény végrehajtja az összes kapcsolódási műveletet, és visszaadja a kapcsolatazonosítót a szerverrel való együttműködéshez. A függvény egy külön ldapquery.php fájlba kerül mentésre

Felsorolás 4. AD szerver kapcsolati funkció
igényel_egyszer $PATH_LIB."/utils.php"; /* * Csatlakozás LDAP szerverhez * @param tömb $_config konfigurációs paraméterek tömbje * @return erőforrás $ldapconn LDAP szerver kapcsolat azonosítója */ függvény ldap_server_connect($_config) ( // Jelszó lekérése egyszerű szövegben $_ldap_pwd = demux_passwd($ _config["root"]["ldap_password"]); // Csatlakozás a szerverhez if (!$ldapconn = ldap_connect($_config["root"]["ldap_szerver"])) safe_logger(sprintf("Nem lehet csatlakozni az LDAP-hoz -server %s", $_config["root"]["ldap_server"]), "DIE"); // AD Windows 2003 és újabb verziókhoz való csatlakozáshoz be kell állítani ezeket a beállításokat ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3 ); ldap_set_option ($ldapconn, LDAP_OPT_REFERRALS, 0); // Bejelentkezés a szerverre ldap_bind($ldapconn, $_config["root"]["ldap_binddn"], $_ldap_pwd); return $ldapconn;

Mire szeretne itt figyelni.

Először is, az LDAP_OPT_PROTOCOL_VERSION ("protokollverzió") és az LDAP_OPT_REFERRALS ("hivatkozási hivatkozások letiltása") opciókat 3-ra, illetve 0-ra kell állítani - ezek nélkül valami furcsa lehet: a szerveren a hitelesítés átmegy, de minden keresés pontosan nulla rekordot ad vissza.

Másodszor, a Bind DN-t pontosan úgy kell beállítani, mint a konfigurációs fájlban, és semmilyen más módon nem. A teljes elutasítás feltüntetése helytelen lesz.

Adatkérés AD-től

Egy külön ldap_data_query függvényt fejlesztettek ki az AD-ből származó adatok lekérdezésére. Ez főleg azért történik, mert a nem ASCII karaktereket tartalmazó adatok (és ezek többsége normál AD-ben) UTF-8 kódolásban vannak tárolva. Mivel a FreeBSD konzol korlátozottan támogatja az UTF-8-at, néhány konverziót el kellett végezni.

Az AD-ből származó adatok kiválasztását az ldap_search függvény végzi, amely egyéb paraméterek mellett egy egydimenziós tömböt fogad el a beszerezendő attribútumokkal. De annak jelzésére, hogy ennek az attribútumnak az értékét újra kell-e kódolni, a függvény egy kétdimenziós tömböt kap, amelyben minden elem maga egy tömb, amely indexnévvel és újrakódolással rendelkező elemekből áll.

A függvény által bemenetként kapott attribútumtömb típusát az 5. lista mutatja (részben).

5. lista. Az adatkérő függvénynek átadott paraméterek tömbje.
array(2) ( => array(2) ( ["név"]=> string(2) "cn" ["recode"]=> string(4) "igaz" ) ... )

Maga az adatlekérdezési funkció a 6. listában látható.

Lista 6. Funkció adatok lekérdezésére az AD-ből.
igényel_egyszer $PATH_LIB."/utils.php"; igényel_egyszer $PATH_LIB."/ldapconnect.php"; /* * Adatkérés az LDAP szervertől * @param tömb $_config Tömb konfigurációs adatokkal * @param erőforrás $ldapconn LDAP szerver kapcsolat azonosító * @param tömb $attribute Az LDAP-tól kérhető attribútumok tömbje * @return tömb $ldapdata Adatok innen a szerver LDAP */ függvénye ldap_data_query($_config, $ldapconn, $attribute) ( $oneadd = array(); $myrecode = array(); $myattrs = array(); // Az adatok lekérdezéséhez egy one- dimenziós tömb foreach ($attribútum mint $oneattr) $myattrs = $oneattr["név"]; // Adatok lekérdezése a konfigurációs fájl általános kiválasztási szűrőjével $result = ldap_search($ldapconn, $_config["root"][ "ldap_basedn"], $_config ["root"]["ldap_common_filter"], $myattrs); // Az összes kiválasztott rekord olvasása $info = ldap_get_entries($ldapconn, $result); // Számukat kinyomtatja a naplóba safe_logger( sprintf("%d rekord olvasása a %s szerverről", $info["count"], $_config["root"]["ldap_server"]), ""); // Kétdimenziós tömb létrehozása kimeneti adatokkal // A tömb minden eleme egy tömb, melynek elemei kulcs - attribútum neve, // és adatok - attribútum értéke; szükség esetén újrakódolva ($i = 0; $i< $info["count"]; $i++) { for ($j = 0, $k = count($attribute); $j < $k; $j++) { $myattr = $attribute[$j]["name"]; if (isset($info[$i][$myattr])) { if ($attribute[$j]["recode"] == "true") $myrecode[$myattr] = _from_utf8($info[$i][$myattr]); else $myrecode[$myattr] = $info[$i][$myattr]; } else $myrecode[$myattr] = ""; $oneadd[$i] = $myrecode; } } return $oneadd; }

A paraméterek kétdimenziós tömbjéből az ldap_search függvényhez egy egydimenziós tömböt képezünk, majd lekérjük az adatokat. Az adatok tömbként kerülnek visszaadásra minden elemmel a 7. listában látható módon.

Lista 7. Az ldap_get_entries függvény által visszaadott adattömb egyik eleme.
=> array(6) ( ["cn"]=> array(2) ( ["count"]=> int(1) => string(13) "Rendszergazda" ) => string(2) "cn" [ "samaccountname"]=> array(2) ( ["count"]=> int(1) => string(13) "Rendszergazda" ) => string(14) "samaccountname" ["count"]=> int( 2) ["dn"]=> string(43) "CN=Rendszergazda,CN=Felhasználók,DC=shelton,DC=net" )

Mint látható, ez nem is egy kétdimenziós, hanem egy háromdimenziós tömb. Az első szinten - a kért adatok, a másodikon - egy objektum attribútumai, a harmadikon - egy többsoros attribútum karakterláncai, amelyek minden esetben karakterlánc-attribútumok. Ezenkívül az első szint minden elemében van egy második szintű dn elem, amely tartalmazza ennek az objektumnak a teljes DN-jét - ez nagyon hasznos lesz számunkra a jövőben. A kimeneti tömb sokkal egyszerűbb, egyetlen elemmel a 8. listában látható. Itt egy nem ASCII adatokkal rendelkező objektumot szándékosan használnak annak bemutatására, hogy az adatok újrakódolásra kerültek.

Lista 8. A kimeneti tömb eleme.
=> array(2) ( ["cn"]=> string(11) "Prostouser" ["samaccountname"]=> string(10) "prostouser" )

Miért veszik figyelembe ennek a függvénynek a bemeneti és kimeneti adatait ilyen részletesen? Mert valójában a fő szkript összes munkája (amelyről a cikk következő részében lesz szó) a hívás előkészítésére és az általa alkotott tömb későbbi feldolgozására korlátozódik.

Következtetés

Amint ebből a cikkből látható, a PHP nagymértékben leegyszerűsíti az LDAP szerverrel végzett munkát, lehetővé téve, hogy felhagyjon az adatok ideiglenes fájlokban való tárolásával kapcsolatos dühös konstrukciókkal, és lecserélje azokat a tömbök sokkal kényelmesebb megjelenítésére a memóriában, lehetővé téve, hogy " menet közben" újrakódolni egy másik kódlapra, és nagyban megkönnyíti a szkriptek hibakeresését.

Ebben a szakaszban megtudhatja, hogyan kereshet és kérhet le adatokat a címtárkiszolgálóról, valamint hogyan adhat hozzá, módosíthat és törölhet bejegyzéseket.

ldap_search()

erőforrás ldap_search (erőforrás link_azonosítója, string base_dn, string filter [, tömb attribútumok [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]])
Az ldap_search() függvény hatékony eszközt kínál a link_identifier által mutatott címtárszerver keresésére. Az LDAP_SCOPE_SUBTREE mélységig fog keresni, ez az érték a korábban bevezetett ldap_set_option() függvénnyel állítható be. Alapértelmezés szerint ez az érték úgy van beállítva, hogy végtelen mélységig keressen, vagy a fa teljes hatókörén keresztül, ahogy azt a base_dn meghatározza. A relációs adatbázis-lekérdezéssel egyenértékű keresési szűrő a szűrőparaméteren keresztül kerül átadásra. Végül az attribútumok paraméteren keresztül pontosan megadhatja, hogy mely attribútumok jelenjenek meg a keresési eredmények között. A fennmaradó négy paraméter nem kötelező, ezért a hely érdekében "gyakorlatként hagyom, hogy többet megtudjon róluk. Nézzünk egy példát:

"; ) ldap_unbind($ad); ?> Az eredményekből egy minta: Gilmore, Jason (Columbus) Shoberg, Jon (Columbus) Streicher, Martin (San Francisco) Wade, Matt (Orlando)

Ennek nagy része valószínűleg egyszerű, kivéve az attribútumértékekre való esetlegesen furcsa hivatkozási módot. Az összes attribútumsor végső soron többdimenziós tömb, ahol minden attribútumértékre sorszám, attribútumnév és attribútumtömb-index kombinációja hivatkozik. Így például még az olyan attribútumok is, mint az „sn”, a felhasználó vezetéknevének attribútumneve, egy indexelt tömb.

ldap_mod_add()

logikai ldap_mod_add(erőforrás link_id, karakterlánc dn, tömbbejegyzés)
A bejegyzések hozzáadása a címtárkiszolgálóhoz az ldap_mod_add() függvényen keresztül történik. Egy új bejegyzés egyszerűen hozzáadható az új sort tartalmazó attribútum/érték-leképezésekből álló tömb létrehozásával. Ezt a folyamatot talán egy példával lehet a legjobban megmagyarázni:

mint minden címtárszerver-feladat esetében, győződjön meg arról, hogy az összerendelés felhasználó megfelelő jogosultságokkal rendelkezik a céladatok hozzáadásához; ellenkező esetben hibák lépnek fel.

ldap_mod_replace()

logikai ldap_mod_replace(erőforrás link_id, karakterlánc dn, tömbbejegyzés)
A bejegyzés attribútumainak módosítása az ldap_mod_replace() függvényen keresztül történik. Pontosan úgy működik, mint az ldap_add(, kivéve a módosítani kívánt bejegyzés azonosításának hozzáadott lépését. Ez egy nagyon specifikus dn-re való rámutatással történik. Az ldap_add()-hez hasonlóan érvényes linkazonosító és egy tömb, amely a következőkből áll. meg kell adni a frissíteni kívánt bejegyzéseket. A következő példa bemutatja, hogy a felhasználó telefonszáma hogyan módosulna, különös tekintettel a nagyon konkrét DN-re (amely az adott bejegyzésemre mutat).

mint minden címtárszerver-feladatnál, győződjön meg arról, hogy az összerendelés felhasználó megfelelő jogosultságokkal rendelkezik a céladatok módosításához; ellenkező esetben váratlan hibák lépnek fel.

ldap_delete()

logikai ldap_delete(erőforrás link_id, string dn)
A legfontosabb PHP LDAP-függvények felmérését az ldap_delete() egészíti ki. Ez a funkció egy meglévő bejegyzés törlésére szolgál. Az ldap_mod_replace(-hez hasonlóan) egy nagyon specifikus DN-t kell megadni a törlés végrehajtásához. A következő példa bemutatja, hogyan távolítható el a "Jason Gilmore" felhasználói bejegyzés az Active Directoryból:

mint minden címtárszerver-feladatnál, győződjön meg arról, hogy az összerendelés felhasználó megfelelő jogosultságokkal rendelkezik a céladatok törléséhez; ellenkező esetben váratlan hibák lépnek fel.

Keresés az Active Directoryban a weben keresztül

Mindig szeretek egy oktatóanyagot egy alkalmazható példával kiegészíteni, amelyet az olvasók azonnal saját igényeikhez tudnak igazítani. Ebben az oktatóanyagban megmutatom, hogyan hozhat létre olyan keresőfelületet, amely képes keresni név, hely vagy telefonszám alapján. Mindössze annyit kell tennie, hogy módosítja a kapcsolati változókat és az alap DN-t. Kezdésként hozzuk létre a keresőfelületet, amely "search.html" néven lesz elmentve:

keresési feltétel:

szűrő:

Az 1. ábra példát mutat arra, hogyan nézne ki ez a keresési űrlap a böngészőben.

1. ábra: Az Active Directory keresési űrlapja

Ezután létre kell hoznunk a keresést befolyásoló logikát. Ez a rövid kódrészlet itt látható:

0) ( for ($i=0; $i<$entries["count"]; $i++) { echo "

Név: ".$entries[$i]["megjelenítési név"]."
"; echo "Telefon: ".$entries[$i]["telefonszám"]."
"; echo "E-mail: ".$entries[$i]["mail"]."

"; ) ) else ( visszhang "

Nincs találat!

"; ) ldap_unbind($ad); ?>

Megváltoztathatja a keresési felületen megadott műveleti célt, rámutatva a fenti szkriptből álló fájlra, vagy kötegelheti ugyanabba a fájlba, mint a keresési felület, és az isset() és egy if feltételes parancsot használhatja a végrehajtás kiváltására. abban az esetben, ha a keresés elküldése gomb le van nyomva. Természetesen az ilyen szkriptek telepítése előtt hozzá kell adni néhány további adatellenőrzési feltételt. A 2. ábra a keresési eredményekből ad mintát.

2. ábra: Keresési eredmények

Következtetés

Bár a PHP régóta az elsődleges nyelvem a webalkalmazások fejlesztéséhez, a Perl-t programozóm eszközkészletének szerves részének találtam. Ha címtárszerverekkel dolgozik, ez a felfogás nem különbözik. Ezért a következő cikk a Perl/LDAP alapjaival foglalkozik. A jelen cikkhez hasonlóan minden példa a Microsoft Active Directoryjára vonatkozik, bár könnyen alkalmazhatónak kell lennie bármely címtárszerver-megvalósításra. A cikket egy példával egészítjük ki, amely bemutatja, hogyan hozhat létre statikusan gyorsítótárazott web- alapú felhasználói könyvtárak Perl parancsfájl és CRON (vagy Windows Feladatütemező) használatával.

Kérdéseket, észrevételeket szívesen fogadok! Küldjön e-mailt a címre [e-mail védett]. Szeretnék többet hallani a Microsoft és a nyílt forráskódú technológiák integrálásával kapcsolatos tapasztalatairól!

A szerzőről

W. Jason Gilmore (http://www.wjgilmore.com/) a Fisher College of Business internetes alkalmazásfejlesztője. Ő a szerzője a következő könyvnek, a PHP 5-nek és a MySQL: Novice to Pro-nak, amelyet az Apress 2004-ben ad ki. Munkássága a számítástechnikai iparág számos vezető kiadványában szerepelt, köztük a Linux Magazine-ban, az O"Reillynet-ben, A Devshed, a Zend.com és a Webreview. Jason az A Programmer's Introduction to PHP 4.0 (453 oldal, Apress) szerzője is. Munkatársával, Jon Shoberggel társszerzője az "Out in the Open" című, a Linux magazinban megjelenő havi rovatnak.

IT Solutions Builder VÁLLALKOZÁSÁNAK ELŐRELÉPÍTÉSÉHEZ VONATKOZÓ LEGJOBB IT FORRÁSOK

Ha hibát észlel, jelöljön ki egy szövegrészt, és nyomja meg a Ctrl + Enter billentyűket
OSSZA MEG: