• R/O
  • HTTP
  • SSH
  • HTTPS

pukiwiki: Commit


Commit MetaInfo

Revisionc3cf8aafd4eb0da0d2f02fe854075440d2d39c1e (tree)
Time2016-02-20 00:05:20
Authorumorigu <umorigu@gmai...>
Commiterumorigu

Log Message

BugTrack2/384 Support LDAP Group - Security Group of Active Directory

Use LDAP_MATCHING_RULE_IN_CHAIN rule of Active Directory LDAP,
that enables nested group check.
For other systems, standard 'memberof' check is used.

Change Summary

Incremental Difference

--- a/lib/auth.php
+++ b/lib/auth.php
@@ -281,6 +281,7 @@ function ensure_valid_auth_user()
281281 $auth_type = AUTH_TYPE_FORM;
282282 }
283283 }
284+ $auth_dynamic_groups = null;
284285 switch ($auth_type) {
285286 case AUTH_TYPE_BASIC:
286287 {
@@ -309,23 +310,28 @@ function ensure_valid_auth_user()
309310 session_start();
310311 $user = '';
311312 $fullname = '';
313+ $dynamic_groups = array();
312314 if (isset($_SESSION['authenticated_user'])) {
313315 $user = $_SESSION['authenticated_user'];
314316 if (isset($_SESSION['authenticated_user_fullname'])) {
315317 $fullname = $_SESSION['authenticated_user_fullname'];
318+ $dynamic_groups = $_SESSION['dynamic_member_groups'];
316319 } else {
317320 $fullname = $user;
318321 if ($auth_type === AUTH_TYPE_EXTERNAL && $ldap_user_account) {
319322 $ldap_user_info = ldap_get_simple_user_info($user);
320323 if ($ldap_user_info) {
321324 $fullname = $ldap_user_info['fullname'];
325+ $dynamic_groups = $ldap_user_info['dynamic_member_groups'];
322326 }
323327 }
324328 $_SESSION['authenticated_user_fullname'] = $fullname;
329+ $_SESSION['dynamic_member_groups'] = $dynamic_groups;
325330 }
326331 }
327332 $auth_user = $user;
328333 $auth_user_fullname = $fullname;
334+ $auth_dynamic_groups = $dynamic_groups;
329335 break;
330336 }
331337 case AUTH_TYPE_EXTERNAL_REMOTE_USER:
@@ -342,6 +348,9 @@ function ensure_valid_auth_user()
342348 break;
343349 }
344350 $auth_user_groups = get_groups_from_username($auth_user);
351+ if ($auth_dynamic_groups && is_array($auth_dynamic_groups)) {
352+ $auth_user_groups = array_values(array_merge($auth_user_groups, $auth_dynamic_groups));
353+ }
345354 return true; // is not basic auth
346355 }
347356
@@ -434,9 +443,11 @@ function ldap_auth($username, $password)
434443 if ($ldap_bind_user) {
435444 $user_info = get_ldap_user_info($ldapconn, $username, $ldap_base_dn);
436445 if ($user_info) {
446+ $ldap_groups = get_ldap_groups_with_user($ldapconn, $username, $user_info['is_ad']);
437447 session_regenerate_id(true); // require: PHP5.1+
438448 $_SESSION['authenticated_user'] = $user_info['uid'];
439449 $_SESSION['authenticated_user_fullname'] = $user_info['fullname'];
450+ $_SESSION['dynamic_member_groups'] = $ldap_groups;
440451 return true;
441452 }
442453 }
@@ -448,9 +459,11 @@ function ldap_auth($username, $password)
448459 if ($user_info) {
449460 $ldap_bind_user2 = ldap_bind($ldapconn, $user_info['dn'], $password);
450461 if ($ldap_bind_user2) {
462+ $ldap_groups = get_ldap_groups_with_user($ldapconn, $username, $user_info['is_ad']);
451463 session_regenerate_id(true); // require: PHP5.1+
452464 $_SESSION['authenticated_user'] = $user_info['uid'];
453465 $_SESSION['authenticated_user_fullname'] = $user_info['fullname'];
466+ $_SESSION['dynamic_member_groups'] = $ldap_groups;
454467 return true;
455468 }
456469 }
@@ -473,6 +486,9 @@ function ldap_get_simple_user_info($username)
473486 if ($ldap_bind) {
474487 $user_info = get_ldap_user_info($ldapconn, $username, $ldap_base_dn);
475488 if ($user_info) {
489+ $ldap_groups = get_ldap_groups_with_user($ldapconn,
490+ $username, $user_info['is_ad']);
491+ $user_info['dynamic_member_groups'] = $ldap_groups;
476492 return $user_info;
477493 }
478494 }
@@ -499,10 +515,12 @@ function get_ldap_user_info($ldapconn, $username, $base_dn) {
499515 if (isset($info['dn'])) {
500516 $user_dn = $info['dn'];
501517 $cano_username = $username;
518+ $is_active_directory = false;
502519 if (isset($info['uid'][0])) {
503520 $cano_username = $info['uid'][0];
504521 } elseif (isset($info['samaccountname'][0])) {
505522 $cano_username = $info['samaccountname'][0];
523+ $is_active_directory = true;
506524 }
507525 $cano_fullname = $username;
508526 if (isset($info['displayname'][0])) {
@@ -514,7 +532,8 @@ function get_ldap_user_info($ldapconn, $username, $base_dn) {
514532 'dn' => $user_dn,
515533 'uid' => $cano_username,
516534 'fullname' => $cano_fullname,
517- 'mail' => $info['mail'][0]
535+ 'mail' => $info['mail'][0],
536+ 'is_ad' => $is_active_directory,
518537 );
519538 }
520539 return false;
@@ -551,3 +570,125 @@ function get_auth_external_login_url($page, $url_after_login) {
551570 . '&url_after_login=' . rawurlencode($url_after_login);
552571 return $url;
553572 }
573+
574+function get_auth_user_prefix() {
575+ global $ldap_user_account, $auth_type;
576+ global $auth_provider_user_prefix_default;
577+ global $auth_provider_user_prefix_ldap;
578+ global $auth_provider_user_prefix_external;
579+ $user_prefix = '';
580+ switch ($auth_type) {
581+ case AUTH_TYPE_BASIC:
582+ $user_prefix = $auth_provider_user_prefix_default;
583+ break;
584+ case AUTH_TYPE_EXTERNAL:
585+ case AUTH_TYPE_EXTERNAL_REMOTE_USER:
586+ case AUTH_TYPE_EXTERNAL_X_FORWARDED_USER:
587+ $user_prefix = $auth_provider_user_prefix_external;
588+ break;
589+ case AUTH_TYPE_FORM:
590+ if ($ldap_user_account) {
591+ $user_prefix = $auth_provider_user_prefix_ldap;
592+ } else {
593+ $user_prefix = $auth_provider_user_prefix_default;
594+ }
595+ break;
596+ }
597+ return $user_prefix;
598+}
599+
600+function get_ldap_related_groups() {
601+ global $read_auth_pages, $edit_auth_pages;
602+ global $auth_provider_user_prefix_ldap;
603+ $ldap_groups = array();
604+ foreach ($read_auth_pages as $pattern=>$groups) {
605+ $sp_groups = explode(',', $groups);
606+ foreach ($sp_groups as $group) {
607+ if (strpos($group, $auth_provider_user_prefix_ldap) === 0) {
608+ $ldap_groups[] = $group;
609+ }
610+ }
611+ }
612+ foreach ($edit_auth_pages as $pattern=>$groups) {
613+ $sp_groups = explode(',', $groups);
614+ foreach ($sp_groups as $group) {
615+ if (strpos($group, $auth_provider_user_prefix_ldap) === 0) {
616+ $ldap_groups[] = $group;
617+ }
618+ }
619+ }
620+ $ldap_groups_unique = array_values(array_unique($ldap_groups));
621+ return $ldap_groups_unique;
622+}
623+
624+/**
625+ * Get LDAP groups user belongs to
626+ *
627+ * @param Resource $ldapconn
628+ * @param String $user
629+ * @param bool $is_ad
630+ * @return Array
631+ */
632+function get_ldap_groups_with_user($ldapconn, $user, $is_ad) {
633+ global $auth_provider_user_prefix_ldap;
634+ global $ldap_base_dn;
635+ $related_groups = get_ldap_related_groups();
636+ if (count($related_groups) == 0) {
637+ return array();
638+ }
639+ $gfilter = '(|';
640+ foreach ($related_groups as $group_full) {
641+ $g = substr($group_full, strlen($auth_provider_user_prefix_ldap));
642+ $gfilter .= sprintf('(cn=%s)', pkwk_ldap_escape_filter($g));
643+ if ($is_ad) {
644+ $gfilter .= sprintf('(sAMAccountName=%s)', pkwk_ldap_escape_filter($g));
645+ }
646+ }
647+ $gfilter .= ')';
648+ $result_g = ldap_search($ldapconn, $ldap_base_dn, $gfilter,
649+ array('dn', 'uid', 'cn', 'samaccountname'));
650+ $entries = ldap_get_entries($ldapconn, $result_g);
651+ if (!isset($entries[0])) {
652+ return false;
653+ }
654+ if (!$entries) {
655+ return array();
656+ }
657+ $entry_count = $entries['count'];
658+ $group_list = array();
659+ for ($i = 0; $i < $entry_count; $i++) {
660+ $group_name = $entries[$i]['cn'][0];
661+ if ($is_ad) {
662+ $group_name = $entries[$i]['samaccountname'][0];
663+ }
664+ $group_list[] = array(
665+ 'name' => $group_name,
666+ 'dn' => $entries[$i]['dn']
667+ );
668+ }
669+ $groups_member = array();
670+ $groups_nonmember = array();
671+ foreach ($group_list as $gp) {
672+ $fmt = '(&(uid=%s)(memberOf=%s))';
673+ if ($is_ad) {
674+ // LDAP_MATCHING_RULE_IN_CHAIN: Active Directory specific rule
675+ $fmt = '(&(sAMAccountName=%s)(memberOf:1.2.840.113556.1.4.1941:=%s))';
676+ }
677+ $user_gfilter = sprintf($fmt,
678+ pkwk_ldap_escape_filter($user),
679+ pkwk_ldap_escape_filter($gp['dn']));
680+ $result_e = ldap_search($ldapconn, $ldap_base_dn, $user_gfilter,
681+ array('dn'), 0, 1);
682+ $user_e = ldap_get_entries($ldapconn, $result_e);
683+ if (isset($user_e['count']) && $user_e['count'] > 0) {
684+ $groups_member[] = $gp['name'];
685+ } else {
686+ $groups_nonmember[] = $gp['name'];
687+ }
688+ }
689+ $groups_full = array();
690+ foreach ($groups_member as $g) {
691+ $groups_full[] = $auth_provider_user_prefix_ldap . $g;
692+ }
693+ return $groups_full;
694+}
--- a/lib/file.php
+++ b/lib/file.php
@@ -169,10 +169,7 @@ function make_str_rules($source)
169169
170170 function add_author_info($wikitext)
171171 {
172- global $auth_user, $auth_user_fullname, $auth_type, $ldap_user_account;
173- global $auth_provider_user_prefix_default;
174- global $auth_provider_user_prefix_ldap;
175- global $auth_provider_user_prefix_external;
172+ global $auth_user, $auth_user_fullname;
176173 $author = preg_replace('/"/', '', $auth_user);
177174 $fullname = $auth_user_fullname;
178175 if (!$fullname && $author) {
@@ -180,24 +177,7 @@ function add_author_info($wikitext)
180177 $fullname = preg_replace('/^[^:]*:/', '', $author);
181178 }
182179 $displayname = preg_replace('/"/', '', $fullname);
183- $user_prefix = '';
184- switch ($auth_type) {
185- case AUTH_TYPE_BASIC:
186- $user_prefix = $auth_provider_user_prefix_default;
187- break;
188- case AUTH_TYPE_EXTERNAL:
189- case AUTH_TYPE_EXTERNAL_REMOTE_USER:
190- case AUTH_TYPE_EXTERNAL_X_FORWARDED_USER:
191- $user_prefix = $auth_provider_user_prefix_external;
192- break;
193- case AUTH_TYPE_FORM:
194- if ($ldap_user_account) {
195- $user_prefix = $auth_provider_user_prefix_ldap;
196- } else {
197- $user_prefix = $auth_provider_user_prefix_default;
198- }
199- break;
200- }
180+ $user_prefix = get_auth_user_prefix();
201181 $author_text = sprintf('#author("%s","%s","%s")',
202182 get_date_atom(UTIME + LOCALZONE),
203183 ($author ? $user_prefix . $author : ''),
Show on old repository browser