PHP LDAP Active Directory 연동

요즘 하는 일이 Linux Server 들에 대하여 Active Directory 와 인증 통합을 하는 작업을 하고 있습니다. 물론 kerberos 나 ldap 을 이용해서 Linux Server들의 인증을 하는 것은 아니고, Windows 2003 R2 에 Server For Unix 의 NIS password entry 를 받아와서 Linux NIS server 를 운영하게 하는데, 이 과정에서 AD 정도 변경이 실시간으로 Linux NIS Server 로 반영이 되게 하기 위해서 관리 tool 을 만들고 있습니다.

이 과정에서 PHP Ldap API를 이용하여 Active Directory 를 관리하는데, 다른 정보를 변경하는 것은 별 무리가 없으나, Active Directory 의 Password 를 변경할 경우, AD에서 ldap ssl 로 연결을 할 경우에만 Password 변경이 가능 합니다. 이 부분 때문에 엄청난 삽질을 하게 되었습니다. 뭐 기본적으로 ldap 에 대한 지식이 별로 없었던 것이 삽질의 가장 주된 원인이기는 했지만, 검색에 걸린 대부분의 문서들이 ldap 에 대한 지식이 있다는 가정하에 설명을 하다보니 미치고 환장하겠더군요 ^^;

각설하고, 여기에서는 Active Directory 의 Password 변경이 가능하도록 PHP에서 Ldap SSL 로 연결하는 것에 대한 설명을 하고자 합니다.

기본적인 전제 조건으로는, Windows 2003 에 Active Directory Domain controller 가 구성이 되어 있고, 이 서버에서 Ldap SSL (ldaps://) connection 이 가능하도록 설정이 되어 있다는 가정하에 설명을 하도록 하겠습니다. Domain controller 에 Ldap SSL 을 설정하는 것은 googling 으로 쉽게 찾을 수 있으므로.. 생략 하도록 하겠습니다.

1. Client 에서 사용할 CACERT 인증서 생성

Domain controller 에서 사용되는 인증서를 "DER로 인코딩된 X.509 바이너리(.CER)" 로 export 를 합니다. export 한 CA 인증서를 Unix 서버로 이동한 후에, 다음의 명령으로 .pem file 로 전환을 합니다.

shell> openssl x509 -in cacert.cer -inform DER -out cacert.pem -outform PEM


2. PHP Ldap Extension 확인

phpinfo() 함수를 이용해서, ldap extension 이 지원되는지와, ldap 에서 SASL 지원이 되는지를 확인 합니다.

LDAP Support => enabled RCS Version => $Id: ldap.c,v 1.161.2.3.2.13 2008/05/04 21:19:17 colder Exp $ Total Links => 0/unlimited API Version => 3001 Vendor Name => OpenLDAP Vendor Version => 20327 SASL Support => Enabled


3. Coding

Active Directory 에서 AD Password 는 unicodePwd 라는 entry 에 UTF16 형식의 plain text 를 입력을 해 주면 됩니다. 이 의미는 abcd 를 입력하려면 'a\000b\000c\000d\000' 과 같이 입력을 하면 된다는 의미 입니다.

간단하게 코드의 예를 들자면 다음과 같이 생성할 수 있습니다. (단 주의할 것은 ASCII 범위 밖의 문자열을 입력하시면 안됩니다.)

<?php function make_ad_passwd ($pass) { $pass = '"' . $pass . '"'; $len = strlen ($pass); for ( $i=0; $i<$len; $i++ ) $newpass .= $pass[$i] . "\000"; return $newpass; } ?>


그럼, AD password 함수를 변경하는 코드의 예를 보도록 하겠습니다. 이 코드에서 중요한 것은, 또는 다른 문서에 나오지 않는 내용은, unicodePwd entry 를 변경하기 위해서는 ldap ssl 연결을 사용해야 한다는 것이고, 또 하나는 SSL 연결을 위한 인증서 설정 입니다.

<?php # SSL 로 접속을 해야 하기 때문에 ldaps:// protocol 을 사용한다. $host = "ldaps://ad.domain.controller.com"; # ldaps 의 기본 포트는 636 을 사용한다. $port = "636"; # 인증서 설정 $certfile = '/some/path/cacert.pem'; # default DN $defaultdn = 'domain_manager@DOMAIN.NAME.COM'; $accesspw = 'password_of_domain_manager'; # 관리 OU $ou = "OU=Users,DS=DOMAIN,DS=NAME,DS=com" $username = $argv[1]; $userpass = $argv[2] ? $argv[2] : 'abcd'; if ( ! $username ) { echo "ERROR: You must input changed username on argv[1]\n"; exit 1; } # # system 의 ldap 설정을 건드리지 않고 하기 위해서 다음의 환경 변수를 설정한다. putenv ('LDAPTLS_REQCERT=never'); putenv ("LDAPTLS_CACERT={$certfile}"); $ldap = ldap_connect ($host, $port); if ( $ldap === false ) { echo "ERROR: connect failed to $host\n"; exit 1; } $bind = @ldap_bind ($ldap, $defaultdn, $accesspw); if ( $bind === false ) { echo ldap_error ($ldap) . "\n"; exit 1; } $filter = "(samaccountname={$username})"; $result = ldap_search ($ldap, $ou, $filter); ldap_sort ($ldap, $result, 'sn'); $info = ldap_get_entries ($ldap, $result); for ( $i=0; $i<$info['count']; $i++ ) { echo "You are changing the password for " . $info[$i]['givenname'][0] . ", " . $info[$i]['sn'][0] . " (" . $info[$i]['samaccountname'][0] . ") to {$userpass}\n"; $userdata['unicodePwd'] = make_ad_passwd ($userpass); $result = ldap_mod_replace ($ldap, $info[$i]['distinguishedname'][0], $userdata); if ( $result === false ) echo "There was a problem changing your password, please call IT for help\n"; else echo "Your password han been changed!\n"; } @ldap_close ($ldap); ?>

Posted by 김정균

2009/01/28 21:50 2009/01/28 21:50
, , , , , , , ,
Response
No Trackback , 5 Comments
RSS :
http://my.oops.org/rss/response/125

Trackback URL : http://my.oops.org/trackback/125

« Previous : 1 : ... 21 : 22 : 23 : 24 : 25 : 26 : 27 : 28 : 29 : ... 135 : Next »

Valid XHTML 1.0 Transitional Valid CSS 2.0!
뭘 이런걸..

뭘 이런걸..

Notices

Categories

전체 (135)
주절주절 (27)
군이 (11)
둘째 사고 일지 (3)
Tech (94)

Calendar

«   2012/02   »
      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      

Site Stats