Branch 'production' - kolab.org/www

Torsten Grote grote at kolabsys.com
Tue Jul 31 14:49:27 CEST 2012


 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/.cvsignore                   |    1 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ChangeLog                    |   32 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/LICENSE.txt                  |  601 +++++----
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/README-PUID.txt              |  115 +
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/changelog.txt                |   83 +
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/includes/LDAPInterface.inc   |   85 -
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/includes/ldap.core.inc       |  658 +++++++++
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.admin.inc           |  326 ++++
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.admin.js            |   30 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.api.php             |  118 +
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.features.inc        |  250 +++
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.info                |   10 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.install             |  242 +++
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.module              |  403 ++++--
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.theme.inc           |   10 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.admin.inc           |   24 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.info                |    7 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.install             |    2 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.module              |  661 +++++++++-
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.theme.inc           |    1 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.admin.inc         |  362 +++++
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.api.php           |   47 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.inc               |  309 +++-
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.info              |    7 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.install           |    1 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.module            |  170 ++
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.css        |    9 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.info       |   12 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.module     |  364 +++++
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp_status.inc |  373 +++++
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp_wizard.inc |  368 +++++
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.admin.inc           |  140 ++
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.info                |   14 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.install             |   29 
 kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.module              |  423 ++++++
 35 files changed, 5609 insertions(+), 678 deletions(-)

New commits:
commit 5a1c6f86ba34168745e76c16ce23ac9cea2edf32
Author: Torsten Grote <grote at kolabsys.com>
Date:   Tue Jul 31 14:49:14 2012 +0200

    updated ldap integration plugin

diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/.cvsignore b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/.cvsignore
deleted file mode 100644
index 3a4edf6..0000000
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-.project
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ChangeLog b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ChangeLog
deleted file mode 100644
index f3c4b7e..0000000
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ChangeLog
+++ /dev/null
@@ -1,32 +0,0 @@
-2007-08-29  kreaper  <http://rajeev.name>
-
-	* ldapauth.module: http://drupal.org/node/171440
-	the extra <strong> the problem with the fieldset and is removed.
-
-2007-08-22 kreaper <http://rajeev.name>
-
-	* ldap_integration/LDAPInterface.php: http://drupal.org/node/164049
-	Allow anonymous LDAP connect();
-
-	* ldapauth.module: http://drupal.org/node/164078
-	HTML fixes
-
-	* ldap_integration/LDAPInterface.php: http://drupal.org/node/158671
-	No longer initializing $ldap->server to "example.com"
-	
-2007-07-22 kreaper <http://rajeev.name>
-
-	* ldapauth.module: http://drupal.org/node/158671
-	contributed code that modifies code flow and also enabled ldapauth_auth() to work with other modules. 
-
-	* ldapdata.module: bug fix for http://drupal.org/node/136068
-	http://bugs.mysql.com/bug.php?id=25520 specifies that in Windows, TEXT/BLOB cannot have a default value
-
-2007-07-09 kreaper <http://rajeev.name>
-
-	* ldapgroups.module: renamed the global variable $ldap to $ldapgroups_ldap. 
-	Created a new function _ldapgroups_ldap_init() to setup the ldapgroups_ldap object.
-
-	* ldapdata.module: renamed the global variable $ldap to $ldapdata_ldap
-
-	* ldapauth.module: renamed the global variable $ldap to $ldapauth_ldap
\ No newline at end of file
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/LICENSE.txt b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/LICENSE.txt
index 2c095c8..d159169 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/LICENSE.txt
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/LICENSE.txt
@@ -1,274 +1,339 @@
-GNU GENERAL PUBLIC LICENSE
-
-              Version 2, June 1991
-
-Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,
-Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute
-verbatim copies of this license document, but changing it is not allowed.
-
-                  Preamble
-
-The licenses for most software are designed to take away your freedom to
-share and change it. By contrast, the GNU General Public License is
-intended to guarantee your freedom to share and change free software--to
-make sure the software is free for all its users. This General Public License
-applies to most of the Free Software Foundation's software and to any other
-program whose authors commit to using it. (Some other Free Software
-Foundation software is covered by the GNU Library General Public License
-instead.) You can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the
-freedom to distribute copies of free software (and charge for this service if
-you wish), that you receive source code or can get it if you want it, that you
-can change the software or use pieces of it in new free programs; and that
-you know you can do these things.
-
-To protect your rights, we need to make restrictions that forbid anyone to
-deny you these rights or to ask you to surrender the rights. These restrictions
-translate to certain responsibilities for you if you distribute copies of the
-software, or if you modify it.
-
-For example, if you distribute copies of such a program, whether gratis or for
-a fee, you must give the recipients all the rights that you have. You must make
-sure that they, too, receive or can get the source code. And you must show
-them these terms so they know their rights.
-
-We protect your rights with two steps: (1) copyright the software, and (2)
-offer you this license which gives you legal permission to copy, distribute
-and/or modify the software.
-
-Also, for each author's protection and ours, we want to make certain that
-everyone understands that there is no warranty for this free software. If the
-software is modified by someone else and passed on, we want its recipients
-to know that what they have is not the original, so that any problems
-introduced by others will not reflect on the original authors' reputations.
-
-Finally, any free program is threatened constantly by software patents. We
-wish to avoid the danger that redistributors of a free program will individually
-obtain patent licenses, in effect making the program proprietary. To prevent
-this, we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
-The precise terms and conditions for copying, distribution and modification
-follow.
-
-           GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
-               MODIFICATION
-
-0. This License applies to any program or other work which contains a notice
-placed by the copyright holder saying it may be distributed under the terms
-of this General Public License. The "Program", below, refers to any such
-program or work, and a "work based on the Program" means either the
-Program or any derivative work under copyright law: that is to say, a work
-containing the Program or a portion of it, either verbatim or with
-modifications and/or translated into another language. (Hereinafter, translation
-is included without limitation in the term "modification".) Each licensee is
-addressed as "you".
-
-Activities other than copying, distribution and modification are not covered
-by this License; they are outside its scope. The act of running the Program is
-not restricted, and the output from the Program is covered only if its contents
-constitute a work based on the Program (independent of having been made
-by running the Program). Whether that is true depends on what the Program
-does.
-
-1. You may copy and distribute verbatim copies of the Program's source
-code as you receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice and
-disclaimer of warranty; keep intact all the notices that refer to this License
-and to the absence of any warranty; and give any other recipients of the
-Program a copy of this License along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and you
-may at your option offer warranty protection in exchange for a fee.
-
-2. You may modify your copy or copies of the Program or any portion of it,
-thus forming a work based on the Program, and copy and distribute such
-modifications or work under the terms of Section 1 above, provided that you
-also meet all of these conditions:
-
-a) You must cause the modified files to carry prominent notices stating that
-you changed the files and the date of any change.
-
-b) You must cause any work that you distribute or publish, that in whole or in
-part contains or is derived from the Program or any part thereof, to be
-licensed as a whole at no charge to all third parties under the terms of this
-License.
-
-c) If the modified program normally reads commands interactively when run,
-you must cause it, when started running for such interactive use in the most
-ordinary way, to print or display an announcement including an appropriate
-copyright notice and a notice that there is no warranty (or else, saying that
-you provide a warranty) and that users may redistribute the program under
-these conditions, and telling the user how to view a copy of this License.
-(Exception: if the Program itself is interactive but does not normally print such
-an announcement, your work based on the Program is not required to print
-an announcement.)
-
-These requirements apply to the modified work as a whole. If identifiable
-sections of that work are not derived from the Program, and can be
-reasonably considered independent and separate works in themselves, then
-this License, and its terms, do not apply to those sections when you distribute
-them as separate works. But when you distribute the same sections as part
-of a whole which is a work based on the Program, the distribution of the
-whole must be on the terms of this License, whose permissions for other
-licensees extend to the entire whole, and thus to each and every part
-regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest your rights to
-work written entirely by you; rather, the intent is to exercise the right to
-control the distribution of derivative or collective works based on the
-Program.
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
 
 In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of a
-storage or distribution medium does not bring the other work under the scope
-of this License.
-
-3. You may copy and distribute the Program (or a work based on it, under
-Section 2) in object code or executable form under the terms of Sections 1
-and 2 above provided that you also do one of the following:
-
-a) Accompany it with the complete corresponding machine-readable source
-code, which must be distributed under the terms of Sections 1 and 2 above
-on a medium customarily used for software interchange; or,
-
-b) Accompany it with a written offer, valid for at least three years, to give
-any third party, for a charge no more than your cost of physically performing
-source distribution, a complete machine-readable copy of the corresponding
-source code, to be distributed under the terms of Sections 1 and 2 above on
-a medium customarily used for software interchange; or,
-
-c) Accompany it with the information you received as to the offer to distribute
-corresponding source code. (This alternative is allowed only for
-noncommercial distribution and only if you received the program in object
-code or executable form with such an offer, in accord with Subsection b
-above.)
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
 
 The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source code
-means all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation and
-installation of the executable. However, as a special exception, the source
-code distributed need not include anything that is normally distributed (in
-either source or binary form) with the major components (compiler, kernel,
-and so on) of the operating system on which the executable runs, unless that
-component itself accompanies the executable.
-
-If distribution of executable or object code is made by offering access to
-copy from a designated place, then offering equivalent access to copy the
-source code from the same place counts as distribution of the source code,
-even though third parties are not compelled to copy the source along with the
-object code.
-
-4. You may not copy, modify, sublicense, or distribute the Program except as
-expressly provided under this License. Any attempt otherwise to copy,
-modify, sublicense or distribute the Program is void, and will automatically
-terminate your rights under this License. However, parties who have received
-copies, or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-5. You are not required to accept this License, since you have not signed it.
-However, nothing else grants you permission to modify or distribute the
-Program or its derivative works. These actions are prohibited by law if you
-do not accept this License. Therefore, by modifying or distributing the
-Program (or any work based on the Program), you indicate your acceptance
-of this License to do so, and all its terms and conditions for copying,
-distributing or modifying the Program or works based on it.
-
-6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the original
-licensor to copy, distribute or modify the Program subject to these terms and
-conditions. You may not impose any further restrictions on the recipients'
-exercise of the rights granted herein. You are not responsible for enforcing
-compliance by third parties to this License.
-
-7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues), conditions
-are imposed on you (whether by court order, agreement or otherwise) that
-contradict the conditions of this License, they do not excuse you from the
-conditions of this License. If you cannot distribute so as to satisfy
-simultaneously your obligations under this License and any other pertinent
-obligations, then as a consequence you may not distribute the Program at all.
-For example, if a patent license would not permit royalty-free redistribution
-of the Program by all those who receive copies directly or indirectly through
-you, then the only way you could satisfy both it and this License would be to
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
 refrain entirely from distribution of the Program.
 
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply and
-the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any patents or
-other property right claims or to contest validity of any such claims; this
-section has the sole purpose of protecting the integrity of the free software
-distribution system, which is implemented by public license practices. Many
-people have made generous contributions to the wide range of software
-distributed through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing to
-distribute software through any other system and a licensee cannot impose
-that choice.
-
-This section is intended to make thoroughly clear what is believed to be a
-consequence of the rest of this License.
-
-8. If the distribution and/or use of the Program is restricted in certain
-countries either by patents or by copyrighted interfaces, the original copyright
-holder who places the Program under this License may add an explicit
-geographical distribution limitation excluding those countries, so that
-distribution is permitted only in or among countries not thus excluded. In such
-case, this License incorporates the limitation as if written in the body of this
-License.
-
-9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will be
-similar in spirit to the present version, but may differ in detail to address new
-problems or concerns.
-
-Each version is given a distinguishing version number. If the Program specifies
-a version number of this License which applies to it and "any later version",
-you have the option of following the terms and conditions either of that
-version or of any later version published by the Free Software Foundation. If
-the Program does not specify a version number of this License, you may
-choose any version ever published by the Free Software Foundation.
-
-10. If you wish to incorporate parts of the Program into other free programs
-whose distribution conditions are different, write to the author to ask for
-permission. For software which is copyrighted by the Free Software
-Foundation, write to the Free Software Foundation; we sometimes make
-exceptions for this. Our decision will be guided by the two goals of
-preserving the free status of all derivatives of our free software and of
-promoting the sharing and reuse of software generally.
-
-               NO WARRANTY
-
-11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE,
-THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT
-PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
-STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
-WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
-PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
-NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
-AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR
-ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
-LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
-SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
-ARISING OUT OF THE USE OR INABILITY TO USE THE
-PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
-OR DATA BEING RENDERED INACCURATE OR LOSSES
-SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
-PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN
-IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.
-
-          END OF TERMS AND CONDITIONS
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/README-PUID.txt b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/README-PUID.txt
new file mode 100644
index 0000000..367e375
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/README-PUID.txt
@@ -0,0 +1,115 @@
+
+LDAP Integration Module - Persistent and Unique IDs (PUID)
+
+Overview
+========
+
+LDAP Integration needs to map Drupal users to LDAP user.  Generally, just 
+mapping via the user name works.  However, LDAP in enterprise settings can
+be a very dynamic. People can change user names and e-mail addresses, be moved 
+between LDAP trees (e.g. ou=Contract -> ou=Employee), and the like.
+
+The PUID attribute can be used to better map LDAP users to Drupal users.  This
+will allow LDAP Integration to definitively map an LDAP object to a Drupal user.
+
+The PUID can be a site specific attribute such as employeeNumber.  It can also
+use one of the various default attributes that LDAP servers supply for this
+purpose.  Some examples are:
+
+entryUUID - RFC 4530 standard operational attribute which the server assigns
+            a unique GUID to each LDAP object.  OpenLDAP, Apache DS, and other
+            impliment this.
+            
+objectGUID - Microsoft Active Directory standard attribute which get a unique
+             GUID as well.  NOTE:  This is a binary attributes.
+
+Note that most major LDAP servers currently have an attribute that supplies
+this functionality, even if the don't support RFC 4530.  Review your server
+documentation to determine what this is.
+             
+             
+Using PUID with LDAP Integration
+================================
+
+The first step is make sure you have the latest version of LDAP Integration
+install (after 4/24/2012) and have run UPDATE.php
+
+Next, you can edit your LDAP server settings to define the attribute to use
+for a PUID.
+
+Once you define a PUID, new users will be automatically be associated with 
+this as their accounts are created.  Existing users will be mapped to the
+PUID as they log on.  With the next version of ldapsync, this can also be 
+done by syncing the LDAP to Drupal users.
+
+An existing Drupal user is mapped via the PUID to an LDAP user if the following
+test are all true:
+
+- The Drupal user name matches the Authenticated ldap user name attribute.
+- The matching user is marked as an ldap user.
+- The Drupal user's stored dn matches the ldap dn
+- The Drupal user's server id matches the ldap server id or the Drupal sid does 
+  not exist anymore (i.e. server deleted/recreated)
+  
+Note that if the matching user is not an ldap user, the User conflict settings
+will be used to associate this or deny access.
+
+Some Operational Notes
+======================
+
+The PUID LDAP to Drupal user mappings are cleared when:
+
+- The PUID attribute is changed (or set initially) or
+- The Server entry is deleted.
+
+This should not have any major impact other than causing the "matching" rules
+to come into play as existing users log in.  You may want to use ldapsync to
+prevent any problems with name changes before the person logs in.
+
+
+Note that not all tools and LDAP backup software will properly migrate 
+the operational UUID attributes.  Many do, so make sure that your backup 
+and recovery/migrate processes include the PUID attributes.
+
+If your recover/migrate without these, you will have to clear the 
+ldapauth_users info for the effected server(s).  This can be done by 
+blanking out the PUID attribute, saving the server, then reentering the
+PUID value and saving the server.  Existing users will be mapped according 
+to the rules above. 
+
+Developer Notes:
+================
+
+The PUID mapping information is stored in the ldapauth_users table and can be
+managed by the ldapauth_userinfo_* CRUD functions in the ldap.core.inc file.
+
+There are two hooks that can effect Drupal to LDAP user mapping.  These are:
+
+/**
+ * Called if the LDAP user's PUID attribute does not exist or is empty.
+ */
+hook_ldap_user_puid_alter( &$puid, $name, $dn, $sid)
+
+This is a way for a site specific module to create or calculate PUID values for
+users.  Note that implementors will need to save this to the LDAP entry since 
+ldapauth may not have LDAP auth write priviledges.
+   
+/**
+ * Called after the ldap user is authenticated but before the Drupal user
+ * lookup/create process is done.
+ */
+hook_ldap_drupal_user_name_alter( &$name, $ldap, $dn )
+
+This allows sites to use a custom module to define the Drupal user name that 
+will be used to map to an LDAP user.  
+
+For example, if you have multiple servers with a possiblity of duplicate user 
+names, you can use this to prefix the Drupal name with the server machine name.
+So, LDAP user jsmith on the Student server maps to Drupal user id student-jsmith
+while jsmith on the Staff server maps to staff-jsmith.
+
+With a PUID, both users can log on using jsmith and their password and be 
+correctly mapped to different Drupal users.  Of course, if both users happen 
+to choose the same password... there may be problems.
+   
+See the ldapauth.api.php file for argument details.
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/changelog.txt b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/changelog.txt
new file mode 100644
index 0000000..b0f982d
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/changelog.txt
@@ -0,0 +1,83 @@
+
+LDAP Integration Changelog
+==========================
+Issue #1664384 by cgmonroe Fatal error on viewing a user profile
+Issue #1525752 by cgmonroe Original issue solution needed additional logic to allow for mixed mode users. 
+by cgmonroe Allow Drupal name to be null in ldapauth_drupal_user_lookup
+by cgmonroe Made sure role lookup querys were case insensitive
+by cgmonroe Added hook_ldap_user_groups_alter and hook_ldap_user_roles_alter to ldapgroups and ldapgroups.api.php doc. 
+by cgmonroe Allowed multiple Drupal roles to be defined in the group to role mapping area.
+by cgmonroe Added a test user group mappings option to ldapgroups admin that displays groups found, access rights, and roles for a specific user.
+by cgmonroe Converted ldapgroups "account creation" to ldap access rules.
+by cgmonroe Improved ldapgroups admin screen layout and text
+Issue #492082 by rjmackay, cgmonroe Provide option to disallow changing Username on user edit form
+by cgmonroe Added ability to convert ldap users back to local users (on user profile page).
+Issue #1279166 by cgmonroe Enabling groups overrides roles
+by cgmonroe ldapsync now has a User Conflict resolution option to deal with existing drupal users who match LDAP users
+by cgmonroe added a Sync Existing user only option to ldapsync
+by cgmonroe ldapsync's optional search filter can now contain multiple filters and optionally have the default filter appended.
+by cgmonroe Included ldapauth_users table removal in ldapauth uninstall function.
+Issue #1550504 by superhenne,cgmonroe ldapauth_users table not created on update/installation
+by cgmonroe Convert ldapgroups from $user to recommended $account for user handling.
+Issue #805752 by cgmonroe Detecting Groups failing (when user has no groups and only allow from these groups defined).
+by cgmonroe Restructured ldapgroups to support hook_ldap_user_deny_alter
+Issues #897222 and #949560 by cgmonroe Added hook_ldap_user_deny_alter so ldapgroups (and other modules) could deny an ldap user access to server before account creation/login.
+by cgmonroe Fixed features api so it worked with the new ldap.core structure
+by cgmonroe Restructured ldapsyn to use new core functions and fix multiple issues 
+by cgmonroe Added caching to ldapauth_lookup_user_by_dn
+Issue #862930 by cgmonroe LDAP should not be queried on every hook_user_view call
+Issue #688502 by cgmonroe Changed "sync passwords" option text to be clearer about behaviour.
+by cgmonroe Moved from authmap to checking account settings in a lot of places
+by cgmonroe Converted from include and requires to module_load_include
+by cgmonroe Fixed ldapdata bug that caused non-LDAP admin accounts to "blank out" profile info if they clicked on "Edit"
+by cgmonroe Added hooks for site specific modules to create PUIDs and influence LDAP user id to Drupal User id mapping - See ldapauth.api.php
+by cgmonroe Added/Restructured code to use ldapauth_drupal_user_lookup (map ldap ID to Drupal id) and ldapauth_drupal_user_create (create new Drupal user logic).
+by cgmonroe Refactored ldapauth so "core" functions (used by other modules) are in includes\ldap.core.inc file.
+by cgmonroe (Related to many issues) Added support for Persistent and Unique IDs (PUID) - Requires update.php to be run
+by cgmonroe Fix problem with server name and or machine name not being stored if they are changed in admin screens.
+by cgmonroe Cache attributes needed by sid and op rather than just op.
+Issue #1537556 by macman824,cgmonroe Lastest dev breaks ability to change AD password.
+Issue #1475228 by antgiant LDAP Sync Block Missing Users is Case Sensitive
+Issue #1475234 by antgiant LDAP Sync does show username of enabled users
+by cgmonroe Create D7 style ldapauth.api.php doc
+by cgmonroe Added machine_name as an LDAPInterface option/updated init code
+by cgmonroe Optimized server info caching by converting to ldapauth_server_load calls.
+Issue #1031425 by joelstein,johnbarclay,cgmonroe Return only specific attributes from ldap_read
+Issue #1525752 by msielski,cgmonroe If "Remove email field from form" is selected, user email address can not be changed.
+Issue #1209556 by johnbarclay,ericksm,cgmonroe Need to check for existing emails in ldapauth.module
+by cgmonroe Feature revert now correctly uses machine names to identify existing server entries.
+by cgmonroe Fixed PhP errors that occur if ldapdata attribute mapping still exist when the related *profile module is disabled.
+by cgmonroe Updated field description to include default port numbers.
+by cgmonroe Fixed bug with bindpw being cleared on save
+Issue #1400154 by cgmonroe Ldapdata module support for updating LDAP attributes from Content Profile Nodes
+by cgmonroe Added machine_name to database (requires Update.php run!) and support in admin screens.
+by cgmonroe Fix coder complaints about messages.
+by cgmonroe Added some common CRUD functions for accessing server info..
+by cgmonroe Add server import / export via admin GUI if ctools enabled.
+Issue #692670 by cgmonroe Integration with Features Module
+Issue #62784 by adzuledu,cgmonroe: Mapping image-type attribute from LDAP
+Issue #256226 by paolomainardi: Option to prevent new accounts from LDAP from being added to Drupal 
+Issue #1435486 by eiriksm: Coding Standards
+by cgmonroe: Fixed arraymerge error if no profile fields defined
+Issue #580786 by retsamedoc Standard LDAP Password Encryption
+Issue #1253020 by superhenne,cgmonroe  $profile_fields / $content_profile_fields messed up in ldapdata.module
+Issue #594598 by eporama.  Updated original to work on login page & test for admin.
+Issue #1243564 by wadmiraal.  translation fix.
+Issue #594598 by eporama.  Fix of error message on failed logon when reset password disabled.
+Issue #514986.  Error in error message when start tls fails.
+Issue #3918612 by pembertona.  Content Profile support additions and profile fixes.
+Issue #514986 by jlea9378. Bad error catching when start tls fails.  Produced extra errors.
+Issue #406038.  Fixed wording on fieldset for LDAP groups which allow automatic account creation
+Issue #655918 by sutch.  Fixed working of ldap server directions.
+Issue #821776 by gibus.  fixed use of t() function.
+Issue #953744 by erikwebb.  SQL error in ldap synch fixed.
+Brought last head into synch http://drupalcode.org/project/ldap_integration.git/commit/b16d5e2fd87f99d9abb4c35211da5be8e7977abe.  Primary change was addition of ldap synch.
+Issue #641558 by ShutterFreak :  password field should not be trimmed.
+Issue #171763 by retsamedoc : date support in profile
+Issue #793586 by robb: error catching for fail to connect
+Issue #986322 by lavamind: since email field is simply hidded, don't change in ldap
+Issue #339821 by presleyd: Fix encoding for AD passwords.
+Issue #636150 by patrizio:  allow non ldap users to request new password.
+Issue #417892 by johnbarclay: changed explode on , to ldap_explode_dn function to deal with escaping characters
+Merged Head and Beta2 into head for 6.x-1.x-dev
+Issue #514986 by jlea9378:  start tls not working because of incorrect check.  Patch by catfink.
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/includes/LDAPInterface.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/includes/LDAPInterface.inc
index ba10f8f..8b873cd 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/includes/LDAPInterface.inc
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/includes/LDAPInterface.inc
@@ -1,5 +1,4 @@
 <?php
-// $Id: LDAPInterface.inc,v 1.6 2009/10/27 14:29:18 miglius Exp $
 
 /**
  * @file
@@ -38,6 +37,9 @@ class LDAPInterface {
       case 'name':
         $this->name = $value;
         break;
+      case 'machine_name':
+        $this->machine_name = $value;
+        break;
       case 'server':
         $this->server = $value;
         break;
@@ -47,8 +49,8 @@ class LDAPInterface {
       case 'tls':
         $this->tls = $value;
         break;
-      case 'encrypted':
-        $this->encrypted = $value;
+      case 'enc_type':
+        $this->enc_type = $value;
         break;
       case 'user_attr':
         $this->user_attr = $value;
@@ -62,6 +64,12 @@ class LDAPInterface {
       case 'mail_attr':
         $this->mail_attr = $value;
         break;
+      case 'puid_attr':
+        $this->puid_attr = $value;
+        break;
+      case 'binary_puid':
+        $this->binary_puid = $value;
+        break;
       case 'binddn':
         $this->binddn = $value;
         break;
@@ -84,14 +92,17 @@ class LDAPInterface {
       case 'name':
         $ret = $this->name;
         break;
+      case 'machine_name':
+        $ret = $this->machine_name;
+        break;
       case 'port':
         $ret = $this->port;
         break;
       case 'tls':
         $ret = $this->tls;
         break;
-      case 'encrypted':
-        $ret = $this->encrypted;
+      case 'enc_type':
+        $ret = $this->enc_type;
         break;
       case 'user_attr':
         $ret = isset($this->user_attr) ? $this->user_attr : NULL;
@@ -105,6 +116,12 @@ class LDAPInterface {
       case 'mail_attr':
         $ret = isset($this->mail_attr) ? $this->mail_attr : NULL;
         break;
+      case 'puid_attr':
+        $ret = isset($this->puid_attr) ? $this->puid_attr : NULL;
+        break;
+      case 'binary_puid':
+        $ret = isset($this->binary_puid) ? $this->binary_puid : NULL;
+        break;
       case 'binddn':
         $ret = isset($this->binddn) ? $this->binddn : NULL;
         break;
@@ -129,16 +146,16 @@ class LDAPInterface {
   }
 
   function initConnection() {
-    if (!$con = ldap_connect($this->server, $this->port)) {
+    if (!$this->connection = ldap_connect($this->server, $this->port)) {
       watchdog('ldap', 'LDAP Connect failure to @server:@port', array('@server' => $this->server, '@port' => $this->port), WATCHDOG_ERROR);
       return;
     }
 
-    ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);
-    ldap_set_option($con, LDAP_OPT_REFERRALS, 0);
+    ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, 3);
+    ldap_set_option($this->connection, LDAP_OPT_REFERRALS, 0);
     // TLS encryption contributed by sfrancis at drupal.org
     if ($this->tls) {
-      ldap_get_option($con, LDAP_OPT_PROTOCOL_VERSION, $vers);
+      ldap_get_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $vers);
       if ($vers == -1) {
         watchdog('ldap', 'Could not get LDAP protocol version.', array(), WATCHDOG_ERROR);
         return;
@@ -147,28 +164,32 @@ class LDAPInterface {
         watchdog('ldap', 'Could not start TLS, only supported by LDAP v3.', array(), WATCHDOG_ERROR);
         return;
       }
-      else if (!function_exists('ldap_start_tls')) {
+      elseif (!function_exists('ldap_start_tls')) {
         watchdog('ldap', 'Could not start TLS. It does not seem to be supported by this PHP setup.', array(), WATCHDOG_ERROR);
         return;
       }
-      else if (!ldap_start_tls($con)) {
-        watchdog('ldap', 'Could not start TLS. (Error %errno: %error).', array('%errno' => ldap_errno($con), '%error' => ldap_error($con)), WATCHDOG_ERROR);
+      elseif (!ldap_start_tls($this->connection)) {
+        watchdog('ldap', 'Could not start TLS. (Error %errno: %error).', array('%errno' => ldap_errno($this->connection), '%error' => ldap_error($this->connection)), WATCHDOG_ERROR);
         return;
       }
     }
-    $this->connection = $con;
   }
 
   function connectAndBind($dn = '', $pass = '') {
     $this->initConnection();
 
-    $con = $this->connection;
-    if (!$this->bind($dn, $pass)) {
-      watchdog('ldap', 'LDAP Bind failure for user %user. Error %errno: %error', array('%user' => $dn, '%errno' => ldap_errno($con), '%error' => ldap_error($con)));
-      return NULL;
+    if ($this->connection) {
+      if (!$this->bind($dn, $pass)) {
+        watchdog('ldap', 'LDAP Bind failure for user %user. Error %errno: %error', array('%user' => $dn, '%errno' => ldap_errno($this->connection), '%error' => ldap_error($this->connection)));
+        return NULL;
+      }
+      return $this->connection;
+    }
+    else {
+      return $false;
     }
 
-    return $con;
+
   }
 
   function bind($dn, $pass) {
@@ -204,13 +225,20 @@ class LDAPInterface {
     }
     return $ret;
   }
-
-  // WARNING! WARNING! WARNING!
-  // This function returns its entries with lowercase attribute names.
-  // Don't blame me, blame PHP's own ldap_get_entries()
-  function retrieveAttributes($dn) {
+/**
+ * Retrieve all or some of the attributes for the ldap dn.
+ *
+ * WARNING! WARNING! WARNING!
+ * This function returns its entries with lowercase attribute names.
+ * Don't blame me, blame PHP's own ldap_get_entries()
+ *
+ * @param String $dn Required - The full dn to the object
+ * @param Array  $attributes Optional - an array of specific attributes to
+ *               retrieve.  See ldap_read.
+ */
+  function retrieveAttributes($dn, $attributes = array()) {
     set_error_handler(array('LDAPInterface', 'void_error_handler'));
-    $result = ldap_read($this->connection, $dn, 'objectClass=*');
+    $result = ldap_read($this->connection, $dn, 'objectClass=*', $attributes );
     $entries = ldap_get_entries($this->connection, $result);
     restore_error_handler();
 
@@ -218,7 +246,7 @@ class LDAPInterface {
   }
 
   function retrieveAttribute($dn, $attrname) {
-    $entries = $this->retrieveAttributes($dn);
+    $entries = $this->retrieveAttributes($dn, array($attrname));
     return isset($entries[strtolower($attrname)]) ? $entries[strtolower($attrname)][0] : NULL;
   }
 
@@ -245,6 +273,12 @@ class LDAPInterface {
           ldap_mod_del($this->connection, $dn, array($key => $old_value));
         }
       }
+      //Encodes password for use in Active Directory // http://drupal.org/node/339821
+      if ($key == "unicodePwd") {
+        $cur_val = "\"" . $cur_val . "\"";
+        $attributes[$key] = mb_convert_encoding($cur_val, "UTF-16LE");
+      }
+
       if (is_array ($cur_val)) {
         foreach ($cur_val as $mv_key => $mv_cur_val) {
           if ($mv_cur_val == '') {
@@ -256,7 +290,6 @@ class LDAPInterface {
         }
       }
     }
-
     return ldap_modify($this->connection, $dn, $attributes);
   }
 
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/includes/ldap.core.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/includes/ldap.core.inc
new file mode 100644
index 0000000..2bfde2a
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/includes/ldap.core.inc
@@ -0,0 +1,658 @@
+<?php
+
+/**
+ * @file
+ * The core functions that ldapauth supplies for submodules.  Will be included
+ * by default by ldapauth.
+ *
+ */
+
+//////////////////////////////////////////////////////////////////////////////
+// Server Information CRUD functions
+
+/**
+ * Retrieve server setting object by sid or machine_name
+ * ( menu load function too)
+ *
+ * @param Mixed $sid Either the sid number or the machine name
+ * @param boolean $reset  Cache is cleared if true.
+ * @return The server object or FALSE
+ */
+function ldapauth_server_load( $sid, $reset=FALSE ) {
+  static $servers = array();
+
+  if ( $reset ) {
+    $servers = array();
+  }
+  if ( isset($servers[$sid]) ) {
+    return $servers[$sid];
+  }
+
+  if ( is_numeric($sid) ) {
+    $where = "sid = %d";
+  }
+  else {
+    $where = "machine_name = '%s'";
+  }
+  $server = db_fetch_object(
+    db_query("SELECT * FROM {ldapauth} WHERE " . $where, $sid));
+  $servers[$sid] = $server;
+  return $server;
+}
+/**
+ * Retrieve server settings by human name.
+ *
+ * @param String $name The description name of the server.
+ * @return Object or FALSE if not found.
+ */
+function ldapauth_server_load_by_name( $name ) {
+  $server = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE name = '%s'", $name));
+  if ( ! $server ) {
+    return FALSE;
+  }
+  return $server;
+}
+/**
+ * Retrieve all servers from database.
+ *
+ * @param Boolean $reset Clear the static cache if TRUE
+ * @return An array of server objects ordered by weight with sid as key.
+ */
+function ldapauth_server_load_all( $reset=FALSE ) {
+  static $servers = array();
+  if ( $reset ) {
+    $servers = array();
+  }
+
+  if ( empty($servers) || $reset ) {
+    $results = db_query("SELECT * FROM {ldapauth} ORDER BY weight");
+    while ($server = db_fetch_object($results)) {
+      $servers[$server->sid] = $server;
+    }
+  }
+  return $servers;
+}
+/**
+ * Create/Update server settings... updates if $server->sid is set or not.
+ * Uses machine_name as the key field for features.
+ *
+ * @param Mixed $server Server settings to save as object or array
+ * @param Boolean $quiet If true, no success message will be displayed to user.
+ * @param Boolean $use_sid If true, use sid to update entry rather than machine name.
+ */
+function ldapauth_server_save( &$server, $quiet=FALSE, $use_sid=FALSE ) {
+  if ( is_array($server)) {
+    $server = (object)$server;
+    $array = TRUE;
+  }
+  else {
+    $array = FALSE;
+  }
+  if ( isset($server->sid ) ) {
+    $type = "updated";
+    if ( $use_sid ) {
+      $update = 'sid';
+    }
+    else {
+      $update = 'machine_name';
+    }
+  }
+  else {
+    $type = "added";
+    $update = array();
+  }
+  $params = array('%name' => $server->name, '%type' => $type);
+  if ($rc = drupal_write_record('ldapauth', $server, $update)) {
+    if ( ! $quiet ) {
+      drupal_set_message(t('Server settings for %name have been %type.', $params));
+    }
+    watchdog('ldapauth', 'LDAP Configuration %name has been %type.', $params);
+  }
+  else {
+    drupal_set_message(t('Failed to write the server settings for %name .', array('%name' => $server->name)), 'warning');
+  }
+  if ( $array ) {
+    $server = ( array ) $server;
+  }
+  return $rc;
+}
+/**
+ * Delete server settings
+ *
+ * @param Mixed $server A server object, array, or an integer sid.
+ * @param Boolean $quiet
+ */
+function ldapauth_server_delete( $server, $quiet=FALSE ) {
+  if ( is_numeric( $server ) ) {
+    $server = ldapauth_server_load($server);
+  }
+  elseif ( is_array($server)) {
+    $server = (object)$server;
+  }
+  if ( $server && isset($server->sid) ) {
+    ldapauth_userinfo_delete_by_sid($server);
+    db_query("DELETE FROM {ldapauth} WHERE sid = %d", $server->sid);
+    if ( ! $quiet ) {
+      drupal_set_message(t('LDAP Configuration %name has been deleted.', array('%name' => $server->name)));
+    }
+    watchdog('ldapauth', 'LDAP Configuration %name has been deleted.', array('%name' => $server->name));
+  }
+}
+//////////////////////////////////////////////////////////////////////////////
+// LDAP User Information CRUD functions
+
+/**
+ * Create / Update a record in the ldapauth_users table.
+ *
+ * @param Mixed $userinfo Object or Array containing record info.
+ */
+function ldapauth_userinfo_save( $userinfo ) {
+  if ( is_array($userinfo)) {
+    $userinfo = (object)$userinfo;
+    $array = TRUE;
+  }
+  else {
+    $array = FALSE;
+  }
+  if ( isset($userinfo->luid ) ) {
+    $update = 'luid';
+  }
+  if (!($rc = drupal_write_record('ldapauth_users', $userinfo, $update))) {
+    drupal_set_message(t('Failed to write the ldap user info for uid: %name .', array('%name' => $userinfo->uid)), 'warning');
+  }
+  if ( $array ) {
+    $userinfo = ( array ) $userinfo;
+  }
+  return $rc;
+}
+/**
+ * Load a ldapauth_user record
+ *
+ * @param unknown_type $luid
+ */
+function ldapauth_userinfo_load( $luid ) {
+  $userinfo = db_fetch_object(
+    db_query("SELECT * FROM {ldapauth_users} WHERE luid = '%s'", $luid));
+  return $userinfo;
+}
+/**
+ * Load a ldapauth_user record by puid
+ *
+ * @param String $puid The users puid (after convertion from binary if needed).
+ */
+function ldapauth_userinfo_load_by_puid( $puid ) {
+  $userinfo = db_fetch_object(
+    db_query("SELECT * FROM {ldapauth_users} WHERE puid = '%s'", $puid));
+  return $userinfo;
+}
+/**
+ * Load a ldapauth_user record by uid
+ *
+ * @param int $uid The user's uid
+ */
+function ldapauth_userinfo_load_by_uid( $uid ) {
+  $userinfo = db_fetch_object(
+    db_query("SELECT * FROM {ldapauth_users} WHERE uid = %d", $uid));
+  return $userinfo;
+}/**
+ * Delete a ldapauth_users record.
+ *
+ * @param Mixed $userinfo Either the luid or the full object to delete
+ */
+function ldapauth_userinfo_delete( $userinfo ) {
+  if ( is_numeric( $userinfo ) ) {
+    $userinfo = ldapauth_userinfo_load($userinfo);
+  }
+  elseif ( is_array($userinfo)) {
+    $userinfo = (object)$userinfo;
+  }
+  if ( $userinfo && isset($userinfo->luid) ) {
+    db_query("DELETE FROM {ldapauth_users} WHERE luid = %d", $userinfo->luid);
+  }
+}
+/**
+ * Clear all entries from {ldapauth_users} who match the given server id.
+ *
+ * @param Mixed $sid A server object or sid
+ */
+function ldapauth_userinfo_delete_by_sid( $server ) {
+  if ( isset($server->sid ) ) {
+    $sid = $server->sid;
+  }
+  else {
+    $sid = $server;
+  }
+  if ( is_numeric($sid)  ) {
+    db_query("DELETE FROM {ldapauth_users} WHERE sid = %d", $sid);
+  }
+}
+//////////////////////////////////////////////////////////////////////////////
+// Attribute search functions.
+/**
+ * get array of required attributes for an ldap query.
+ *
+ * The op parameter should be one of the LDAPAUTH_SYNC_CONTEXT* constants.
+ *
+ * @param string $op is operation being performed
+ * @param string $sid server id being used
+ */
+function ldapauth_attributes_needed($op, $sid = NULL, $reset=FALSE) {
+  static $attributes = array();
+  if ( $reset ) {
+    $attributes = array();
+  }
+  if (!isset($attributes[$sid][$op])) {
+    drupal_alter('ldap_attributes_needed', $attributes[$sid][$op], $op, $sid);
+    // attributes array needs to have no gaps of ldap_search(), ldap_read(), ldap_list() so apply array_values()
+    $attributes[$sid][$op] = array_values(array_unique($attributes[$sid][$op]));
+  }
+  return $attributes[$sid][$op];
+}
+//////////////////////////////////////////////////////////////////////////////
+// PUID Common functions
+/**
+ * Extracts the puid value from an ldap search result with binary handling
+ *
+ * @param Mixed $server The server object or sid
+ * @param The drupal user name
+ * @param Array $ldap_entry LDAP search or retrieveAttributes result.
+ */
+function ldapauth_extract_puid( $server, $name, $ldap_entry ) {
+  if ( is_numeric( $server )) {
+    $server = ldapauth_server_load($server);
+  }
+  // DO NOT CONVERT TO Drupal STRING FUNCTIONS AS CODER SUGGESTS...
+  // These are byte operations.
+  $puid = $ldap_entry[strtolower($server->puid_attr)][0];
+  if ( $puid && $server->binary_puid ) {
+    if (strlen($puid) == 16) {  // Assume a binary GUID ala MS
+      $hex_string = bin2hex($puid);
+      // (MS?) GUID are displayed with first three GUID parts as "big endian"
+      // Doing this so String value matches what other LDAP tool displays for AD.
+      $puid=strtoupper(substr( $hex_string, 6, 2) . substr( $hex_string, 4, 2) .
+        substr( $hex_string, 2, 2) . substr( $hex_string, 0, 2) . '-' .
+        substr( $hex_string, 10, 2) . substr( $hex_string, 8, 2) . '-' .
+        substr( $hex_string, 14, 2) . substr( $hex_string, 12, 2) . '-' .
+        substr( $hex_string, 16, 4) . '-' . substr( $hex_string, 20, 12));
+    }
+    else {
+      $puid = bin2hex($puid);
+    }
+  }
+  if ( empty($puid) ) {
+     // Give other modules a chance to create a puid if needed.
+     drupal_alter('ldap_user_puid', $puid, $name, $ldap_entry['dn'], $server->sid);
+  }
+  return $puid;
+}
+/**
+ * Create a "binary safe" LDAP search filter for finding objects from puid.
+ *
+ * @param Mixed $server Server object or sid
+ * @param String $puid The puid value from ldapauth_users
+ */
+function ldapauth_puid_filter( $server, $puid ) {
+  if ( is_numeric( $server )) {
+    $server = ldapauth_server_load($server);
+  }
+  $filter = $server->puid_attr . "=";
+  $match = '';
+  if ( $server->binary_puid ) {
+    // Is it a simple Hex string
+    if ( preg_match('/^[a-f0-9]+$/i', $puid ) ) {
+      for ( $i=0; $i < strlen($puid); $i=$i+2 ) {
+        $match .= '\\' . substr($puid, $i, 2);
+      }
+    }
+    elseif ( preg_match('/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i', $puid)) {
+      // Reconstruct proper "memory" order from GUID string.
+      $hex_string = str_replace('-', '', $puid);
+      $puid = substr( $hex_string, 6, 2) . substr( $hex_string, 4, 2) .
+        substr( $hex_string, 2, 2) . substr( $hex_string, 0, 2) .
+        substr( $hex_string, 10, 2) . substr( $hex_string, 8, 2) .
+        substr( $hex_string, 14, 2) . substr( $hex_string, 12, 2) .
+        substr( $hex_string, 16, 4) . substr( $hex_string, 20, 12);
+      for ( $i=0; $i < strlen($puid); $i=$i+2 ) {
+        $match .= '\\' . substr($puid, $i, 2);
+      }
+    }
+  }
+  else {
+    $match = $puid;
+  }
+  return $filter . $match;
+}
+/**
+ * Map an LDAP user to a Drupal user account if one exists.
+ *
+ * @param LDAPInterface $ldap An initialized LDAP server interface object.
+ * @param String $name The user name (from login form)
+ * @param String $dn The user's dn
+ * @param String $error An error message or '' if no errors.  NOTE: Errors NOT reported via watchdog
+ * @param String $puid Save an ldap query if the PUID is already known (e.g ldapsync)
+ *
+ * @return A user object, FALSE (user not found) or NULL (if error)
+ */
+function ldapauth_drupal_user_lookup( $ldap, $name, $dn, &$error, $puid=NULL ) {
+
+  $error = '';
+  if (!$ldap) {
+    $error = t('LDAPInterface not initialized in ldapauth_drupal_user_lookup!');
+    return NULL;
+  }
+
+  $sid = $ldap->getOption('sid');
+
+  // If a PUID attribute is set, then use this to map users
+  if ( $ldap->getOption('puid_attr')) {
+    if ( ! $puid ) {
+      $ldap_entry = ldapauth_user_lookup_by_dn($ldap, $dn, LDAPAUTH_SYNC_CONTEXT_AUTHENTICATE_DRUPAL_USER);
+      if ( empty($ldap_entry )) {
+        $error = t("Error looking up user in LDAP:  Supplied dn not found! sid=%sid dn=%dn", array('%sid' => $sid, '%dn' => $dn));
+        return NULL;
+      }
+      $puid = ldapauth_extract_puid($sid, $name, $ldap_entry);
+    }
+
+    // Try to get PUID to UID mapping.
+    if ( ! empty($puid) ) {
+      $user_info = ldapauth_userinfo_load_by_puid( $puid );
+      // Found matching ldapauth_users entry.  Return this users.
+      if ( isset($user_info->uid ) ) {
+        $account = user_load($user_info->uid);
+        $account->ldap_puid = $puid;
+        return $account;
+      }
+    }
+    else {
+      $error = t("LDAP user did not have required PUID attribute, %puid_attr! sid=%sid dn=%dn", array('%puid_attr' => $ldap->getOption('puid_attr'), '%sid' => $sid, '%dn' => $dn));
+      return NULL;
+    }
+
+    // Have PUID but no matching userinfo, then see if entry needs to be rebuilt.
+    // Most likely one of the following:
+    //   Converting from prePUID to PUID;
+    //   Changed PUID attribute; or
+    //   Server re-created with new sid.
+    // TODO: Make this configurable?
+    $drupal_name = ldapauth_drupal_user_name($name, $ldap, $dn);;
+    $account = user_load(array('name' => $drupal_name));
+    if ( ! $account ) {
+      return FALSE;
+    }
+    // Does the name map to an existing LDAP related account.
+    if ( isset($account->ldap_authentified) ) {
+      $user_info = ldapauth_userinfo_load_by_uid( $account->uid );
+      // No user with different PUID
+      if ( empty( $user_info )) {
+        // DNs match.
+        if ( drupal_strtolower($account->ldap_dn) == drupal_strtolower($dn)) {
+          $old_server = ldapauth_server_load($account->ldap_config);
+          // Do sids match or old sid does not exist
+          if ( $account->ldap_config == $sid || empty( $old_server )) {
+            $user_info = array(
+              'uid' => $account->uid,
+              'sid' => $sid,
+              'machine_name' => $ldap->getOption('machine_name'),
+              'dn' => $dn,
+              'puid' => $puid,
+            );
+            ldapauth_userinfo_save($user_info);
+            $account->ldap_puid = $puid;
+            return $account;
+          }
+        }
+      }
+      else {
+        $error = t('User, %name, already associated with a different LDAP user', array('%name' => $name));
+        return NULL;
+      }
+    }
+    // Return normal drupal account so login process can decide to map or not.
+    $account->ldap_puid = $puid;
+    return $account;
+  }
+  // Not using PUID so just use name.
+  else {
+    $drupal_name = ldapauth_drupal_user_name($name, $ldap, $dn);;
+    $account = user_load(array('name' => $drupal_name));
+
+    if ( ! $account ) {
+      return FALSE;
+    }
+    // Double check that ldap user matches this account.
+    if ( $account->ldap_authentified ) {
+      // Do DNs map
+      if ( drupal_strtolower($account->ldap_dn) == drupal_strtolower($dn)) {
+        $old_server = ldapauth_server_load($account->ldap_config);
+        // Do sids match or old sid does not exist
+        if ( $account->ldap_config == $sid || empty( $old_server )) {
+          $account->ldap_puid = $name;  // Default if puid attr not set.
+          return $account;
+        }
+      }
+      return FALSE;
+    }
+    $account->ldap_puid = $name;  // Default if puid attr not set.
+    return $account;
+  }
+}
+/**
+ * Create a new Drupal user from an LDAP user entry with checks to ensure that:
+ *
+ * The admin settings allow account creation
+ * The user name is unique.
+ * The e-mail is unique and not a reserved address.
+ * If PUID are used that the PUID is unique and not null.
+ *
+ * @param LDAPInterface $ldap An initialized LDAP server Interface object
+ * @param String $name The LDAP user name/login name.  If Null, user name will be extracted from attributes.
+ * @param Mixed $ldap_user The user's dn or and with the user's ldap attributes.
+ * @param String $error An error message or '' if no errors.  Errors also logged via watchdog.
+ * @return The new user object or FALSE if an error occured.
+ */
+function ldapauth_drupal_user_create( $ldap, $name, $ldap_user, &$error ) {
+
+  if ( is_string( $ldap_user ) ) {
+    $is_dn = TRUE;
+    $dn = $ldap_user;
+  }
+  elseif ( isset($ldap_user['dn'])) {
+    $is_dn = FALSE;
+    $dn = $ldap_user['dn'];
+  }
+  else { // Hmm invalid entry maybe should log this?
+    $error = t('Invalid LDAP information supplied!  Could not find dn.');
+    watchdog('ldapauth', 'Drupal user %name could not be created because the ldap_user parameter did not contain a valid dn.', array('%name' => $name), WATCHDOG_ERROR);
+    return FALSE;
+  }
+
+  $error = '';
+  // Has the admin turned of automatic account creation?
+  if (!variable_get('ldapauth_create_users', TRUE)) {
+    $error = t('Your account is not authorized to access this system.');
+    watchdog('ldapauth', 'The valid LDAP account %name was denied access because there was no matching Drupal account.', array('%name' => $name), WATCHDOG_ERROR);
+    return FALSE;
+  }
+
+  if ( $is_dn ) {
+    $ldap_user = ldapauth_user_lookup_by_dn($ldap, $dn, LDAPAUTH_SYNC_CONTEXT_AUTHENTICATE_DRUPAL_USER );
+  }
+
+  // Get drupal name from ldap uid name
+  if ( ! $name ) {
+    $name_attr = $ldap->getOption('user_attr') ? $ldap->getOption('user_attr') : LDAPAUTH_DEFAULT_USER_ATTR;
+    $name = isset($ldap_user[$name_attr][0]) ? $ldap_user[$name_attr][0] : (isset($ldap_user[drupal_strtolower($name_attr)][0]) ? $ldap_user[drupal_strtolower($name_attr)][0] : $name);
+  }
+  // Let other modules change this if needed.
+  $drupal_name = ldapauth_drupal_user_name($name, $ldap, $dn);
+  // Check for unique name probably already done but double check to be sure.
+  if ( user_load(array('name' => $drupal_name) ) ) {
+    watchdog('ldapauth', 'LDAP user with DN %dn has a naming conflict with a local Drupal user %name', array('%dn' => $dn, '%name' => $drupal_name), WATCHDOG_ERROR);
+    $error = t('Another user already exists in the system with the same login name. You should contact the system administrator in order to solve this conflict.');
+    return FALSE;
+  }
+
+
+  if ( $ldap_user) {
+    // If mail attribute is missing, set the name as mail.
+    $init = $mail = key_exists(($ldap->getOption('mail_attr') ? $ldap->getOption('mail_attr') : LDAPAUTH_DEFAULT_MAIL_ATTR), $ldap_user) ? $ldap_user[$ldap->getOption('mail_attr')][0] : $name;
+
+    // Check that the e-mail is not denied.
+    if (drupal_is_denied('mail', $mail)) {
+      $error = t('The name %name is registered using a reserved e-mail address and therefore could not be logged in.', array('%name' => $name));
+      return FALSE;
+    }
+
+    // Check that e-mail is unique
+    if ( $existing_user_by_email = user_load(array('mail' => $mail))) {
+      $error = t('The e-mail address, %mail, associated with this account is already in use.', array('%mail' => $mail));
+      watchdog('ldapauth', 'The valid LDAP account %name was denied access their email address, %mail, was already in use.', array('%name' => $name, '%mail' => $mail), WATCHDOG_ERROR);
+      return FALSE;
+    }
+
+    $sid = $ldap->getOption('sid');
+
+    // Validate / Create PUID entry.
+    if ( $ldap->getOption('puid_attr') ) {
+      $puid = ldapauth_extract_puid($sid, $name, $ldap_user);
+      if ( empty($puid) ) {
+        // Give other modules a chance to create a puid if needed.
+        drupal_alter('ldap_user_puid', $puid, $name, $dn, $sid);
+      }
+      if ( empty($puid) ) {
+        $error = t("This LDAP user entry was not configured properly (No PUID).  Please contact your system administrator.");
+        watchdog('ldapauth', 'LDAP user did not have required PUID attribute! ldap_attr=%attr sid=%sid dn=%dn',
+          array(
+            '%attr' => $ldap->getOption('puid_attr'),
+            '%sid' => $sid,
+            '%dn' => $dn
+          ),
+          WATCHDOG_ERROR);
+        return FALSE;
+      }
+      if ( ldapauth_userinfo_load_by_puid( $puid ) ) {
+        $error = t("This LDAP user entry was not configured properly (Duplicate PUID).  Please contact your system administrator.");
+        watchdog('ldapauth', 'A duplicate PUID was found! attr=%attr sid=%sid dn=%dn',
+          array(
+            '%attr' => $ldap->getOption('puid_attr'),
+            '%sid' => $sid,
+            '%dn' => $dn
+          ),
+          WATCHDOG_ERROR);
+        return FALSE;
+      };
+    }
+    else {
+      $puid = $name; // default to $name for PUID.
+    }
+
+    // Use name as is set in the LDAP server.
+    $name_attr = $ldap->getOption('user_attr') ? $ldap->getOption('user_attr') : LDAPAUTH_DEFAULT_USER_ATTR;
+    $name_new = isset($ldap_user[$name_attr][0]) ? $ldap_user[$name_attr][0] : (isset($ldap_user[drupal_strtolower($name_attr)][0]) ? $ldap_user[drupal_strtolower($name_attr)][0] : $name);
+    // Unless another module has altered it.
+    if ( $drupal_name != $name ) {
+      $name_new = $drupal_name;
+    }
+    // Generate a random drupal password. LDAP password will be used anyways.
+    $pass_new = (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_EXCLUSIVED || !LDAPAUTH_SYNC_PASSWORDS) ? user_password(20) : $pass;
+
+    $new_user = array(
+      'name' => $name_new,
+      'pass' => $pass_new,
+      'mail' => $mail,
+      'init' => $init,
+      'status' => 1,
+      'authname_ldapauth' => $name,
+      'ldap_authentified' => TRUE,
+      'ldap_dn' => $ldap_user['dn'],
+      'ldap_config' => $ldap->getOption('sid'),
+      'ldap_name' => $name,
+    );
+    $account = user_save('', $new_user);
+
+    // Save ldapauth_users info.
+    $user_info = array(
+      'uid' => $account->uid,
+      'sid' => $sid,
+      'machine_name' => $ldap->getOption('machine_name'),
+      'dn' => $dn,
+      'puid' => $puid,
+    );
+    ldapauth_userinfo_save($user_info);
+    watchdog('ldapauth', 'New external user %name created from the LDAP server %server.', array('%name' => $name, '%server' => $ldap->getOption('name')), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
+    // Invoke post user creation hook.
+    module_invoke_all('ldapauth_create', $account);
+    return $account;
+  }
+  $error = t("Could not find dn entry! dn=%dn", array('%dn' => $dn));
+  return FALSE;
+}
+/**
+ * Retrieves required attributes for specific user and operation.
+ *
+ * @param LDAPInterface $ldap An initialized LDAP server Interface object
+ * @param String $dn The LDAP user's dn
+ * @param String $op The type of load operation (see LDAPAUTH_SYNC_CONTEXT* constants)
+ * @param boolean $reset If true the cache will be cleared.
+ * @return An array of the user's ldap attributes as defined by the operation.
+ */
+function ldapauth_user_lookup_by_dn( $ldap, $dn, $op, $reset=FALSE ) {
+  static $ldap_user_cache = array();;
+
+  if ( $reset ) {
+    $ldap_user_cache = array();
+  }
+
+  if ( ! $ldap ) {  // Allow cache resets without lookup.
+    return FALSE;
+  }
+  $sid = $ldap->getOption('sid');
+  if ( ! isset( $ldap_user_cache[$op][$sid][$dn]) ) {
+    $attrs = ldapauth_attributes_needed($op, $ldap->getOption('sid'));
+    $ldap_user_cache[$op][$sid][$dn] = $ldap->retrieveAttributes($dn, $attrs );
+  }
+  return $ldap_user_cache[$op][$sid][$dn];
+}
+/**
+ * Allow modules to do site dependent login form name to drupal account name
+ * mapping.
+ *
+ * Calls the hook_ldap_drupal_user_name_alter function(s) once per name.
+ *
+ * @param String $name Name entered on login form (case insensitive match to user attr).
+ * @param LDAPInterface $ldap Fully initialized LDAP server interface object
+ * @param boolean $reset If true the cache will be cleared.
+ * @param String $dn The DN that has been authenticated with LDAP.
+ */
+function ldapauth_drupal_user_name( $name, $ldap, $dn, $reset=FALSE ) {
+  static $drupal_names = array();
+
+  if ( $reset ) {
+    $drupal_name = array();
+  }
+  if ( ! $name ) {  // Allow reset with no lookup.
+    return FALSE;
+  }
+
+  if ( ! isset($drupal_names[$name])) {
+    drupal_alter('ldap_drupal_user_name', $name, $ldap, $dn);
+    $drupal_names[$name] = $name;
+  }
+  return $drupal_names[$name];
+}
+/**
+ * Allows other modules (like ldapgroups) to deny an ldap user access to the
+ * server.
+ *
+ * @param LDAPInterface $ldap Fully initialized LDAP server interface object
+ * @param String $name The ldap user name (from login form)
+ * @param String $dn The DN for the authenticated user
+ * @param Object $account The local drupal account object or FALSE if none found.
+ * @return TRUE is user is to be denied access.
+ */
+function ldapauth_user_denied( $ldap, $name, $dn, $account ) {
+  $denied = FALSE;
+  drupal_alter('ldap_user_deny', $denied, $ldap, $name, $dn, $account );
+  return $denied;
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.admin.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.admin.inc
index 3a2cbc6..731d5e4 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.admin.inc
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.admin.inc
@@ -1,5 +1,4 @@
 <?php
-// $Id: ldapauth.admin.inc,v 1.6 2009/10/27 14:29:16 miglius Exp $
 
 /**
  * @file
@@ -24,6 +23,11 @@ function ldapauth_admin_settings() {
     LDAPAUTH_CONFLICT_LOG => t('Disallow login and log the conflict'),
     LDAPAUTH_CONFLICT_RESOLVE => t('Associate local account with the LDAP entry')
   );
+  $options_username_field = array(
+    LDAPAUTH_USERNAME_FIELD_NO => t('Do nothing'),
+    LDAPAUTH_USERNAME_FIELD_REMOVE => t('Remove username field from form'),
+    LDAPAUTH_USERNAME_FIELD_DISABLE => t('Disable username field on form'),
+  );
 
   $form['system-options'] = array(
     '#type' => 'fieldset',
@@ -35,7 +39,7 @@ function ldapauth_admin_settings() {
   $form['system-options']['ldapauth_login_process'] = array(
     '#type' => 'radios',
     '#title' => t('Choose authentication mode'),
-    '#description' => t('Pick the mode based on the types of user accounts and other configuration decisions. If <i>LDAP directory only</i> option is activated some UI modications will be applied.'),
+    '#description' => t('Pick the mode based on the types of user accounts and other configuration decisions. If <i>LDAP directory only</i> option is activated some UI modifications will be applied.'),
     '#default_value' => LDAPAUTH_LOGIN_PROCESS,
     '#options' => $options_login_process,
     '#required' => TRUE,
@@ -65,7 +69,13 @@ function ldapauth_admin_settings() {
     '#type' => 'checkbox',
     '#title' => t('Sync LDAP password with the Drupal password'),
     '#default_value' => LDAPAUTH_SYNC_PASSWORDS,
-    '#description' => t('If checked, then LDAP and Drupal passwords will be syncronized. This might be useful if some other modules need to authenticate against the user password hash stored in Drupal and works only in Mixed mode. It might introduce security issues in the Mixed mode since after deletion of the LDAP account user still be able to login to Drupal with his password. If unsure, leave this unchecked.'),
+    '#description' => t('If checked, then LDAP and Drupal passwords will be syncronized. This might be useful if some other modules need to authenticate against the user password hash stored in Drupal and works only in Mixed mode. It might introduce security issues in the Mixed mode since after the deletion of the LDAP account, the Drupal user will still exist and may be able to login to Drupal with his password if ldapauth is disabled. If unsure, leave this unchecked.'),
+  );
+  $form['security-options']['ldapauth_create_users'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Create new Drupal user if not present'),
+    '#default_value' => variable_get('ldapauth_create_users', TRUE),
+    '#description' => t('If checked, then LDAP will create a new Drupal user against the user information supplied by the user authenticated by LDAP. If not checked only the already available users will be authenticated.'),
   );
 
   $form['ldap-ui'] = array(
@@ -75,11 +85,19 @@ function ldapauth_admin_settings() {
     '#collapsible' => TRUE,
     '#collapsed' => TRUE,
   );
+  $form['ldap-ui']['ldapauth_alter_username_field'] = array(
+    '#type' => 'radios',
+    '#title' => t('Alter username field on user edit form'),
+    '#description' => t('Remove or disable username field from user edit form for LDAP authenticated users, even admin users.'),
+    '#default_value' => LDAPAUTH_ALTER_USERNAME_FIELD,
+    '#options' => $options_username_field,
+    '#required' => TRUE,
+  );
   $form['ldap-ui']['ldapauth_disable_pass_change'] = array(
     '#type' => 'checkbox',
     '#title' => t('Remove password change fields from user edit form'),
     '#default_value' => LDAPAUTH_DISABLE_PASS_CHANGE,
-    '#description' => t('<strong>NOTE:</strong> Request new password feature will be disabled for all users even for the user with uid 1.'),
+    '#description' => t('If left unchecked, ldap users will receive warning that they may not request new password here.  <strong>NOTE:</strong> Request new password feature will be disabled for all users even for the user with uid 1.'),
   );
   $options_email_field = array(
     LDAPAUTH_EMAIL_FIELD_NO => t('Do nothing'),
@@ -120,6 +138,8 @@ function ldapauth_admin_settings_submit($form, &$form_state) {
       variable_set('ldapauth_sync_passwords', $values['ldapauth_sync_passwords']);
       variable_set('ldapauth_disable_pass_change', $values['ldapauth_disable_pass_change']);
       variable_set('ldapauth_alter_email_field', $values['ldapauth_alter_email_field']);
+      variable_set('ldapauth_create_users', $values['ldapauth_create_users']);
+      variable_set('ldapauth_alter_username_field', $values['ldapauth_alter_username_field']);
 
       drupal_set_message(t('The configuration options have been saved.'));
       break;
@@ -130,7 +150,8 @@ function ldapauth_admin_settings_submit($form, &$form_state) {
       variable_del('ldapauth_sync_passwords');
       variable_del('ldapauth_disable_pass_change');
       variable_del('ldapauth_alter_email_field');
-
+      variable_del('ldapauth_create_users');
+      variable_del('ldapauth_alter_username_field');
       drupal_set_message(t('The configuration options have been reset to their default values.'));
       break;
   }
@@ -203,27 +224,36 @@ function ldapauth_admin_form(&$form_state, $op = NULL, $sid = NULL) {
   drupal_add_js(drupal_get_path('module', 'ldapauth') .'/ldapauth.admin.js');
 
   if ($op == "edit" && $sid) {
-    $edit = db_fetch_array(db_query("SELECT * FROM {ldapauth} WHERE sid = %d", $sid));
+    $edit = (array) ldapauth_server_load( $sid );
     $form['sid'] = array(
       '#type' => 'hidden',
       '#value' => $sid,
     );
+    $form['original_server'] = array(
+      '#type' => 'value',
+      '#value' => ldapauth_server_load( $sid ),
+    );
+    $name_classes = "ldapauth-name-update";
   }
   else {
     $edit = array(
       'name' => '',
+      'machine_name' => '',
       'server' => '',
       'port' => '389',
       'tls' => 0,
-      'encrypted' => 0,
+      'enc_type' => 0,
       'basedn' => '',
       'user_attr' => LDAPAUTH_DEFAULT_USER_ATTR,
       'mail_attr' => LDAPAUTH_DEFAULT_MAIL_ATTR,
+      'puid_attr' => '',
+      'binary_puid' => 0,
       'binddn' => '',
       'bindpw' => FALSE,
       'login_php' => '',
       'filter_php' => '',
     );
+    $name_classes = "ldapauth-name";
   }
 
   $form['server-settings'] = array(
@@ -240,14 +270,25 @@ function ldapauth_admin_form(&$form_state, $op = NULL, $sid = NULL) {
     '#size' => 50,
     '#maxlength' => 255,
     '#required' => TRUE,
+    '#attributes' => array('class' => $name_classes),
+  );
+  $form['server-settings']['machine_name'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Machine-readable name'),
+    '#description' => t('Example: primary_domain_server') . '<br/>' . t('May only contain lowercase letters, numbers and underscores. <strong>Try to avoid conflicts with the names of existing Drupal projects.</strong>'),
+    '#required' => TRUE,
+    '#default_value' => $edit['machine_name'],
+    '#attributes' => array('class' => 'ldapauth-machine-name'),
+    '#element_validate' => array('ldapauth_admin_form_validate_field'),
   );
+
   $form['server-settings']['server'] = array(
     '#type' => 'textfield',
     '#title' => t('LDAP server'),
     '#default_value' => $edit['server'],
     '#size' => 50,
     '#maxlength' => 255,
-    '#description' => t('The domain name or IP address of your LDAP Server.'),
+    '#description' => t('The domain name or IP address of your LDAP Server. Prefix the hostname or IP address with ldaps:// if the LDAP server connection uses SSL.'),
     '#required' => TRUE,
   );
   $form['server-settings']['port'] = array(
@@ -256,7 +297,7 @@ function ldapauth_admin_form(&$form_state, $op = NULL, $sid = NULL) {
     '#default_value' => $edit['port'],
     '#size' => 5,
     '#maxlength' => 5,
-    '#description' => t('The TCP/IP port on the above server which accepts LDAP connections. Must be an integer.'),
+    '#description' => t('The TCP/IP port on the above server which accepts LDAP connections. Must be an integer. Standard ports are 389 and 636(SSL).'),
   );
   $form['server-settings']['tls'] = array(
     '#type' => 'checkbox',
@@ -264,11 +305,12 @@ function ldapauth_admin_form(&$form_state, $op = NULL, $sid = NULL) {
     '#default_value' => $edit['tls'],
     '#description' => t('Secure the connection between the Drupal and the LDAP servers using TLS.<br /><em>Note: To use START-TLS, you must set the LDAP Port to 389.</em>'),
   );
-  $form['server-settings']['encrypted'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Store passwords in encrypted form'),
-    '#default_value' => $edit['encrypted'],
-    '#description' => t('Secure the password in LDAP by storing it MD5 encrypted (use with care, as some LDAP directories may do this automatically, what would cause logins problems).'),
+  $form['server-settings']['enc_type'] = array(
+    '#type' => 'select',
+    '#options' => valid_enc_types(),
+    '#title' => t('LDAP password encryption type'),
+    '#default_value' => $edit['enc_type'],
+    '#description' => t('This lists which type of Standard LDAP encryption should be used. Use with care as some LDAP directories may do this automatically, what would cause login issues. If unsure, use cleartext.'),
   );
 
   $form['login-procedure'] = array(
@@ -301,13 +343,27 @@ function ldapauth_admin_form(&$form_state, $op = NULL, $sid = NULL) {
     '#maxlength' => 255,
     '#description' => t('The attribute that holds the users\' email address. (eg. <em style="font-style: normal; padding: 1px 3px; border: 1px solid #8888CC; background-color: #DDDDFF">mail</em>).'),
   );
+  $form['login-procedure']['puid_attr'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Persistent and Unique User Id attribute'),
+    '#default_value' => $edit['puid_attr'],
+    '#size' => 30,
+    '#maxlength' => 255,
+    '#description' => t("In some LDAPs, a user's DN, CN, or mail may change when a user's name changes or for other reasons. In order to avoid creation of multiple accounts and definitively map ldap entries to Drupal users, you can enter an attribute that will be persistent and unique across LDAP changes, e.g. employeeNumber, entryUUID, objectGUID, and the like. If no such attribute exists, just leave blank."),
+  );
+  $form['login-procedure']['binary_puid'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('PUID is binary'),
+    '#default_value' => $edit['binary_puid'],
+    '#description' => t("Some attributes that can be used for PUIDs are binary and require special handing, e.g. objectGUID.  Check this if the puid attribute is binary."),
+  );
   $form['login-procedure']['login_php'] = array(
     '#type' => 'textarea',
     '#title' => t('PHP to transform login name'),
     '#default_value' => $edit['login_php'],
     '#cols' => 25,
     '#rows' => 5,
-    '#description' => t('Enter PHP to transform login name before it is sent to LDAP for authentication. Careful, bad PHP code here will break your site. If left empty, no name transformation will be done. Change following example code to enable transformation:<br /><code>return $name;</code>'),
+    '#description' => check_plain(t('Enter PHP to transform login name before it is sent to LDAP for authentication. Careful, bad PHP code here will break your site. If left empty, no name transformation will be done. Change following example code to enable transformation:<br /><code>return $name;</code>')),
   );
   $form['login-procedure']['filter_php'] = array(
     '#type' => 'textarea',
@@ -315,7 +371,7 @@ function ldapauth_admin_form(&$form_state, $op = NULL, $sid = NULL) {
     '#default_value' => $edit['filter_php'],
     '#cols' => 25,
     '#rows' => 5,
-    '#description' => t('Enter PHP to filter users which are allowed to login based on their LDAP data. Careful, bad PHP code here will break your site. If left empty, no filtering will be done. The code should return TRUE to allow authentication. Following example shows how to disallow users without their homeDirectory set:<br /><code>return isset($ldap[\'homeDirectory\']) && isset($ldap[\'homedirectory\'][0]);</code>'),
+    '#description' => check_plain(t('Enter PHP to filter users which are allowed to login based on their LDAP data. Careful, bad PHP code here will break your site. If left empty, no filtering will be done. The code should return TRUE to allow authentication. Following example shows how to disallow users without their homeDirectory set:<br /><code>return isset($ldap[\'homeDirectory\']) && isset($ldap[\'homedirectory\'][0]);</code>')),
   );
 
   $form['advanced'] = array(
@@ -377,6 +433,9 @@ function ldapauth_admin_form_validate($form, &$form_state) {
     if (db_fetch_object(db_query("SELECT name FROM {ldapauth} WHERE name = '%s'", $values['name']))) {
       form_set_error('name', t('An LDAP config with the  name %name already exists.', array('%name' => $values['name'])));
     }
+    if (db_fetch_object(db_query("SELECT machine_name FROM {ldapauth} WHERE machine_name = '%s'", $values['machine_name']))) {
+      form_set_error('name', t('An LDAP config with the machine name %name already exists.', array('%name' => $values['machine_name'])));
+    }
   }
   if (!is_numeric($values['port'])) {
     form_set_error('port', t('The TCP/IP port must be an integer.'));
@@ -391,24 +450,43 @@ function ldapauth_admin_form_submit($form, &$form_state) {
   $values = $form_state['values'];
   switch ($op) {
     case t('Save configuration'):
-      if (!isset($values['sid'])) {
-        db_query("INSERT INTO {ldapauth} (name, status, server, port, tls, encrypted, basedn, user_attr, mail_attr, binddn, bindpw, login_php, filter_php) VALUES ('%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s')", $values['name'], 1, $values['server'], $values['port'], $values['tls'], $values['encrypted'], $values['basedn'], trim($values['user_attr']), trim($values['mail_attr']), $values['binddn'], $values['bindpw'], trim($values['login_php']), trim($values['filter_php']));
-        drupal_set_message(t('LDAP configuration %name has been added.', array('%name' => $values['name'])));
-        watchdog('ldapauth', 'LDAP configuration %name has been added.', array('%name' => $values['name']));
-      }
-      else {
-        if (isset($values['bindpw_clear'])) {
-          db_query("UPDATE {ldapauth} SET name = '%s', server = '%s', port = %d, tls = %d, encrypted = %d, basedn = '%s', user_attr = '%s', mail_attr = '%s', login_php = '%s', filter_php = '%s' WHERE sid = %d", $values['name'], $values['server'], $values['port'], $values['tls'], $values['encrypted'], $values['basedn'], trim($values['user_attr']), trim($values['mail_attr']), trim($values['login_php']), trim($values['filter_php']), $values['sid']);
-          if ($values['bindpw_clear']) {
-            db_query("UPDATE {ldapauth} SET bindpw = '' WHERE sid = %d", $values['sid']);
-          }
+      $server = array(
+        'name' => $values['name'],
+        'machine_name' => $values['machine_name'],
+        'status' => 1,
+        'server' => $values['server'],
+        'port' => $values['port'],
+        'tls' => $values['tls'],
+        'enc_type' => $values['enc_type'],
+        'basedn' => $values['basedn'],
+        'user_attr' => trim($values['user_attr']),
+        'mail_attr' => trim($values['mail_attr']),
+        'puid_attr' => trim($values['puid_attr']),
+        'binary_puid' => trim($values['binary_puid']),
+        'binddn' => $values['binddn'],
+        'bindpw' => $values['bindpw'],
+        'login_php' => trim($values['login_php']),
+        'filter_php' => trim($values['filter_php']),
+      );
+      if ( isset($values['sid'])) {
+        $old_server = $values['original_server'];
+        $server['sid'] = $values['sid'];
+
+        // If machine name has changed, update ldapauth_users values.
+        if ( $old_server->machine_name != $server['machine_name'] ) {
+          db_query("UPDATE {ldapauth_users SET machine_name='%s' WHERE sid = %d", $server['machine_name'], $server['sid']);
         }
-        else {
-          db_query("UPDATE {ldapauth} SET name = '%s', server = '%s', port = %d, tls = %d, encrypted = %d, basedn = '%s', user_attr = '%s', mail_attr = '%s', binddn = '%s', bindpw = '%s', login_php = '%s', filter_php = '%s' WHERE sid = %d", $values['name'], $values['server'], $values['port'], $values['tls'], $values['encrypted'], $values['basedn'], trim($values['user_attr']), trim($values['mail_attr']), $values['binddn'], $values['bindpw'], trim($values['login_php']), trim($values['filter_php']), $values['sid']);
+
+        // If puid attr has changed, clear out old values.
+        if ( $old_server->puid_attr != $server['puid_attr'] ) {
+          ldapauth_userinfo_delete_by_sid($server['sid']);
+          drupal_set_message(t("NOTICE: The PUID info for current users were cleared because PUID Attribute changed.  You can either let this information be rebuild as users log in or use ldapsync to rebuild."), 'warning');
         }
-        drupal_set_message(t('LDAP Configuration %name has been updated.', array('%name' => $values['name'])));
-        watchdog('ldapauth', 'LDAP Configuration %name has been updated.', array('%name' => $values['name']));
       }
+      if ( ! empty($values['bindpw_clear'])) {
+        $server['bindpw'] = '';
+      }
+      ldapauth_server_save($server, FALSE, TRUE);
 
       $form_state['redirect'] = 'admin/settings/ldap/ldapauth/list';
       break;
@@ -542,9 +620,7 @@ function ldapauth_admin_delete(&$form_state, $sid) {
 function ldapauth_admin_delete_submit($form, &$form_state) {
   $values = $form_state['values'];
   if ($values['confirm'] && $values['sid']) {
-    db_query("DELETE FROM {ldapauth} WHERE sid = %d", $values['sid']);
-    drupal_set_message(t('LDAP Configuration %name has been deleted.', array('%name' => $values['name'])));
-    watchdog('ldapauth', 'LDAP Configuration %name has been deleted.', array('%name' => $values['name']));
+    ldapauth_server_delete($values['sid']);
   }
   drupal_goto('admin/settings/ldap/ldapauth/list');
 }
@@ -560,6 +636,46 @@ function ldapauth_admin_menu_block_page() {
 }
 
 /**
+ * Returns an array of valid encryption types.
+ *
+ *  *Most of the code here is from phpLDAPadmin.
+ */
+function valid_enc_types() {
+
+  // Clear Text
+  $valid_types[0] = t('Clear');
+
+  // Crypt + Salted Crypt
+  $valid_types[2] = t('Crypt');
+  $valid_types[3] = t('Salted Crypt');
+
+  // Extended DES
+  if ( defined( 'CRYPT_EXT_DES' ) || CRYPT_EXT_DES == 1 )
+    $valid_types[4] = t('Extended DES');
+
+  // MD5Crypt
+  if ( defined( 'CRYPT_MD5' ) || CRYPT_MD5 == 1 )
+    $valid_types[5] = t('MD5Crypt');
+
+  // Blowfish
+  if ( defined( 'CRYPT_BLOWFISH' ) || CRYPT_BLOWFISH == 1 )
+    $valid_types[6] = t('Blowfish');
+
+  // MD5
+  $valid_types[1] = t('MD5');
+
+  // SMD5 + SHA +  SSHA
+  if (function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) {
+    $valid_types[7] = t('Salted MD5');
+    $valid_types[8] = t('SHA');
+    $valid_types[9] = t('Salted SHA');
+  }
+
+  return $valid_types;
+}
+
+
+/**
  * Implements the AJAX server test.
  *
  * @param $sid
@@ -589,4 +705,144 @@ function _ldapauth_ajax_test($sid) {
   drupal_json($_ldapauth_ldap->connect($binddn, $bindpw) ? array('status' => 1, 'message' => t('Authentication with the LDAP server succeeded.')) : array('status' => 0, 'message' => t('Authentication with the LDAP server failed.')));
   exit;
 }
-
+/**
+ * Export server settings form.
+ *
+ * @param $sid
+ *   The server id.
+ */
+function ldapauth_admin_export_form($form_state, $sid) {
+  drupal_set_title(t('Export setting for server %description',
+    array('%description' => $sid->name)));
+
+  // Get export code with Ctools.
+  ctools_include('export');
+
+  $export = ctools_export_object('ldapauth', $sid);
+  //              $ldapserver->sid   =    ' 1  '    ;
+//  preg_replace('/\$ldapserver->sid\s*=\s*\'\d+\'\s*\;\s*\n/', '', $export);
+  $export = "<?php\n{$export}return serialize(\$ldapserver);\n?>";
+  $lines = substr_count($export, "\n");;
+
+  // Create the export code textarea.
+  $form = array(
+    'info' => array(
+      '#type' => 'markup',
+      '#value' => t('Copy the export text below and paste it into another ' .
+        'ldapauth site using the import server tab.'),
+    ),
+    'export' => array(
+      '#type' => 'textarea',
+      '#title' => t('Server settings'),
+      '#rows' => $lines,
+      '#default_value' => $export,
+    ),
+  );
+  return $form;
+}
+/**
+ * Import server settings form .
+ */
+function ldapauth_admin_import_form($form_state) {
+  $form = array(
+    'info' => array(
+      '#type' => 'markup',
+      '#value' => '<p>' .
+        t('Paste the text from the export a server option here ' .
+          'to create a <b>new</b> server with the same options. ') .
+        '</p><p>' .
+        t('Notes:') .
+        '<ul><li>' .
+        t('The imported server name can not duplicate any existing server name') .
+        '</li><li>' .
+        t('If the ldapdata or ldapgroups modules were enabled on ' .
+          'the source server, they will need to be enabled on this server.') .
+        '</li><li>' .
+        t('If this server config is replacing an existing server config, ' .
+          'there may be user data issues. Users may be marked with the old ' .
+          'database sid value rather than the imported value.') .
+        '</li></ul></p>'
+    ),
+    'import' => array(
+      '#type' => 'textarea',
+      '#rows' => 20,
+    ),
+    'submit' => array(
+      '#type' => 'submit',
+      '#value' => t('Import')
+    ),
+  );
+  return $form;
+}
+/**
+ * Validate a server settings import.
+ */
+function ldapauth_admin_import_form_validate($form, &$form_state) {
+  // Run the import code, which should return a serialized $preset object.
+  $ldapserver =  unserialize(drupal_eval($form_state['values']['import']));
+  if (empty($ldapserver) || !is_object($ldapserver) || empty($ldapserver->name)) {
+    form_set_error('import', t('The submitted preset code could not be interperated.'));
+  }
+  elseif ( isset($ldapserver->sid) ) {
+    form_set_error('import', t('Imported server can not have an sid field value,'));
+  }
+  elseif (ldapauth_server_load_by_name($ldapserver->name)) {
+    form_set_error('import', t('A server with the name, @server already exists.',
+      array('@server' => $ldapserver->name)));
+  }
+  elseif (ldapauth_server_load($ldapserver->machine_name)) {
+    form_set_error('import', t('A server with the machine name, @server already exists.',
+      array('@server' => $ldapserver->machine_name)));
+  }
+  else {
+    // Pass the parsed object on to the submit handler.
+    $form_state['values']['import_parsed'] = $ldapserver;
+  }
+}
+/**
+ * Submit handler to import server settings.
+ */
+function ldapauth_admin_import_form_submit($form, &$form_state) {
+  $server = (array) $form_state['values']['import_parsed'];
+  ldapauth_server_save($server);
+  $form_state['redirect'] = 'admin/settings/ldap/ldapauth';
+}
+/**
+ * Validation for machine name field.
+ */
+function ldapauth_admin_form_validate_field($element, &$form_state) {
+  switch ($element['#name']) {
+    case 'machine_name':
+      if (!preg_match('!^[a-z0-9_]+$!', $element['#value'])) {
+        form_error($element, t('The machine-readable name must contain only lowercase letters, numbers, and underscores.'));
+      }
+      // If user is filling out the feature name for the first time and uses
+      // the name of an existing module throw an error.
+      elseif (empty($element['#default_value']) && ldapauth_server_load($element['#value'])) {
+        form_error($element, t('A server with the machine_name, @name, already exists on your site. Please choose a different name.', array('@name' => $element['#value'])));
+      }
+      break;
+  }
+}
+/**
+ * Page callback function to convert a user from an LDAP authenticated user to
+ * a normal drupal user.
+ *
+ * @param unknown_type $account
+ */
+function ldapauth_user_to_local_user( $account ) {
+  if ( $account->ldap_authentified ) {
+    $data = array(
+      'ldap_dn' => NULL,
+      'ldap_config' => NULL,
+      'ldap_name' => NULL,
+      'ldap_authentified' => NULL,
+    );
+    $userinfo = ldapauth_userinfo_load_by_uid($account->uid);
+    ldapauth_userinfo_delete($userinfo);
+    db_query("DELETE FROM {authmap} WHERE uid = %d AND module = 'ldapauth'", $account->uid);
+    user_save($account, $data);
+    drupal_set_message(t('User, @name, converted from an LDAP authenticated user to a local Drupal user.', array('@name' => $account->name)));
+    }
+  drupal_goto( 'user/' . $account->uid );
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.admin.js b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.admin.js
index dcf122e..f73a829 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.admin.js
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.admin.js
@@ -1,4 +1,3 @@
-// $Id: ldapauth.admin.js,v 1.1 2009/07/28 14:03:05 miglius Exp $
 
 /**
  * Behaviours are bound to the Drupal namespace.
@@ -18,5 +17,32 @@ Drupal.behaviors.ldapauth = function(context) {
       }, "json");
     return false;
   });
-}
+  // Server edit/create form machine_name JS
+  $('.ldapauth-name:not(.processed)').each(function() {
+    $('.ldapauth-name')
+      .addClass('processed')
+      .after(' <small class="ldapauth-machine-name-suffix"> </small>');
+    if ($('.ldapauth-machine-name').val() === $('.ldapauth-name').val().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/_+/g, '_') || $('.ldapauth-machine-name').val() === '') {
+      $('.ldapauth-machine-name').parents('.form-item').hide();
+      $('.ldapauth-name').bind('keyup change', function() {
+        var machine = $(this).val().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/_+/g, '_');
+        if (machine !== '_' && machine !== '') {
+          $('.ldapauth-machine-name').val(machine);
+          $('.ldapauth-machine-name-suffix').empty().append(' Machine name: ' + machine + ' [').append($('<a href="#">'+ Drupal.t('Edit') +'</a>').click(function() {
+            $('.ldapauth-machine-name').parents('.form-item').show();
+            $('.ldapauth-machine-name-suffix').hide();
+            $('.ldapauth-name').unbind('keyup');
+            return false;
+          })).append(']');
+        }
+        else {
+          $('.ldapauth-machine-name').val(machine);
+          $('.ldapauth-machine-name-suffix').text('');
+        }
+      });
+      $('.ldapauth-name').keyup();
+    }
+  });
+  
+};
 
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.api.php b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.api.php
new file mode 100644
index 0000000..7b113a9
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.api.php
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * @file
+ * LDAPAuth API function documentation
+ */
+
+/**
+ * hook_ldapauth_create
+ *
+ * Ldapauth will invoke this after a new Drupal user has been created from
+ * the LDAP data and saved.
+ *
+ * @param User $account The user object for the new user.
+ */
+function hook_ldapauth_create( $account ) {
+  // Some example code to create an e-mail if ldap didn't provide one
+  if ( $account->name == $account->mail ) {
+    user_save($account, array( 'mail' => $account->name . "@mydomain.com", ));
+  }
+}
+/**
+ * hook_default_ldap_servers
+ *
+ * Called by features revert and rebuild hooks
+ */
+function hook_default_ldap_servers() {
+
+}
+
+/**
+ * Perform alterations of ldap attributes before query is made.
+ *
+ * To avoid excessive attributes in an ldap query, modules should
+ * alter attributes needed based on $op parameter
+ *
+ * See ldapauth_attributes_needed() function.
+ *
+ * @param array $attributes
+ *   array of attributes to be returned from ldap queries
+ * @param enum $op
+ *   context query will be run in. Should be one of the LDAPATUH_SYNC_CONTEXT* constants.
+ * @param mixed $server
+ *   server id (sid) or server object.
+ *
+ */
+function hook_ldap_attributes_needed_alter(&$attributes, $op, $server) {
+  // Sample code to add homedirectory attribute to all standard calls..
+
+  $attributes[] = 'dn';  // DN is minimum attribute for all ops.
+
+  if ( $server ) {
+    $ldap_server = is_object( $server ) ? $server : ldapauth_server_loade($server);
+
+    switch ($op) {
+      case LDAPAUTH_SYNC_CONTEXT_AUTHENTICATE_DRUPAL_USER:
+      case LDAPAUTH_SYNC_CONTEXT_INSERT_DRUPAL_USER:
+      case LDAPAUTH_SYNC_CONTEXT_UPDATE_DRUPAL_USER:
+        $attributes[] = 'homedirectory';
+        break;
+    }
+  }
+}
+/**
+ * Called if PUID attribute is defined but a valid LDAP user does not have
+ * this attribute (or is empty).
+ *
+ * This is intended to allow modules to generate a PUID for new users if needed.
+ * Note that LDAPAuth will NOT write this to LDAP.  The implementor will need
+ * to do this.
+ *
+ * @param String $puid The PUID (empty or null)
+ * @param String $dn The user's dn
+ * @param Integer $sid The id of server the user was found on.
+ */
+function hook_ldap_user_puid_alter( &$puid, $name, $dn, $sid) {
+
+}
+/**
+ * Called after LDAP user has been authenticated but before the drupal
+ * user mapping/creation done.
+ *
+ * Allows modules to alter the drupal account name that maps to an ldap account.
+ * For example, adding a prefix or suffix based on server.
+ *
+ * @param String $name The name to alter
+ * @param LDAPInterface $ldap LDAP server interface object bound to server as ldap user.
+ * @param String $dn The DN for the authenticated user
+ */
+function hook_ldap_drupal_user_name_alter( &$name, $ldap, $dn ) {
+  // Some example code to add the server machine name to the drupal name
+  // E.g. LDAP user on server AD1 with sAMAccount=jsmith will map to drupal
+  // user AD1-jsmith.  While LDAP user on server OL1 with uid=jsmith will
+  // map to drupal user OL1-jsmith.
+  $server = ldapauth_server_load($ldap->getOption('sid'));
+  $name = $server->machine_name . "-" . $name;
+}
+/**
+ * Allow other modules (e.g. ldapgroups) to deny ldap user access to
+ * the server.
+ *
+ * Called after ldap user authenticated and mapped to Drupal account (if any)
+ * but before new account creation / existing account updates.
+ *
+ * @param boolean $denied If set to TRUE, the account will be denied.
+ *                        Implementors should not reset to FALSE.
+ * @param LDAPInterface $ldap LDAP server interface object bound to server as ldap user.
+ * @param String $name The ldap user name (from login form)
+ * @param String $dn The DN for the authenticated user
+ * @param Object $account The local drupal account object or FALSE if none found.
+ */
+function hook_ldap_user_deny_alter( &$denied, $ldap, $name, $dn, $account ) {
+  // Some example code to deny if homedirectory attribute not set
+  $ldap = ldapauth_user_lookup_by_dn($ldap, $dn, LDAPAUTH_SYNC_CONTEXT_AUTHENTICATE_DRUPAL_USER);
+  if ( ! isset( $ldap['homedirectory'][0] )) { //Note attribute name must be lowercase
+    $denied = TRUE;
+  }
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.features.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.features.inc
new file mode 100644
index 0000000..3c749de
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.features.inc
@@ -0,0 +1,250 @@
+<?php
+/**
+ * @file
+ * Feature related functions.
+ */
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Code for feature component: ldap_servers
+/**
+ * Implementation of hook_features_export_options. [component_hook]
+ *
+ * This hook will alert features of which specific items of this component may
+ * be exported. Using ctools export info here.
+ *
+ * @return array
+ *   A keyed array of items, suitable for use with a FormAPI select or
+ *   checkboxes element.
+ */
+function ldap_servers_features_export_options() {
+  module_load_include('inc', 'ldapauth', 'includes/ldap.core');
+  $options = array();
+  $servers = ldapauth_server_load_all();
+  foreach ( $servers as $server ) {
+    $options[$server->machine_name] = $server->name;
+  }
+  return $options;
+}
+
+/**
+ * Implementation of hook_features_export [component hook]
+ *
+ * This defines the component dependencies and ldap server records to export.
+ *
+ * @param array $data
+ * @param array &$export
+ * @param string $module_name
+ * @return array
+ */
+function ldap_servers_features_export($data, &$export, $module_name = "") {
+  module_load_include('inc', 'ldapauth', 'includes/ldap.core');
+  $export['dependencies']['ldapauth'] = 'ldapauth';
+  $submodules = ldapauth_submodules('ldap_servers');
+  foreach ( $submodules as $submodule ) {
+    if ( module_exists($submodule ) ) {
+      $export['dependencies'][$submodule] = $submodule;
+    }
+  }
+  foreach ( $data as $component ) {
+    $export['features']['ldap_servers'][$component] = $component;
+  }
+  return array();
+}
+
+/**
+ * Implementation of hook_features_export_render. [component hook]
+ *
+ * Creates code to export ldapauth DB tabel server records.
+ *
+ * @param string $module_name
+ * @param array $data
+ * @param array $export
+ * @return array
+ */
+function ldap_servers_features_export_render($module, $data, $export) {
+  module_load_include('inc', 'ldapauth', 'includes/ldap.core');
+  $code = array();
+  $code[] = '  $servers = array();';
+  // If this is an override check, export all current servers
+  if ( is_null($export) ) {
+    $servers = ldapauth_server_load_all(TRUE);
+    foreach ($servers as $server) {
+      unset($server->sid);
+      $server = (array) $server;
+      ksort($server);  // Sort because updated tables don't match, new tables
+      $code[] = "  \$servers['{$server['machine_name']}'] = " . features_var_export($server, '  ') . ";";
+    }
+  }
+  else {
+    foreach ($data as $name) {
+      $server = ldapauth_server_load($name);
+      unset($server->sid);
+      $server = (array) $server;
+      ksort($server);
+      $code[] = "  \$servers['{$name}'] = " . features_var_export($server, '  ') . ";";
+    }
+  }
+  $code[] = '  return $servers;';
+  $code = implode("\n", $code);
+  return array('default_ldap_servers' => $code );
+}
+
+/**
+ * Implementation of hook_features_revert(). [component_hook]
+ *
+ * This is called when a feature is "reverted" via the UI.  It will
+ * delete all existing servers not defined by the feature, update
+ * existing servers to match the feature defaults, and add in
+ * any server defined in the feature that don't exist.
+ */
+function ldap_servers_features_revert($module) {
+  module_load_include('inc', 'ldapauth', 'includes/ldap.core');
+  $default_servers = module_invoke($module, 'default_ldap_servers');
+  $servers = ldapauth_server_load_all(TRUE);
+  $existing_servers = array();
+
+  // Update any existing servers in feature and delete those not in the feature.
+  foreach ( $servers as $server ) {
+    $machine_name = $server->machine_name;
+    $existing_servers[$machine_name] = $machine_name;
+    if ( isset($default_servers[$machine_name]) ) { // Update servers
+      $default_servers[$machine_name]['sid'] = $server->sid;
+      ldapauth_server_save($default_servers[$machine_name], TRUE);
+    }
+    else {  // Delete server
+      ldapauth_server_delete($server, TRUE);
+    }
+  }
+  // Add any servers in the feature that don't exist.
+  foreach ( $default_servers as $server ) {
+    if ( ! isset($existing_servers[$server['machine_name']]) ) { // Add in default server not in DB
+      unset($server['sid']);
+      ldapauth_server_save($server, TRUE);
+    }
+  }
+}
+
+/**
+ * Implementation of hook_features_rebuild(). [component_hook]
+ *
+ * This is called the first time a feature is installed.  It will
+ * add any non-existing servers to the site.
+ */
+function ldap_servers_features_rebuild($module) {
+  module_load_include('inc', 'ldapauth', 'includes/ldap.core');
+  $servers = module_invoke($module, 'default_ldap_servers');
+  foreach ($servers as $server) {
+    $existing_server = ldapauth_server_load($server['machine_name']);
+    if ( empty($existing_server) ) {
+      ldapauth_server_save($server);
+    }
+  }
+}
+//////////////////////////////////////////////////////////////////////////////
+// Code for feature component: ldap_settings
+/**
+ * Implementation of hook_features_export_options. [component_hook]
+ *
+ * @return array
+ *   A keyed array of items, suitable for use with a FormAPI select or
+ *   checkboxes element.
+ */
+function ldap_settings_features_export_options() {
+  $info = array(
+    'ldapauth_login_process' => t('Authentication') . ': ' . t('Authentication mode'),
+    'ldapauth_login_conflict' => t('Authentication') . ': ' . t('User conflict resolve process'),
+    'ldapauth_forget_passwords' => t('Authentication') . ': ' . t('Store user passwords'),
+    'ldapauth_sync_passwords' => t('Authentication') . ': ' . t('Sync passwords'),
+    'ldapauth_create_users' => t('Authentication') . ': ' . t('Create new users'),
+    'ldapauth_alter_username_field'  => t('Authentication') . ': ' . t('Alter user name field'),
+    'ldapauth_disable_pass_change' => t('Authentication') . ': ' . t('Remove password fields'),
+    'ldapauth_alter_email_field' => t('Authentication') . ': ' . t('Alter email field'),
+  );
+  ldapauth_submodules("ldap_settings", $info);
+  return $info;
+}
+
+/**
+ * Implementation of hook_features_export [component hook]
+ *
+ * @param array $data
+ *   this is the machine name for the component in question
+ * @param array &$export
+ *   array of all components to be exported
+ * @param string $module_name
+ *   The name of the feature module to be generated.
+ * @return array
+ *   The pipe array of further processors that should be called
+ */
+function ldap_settings_features_export($data, &$export, $module_name = "") {
+  $export['dependencies']['ldapauth'] = 'ldapauth';
+  $submodules = ldapauth_submodules('ldap_settings');
+  foreach ( $submodules as $submodule ) {
+    if ( module_exists($submodule ) ) {
+      $export['dependencies'][$submodule] = $submodule;
+    }
+  }
+  return variable_features_export($data, $export, $module_name);
+}
+
+/**
+ * Implementation of hook_features_export_render() [component_hook]
+ * These are not really called since StrongArm is handling this.
+ */
+function ldap_settings_features_export_render($module, $data) {
+  return variable_features_export_render($module, $data);
+}
+
+/**
+ * Implementation of hook_features_revert(). [component_hook]
+ * These are not really called since StrongArm is handling this.
+ */
+function ldap_settings_features_revert($module) {
+  variable_features_revert($module);
+}
+
+/**
+ * Implementation of hook_features_rebuild(). [component_hook]
+ */
+function ldap_settings_features_rebuild($module) {
+  variable_features_rebuild($module);
+}
+
+/**
+ * Get ldap "submodules" info that effects the feature components.
+ *
+ * TODO: should use a hook(s) to get these rather than hardcoding them.
+ *
+ * @param String $component
+ * @param Array info
+ */
+function ldapauth_submodules( $component, &$info=NULL ) {
+  switch ($component) {
+    case 'ldap_servers':
+      if ( $info ) {
+        return; // Hmmm should not be here
+      }
+      return array( 'ldapdata', 'ldapgroups'); // sync has no server settings
+    case 'ldap_settings':
+      if ( $info ) {
+        if ( module_exists('ldapdata') ) {
+          $info['ldapdata_disable_picture_change'] = t('Data') . ': ' . t('Remove picture fields');
+          $info['ldapdata_sync'] = t('Data') . ': ' . t('Synchronize LDAP data with Drupal profiles');
+        }
+        if ( module_exists('ldapsync') ) {
+          $info['ldapsync_time_interval'] = t('Synchronization') . ': ' . t('Sync time interval');
+          $info['ldapsync_existing_only'] = t('Synchronization') . ': ' . t('Sync existing users only');
+          $info['ldapsync_login_conflict'] = t('Synchronization') . ': ' . t('User conflict resolution');
+          $info['ldapsync_missing_users_action'] = t('Synchronization') . ': ' . t('Missing users action');
+          $info['ldapsync_load_user_by'] = t('Synchronization') . ': ' . t('Existing users test');
+          $info['ldapsync_filter'] = t('Synchronization') . ': ' . t('LDAP Sync filter');
+          $info['ldapsync_filter_append_default'] = t('Synchronization') . ': ' . t('Append default filter');
+        }
+        return;
+      }
+      return array( 'ldapdata', 'ldapsync'); // groups has no global settings
+    default:
+      return;
+  }
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.info b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.info
index 2f47e48..9b31756 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.info
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.info
@@ -1,4 +1,3 @@
-; $Id: ldapauth.info,v 1.3 2009/02/19 16:56:16 miglius Exp $
 name = Authentication
 description = Implements LDAP authentication.
 package = LDAP integration
@@ -6,9 +5,12 @@ core = 6.x
 php = 5.0
 
 
-; Information added by drupal.org packaging script on 2009-10-27
-version = "6.x-1.0-beta2"
+
+
+
+; Information added by drupal.org packaging script on 2012-06-28
+version = "6.x-1.0-beta3"
 core = "6.x"
 project = "ldap_integration"
-datestamp = "1256654469"
+datestamp = "1340919401"
 
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.install b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.install
index 32972f0..def75f2 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.install
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.install
@@ -1,5 +1,4 @@
 <?php
-// $Id: ldapauth.install,v 1.20 2009/10/27 14:29:16 miglius Exp $
 
 /**
  * @file
@@ -14,6 +13,23 @@
  */
 function ldapauth_install() {
   drupal_install_schema('ldapauth');
+  drupal_install_schema('ldapauth_users');
+}
+
+function ldapauth_requirements($phase) {
+
+  $ldap_extension_loaded = extension_loaded('ldap');
+  $t = get_t();
+
+  $requirements = array(
+    'ldapauth' => array(
+      'title' => ($ldap_extension_loaded) ? $t('PHP LDAP extension enabled') : $t('PHP LDAP extension missing or not enabled'),
+      'severity' => ($ldap_extension_loaded) ? REQUIREMENT_OK : REQUIREMENT_ERROR,
+    )
+  );
+
+  return $requirements;
+
 }
 
 /**
@@ -21,6 +37,7 @@ function ldapauth_install() {
  */
 function ldapauth_uninstall() {
   // Remove tables.
+  drupal_uninstall_schema('ldapauth_users');
   drupal_uninstall_schema('ldapauth');
 
   // Remove variables
@@ -30,6 +47,8 @@ function ldapauth_uninstall() {
   variable_del('ldapauth_sync_passwords');
   variable_del('ldapauth_disable_pass_change');
   variable_del('ldapauth_alter_email_field');
+  variable_del('ldapauth_create_users');
+  variable_del('ldapauth_alter_username_field');
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -45,12 +64,18 @@ function ldapauth_schema() {
         'type' => 'serial',
         'size' => 'tiny',
         'not null' => TRUE,
+        'no export' => TRUE,  // Do not export db key
       ),
       'name' => array(
         'type' => 'varchar',
         'length' => 255,
         'not null' => TRUE,
       ),
+      'machine_name' => array(
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+      ),
       'status' => array(
         'type' => 'int',
         'size' => 'tiny',
@@ -73,7 +98,7 @@ function ldapauth_schema() {
         'not null' => TRUE,
         'default' => 0,
       ),
-      'encrypted' => array(
+      'enc_type' => array(
         'type' => 'int',
         'size' => 'tiny',
         'not null' => TRUE,
@@ -90,6 +115,15 @@ function ldapauth_schema() {
         'type' => 'varchar',
         'length' => 255,
       ),
+      'puid_attr' => array(
+        'type' => 'varchar',
+        'length' => 255,
+      ),
+      'binary_puid' => array(
+        'type' => 'int',
+        'size' => 'tiny',
+        'default' => '0',
+      ),
       'binddn' => array(
         'type' => 'varchar',
         'length' => 255,
@@ -113,7 +147,79 @@ function ldapauth_schema() {
       ),
     ),
     'primary key' => array('sid'),
-    'unique keys' => array('name' => array('name')),
+    'unique keys' => array(
+      'name' => array('name'),
+      'machine_name' => array('machine_name'),
+    ),
+// CTools export definitions
+    'export' => array(
+      'key' => 'name',
+      'key name' => 'Server Name',
+      'primary key' => 'sid',
+      'identifier' => 'ldapserver', // Exports will be as $ldapserver
+      'default hook' => 'default_ldapauth_ldapserver',  // Function hook name.
+      'can disable' => FALSE,
+      'api' => array(
+        'owner' => 'ldapauth',
+        'api' => 'default_ldapauth_ldapservers',  // Base name for api include files.
+        'minimum_version' => 1,
+        'current_version' => 1,
+      ),
+    ),
+  );
+  if ($GLOBALS['db_type'] == 'pgsql') {
+    $puid_unique_fields = array('puid');
+  }
+  else {
+    $puid_unique_fields = array(array('puid', 255)); // MySQL limit
+  }
+
+  $schema['ldapauth_users'] = array(
+    'description' => 'Stores information about ldap authenticated users.',
+    'fields' => array(
+      'luid' => array(
+        'description' => 'Primary key: ldapauth users id',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'uid' => array(
+        'description' => '{users}.uid',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'sid' => array(
+        'description' => '{ldapauth}.sid used for authentication',
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+      ),
+      'machine_name' => array(
+        'description' => '{ldapauth}.machine_name for cross server id',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+      ),
+      'dn' => array(
+        'description' => 'LDAP dn user was authenticated with',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'puid' => array(
+        'description' => 'Persistent and Unique User ID value for this user',
+        'type' => 'text', // Text because dn's can be long
+        'not null' => TRUE,
+      ),
+    ),
+    'primary key' => array('luid'),
+    'unique keys' => array(
+      'uid' => array('uid'),
+      'puid_uniq' => $puid_unique_fields,
+    ),
+    'indexes' => array(
+      'puid_idx' => array(array('puid', 255)),  // MySQL limit
+    ),
   );
   return $schema;
 }
@@ -141,15 +247,15 @@ function ldapauth_update_6000() {
 
 function ldapauth_update_6001() {
   $ret = array();
-  db_add_field($ret, 'ldapauth', 'login_php', array(
+  db_add_field($ret, 'ldapauth', 'login_php',  array(
     'type' => 'text',
     'not null' => FALSE,
   ));
-  db_add_field($ret, 'ldapauth', 'filter_php', array(
+  db_add_field($ret, 'ldapauth', 'filter_php',  array(
     'type' => 'text',
     'not null' => FALSE,
   ));
-  db_add_field($ret, 'ldapauth', 'weight', array(
+  db_add_field($ret, 'ldapauth', 'weight',  array(
     'type' => 'int',
     'not null' => TRUE,
     'default' => 0,
@@ -174,3 +280,127 @@ function ldapauth_update_6003() {
   return $ret;
 }
 
+function ldapauth_update_6004() {
+  $ret = array();
+  //db_query(" CHANGE COLUMN encrypted enc_type TINYINT NOT NULL DEFAULT 0");
+  db_change_field($ret, 'ldapauth', 'encrypted', 'enc_type',  array(
+    'type' => 'int',
+    'size' => 'tiny',
+    'not null' => TRUE,
+    'default' => 0,
+  ));
+  return $ret;
+}
+// Add the machine_name field and create values for existing rows
+function ldapauth_update_6005() {
+  $ret = array();
+  db_add_field($ret, 'ldapauth', 'machine_name', array(
+    'type' => 'varchar',
+    'length' => 255,
+  ));
+  //Create machine names for existing servers!
+  $mnames = array();
+  $result = db_query('SELECT sid, name from {ldapauth}');
+  while ( $server = db_fetch_object($result)) {
+    $machine_name = drupal_strtolower($server->name);
+    $machine_name = preg_replace('/\s+/', '_', $machine_name);
+    $machine_name = preg_replace('/[^a-z0-9_]/', '', $machine_name);
+    if ( empty($machine_name) ) {
+      $machine_name = "server_" . $server->sid;
+    }
+    for ( $i = 1; isset($mname[$machine_name]); $i++ ) {  // Must be unique
+      $machine_name .= $i;
+    }
+    $mname[$machine_name] = $machine_name;
+    $ret[] = update_sql("UPDATE {ldapauth} SET machine_name = '{$machine_name}' WHERE sid = {$server->sid}");
+  }
+  // in not null after existing rows have a value.
+  db_change_field($ret, 'ldapauth', 'machine_name', 'machine_name', array(
+    'type' => 'varchar',
+    'length' => 255,
+    'not null' => TRUE,
+  ));
+  db_add_unique_key($ret, 'ldapauth', 'machine_name', array('machine_name'));
+
+  return $ret;
+}
+// Add the puid_attr field and create ldapauth_users table
+function ldapauth_update_6006() {
+  $ret = array();
+  if ( ! db_column_exists('ldapauth', 'puid_attr')) {
+    db_add_field($ret, 'ldapauth', 'puid_attr', array(
+      'type' => 'varchar',
+      'length' => 255,
+    ));
+  }
+  if ( ! db_column_exists('ldapauth', 'binary_puid')) {
+    db_add_field($ret, 'ldapauth', 'binary_puid', array(
+        'type' => 'int',
+        'size' => 'tiny',
+        'default' => '0',
+    ));
+  }
+
+  // Initial ldapauth_users definition
+  if (db_table_exists('ldapauth_users')) {  // Update being re-run.
+    return $ret;
+  }
+
+  if ($GLOBALS['db_type'] == 'pgsql') {
+    $puid_unique_fields = array('puid');
+  }
+  else {
+    $puid_unique_fields = array(array('puid', 255)); // MySQL limit
+  }
+
+  $table = array(
+    'description' => 'Stores information about ldap authenticated users.',
+    'fields' => array(
+      'luid' => array(
+        'description' => 'Primary key: ldapauth users id',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'uid' => array(
+        'description' => '{users}.uid',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'sid' => array(
+        'description' => '{ldapauth}.sid used for authentication',
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+      ),
+      'machine_name' => array(
+        'description' => '{ldapauth}.machine_name for cross server id',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+      ),
+      'dn' => array(
+        'description' => 'LDAP dn user was authenticated with',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'puid' => array(
+        'description' => 'Persistent and Unique User ID value for this user',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+    ),
+    'primary key' => array('luid'),
+    'unique keys' => array(
+      'uid' => array('uid'),
+      'puid_uniq' => $puid_unique_fields,
+    ),
+    'indexes' => array(
+      'puid_idx' => array(array('puid', 255)),  // MySQL limit
+    ),
+  );
+  db_create_table($ret, 'ldapauth_users', $table);
+  return $ret;
+}
+
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.module b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.module
index 0dcd4e2..dd5eb2e 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.module
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.module
@@ -1,11 +1,11 @@
 <?php
-// $Id: ldapauth.module,v 1.46 2009/10/27 14:29:16 miglius Exp $
 
 /**
  * @file
  * ldapauth provides authentication against ldap server.
  */
 
+
 //////////////////////////////////////////////////////////////////////////////
 
 define('LDAPAUTH_AUTH_MIXED',           0);
@@ -17,15 +17,27 @@ define('LDAPAUTH_EMAIL_FIELD_REMOVE',   1);
 define('LDAPAUTH_EMAIL_FIELD_DISABLE',  2);
 define('LDAPAUTH_PROFILE',              'LDAP authentication');
 define('LDAPAUTH_PROFILE_WEIGHT',       4);
-
-define('LDAPAUTH_LOGIN_PROCESS',       variable_get('ldapauth_login_process', LDAPAUTH_AUTH_MIXED));
-define('LDAPAUTH_LOGIN_CONFLICT',      variable_get('ldapauth_login_conflict', LDAPAUTH_CONFLICT_LOG));
-define('LDAPAUTH_FORGET_PASSWORDS',    variable_get('ldapauth_forget_passwords', TRUE));
-define('LDAPAUTH_SYNC_PASSWORDS',      variable_get('ldapauth_sync_passwords', FALSE));
-define('LDAPAUTH_DISABLE_PASS_CHANGE', variable_get('ldapauth_disable_pass_change', FALSE));
-define('LDAPAUTH_ALTER_EMAIL_FIELD',   variable_get('ldapauth_alter_email_field', LDAPAUTH_EMAIL_FIELD_NO));
-define('LDAPAUTH_DEFAULT_USER_ATTR',   variable_get('ldapauth_default_user_attr', 'uid'));
-define('LDAPAUTH_DEFAULT_MAIL_ATTR',   variable_get('ldapauth_default_mail_attr', 'mail'));
+define('LDAPAUTH_USERNAME_FIELD_NO',       0);
+define('LDAPAUTH_USERNAME_FIELD_REMOVE',   1);
+define('LDAPAUTH_USERNAME_FIELD_DISABLE',  2);
+
+// hook_*_alter operations (a.la. ldap in Drupal 7)
+define('LDAPAUTH_SYNC_CONTEXT_INSERT_DRUPAL_USER', 1);
+define('LDAPAUTH_SYNC_CONTEXT_UPDATE_DRUPAL_USER', 2);
+define('LDAPAUTH_SYNC_CONTEXT_AUTHENTICATE_DRUPAL_USER', 3);
+define('LDAPAUTH_SYNC_CONTEXT_CRON', 4);
+define('LDAPAUTH_SYNC_CONTEXT_DELETE_DRUPAL_USER', 5);
+define('LDAPAUTH_SYNC_CONTEXT_DISABLE_DRUPAL_USER', 6);
+
+define('LDAPAUTH_LOGIN_PROCESS',        variable_get('ldapauth_login_process', LDAPAUTH_AUTH_MIXED));
+define('LDAPAUTH_LOGIN_CONFLICT',       variable_get('ldapauth_login_conflict', LDAPAUTH_CONFLICT_LOG));
+define('LDAPAUTH_FORGET_PASSWORDS',     variable_get('ldapauth_forget_passwords', TRUE));
+define('LDAPAUTH_SYNC_PASSWORDS',       variable_get('ldapauth_sync_passwords', FALSE));
+define('LDAPAUTH_DISABLE_PASS_CHANGE',  variable_get('ldapauth_disable_pass_change', FALSE));
+define('LDAPAUTH_ALTER_EMAIL_FIELD',    variable_get('ldapauth_alter_email_field', LDAPAUTH_EMAIL_FIELD_NO));
+define('LDAPAUTH_DEFAULT_USER_ATTR',    variable_get('ldapauth_default_user_attr', 'uid'));
+define('LDAPAUTH_DEFAULT_MAIL_ATTR',    variable_get('ldapauth_default_mail_attr', 'mail'));
+define('LDAPAUTH_ALTER_USERNAME_FIELD', variable_get('ldapauth_alter_username_field', LDAPAUTH_USERNAME_FIELD_NO));
 
 //////////////////////////////////////////////////////////////////////////////
 // Core API hooks
@@ -34,7 +46,8 @@ define('LDAPAUTH_DEFAULT_MAIL_ATTR',   variable_get('ldapauth_default_mail_attr'
  * Implements hook_init().
  */
 function ldapauth_init() {
-  require_once(drupal_get_path('module', 'ldapauth') .'/includes/LDAPInterface.inc');
+  module_load_include('inc', 'ldapauth', 'includes/LDAPInterface');
+  module_load_include('inc', 'ldapauth', 'includes/ldap.core');
 }
 
 /**
@@ -51,7 +64,7 @@ function ldapauth_help($path, $arg) {
  * Implements hook_menu().
  */
 function ldapauth_menu() {
-  return array(
+  $items = array(
     'admin/settings/ldap' => array(
       'title' => 'LDAP',
       'description' => 'Configure LDAP integration settings.',
@@ -65,7 +78,7 @@ function ldapauth_menu() {
       'page callback' => 'drupal_get_form',
       'page arguments' => array('ldapauth_admin_settings'),
       'access arguments' => array('administer ldap modules'),
-     'file' => 'ldapauth.admin.inc',
+      'file' => 'ldapauth.admin.inc',
     ),
     'admin/settings/ldap/ldapauth/configure' => array(
       'title' => 'Settings',
@@ -129,7 +142,37 @@ function ldapauth_menu() {
       'type' => MENU_CALLBACK,
       'file' => 'ldapauth.admin.inc',
     ),
+    'admin/settings/ldap/ldapauth/user/%user/tolocal' => array(
+      'title' => 'Convert LDAP user to local user',
+      'page callback' => 'ldapauth_user_to_local_user',
+      'page arguments' => array(5),
+      'type' => MENU_CALLBACK,
+      'access arguments' => array('administer users'),
+      'file' => 'ldapauth.admin.inc',
+    ),
+
   );
+  // Need ctools to export or import
+  if ( module_exists("ctools") ) {
+    $items['admin/settings/ldap/ldapauth/export/%ldapauth_server'] = array(
+      'title' => 'Export Server Settings',
+      'page callback' => 'drupal_get_form',
+      'page arguments' => array('ldapauth_admin_export_form', 5),
+      'type' => MENU_CALLBACK,
+      'access arguments' => array('administer ldap modules'),
+      'file' => 'ldapauth.admin.inc',
+    );
+    $items['admin/settings/ldap/ldapauth/import'] = array(
+      'title' => 'Import Server',
+      'page callback' => 'drupal_get_form',
+      'page arguments' => array('ldapauth_admin_import_form'),
+      'type' => MENU_LOCAL_TASK,
+      'weight' => 3,
+      'access arguments' => array('administer ldap modules'),
+      'file' => 'ldapauth.admin.inc',
+    );
+  }
+  return $items;
 }
 
 /**
@@ -149,7 +192,12 @@ function ldapauth_theme() {
  */
 function ldapauth_user($op, &$edit, &$account, $category = NULL) {
   switch ($op) {
-    case 'update':
+    case 'validate':
+      if (isset($account->ldap_authentified) && LDAPAUTH_ALTER_EMAIL_FIELD == LDAPAUTH_EMAIL_FIELD_REMOVE || LDAPAUTH_ALTER_EMAIL_FIELD == LDAPAUTH_EMAIL_FIELD_DISABLE ) {
+        unset($edit['mail']);
+      }
+      break;
+    case 'update':  // Handle password mods after ldapdata does update in submit
       if ($category == 'account') {
 
         // If authentication is being done in "LDAP only" mode, passwords
@@ -158,23 +206,51 @@ function ldapauth_user($op, &$edit, &$account, $category = NULL) {
         if (isset($account->ldap_authentified) && (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_EXCLUSIVED || !LDAPAUTH_SYNC_PASSWORDS))
           $edit['pass'] = NULL;
       }
-
-      if (LDAPAUTH_ALTER_EMAIL_FIELD == LDAPAUTH_EMAIL_FIELD_REMOVE)
-        unset($edit['mail']);
       break;
     case 'view':
       if (user_access('administer users') && isset($account->ldap_authentified) && $account->ldap_dn) {
-        $row = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE sid = %d", $account->ldap_config));
+        $server = ldapauth_server_load( $account->ldap_config );
         $account->content[t(LDAPAUTH_PROFILE)] = array(
-         '#type' => 'user_profile_category',
-         '#title' => t(LDAPAUTH_PROFILE),
-         '#attributes' => array('class' => 'ldapauth-entry'),
-         '#weight' => LDAPAUTH_PROFILE_WEIGHT,
-         'ldap_server' => array('#type' => 'user_profile_item', '#title' => t('LDAP server'), '#value' => l($row->name, 'admin/settings/ldap/ldapauth/edit/'. $row->sid), '#weight' => 0),
-         'ldap_dn' => array('#type' => 'user_profile_item', '#title' => t('LDAP dn'), '#value' => $account->ldap_dn, '#weight' => 1),
+          '#type' => 'user_profile_category',
+          '#title' => t(LDAPAUTH_PROFILE),
+          '#attributes' => array('class' => 'ldapauth-entry'),
+          '#weight' => LDAPAUTH_PROFILE_WEIGHT,
+          'ldap_to_local' => array(
+            '#type' => 'user_profile_item',
+            '#title' => t('Convert User'),
+            '#value' => l(t('Convert from LDAP user to local Drupal user'), 'admin/settings/ldap/ldapauth/user/' . $account->uid . '/tolocal'),
+            '#weight' => -1,
+          ),
+        'ldap_server' => array(
+            '#type' => 'user_profile_item',
+            '#title' => t('LDAP server'),
+            '#value' => l($server->name, 'admin/settings/ldap/ldapauth/edit/'. $server->sid),
+            '#weight' => 0,
+          ),
+          'ldap_dn' => array(
+            '#type' => 'user_profile_item',
+            '#title' => t('LDAP dn'),
+            '#value' => $account->ldap_dn,
+            '#weight' => 1,
+          ),
         );
+        if ( ! empty($server->puid_attr) ) {
+          $user_info = ldapauth_userinfo_load_by_uid($account->uid);
+          $puid = $user_info ? $user_info->puid : t("PUID MISSING!!!!");
+          $account->content[t(LDAPAUTH_PROFILE)]['ldap_puid'] = array(
+           '#type' => 'user_profile_item',
+           '#title' => t('LDAP PUID'),
+         '#value' => $puid,
+         '#weight' => 3,
+          );
+        }
       }
       break;
+    case 'delete':
+      $user_info = ldapauth_userinfo_load_by_uid($account->uid);
+      ldapauth_userinfo_delete($user_info);
+      db_query("DELETE FROM {authmap} WHERE uid = %d AND module = 'ldapauth'", $account->uid);
+      break;
   }
 }
 
@@ -205,14 +281,30 @@ function ldapauth_form_alter(&$form, $form_state, $form_id) {
 
   switch ($form_id) {
     case 'user_login_block':
-      if (LDAPAUTH_DISABLE_PASS_CHANGE)
+    case 'user_login':
+      if (LDAPAUTH_DISABLE_PASS_CHANGE && $user->uid != 1) {
         unset($form['links']);
+        $key = array_search('user_login_final_validate', $form['#validate']);
+        $form['#validate'][$key] = 'ldapauth_user_login_final_validate';
+      }
       break;
     case 'user_profile_form':
       $account = $form["_account"]["#value"];
       if ($user->uid != 1 && isset($account->ldap_authentified)) {
-        if (LDAPAUTH_DISABLE_PASS_CHANGE)
-        unset($form['account']['pass']);
+        switch (LDAPAUTH_ALTER_USERNAME_FIELD) {
+          case LDAPAUTH_USERNAME_FIELD_REMOVE :
+            $form['account']['name']['#type'] = 'hidden';
+            $form['account']['name']['#attributes']['READONLY'] = 'READONLY';
+            break;
+          case LDAPAUTH_USERNAME_FIELD_DISABLE :
+            $form['account']['name']['#attributes']['READONLY'] = 'READONLY';
+            $form['account']['name']['#description'] = t('NOTE: Can only be changed on the LDAP server.') . '<br/>' . $form['account']['name']['#description'];
+            break;
+        }
+
+        if (LDAPAUTH_DISABLE_PASS_CHANGE) {
+          unset($form['account']['pass']);
+        }
 
         switch (LDAPAUTH_ALTER_EMAIL_FIELD) {
           case LDAPAUTH_EMAIL_FIELD_REMOVE :
@@ -234,6 +326,33 @@ function ldapauth_form_alter(&$form, $form_state, $form_id) {
   }
 }
 
+function ldapauth_user_login_final_validate($form_id, &$form_states) {
+  global $user;
+  if (!$user->uid) {
+    form_set_error('name', t('Sorry, unrecognized username or password.'));
+    watchdog('user', 'Login attempt failed for %user.', array('%user' => $form_values['name']));
+  }
+}
+
+function ldapauth_form_user_pass_alter(&$form, &$form_state) {
+  $form['#validate'][] = 'ldapauth_user_pass';
+}
+
+function ldapauth_user_pass($form, &$form_state) {
+
+  if (isset($form_state['values']['account']) && !empty($form_state['values']['account'])) {
+    $account = $form_state['values']['account'];
+
+    if (isset($account->ldap_authentified)) {
+      form_set_error('name', t("This is an LDAP account, to change or retrieve the password, please, contact your LDAP administrator"));
+      unset($form_state['values']['account']);
+    }
+  }
+
+}
+
+
+
 /**
  * Implements hook_cron().
  */
@@ -256,7 +375,7 @@ function ldapauth_exit() {
 // Login process functions
 
 /**
- * Main user validation function.
+ * Main user validation function.  Replaces Drupal default login form validation.
  *
  * If successful, sets the global $user object.
  */
@@ -265,7 +384,7 @@ function ldapauth_login_authenticate_validate($form, &$form_state) {
 }
 
 /**
- * Main user authentication function.
+ * Main user authentication function.  Called by form validator.
  *
  * If successful, sets the global $user object.
  */
@@ -273,7 +392,7 @@ function ldapauth_authenticate($form_values = array()) {
   global $user, $_ldapauth_ldap;
 
   $name = $form_values['name'];
-  $pass = trim($form_values['pass']);
+  $pass = $form_values['pass'];
 
   // The user_login_name_validate() is not called if the user is being authenticated
   // from the httpauth or services modules, therefore call it here.
@@ -283,7 +402,7 @@ function ldapauth_authenticate($form_values = array()) {
   // (Design decision) uid=1 (admin user) must always authenticate to local database
   // this user is critical for all drupal admin and upgrade operations so it is best
   // left with drupal's native authentication.
-  $result = db_query("SELECT uid FROM {users} WHERE name = '%s' AND uid = '1'", $name);
+  $result = db_query("SELECT uid FROM {users} WHERE LOWER(name) = LOWER('%s') AND uid = '1'", $name);
   if ($account = db_fetch_object($result)) {
     user_authenticate($form_values);
     return;
@@ -291,7 +410,7 @@ function ldapauth_authenticate($form_values = array()) {
 
   if (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_MIXED) {
     // Authenticate local users first.
-    $result = db_query("SELECT name, data FROM {users} WHERE name='%s'", $name);
+    $result = db_query("SELECT name, data FROM {users} WHERE LOWER(name) = LOWER('%s')", $name);
     if ($row = db_fetch_array($result)) {
       $data = unserialize($row['data']);
       if (!isset($data['ldap_authentified']) || $data['ldap_authentified'] == 0) {
@@ -305,48 +424,61 @@ function ldapauth_authenticate($form_values = array()) {
     }
   }
 
-  $account = user_load(array('name' => $name, 'status' => 1));
-  if ($account && drupal_is_denied('mail', $account->mail)) {
-    form_set_error('name', t('The name %name is registered using a reserved e-mail address and therefore could not be logged in.', array('%name' => $account->name)));
+  // Find and Authenticate LDAP user.
+  if (!($dn = _ldapauth_auth($name, $pass))) {
+    return;
+  }
+  // See if there is a matching Drupal user account
+  $error = '';
+  $account = ldapauth_drupal_user_lookup($_ldapauth_ldap, $name, $dn, $error );
+  if ( $account === NULL ) {
+    form_set_error("name", $error);
+    watchdog('ldapauth', $error, NULL, WATCHDOG_ERROR);
   }
 
-  // If there is any validations errors, we do not query LDAP.
-  if (form_get_errors())
+  // Allow other modules to determine if this ldap user can access server.
+  if ( ldapauth_user_denied( $_ldapauth_ldap, $name, $dn, $account ) ) {
     return;
+  }
+
+  // Have account: Do some default login checks
+  if ( $account !== FALSE ) {
+    if ( $account->status != 1 ) {  // User is blocked.
+      return;  // Returns default unknown id/password msg per core
+    }
+    if (drupal_is_denied('mail', $account->mail)) {
+      form_set_error('name', t('The name %name is registered using a reserved e-mail address and therefore could not be logged in.', array('%name' => $account->name)));
+    }
+    if ( $account->uid == 1 ) {
+      return; // LDAP user matched superuser!! Shouldn't get here but just in case
+    }
+  }
 
-  // Authenticate LDAP user.
-  if (!($dn = _ldapauth_auth($name, $pass)))
+  // If there is any validations errors, we do not query LDAP.
+  if (form_get_errors())
     return;
 
+  // No matching Drupal user, try to create one for this LDAP account.
   if (!$account) {
-    // Register this new user.
-    if ($ldap_user = _ldapauth_user_lookup($name)) {
-      // If mail attribute is missing, set the name as mail.
-      $init = $mail = key_exists(($_ldapauth_ldap->getOption('mail_attr') ? $_ldapauth_ldap->getOption('mail_attr') : LDAPAUTH_DEFAULT_MAIL_ATTR), $ldap_user) ? $ldap_user[$_ldapauth_ldap->getOption('mail_attr')][0] : $name;
-
-      // Check if the e-mail is not denied.
-      if (drupal_is_denied('mail', $mail)) {
-        form_set_error('name', t('The name %name is registered using a reserved e-mail address and therefore could not be logged in.', array('%name' => $name)));
-        return;
-      }
-
-      // Generate a random drupal password. LDAP password will be used anyways.
-      $pass_new = (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_EXCLUSIVED || !LDAPAUTH_SYNC_PASSWORDS) ? user_password(20) : $pass;
-
-      $userinfo = array('name' => $name, 'pass' => $pass_new, 'mail' => $mail, 'init' => $init, 'status' => 1, 'authname_ldapauth' => $name, 'ldap_authentified' => TRUE, 'ldap_dn' => $ldap_user['dn'], 'ldap_config' => $_ldapauth_ldap->getOption('sid'));
-      $user = user_save('', $userinfo);
-      watchdog('ldapauth', 'New external user %name created from the LDAP server %server.', array('%name' => $name, '%server' => $_ldapauth_ldap->getOption('name')), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
+    $error = '';
+    $account = ldapauth_drupal_user_create($_ldapauth_ldap, $name, $dn, $error);
+    if ( $account === FALSE ) {
+      form_set_error('name', $error);
+      return;
     }
+    $user = $account;
   }
+
+  // Login existing user.
   else {
-    // Login existing user.
     $data = array(
       'ldap_dn' => $dn,
       'ldap_config' => $_ldapauth_ldap->getOption('sid'),
+      'ldap_name' => $name,
     );
 
+    // LDAP and local user conflict.
     if (!isset($account->ldap_authentified)) {
-      // LDAP and local user conflict.
       if (LDAPAUTH_LOGIN_CONFLICT == LDAPAUTH_CONFLICT_LOG) {
         watchdog('ldapauth', 'LDAP user with DN %dn has a naming conflict with a local drupal user %name', array('%dn' => $dn, '%name' => $account->name), WATCHDOG_ERROR);
         drupal_set_message(t('Another user already exists in the system with the same login name. You should contact the system administrator in order to solve this conflict.'), 'error');
@@ -354,15 +486,29 @@ function ldapauth_authenticate($form_values = array()) {
       }
       else {
         $data['ldap_authentified'] = TRUE;
-        $data['authname_ldapauth'] = $name;
+        $drupal_name = ldapauth_drupal_user_name($name, $_ldapauth_ldap, $dn);
+        $data['authname_ldapauth'] = $drupal_name;
       }
     }
 
     // Successfull login.
     // Save the new login data.
-    if (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_MIXED && LDAPAUTH_SYNC_PASSWORDS)
+    if (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_MIXED && LDAPAUTH_SYNC_PASSWORDS) {
       $data['pass'] = $pass;
+    }
     $user = user_save($account, $data);
+
+    // Make sure the ldapauth_users info is current (User object may have been moved).
+    $user_info = ldapauth_userinfo_load_by_uid( $user->uid );
+    if ( empty($user_info) ) {   // Don't have entry, so make one.
+      $user_info = new stdClass();
+      $user_info->uid = $user->uid;
+    }
+    $user_info->sid = $user->ldap_config;
+    $user_info->machine_name = $_ldapauth_ldap->getOption('machine_name');
+    $user_info->dn = $dn;
+    $user_info->puid = $account->ldap_puid; // set in drupal_user_lookup
+    ldapauth_userinfo_save($user_info);
   }
 
   // Save user's authentication data to the session.
@@ -374,7 +520,9 @@ function ldapauth_authenticate($form_values = array()) {
 }
 
 /**
- * Authenticate the user against LDAP server.
+ * Authenticate the user against LDAP servers.
+ *
+ * Note: Related server information is passed via the global _ldapauth_ldap variable.
  *
  * @param $name
  *   A username.
@@ -384,7 +532,8 @@ function ldapauth_authenticate($form_values = array()) {
  * @return
  *  User's LDAP dn success, FALSE otherwise.
  */
-function _ldapauth_auth($name, $pass) {
+function _ldapauth_auth($name, $pass, $create_account = FALSE) {
+
   global $_ldapauth_ldap;
 
   // Don't allow empty passwords because they cause problems on some setups.
@@ -412,6 +561,16 @@ function _ldapauth_auth($name, $pass) {
     if (!$_ldapauth_ldap->connect($ldap['dn'], $pass))
       continue;
 
+    // Register this new user.  See http://drupal.org/node/553482 and http://drupal.org/node/551738
+    if ( $create_account ) {
+      $error = '';
+      $account = ldapauth_drupal_user_create($_ldapauth_ldap, $name, $ldap['dn'], $error);
+      if ( $account === FALSE ) {
+        drupal_set_message( check_plain($error), 'error');
+        return;
+      }
+    }
+
     return $ldap['dn'];
   }
   return FALSE;
@@ -420,6 +579,8 @@ function _ldapauth_auth($name, $pass) {
 /**
  * Queries LDAP server for the user.
  *
+ * Note: Assumes that global $_ldapauth_ldap variable has been initialized.
+ *
  * @param $name
  *   A login name.
  *
@@ -436,14 +597,19 @@ function _ldapauth_user_lookup($name) {
   $login_name = ($code = _ldapauth_ldap_info($_ldapauth_ldap->getOption('sid'), 'login_php')) ? eval($code) : $name;
 
   // If there is no bindn and bindpw - the connect will be an anonymous connect.
-  $_ldapauth_ldap->connect($_ldapauth_ldap->getOption('binddn'), $_ldapauth_ldap->getOption('bindpw'));
+  $success = $_ldapauth_ldap->connect($_ldapauth_ldap->getOption('binddn'), $_ldapauth_ldap->getOption('bindpw'));
+  if (!$success) {
+    watchdog('ldapauth', "Failed to connect to ldap in _ldapauth_user_lookup()", array(), WATCHDOG_ERROR);
+    return;
+  }
   foreach (explode("\r\n", $_ldapauth_ldap->getOption('basedn')) as $base_dn) {
     if (empty($base_dn))
       continue;
 
     $name_attr = $_ldapauth_ldap->getOption('user_attr') ? $_ldapauth_ldap->getOption('user_attr') : LDAPAUTH_DEFAULT_USER_ATTR;
     $filter = $name_attr .'='. $login_name;
-    $result = $_ldapauth_ldap->search($base_dn, $filter);
+    $attrs = ldapauth_attributes_needed(LDAPAUTH_SYNC_CONTEXT_AUTHENTICATE_DRUPAL_USER, $_ldapauth_ldap->getOption('sid'));
+    $result = $_ldapauth_ldap->search( $base_dn, $filter, $attrs );
     if (!$result)
       continue;
 
@@ -497,35 +663,36 @@ function _ldapauth_init($sid) {
   if (!($sid = is_object($sid) ? (isset($sid->ldap_config) ? $sid->ldap_config : NULL) : $sid))
     return;
 
-  static $servers = array();
-  if (!isset($servers[$sid]))
-    $servers[$sid] = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE status = 1 AND sid = %d", $sid));
+  $server = ldapauth_server_load($sid);
 
-  if ($servers[$sid]) {
+  if ( ! empty($server) && $server->status == 1 ) {
     $_ldapauth_ldap = new LDAPInterface();
     $_ldapauth_ldap->setOption('sid', $sid);
-    $_ldapauth_ldap->setOption('name', $servers[$sid]->name);
-    $_ldapauth_ldap->setOption('server', $servers[$sid]->server);
-    $_ldapauth_ldap->setOption('port', $servers[$sid]->port);
-    $_ldapauth_ldap->setOption('tls', $servers[$sid]->tls);
-    $_ldapauth_ldap->setOption('encrypted', $servers[$sid]->encrypted);
-    $_ldapauth_ldap->setOption('basedn', $servers[$sid]->basedn);
-    $_ldapauth_ldap->setOption('user_attr', $servers[$sid]->user_attr);
-    $_ldapauth_ldap->setOption('mail_attr', $servers[$sid]->mail_attr);
-    $_ldapauth_ldap->setOption('binddn', $servers[$sid]->binddn);
-    $_ldapauth_ldap->setOption('bindpw', $servers[$sid]->bindpw);
+    $_ldapauth_ldap->setOption('name', $server->name);
+    $_ldapauth_ldap->setOption('machine_name', $server->machine_name);
+    $_ldapauth_ldap->setOption('server', $server->server);
+    $_ldapauth_ldap->setOption('port', $server->port);
+    $_ldapauth_ldap->setOption('tls', $server->tls);
+    $_ldapauth_ldap->setOption('enc_type', $server->enc_type);
+    $_ldapauth_ldap->setOption('basedn', $server->basedn);
+    $_ldapauth_ldap->setOption('user_attr', $server->user_attr);
+    $_ldapauth_ldap->setOption('mail_attr', $server->mail_attr);
+    $_ldapauth_ldap->setOption('puid_attr', $server->puid_attr);
+    $_ldapauth_ldap->setOption('binary_puid', $server->binary_puid);
+    $_ldapauth_ldap->setOption('binddn', $server->binddn);
+    $_ldapauth_ldap->setOption('bindpw', $server->bindpw);
     return $_ldapauth_ldap;
   }
   return FALSE;
 }
 
 /**
- * Retrieve the saved ldapgroups saved setting.
+ * Retrieve the saved ldapauth PhP code filters.
  *
  * @param $sid
  *   A server ID or user object.
  * @param $req
- *   An attribute name.
+ *   The filter code needed, e.g. login_php or filter_php.
  *
  * @return
  *   The attribute value.
@@ -534,15 +701,81 @@ function _ldapauth_ldap_info($sid, $req) {
   if (!($sid = is_object($sid) ? (isset($sid->ldap_config) ? $sid->ldap_config : NULL) : $sid))
     return;
 
-  static $servers = array();
-  if (!isset($servers[$sid]))
-    $servers[$sid] = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE sid = %d", $sid));
+  $server = ldapauth_server_load($sid);
 
   switch ($req) {
     case 'login_php':
-      return $servers[$sid]->login_php;
+      return $server->login_php;
     case 'filter_php':
-      return $servers[$sid]->filter_php;
+      return $server->filter_php;
   }
 }
+//////////////////////////////////////////////////////////////////////////////
+// CTools/Features functions
 
+/**
+ * Implementation of hook_ctools_plugin_api().
+ *
+ * Tell CTools that we support the default_ldapauth_ldapservers API.
+ */
+function ldapauth_ctools_plugin_api($owner, $api) {
+  if ($owner == 'ldapauth' && $api == 'default_ldapauth_ldapservers') {
+    return array('version' => 1);
+  }
+}
+
+/**
+ * Implementation of hook_features_api().
+ *
+ * Defines the ldap_settings and ldap_servers feature components.
+ * Note:  This defines feature support for ldapauth, ldapdata, ldapgroups and
+ * ldapsync modules since they all build on ldapauth.
+ */
+function ldapauth_features_api() {
+  $info = array(
+    'ldap_servers' => array(
+      'name' => 'LDAP Integration',
+      'default_hook' => 'default_ldap_servers',
+      'default_file' => FEATURES_DEFAULTS_INCLUDED_COMMON,
+      'feature_source' => TRUE,
+      'file' => drupal_get_path('module', 'ldapauth') .'/ldapauth.features.inc',
+    )
+  );
+  if ( module_exists('strongarm') ) {
+    $info['ldap_settings'] = array(
+      'name' => 'LDAP Integration',
+      'default_hook' => 'default_ldap_settings',
+      'default_file' => FEATURES_DEFAULTS_INCLUDED_COMMON,
+      'feature_source' => TRUE,
+      'file' => drupal_get_path('module', 'ldapauth') .'/ldapauth.features.inc',
+    );
+  }
+  return $info;
+}
+/**
+ * Implements hook_ldap_attributes_needed_alter
+ *
+ * @param Array $attributes array of attributes to be returned from ldap queries
+ * @param String $op The operation being performed
+ * @param Mixed $server Server sid or server object
+ */
+function ldapauth_ldap_attributes_needed_alter( &$attributes, $op, $server = NULL) {
+
+  $attributes[] = 'dn';  // DN is minimum attribute for all ops.
+
+  if ( $server ) {
+    $ldap_server = is_object( $server ) ? $server : ldapauth_server_load($server);
+
+    switch ($op) {
+      case LDAPAUTH_SYNC_CONTEXT_INSERT_DRUPAL_USER:
+      case LDAPAUTH_SYNC_CONTEXT_UPDATE_DRUPAL_USER:
+      case LDAPAUTH_SYNC_CONTEXT_AUTHENTICATE_DRUPAL_USER:
+        $attributes[] = $ldap_server->user_attr;
+        $attributes[] = $ldap_server->mail_attr;
+        if ( ! empty( $ldap_server->puid_attr) ) {
+          $attributes[] = $ldap_server->puid_attr;
+        }
+        break;
+    }
+  }
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.theme.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.theme.inc
index e6ddd91..2805501 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.theme.inc
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapauth.theme.inc
@@ -1,5 +1,4 @@
 <?php
-// $Id: ldapauth.theme.inc,v 1.2 2009/10/27 14:29:17 miglius Exp $
 
 /**
  * @file
@@ -18,7 +17,7 @@ function theme_ldapauth_admin_list($form) {
   $header = array(
     '',
     t('Server'),
-    array('data' => t('Operations'), 'colspan' => 3),
+    array('data' => t('Operations'), 'colspan' => 4),
     t('Weight'),
   );
 
@@ -30,6 +29,12 @@ function theme_ldapauth_admin_list($form) {
       $row[] = l(t('edit'), 'admin/settings/ldap/ldapauth/edit/'. $sid);
       $row[] = l($element['status']['#value'] ? t('de-activate') : t('activate'), 'admin/settings/ldap/ldapauth/'. ($element['status']['#value'] ? 'deactivate' : 'activate') .'/'. $sid);
       $row[] = l(t('delete'), 'admin/settings/ldap/ldapauth/delete/'. $sid);
+      if ( module_exists('ctools')) {
+        $row[] = l(t('export'), 'admin/settings/ldap/ldapauth/export/'. $sid);
+      }
+      else {
+        $row[] = ' ';
+      }
       $element['weight']['#attributes']['class'] = "server-weight";
       $row[] = drupal_render($element['weight']);
       $rows[] = array('data' => $row, 'class' => 'draggable'. ($element['status']['#value'] ? ' menu-enabled' : ' menu-disabled'));
@@ -46,4 +51,3 @@ function theme_ldapauth_admin_list($form) {
   $form['list']['table'] = array('#value' => theme('table', $header, $rows, array('id' => 'ldapauth-list-table')));
   return drupal_render($form);
 }
-
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.admin.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.admin.inc
index 9125f01..df03862 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.admin.inc
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.admin.inc
@@ -1,5 +1,4 @@
 <?php
-// $Id: ldapdata.admin.inc,v 1.9 2009/07/28 14:03:05 miglius Exp $
 
 /**
  * @file
@@ -153,9 +152,11 @@ function ldapdata_admin_edit(&$form_state, $op, $sid) {
     );
     $profile_fields = _ldapdata_retrieve_profile_fields();
     $standard_fields = _ldapdata_retrieve_standard_user_fields();
+    $content_profile_fields = _ldapdata_retrieve_content_profile_fields();
     $drupal_fields = $profile_fields + $standard_fields;
     $form['mapping']['mapping_pre'] = array(
-      '#value' => t('<div class="form-item"><label>Specify mappings below if you selected the second or third option. </label><table><thead><tr><th> Drupal field</th><th>LDAP attribute</th></tr></thead><tbody>'),
+      '#value' => '<div class="form-item"><label>' . t('Specify mappings below if you selected the second or third option.')
+      . ' </label><table><thead><tr><th> ' . t('Drupal field') . '</th><th>' . t('LDAP attribute') . '</th></tr></thead><tbody>',
     );
     $ldap_drupal_reverse_mappings = _ldapdata_reverse_mappings($sid);
     foreach ($drupal_fields as $key => $field) {
@@ -169,6 +170,24 @@ function ldapdata_admin_edit(&$form_state, $op, $sid) {
         '#suffix' => '</td>',
       );
     }
+    // Content profile mapping
+    if ( $content_profile_fields ) {
+      $form['mapping']['mapping_cp'] = array(
+        '#value' => t('<div class="form-item"><label>Specify mappings below if you selected the second or third option. </label><table><thead><tr><th> Content Profile field</th><th>LDAP attribute</th></tr></thead><tbody>'),
+      );
+    }
+    foreach ($content_profile_fields as $key => $field) {
+      $field_tmp = "ldap_amap-". $key;
+      $_prefix = "<tr><td><label for=\"edit[$field_tmp]\">$field</label></td><td>";
+      $form['mapping'][$field_tmp] = array(
+        '#type' => 'textfield',
+        '#default_value' => isset($ldapdata_mappings[$field_tmp]) ? $ldapdata_mappings[$field_tmp] : NULL,
+        '#size' => '20',
+        '#prefix' => $_prefix,
+        '#suffix' => '</td>',
+      );
+    }
+
     $form['mapping']['mapping_post'] = array(
       '#value' => '</tbody></table></div>',
     );
@@ -418,4 +437,3 @@ function _ldapdata_ajax_test($sid) {
   drupal_json($_ldapdata_ldap->connect($binddn, $bindpw) ? array('status' => 1, 'message' => t('Authentication with the LDAP server succeeded.')) : array('status' => 0, 'message' => t('Authentication with the LDAP server failed.')));
   exit;
 }
-
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.info b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.info
index 7b0b146..1d7ccd1 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.info
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.info
@@ -1,4 +1,3 @@
-; $Id: ldapdata.info,v 1.3 2009/02/19 16:56:16 miglius Exp $
 name = Data
 description = Implements LDAP data to Drupal profiles synchronization.
 package = LDAP integration
@@ -6,9 +5,9 @@ dependencies[] = ldapauth
 core = 6.x
 
 
-; Information added by drupal.org packaging script on 2009-10-27
-version = "6.x-1.0-beta2"
+; Information added by drupal.org packaging script on 2012-06-28
+version = "6.x-1.0-beta3"
 core = "6.x"
 project = "ldap_integration"
-datestamp = "1256654469"
+datestamp = "1340919401"
 
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.install b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.install
index 2e23859..9bb78db 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.install
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.install
@@ -1,5 +1,4 @@
 <?php
-// $Id: ldapdata.install,v 1.9 2009/07/20 19:35:40 miglius Exp $
 
 /**
  * @file
@@ -65,6 +64,7 @@ function ldapdata_uninstall() {
 
   // Remove variables
   variable_del('ldapdata_sync');
+  variable_del('ldapauth_disable_picture_change');
 
   return $ret;
 }
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.module b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.module
index 7a716b9..c2d3df0 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.module
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.module
@@ -1,5 +1,4 @@
 <?php
-// $Id: ldapdata.module,v 1.31 2009/10/27 14:29:17 miglius Exp $
 
 /**
  * @file
@@ -8,11 +7,13 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
+// LDAPDATA_SYNC: 0 = user login; 1 = Page load; 2 = Each user load.
 define('LDAPDATA_SYNC',            variable_get('ldapdata_sync', 2));
 define('LDAPDATA_PROFILE',        'LDAP attributes');
 define('LDAPDATA_PROFILE_WEIGHT', 5);
 define('LDAPDATA_USER_TAB',       'LDAP entry');
 define('LDAPDATA_USER_DATA',      'ldapdata_user_data');
+define('LDAPDATA_DISABLE_PICTURE_CHANGE', variable_get('ldapdata_disable_picture_change', FALSE));
 
 // Changed the values to be more unix-line. 6 = rw, 4 = ro, 2 = nothing.
 define('LDAPDATA_MAP_ATTRIBUTES',           6);
@@ -26,7 +27,8 @@ define('LDAPDATA_MAP_NOTHING',              2);
  * Implements hook_init()
  */
 function ldapdata_init() {
-  require_once(drupal_get_path('module', 'ldapdata') .'/includes/LDAPInterface.inc');
+  module_load_include('inc', 'ldapauth', 'includes/ldap.core');
+  module_load_include('inc', 'ldapauth', 'includes/LDAPInterface');
 }
 
 /**
@@ -89,6 +91,11 @@ function ldapdata_menu() {
  * Implements hook_user().
  */
 function ldapdata_user($op, &$edit, &$account, $category = NULL) {
+
+  // Only care about ldap authenticated users.
+  if (!isset($account->ldap_authentified))
+    return;
+
   switch ($op) {
     case 'categories':
       return _ldapdata_user_categories();
@@ -162,7 +169,7 @@ function _ldapdata_user_form(&$user, $category) {
     return;
   }
 
-  $entry = $_ldapdata_ldap->retrieveAttributes($user->ldap_dn);
+  $entry = ldapauth_user_lookup_by_dn( $_ldapdata_ldap, $user->ldap_dn, LDAPAUTH_SYNC_CONTEXT_UPDATE_DRUPAL_USER );
 
   $form['ldap_attributes'] = array(
     '#title' => t(LDAPDATA_PROFILE),
@@ -184,16 +191,24 @@ function _ldapdata_user_form(&$user, $category) {
 
 /**
  * Implements hook_user() load operation.
+ *
+ * @param Object $account User being loaded
+ * @param boolean $sync If true, force the user to be synced.
+ * @param Array $newentry ldapsync generated users to update info from.
  */
-function _ldapdata_user_load(&$account, $sync = FALSE) {
+function _ldapdata_user_load(&$account, $sync = FALSE, $newentry = NULL) {
+
   global $user, $_ldapdata_ldap;
 
   // Setup the global $_ldapdata_ldap object.
+  // NOTE: Other functions assume this function will always initialize this
   if (!_ldapdata_init($account))
     return;
 
-  if (!$sync && (LDAPDATA_SYNC < 1 || LDAPDATA_SYNC < 2 && $user->uid != $account->uid))
+// sync not forced and sync on login set or sync on page load set and it's not the current user.
+  if (!$sync && (LDAPDATA_SYNC == 0 || LDAPDATA_SYNC == 1 && $user->uid != $account->uid)) {
     return;
+  }
 
   static $accounts_synced = array();
   if (isset($accounts_synced[$account->uid])) {
@@ -202,30 +217,82 @@ function _ldapdata_user_load(&$account, $sync = FALSE) {
 
   // See http://drupal.org/node/91786 about user_node().
   // User can be edited by the user or by other authorized users.
-  $authmap = user_get_authmaps($account->name);
-  if (!isset($authmap['ldapauth']) || (_ldapdata_ldap_info($account, 'mapping_type') == LDAPDATA_MAP_NOTHING)) {
+  if (!isset($account->ldap_dn) || (_ldapdata_ldap_info($account, 'mapping_type') == LDAPDATA_MAP_NOTHING)) {
     return;
   }
 
   $accounts_synced[$account->uid] = TRUE;
-  $bind_info = _ldapdata_edition($account);
-  if (!$_ldapdata_ldap->connect($bind_info['dn'], $bind_info['pass'])) {
-    watchdog('ldapdata', "User load: user %name's data could not be read in the LDAP directory", array('%name' => $account->name), WATCHDOG_WARNING);
-    return;
+  if (is_null($newentry)) {
+    $bind_info = _ldapdata_edition($account);
+    if (!$_ldapdata_ldap->connect($bind_info['dn'], $bind_info['pass'])) {
+      watchdog('ldapdata', "User load: user %name's data could not be read in the LDAP directory", array('%name' => $account->name), WATCHDOG_WARNING);
+      return;
+    }
+    $entry = ldapauth_user_lookup_by_dn( $_ldapdata_ldap, $account->ldap_dn, LDAPAUTH_SYNC_CONTEXT_UPDATE_DRUPAL_USER );
+  }
+  else {
+
+    $i=0;
+    foreach ($newentry as $users => $info) {
+      if ($account->ldap_dn == $info['dn']) {
+        $entry = $info['attribs'];
+      }
+      $i++;
+    }
+
   }
 
-  if ($entry = $_ldapdata_ldap->retrieveAttributes($account->ldap_dn)) {
+  if (isset($entry)) {
+
     $ldap_drupal_reverse_mappings = _ldapdata_reverse_mappings($account->ldap_config);
 
     // Retrieve profile fields list.
+    $content_profile_fields = _ldapdata_retrieve_content_profile_fields();
     $profile_fields = _ldapdata_retrieve_profile_fields();
 
+    // Determine which profile fields are dates
+    if ( ! empty($profile_fields) ) {
+      $placeholders = implode(',', array_fill(0, count($profile_fields), "'%s'"));
+      $result = db_query("SELECT name, options from {profile_fields} WHERE name IN ($placeholders) AND type = 'date'", $profile_fields);
+      $date_fields = array();
+      while ($row = db_fetch_object($result)) {
+        array_push($date_fields, $row->name);
+      }
+    }
+
+    // If needed, get the content profile nodes
+    $content_profile_nodes = array();
+    if ( ! empty($content_profile_fields) ) {
+      $cp_types = content_profile_get_types('types');
+      foreach ($cp_types as $type_obj) {
+        $type = $type_obj->type;
+        $profile = content_profile_load($type, $account->uid, '', TRUE);
+        if (!$profile) {
+          $profile = new stdClass();
+          $profile->type = $type;
+          $profile->title = (isset($account->name) ? $account->name : '');
+          $profile->uid = $account->uid;
+          node_save($profile); // Create node to get CCK fields
+        }
+        $content_profile_nodes[] = $profile;
+      }
+    }
+    $updated_nodes = array();
+
     $drupal_fields = array();
     foreach (_ldapdata_reverse_mappings($account->ldap_config) as $drupal_field => $ldap_attr) {
       $value = isset($entry[strtolower($ldap_attr)]) ? $entry[strtolower($ldap_attr)][0] : '';
 
       // Is it a profile field?
-      if (is_numeric($drupal_field)) {
+      if (! empty($profile_fields) && is_numeric($drupal_field)) {
+        if (in_array($profile_fields[$drupal_field], $date_fields)) {
+          $value = serialize( array(
+            "month" => (int)substr($value, 4, 2),
+            "day" => (int)substr($value, 6, 2),
+            "year" => (int)substr($value, 0, 4)
+          ));
+        }
+
         if ($profile_field = isset($profile_fields[$drupal_field]) ? $profile_fields[$drupal_field] : NULL) {
           if ($row = db_fetch_array(db_query("SELECT value FROM {profile_values} WHERE fid = '%d' AND uid = '%d'", $drupal_field, $account->uid))) {
             if ($row['value'] != $value)
@@ -237,17 +304,136 @@ function _ldapdata_user_load(&$account, $sync = FALSE) {
           $account->$drupal_field = $value;
         }
       }
+      // Is it a content profile field?
+      // TODO: Handle multiple value fields
+      elseif ( isset($content_profile_fields[$drupal_field]) ) {
+        // Find a matching profile node.
+        foreach ($content_profile_nodes as $profile_key => $profile) {
+          $node_updated = FALSE;
+          if ( isset($profile->{$drupal_field}) ) {
+            // Determine what kind of field we are dealing with
+            $field_lookup = content_fields($drupal_field);
+            $field_type = $field_lookup['type'];
+            switch ($field_type) {
+              case 'email':
+                if ( $profile->{$drupal_field}[0]['email'] != $value ) {
+                  $profile->{$drupal_field}[0]['email'] = $value;
+                  $node_updated = TRUE;
+                }
+                break;
+              case 'content_taxonomy':
+              // Check to see if there are any terms that match
+                if ($term = taxonomy_get_term_by_name($value)) {
+                  // If so, check to make sure they match the vocabulary
+                  if ($term[0]->vid == $field_lookup['vid']) {
+                    if ( $profile->{$drupal_field}[0]['value'] != $term[0]->tid ) {
+                      $profile->{$drupal_field}[0]['value'] = $term[0]->tid;
+                      $node_updated = TRUE;
+                    }
+                  }
+                  else {
+                    $newtid = _ldapdata_add_taxonomy_term($value, $field_lookup['vid']);
+                    $profile->{$drupal_field}[0]['value'] = $newtid;
+                    $node_updated = TRUE;
+                  }
+                }
+                else {
+                  $newtid = _ldapdata_add_taxonomy_term($value, $field_lookup['vid']);
+                  $profile->{$drupal_field}[0]['value'] = $newtid;
+                  $node_updated = TRUE;
+                }
+                break;
+              default:
+                if ( $profile->{$drupal_field}[0]['value'] != $value ) {
+                  $profile->{$drupal_field}[0]['value'] = $value;
+                  $node_updated = TRUE;
+                }
+            }
+            // Only save node if something changed. Prevents node modified errors.
+            if ( $node_updated ) {
+              $updated_nodes[$profile_key] = $profile;
+            }
+          }
+        }
+      }
+
       // Then it might be a Drupal field.
-      else if (isset($account->$drupal_field) && !in_array($drupal_field, array('pass'))) {
+      elseif (isset($account->$drupal_field) && !in_array($drupal_field, array('pass'))) {
         $drupal_fields = array_merge($drupal_fields, array($drupal_field => $value));
       }
     }
-    if (!empty($drupal_fields))
+    if (!empty($drupal_fields)) {
+      if ( !empty($drupal_fields['picture']) ) {
+        $fname = file_directory_path() . "/" .
+          variable_get('user_picture_path', 'pictures') .
+          "/picture-" . $account->uid . ".jpg";
+        if ( ($fhandle = fopen($fname, 'w'))) {
+          fwrite($fhandle, $drupal_fields['picture']);
+          fclose($fhandle);
+          $drupal_fields['picture']= $fname;
+        }
+        else {
+          watchdog('ldapdata', "Could not open user picture file for writing.  File=%file!", array('%file' => $fname), WATCHDOG_WARNING);
+          unset($drupal_fields['picture']);
+        }
+      }
       $account = user_save($account, $drupal_fields);
+    }
+    if (!empty($updated_nodes)) {
+      foreach ( $updated_nodes as $profile ) {
+        // Flag this profile node as already synched.
+        $profile->ldap_synched = TRUE;
+        node_save($profile);
+        node_load($profile->nid, $profile->vid, TRUE); // Force cache refresh
+      }
+    }
   }
   $_ldapdata_ldap->disconnect();
 }
 
+ /**
+ * Retrieve content profile fields.
+ *
+ * @return
+ *   An array with a field_name key and descriptive value.
+ */
+function _ldapdata_retrieve_content_profile_fields() {
+  $fields = array();
+  if (module_exists('content_profile')) {
+    $cp_types = content_profile_get_types('types');
+    foreach ($cp_types as $type_obj) {
+      $type = $type_obj->type;
+      $all_fields = content_fields(NULL, $type);
+      if ($all_fields) {
+        foreach ($all_fields as $field_name => $field_attributes) {
+          // If it's not the type we are looking for, then skip the field.
+          if ($field_attributes['type_name'] != $type) {
+            continue;
+          }
+          $fields[$field_name] = "{$type}->{$field_name}";
+        }
+      }
+    }
+
+  }
+  return $fields;
+}
+
+/**
+ * Adds a new taxonomy term
+ */
+function _ldapdata_add_taxonomy_term($name, $vid, $description = '', $weight = 0) {
+  $form_values = array();
+  $form_values['name'] = $name;
+  $form_values['description'] = $description;
+  $form_values['vid'] = $vid;
+  $form_values['weight'] = $weight;
+  taxonomy_save_term($form_values);
+
+  return $form_values['tid'];
+}
+
+
 /**
  * Implements hook_user() login operation.
  */
@@ -265,12 +451,12 @@ function _ldapdata_user_login(&$user) {
 function _ldapdata_user_submit(&$edit, &$user, $category) {
   global $_ldapdata_ldap;
 
-  // Setup the global $_ldapdata_ldap object.
-  if (!_ldapdata_init($user))
+  // Only care about ldap authenticated users.
+  if (!isset($user->ldap_authentified))
     return;
 
-  $authmap = user_get_authmaps($user->name);
-  if (!isset($authmap['ldapauth']))
+  // Setup the global $_ldapdata_ldap object.
+  if (!_ldapdata_init($user))
     return;
 
   // Three cases here:
@@ -286,7 +472,7 @@ function _ldapdata_user_submit(&$edit, &$user, $category) {
     // Case 1:
     $writeout = array_merge($writeout, _ldapdata_user_update_ldap_attributes($edit, $user));
   }
-  else if ($category == 'account') {
+  elseif ($category == 'account') {
     // Cases 2 && 3:
     $writeout = array_merge($writeout, _ldapdata_user_update_drupal_account($edit, $user));
   }
@@ -312,12 +498,17 @@ function _ldapdata_user_submit(&$edit, &$user, $category) {
 function _ldapdata_user_view(&$user) {
   global $_ldapdata_ldap;
 
-  // Setup the global $_ldapdata_ldap object.
-  if (!_ldapdata_init($user))
+  // Only care about ldap authenticated users.
+  if (!isset($user->ldap_authentified))
+    return;
+
+  $ldapdata_attrs = _ldapdata_ldap_info($user, 'ldapdata_attrs');
+  if ( empty($ldapdata_attrs)) {  // No LDAP attributes defined, we're done.
     return;
+  }
 
-  $authmap = user_get_authmaps($user->name);
-  if (!isset($authmap['ldapauth']))
+  // Setup the global $_ldapdata_ldap object.
+  if (!_ldapdata_init($user))
     return;
 
   $bind_info = _ldapdata_edition($user);
@@ -326,11 +517,11 @@ function _ldapdata_user_view(&$user) {
     return;
   }
 
-  $entry = $_ldapdata_ldap->retrieveAttributes($user->ldap_dn);
+  $entry = ldapauth_user_lookup_by_dn( $_ldapdata_ldap, $user->ldap_dn, LDAPAUTH_SYNC_CONTEXT_UPDATE_DRUPAL_USER );
   $allowed_attrs = _ldapdata_ldap_info($user, 'ldapdata_roattrs');
   $items = array();
   $i = 0;
-  foreach (_ldapdata_ldap_info($user, 'ldapdata_attrs') as $attr_name => $attr_info) {
+  foreach ($ldapdata_attrs as $attr_name => $attr_info) {
     if (in_array($attr_name, $allowed_attrs)) {
       $item = array(
         '#type' => 'user_profile_item',
@@ -401,8 +592,25 @@ function _ldapdata_user_update_drupal_account(&$edit, &$user) {
       if ($ldap_attr = isset($d2l_map[$key]) ? $d2l_map[$key] : NULL) {
         if ($key == 'pass') {
           if ($value) {
-            $pw = $_ldapdata_ldap->getOption('encrypted') ? '{md5}'. base64_encode(pack('H*', md5($value))) : $value;
-            $writeout[$ldap_attr] = $pw;
+            $writeout[$ldap_attr] = encode_password($value);
+          }
+        }
+        elseif ($key == 'mail') {
+          if (LDAPAUTH_ALTER_EMAIL_FIELD != LDAPAUTH_EMAIL_FIELD_REMOVE) {
+            $writeout[$ldap_attr] = $value;
+          }
+        }
+        elseif ($key == 'picture') {
+          if ($value) {
+            if (($fhandle = fopen($value, 'r'))) {
+              $writeout[$ldap_attr] = fread($fhandle, filesize($value));
+            }
+            else {
+              watchdog('ldapdata', "Could not open user picture file for reading.  File=%file", array('%file' => $value), WATCHDOG_WARNING);
+            }
+          }
+          else {
+            $writeout[$ldap_attr] = '';
           }
         }
         else {
@@ -433,11 +641,25 @@ function _ldapdata_user_update_profile(&$edit, &$user) {
 
   // Retrieve profile fields list.
   $profile_fields = _ldapdata_retrieve_profile_fields();
+  if ( empty($profile_fields) ) {
+    return array();
+  }
+  // Determine which profile fields are dates
+  $placeholders = implode(',', array_fill(0, count($profile_fields), "'%s'"));
+  $result = db_query("SELECT name, options from {profile_fields} WHERE name IN ($placeholders) AND type = 'date'", $profile_fields);
+  $date_fields = array();
+  while ($row = db_fetch_object($result)) {
+    array_push($date_fields, $row->name);
+  }
 
   // Compare against $edit list.
   $writeout = array();
   foreach ($profile_fields as $key => $field) {
-    if (isset($edit[$field]) && isset($ldap_drupal_reverse_mappings[$key])) {
+    if (isset($edit[$field]) && isset($ldap_drupal_reverse_mappings[$key]) && in_array($field, $date_fields)) {
+      // LDAP GeneralizedTime/Integer Format -> YYYYMMDD
+      $writeout[$ldap_drupal_reverse_mappings[$key]] = sprintf('%04d%02d%02d', $edit[$field]['year'], $edit[$field]['month'], $edit[$field]['day']);
+    }
+    elseif (isset($edit[$field]) && isset($ldap_drupal_reverse_mappings[$key])) {
       $writeout[$ldap_drupal_reverse_mappings[$key]] = $edit[$field];
     }
   }
@@ -460,11 +682,11 @@ function _ldapdata_attribute_form($value, $info) {
     case 'textfield':
       $form = array(
         '#type' => 'textfield',
-        '#title' => array_shift($info),
+        '#title' => check_plain(array_shift($info)),
         '#default_value' => $value,
         '#size' => array_shift($info),
         '#maxlength' => array_shift($info),
-        '#description' => array_shift($info),
+        '#description' => check_plain(array_shift($info)),
         '#attributes' => array_shift($info),
         '#required' => array_shift($info),
       );
@@ -472,11 +694,11 @@ function _ldapdata_attribute_form($value, $info) {
     case 'password':
       $form = array(
         '#type' => 'password',
-        '#title' => array_shift($info),
+        '#title' => check_plain(array_shift($info)),
         '#default_value' => $value,
         '#size' => array_shift($info),
         '#maxlength' => array_shift($info),
-        '#description' => array_shift($info),
+        '#description' => check_plain(array_shift($info)),
       );
       break;
   }
@@ -525,6 +747,9 @@ function _ldapdata_retrieve_standard_user_fields() {
     'pass' => 'pass',
     'signature' => 'signature',
   );
+  if ( variable_get('user_pictures', '0') ) {
+    $fields['picture'] =  'picture';
+  }
   return $fields;
 }
 
@@ -556,11 +781,11 @@ function _ldapdata_edition($sid) {
   if (!($sid = is_object($sid) ? (isset($sid->ldap_config) ? $sid->ldap_config : NULL) : $sid))
     return;
 
-  $row = db_fetch_object(db_query("SELECT ldapdata_binddn, ldapdata_bindpw FROM {ldapauth} WHERE sid = %d", $sid));
+  $server = ldapauth_server_load($sid);
 
   return array(
-    'dn' => $row->ldapdata_binddn ? $row->ldapdata_binddn : (isset($_SESSION['ldap_login']['dn']) ? $_SESSION['ldap_login']['dn'] : ''),
-    'pass' => $row->ldapdata_bindpw ? $row->ldapdata_bindpw : (isset($_SESSION['ldap_login']['pass']) ? $_SESSION['ldap_login']['pass'] : ''),
+    'dn' => $server->ldapdata_binddn ? $server->ldapdata_binddn : (isset($_SESSION['ldap_login']['dn']) ? $_SESSION['ldap_login']['dn'] : ''),
+    'pass' => $server->ldapdata_bindpw ? $server->ldapdata_bindpw : (isset($_SESSION['ldap_login']['pass']) ? $_SESSION['ldap_login']['pass'] : ''),
   );
 }
 
@@ -596,23 +821,30 @@ function _ldapdata_init($sid) {
   if (!($sid = is_object($sid) ? (isset($sid->ldap_config) ? $sid->ldap_config : NULL) : $sid))
     return;
 
-  static $servers = array();
-  if (!isset($servers[$sid]))
-    $servers[$sid] = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE status = 1 AND sid = %d", $sid));
+  // Other modules can invoke user load from hook_init() before ldapdata.
+  // so get include files if we need them.
+  if ( ! function_exists("ldapauth_server_load") ) {
+    module_load_include('inc', 'ldapauth', 'includes/ldap.core');
+    module_load_include('inc', 'ldapauth', 'includes/LDAPInterface');
+  }
 
-  if ($servers[$sid]) {
-    // Other modules can invoke user load from hook_init() before ldapdata.
-    require_once(drupal_get_path('module', 'ldapdata') .'/includes/LDAPInterface.inc');
+  $server = ldapauth_server_load($sid);
+
+  if (! empty($server) ) {
 
     $_ldapdata_ldap = new LDAPInterface();
     $_ldapdata_ldap->setOption('sid', $sid);
-    $_ldapdata_ldap->setOption('name', $servers[$sid]->name);
-    $_ldapdata_ldap->setOption('server', $servers[$sid]->server);
-    $_ldapdata_ldap->setOption('port', $servers[$sid]->port);
-    $_ldapdata_ldap->setOption('tls', $servers[$sid]->tls);
-    $_ldapdata_ldap->setOption('encrypted', $servers[$sid]->encrypted);
-    $_ldapdata_ldap->setOption('basedn', $servers[$sid]->basedn);
-    $_ldapdata_ldap->setOption('user_attr', $servers[$sid]->user_attr);
+    $_ldapdata_ldap->setOption('name', $server->name);
+    $_ldapdata_ldap->setOption('machine_name', $server->machine_name);
+    $_ldapdata_ldap->setOption('server', $server->server);
+    $_ldapdata_ldap->setOption('port', $server->port);
+    $_ldapdata_ldap->setOption('tls', $server->tls);
+    $_ldapdata_ldap->setOption('enc_type', $server->enc_type);
+    $_ldapdata_ldap->setOption('basedn', $server->basedn);
+    $_ldapdata_ldap->setOption('user_attr', $server->user_attr);
+    $_ldapdata_ldap->setOption('mail_attr', $server->mail_attr);
+    $_ldapdata_ldap->setOption('puid_attr', $server->puid_attr);
+    $_ldapdata_ldap->setOption('binary_puid', $server->binary_puid);
     $_ldapdata_ldap->setOption('attr_filter', '_ldapdata_attribute_filter');
     return $_ldapdata_ldap;
   }
@@ -634,28 +866,335 @@ function _ldapdata_ldap_info($sid, $req) {
   if (!($sid = is_object($sid) ? (isset($sid->ldap_config) ? $sid->ldap_config : NULL) : $sid))
     return;
 
-  static $servers = array();
-  if (!isset($servers[$sid]))
-    $servers[$sid] = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE sid = %d", $sid));
-
+  $server = ldapauth_server_load($sid);
   switch ($req) {
     case 'mapping_type':
-      $ldapdata_mappings = !empty($servers[$sid]->ldapdata_mappings) ? unserialize($servers[$sid]->ldapdata_mappings) : array();
+      $ldapdata_mappings = !empty($server->ldapdata_mappings) ? unserialize($server->ldapdata_mappings) : array();
       return isset($ldapdata_mappings['access']) ? $ldapdata_mappings['access'] : LDAPDATA_MAP_NOTHING;
     case 'ldapdata_mappings':
-      return !empty($servers[$sid]->ldapdata_mappings) ? unserialize($servers[$sid]->ldapdata_mappings) : array();
+      return !empty($server->ldapdata_mappings) ? unserialize($server->ldapdata_mappings) : array();
     case 'ldapdata_roattrs':
-      return !empty($servers[$sid]->ldapdata_roattrs) ? unserialize($servers[$sid]->ldapdata_roattrs) : array();
+      return !empty($server->ldapdata_roattrs) ? unserialize($server->ldapdata_roattrs) : array();
     case 'ldapdata_rwattrs':
-      return !empty($servers[$sid]->ldapdata_rwattrs) ? unserialize($servers[$sid]->ldapdata_rwattrs) : array();
+      return !empty($server->ldapdata_rwattrs) ? unserialize($server->ldapdata_rwattrs) : array();
     case 'ldapdata_binddn':
-      return $servers[$sid]->ldapdata_binddn;
+      return $server->ldapdata_binddn;
     case 'ldapdata_bindpw':
-      return $servers[$sid]->ldapdata_bindpw;
+      return $server->ldapdata_bindpw;
     case 'ldapdata_attrs':
-      return !empty($servers[$sid]->ldapdata_attrs) ? unserialize($servers[$sid]->ldapdata_attrs) : array();
+      return !empty($server->ldapdata_attrs) ? unserialize($server->ldapdata_attrs) : array();
     case 'ldapdata_filter_php':
-      return $servers[$sid]->ldapdata_filter_php;
+      return $server->ldapdata_filter_php;
+  }
+}
+
+/**
+ * Return a random salt of a given length for crypt-style passwords
+ *
+ *  *Most of the code here is from phpLDAPadmin.
+ *
+ */
+function random_salt( $length ) {
+  $possible = '0123456789'.
+              'abcdefghijklmnopqrstuvwxyz'.
+              'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
+              './';
+  $str = "";
+
+  mt_srand((double)microtime() * 1000000);
+  while ( strlen( $str ) < $length )
+    $str .= substr( $possible, ( rand() % strlen( $possible ) ), 1 );
+
+  return $str;
+}
+
+/**
+ * Return an encrypted password
+ *
+ *  *Most of the code here is from phpLDAPadmin.
+ *
+ */
+function encode_password($clearTxt) {
+  global $_ldapdata_ldap;
+
+  switch ($_ldapdata_ldap->getOption('enc_type')) {
+    case 1: // MD5
+      $cipherTxt = '{MD5}' . base64_encode( pack( 'H*' , md5( $clearTxt) ) );
+      break;
+
+    case 2: // Crypt
+      $cipherTxt = '{CRYPT}' . crypt($clearTxt, substr($clearTxt, 0, 2));
+      break;
+
+    case 3: // Salted Crypt
+      $cipherTxt = '{CRYPT}' . crypt($clearTxt, random_salt(2));
+      break;
+
+    case 4: // Extended DES
+      $cipherTxt = '{CRYPT}' . crypt( $clearTxt, '_' . random_salt(8) );
+      break;
+
+    case 5: // MD5Crypt
+      $cipherTxt = '{CRYPT}' . crypt( $clearTxt , '$1$' . random_salt(9) );
+      break;
+
+    case 6: // Blowfish
+      $cipherTxt = '{CRYPT}' . crypt( $clearTxt , '$2a$12$' . random_salt(13) );
+      break;
+
+    case 7: // Salted MD5
+      mt_srand( (double) microtime() * 1000000 );
+      $salt = mhash_keygen_s2k( MHASH_MD5, $clearTxt, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
+      $cipherTxt = "{SMD5}" . base64_encode( mhash( MHASH_MD5, $clearTxt . $salt ) . $salt );
+      break;
+
+    case 8: // SHA
+      if ( function_exists('sha1') ) {
+        $cipherTxt = '{SHA}' . base64_encode( pack( 'H*' , sha1( $clearTxt) ) );
+      }
+      elseif ( function_exists( 'mhash' ) ) {
+        $cipherTxt = '{SHA}' . base64_encode( mhash( MHASH_SHA1, $clearTxt) );
+      }
+      break;
+
+    case 9: // Salted SHA
+      mt_srand( (double) microtime() * 1000000 );
+      $salt = mhash_keygen_s2k( MHASH_SHA1, $clearTxt, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
+      $cipherTxt = "{SSHA}" . base64_encode( mhash( MHASH_SHA1, $clearTxt . $salt ) . $salt );
+      break;
+
+    default: // Cleartext
+      $cipherTxt = $clearTxt;
+  }
+  return $cipherTxt;
+}
+/**
+ * Implementation of hook_form_alter().
+ *
+ * Note: Provides support for avatarcrop module (AC).  However, the AC module
+ * needs to have the drupal_goto call in the cropUserPic form replaces with
+ * a $form_state['redirect'] call and the uid added as a form value.
+ * Patch for AC will soon be created.
+ */
+function ldapdata_form_alter(&$form, $form_state, $form_id) {
+  switch ( $form_id ) {
+    case 'cropUserPic':
+      $form['#submit'][] = 'ldapdata_avatarcrop_submit';
+      break;
+// Add picture UI options
+    case 'ldapauth_admin_settings':
+      if ( variable_get('user_pictures', '0')) {
+        $form['ldap-ui']['ldapdata_disable_picture_change'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Remove picture upload and delete fields from user edit form'),
+          '#default_value' => LDAPDATA_DISABLE_PICTURE_CHANGE,
+          '#description' => t('If checked, LDAP users will not see these change user picture fields. Use this if ldapdata maps the user picture to an ldap attribute and the map type is "read only" since LDAP users will not be able to change pictures via Drupal.'),
+        );
+        $form['#submit'][] = 'ldapdata_ldapauth_admin_settings_submit';
+      }
+      break;
+    // Remove user picture fields if needed
+    case 'user_profile_form':
+      $account = $form["_account"]["#value"];
+      if ($user->uid != 1 && isset($account->ldap_authentified) && LDAPDATA_DISABLE_PICTURE_CHANGE && isset($form['picture'])) {
+        unset($form['picture']);
+      }
+      break;
+  }
+}
+/**
+ * Submit hook for the ldapauth settings form.
+ * Handles ui addition
+ */
+function ldapdata_ldapauth_admin_settings_submit($form, &$form_state) {
+  $op = $form_state['clicked_button']['#value'];
+  $values = $form_state['values'];
+  switch ($op) {
+    case t('Save configuration'):
+      variable_set('ldapdata_disable_picture_change', $values['ldapdata_disable_picture_change']);
+      break;
+    case t('Reset to defaults'):
+      variable_del('ldapdata_disable_picture_change');
+      break;
+  }
+}
+
+/**
+ * Handle updating ldap when avatarcrop updates picture.
+ *
+ * @param Array $form
+ * @param Array $form_state
+ */
+function ldapdata_avatarcrop_submit($form, &$form_state) {
+  $uid = $form_state['values']['change_pic_uid'];
+  $result = db_fetch_object(db_query("SELECT picture FROM {users} WHERE uid=%d", $uid));
+  if ( ! empty($result->picture)) {
+    $account = user_load($uid);
+    $update = array(
+      'picture' => $result->picture,
+    );
+    _ldapdata_user_submit($update, $account, 'account');
+  }
+}
+/**
+ * Implementation of hook_schema_alter().
+ *
+ * @param &$schema Nested array describing the schemas for all modules.
+ */
+function ldapdata_schema_alter($schema) {
+  $schema['ldapauth']['fields']['ldapdata_binddn'] = array(
+    'type' => 'varchar',
+    'length' => 255,
+  );
+  $schema['ldapauth']['fields']['ldapdata_bindpw'] = array(
+    'type' => 'varchar',
+    'length' => 255,
+  );
+  $schema['ldapauth']['fields']['ldapdata_rwattrs'] = array(
+    'type' => 'text',
+    'not null' => FALSE,
+  );
+  $schema['ldapauth']['fields']['ldapdata_roattrs'] = array(
+    'type' => 'text',
+    'not null' => FALSE,
+  );
+  $schema['ldapauth']['fields']['ldapdata_mappings'] = array(
+    'type' => 'text',
+    'not null' => FALSE,
+  );
+  $schema['ldapauth']['fields']['ldapdata_attrs'] = array(
+    'type' => 'text',
+    'not null' => FALSE,
+  );
+  $schema['ldapauth']['fields']['ldapdata_filter_php'] = array(
+    'type' => 'text',
+    'not null' => FALSE,
+  );
+}
+/**
+ * Implementation of hook_nodeapi().
+ *
+ * @param &$node The node the action is being performed on.
+ * @param $op What kind of action is being performed. Possible values: alter, delete, delete revision, insert, load, prepare, prepare translation, print, rss item, search result, presave, update, update index, validate, view
+ * @param $a3
+ * @param $a4
+ */
+function ldapdata_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
+  switch ( $op ) {
+    case 'update':
+      ldapdata_node_update($node);
+      break;
+    default:
   }
 }
+/**
+ * Drupal 7 hook_node_update.  Handles the case of content profile updates
+ * being written back to ldap if needed.
+ *
+ * @param Object $node
+ */
+function ldapdata_node_update( $node ) {
+  global $_ldapdata_ldap;
+
+  // Is this being called after the normal sync rules have been applied?
+  if ( isset($node->ldap_synched) ) {
+    return;
+  }
+
+  if ( module_exists('content_profile') && is_content_profile($node->type)) {
 
+    $account = user_load($node->uid);
+
+    // Only care about ldap authenticated users.
+    if (!isset($account->ldap_authentified))
+      return;
+
+    // Setup the global $_ldapdata_ldap object.
+    if (!_ldapdata_init($account))
+      return;
+
+    $writeout = _ldapdata_user_update_content_profile($node, $account);
+    if ($writeout) {
+      $bind_info = _ldapdata_edition($account);
+      if (!$_ldapdata_ldap->connect($bind_info['dn'], $bind_info['pass'])) {
+        watchdog('ldapdata', "User update: user %name's data could not be updated in the LDAP directory", array('%name' => $account->name), WATCHDOG_NOTICE);
+        return;
+      }
+      if (!($_ldapdata_ldap->writeAttributes($account->ldap_dn, $writeout))) {
+        drupal_set_message(t('The data was not written to LDAP.'), 'error');
+      }
+    }
+    $_ldapdata_ldap->disconnect();
+    $node->ldap_synched = TRUE;  // Just in case update called twice in a page.
+  }
+}
+/**
+ * Find out which content profile attributes should be synced back to LDAP.
+ *
+ * @param $node
+ *   A content profile node being updated.
+ * @param $account
+ *   A user object.
+ *
+ * @return
+ *   An associated array of attributes to write to LDAP.
+ */
+function _ldapdata_user_update_content_profile(&$node, &$account) {
+  if (_ldapdata_ldap_info($account, 'mapping_type') != LDAPDATA_MAP_ATTRIBUTES)
+    return array();
+
+  $ldap_drupal_reverse_mappings = _ldapdata_reverse_mappings($account->ldap_config);
+
+  // Retrieve profile fields list.
+  $content_profile_fields = _ldapdata_retrieve_content_profile_fields();
+
+  // Compare against $edit list.
+  $writeout = array();
+  foreach ($content_profile_fields as $key => $field_name) {
+    $field = $node->$key;
+    if (isset($field) && isset($ldap_drupal_reverse_mappings[$key])) {
+
+      // Determine what kind of field we are dealing with
+      // TODO: Handle multiple value fields
+      $field_lookup = content_fields($key);
+      $field_type = $field_lookup['type'];
+      switch ($field_type) {
+        case 'email':
+          $writeout[$ldap_drupal_reverse_mappings[$key]] = $field[0]['email'];
+          break;
+        case 'content_taxonomy':
+          // Convert tid to term name since that is what the _load_user does
+          if ($term = taxonomy_get_term($field[0]['value'])) {
+            $writeout[$ldap_drupal_reverse_mappings[$key]] = $term;
+          }
+          break;
+        default:
+          $writeout[$ldap_drupal_reverse_mappings[$key]] = $field[0]['value'];
+      }
+    }
+  }
+  return $writeout;
+}
+/**
+ * Implements hook_ldap_attributes_needed_alter
+ *
+ * @param Array $attributes array of attributes to be returned from ldap queries
+ * @param String $op The operation being performed such as 'user_update', 'user_insert', ...
+ * @param Mixed $server Server sid or server object
+ */
+function ldapdata_ldap_attributes_needed_alter( &$attributes, $op, $server = NULL) {
+  if ( $server ) {
+    $sid = is_object( $server ) ? $server->sid : $server;
+    switch ($op) {
+      case LDAPAUTH_SYNC_CONTEXT_INSERT_DRUPAL_USER:
+      case LDAPAUTH_SYNC_CONTEXT_UPDATE_DRUPAL_USER:
+        $attributes[] = 'dn';
+        foreach (_ldapdata_ldap_info($sid, 'ldapdata_mappings') as $key => $value) {
+          if ( ! in_array($key, array('access', 'status'))) {
+            $attributes[] = $value;
+          }
+        }
+        break;
+    }
+  }
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.theme.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.theme.inc
index 65bc69d..7077d1a 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.theme.inc
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapdata.theme.inc
@@ -1,5 +1,4 @@
 <?php
-// $Id: ldapdata.theme.inc,v 1.3 2009/03/18 12:12:02 miglius Exp $
 
 /**
  * @file
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.admin.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.admin.inc
index 3f24d33..8443d19 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.admin.inc
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.admin.inc
@@ -1,5 +1,4 @@
 <?php
-// $Id: ldapgroups.admin.inc,v 1.11 2009/05/04 00:26:17 miglius Exp $
 
 /**
  * @file
@@ -85,39 +84,51 @@ function ldapgroups_admin_edit(&$form_state, $op, $sid) {
       '#value' => t('Configure LDAP groups to Drupal roles mapping settings for the %server.', array('%server' => $edit['name'])),
     );
 
-    $form['group_dn'] = array(
+    // How to find groups section
+    $form['group-definitions'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Group Definitions'),
+      '#description' => t('Define how group information is stored in your LDAP database by using one or more of the methods below.'),
+      '#collapsible' => TRUE,
+      '#collapsed' => FALSE,
+    );
+
+    $form['group-definitions']['group_dn'] = array(
       '#type' => 'fieldset',
       '#title' => t('Group by DN'),
+      '#description' => t('Use this method if your users\' DNs look like <em style="font-style: normal; padding: 1px 3px; border: 1px solid #8888CC; background-color: #DDDDFF">cn=jdoe,<strong>ou=Group1</strong>,cn=example,cn=com</em> and <em style="font-style: normal; padding: 1px 3px; border: 1px solid #8888CC; background-color: #DDDDFF">Group1</em> turns out to be the group you want.</p>'),
       '#collapsible' => TRUE,
       '#collapsed' => !$edit['ldapgroups_in_dn'],
     );
-    $form['group_dn']['ldapgroups_in_dn'] = array(
+    $form['group-definitions']['group_dn']['ldapgroups_in_dn'] = array(
       '#type' => 'checkbox',
       '#title' => t('Group is specified in user\'s DN'),
       '#default_value' => $edit['ldapgroups_in_dn'],
-      '#description' => '<p>Check this option if your users\' DNs look like <em style="font-style: normal; padding: 1px 3px; border: 1px solid #8888CC; background-color: #DDDDFF">cn=jdoe,<strong>ou=Group1</strong>,cn=example,cn=com</em> and <em style="font-style: normal; padding: 1px 3px; border: 1px solid #8888CC; background-color: #DDDDFF">Group1</em> turns out to be the group you want.</p>'
+      '#description' => t('Check to enable this method.'),
     );
-    $form['group_dn']['ldapgroups_dn_attribute'] = array(
+    $form['group-definitions']['group_dn']['ldapgroups_dn_attribute'] = array(
       '#type' => 'textfield',
       '#title' => t('Attribute of the DN which contains the group name'),
       '#default_value' => $edit['ldapgroups_dn_attribute'],
       '#size' => 50,
       '#maxlength' => 255,
-      '#description' => t('The name of the attribute which contains the group name. In the example above, it would be <em style="font-style: normal; padding: 1px 3px; border: 1px solid #8888CC; background-color: #DDDDFF">ou</em>, as the DN contains the string <em style="font-style: normal; padding: 1px 3px; border: 1px solid #8888CC; background-color: #DDDDFF">ou=Group1</em> and <em style="font-style: normal; padding: 1px 3px; border: 1px solid #8888CC; background-color: #DDDDFF">Group1</em> happens to be the desired group name.'),
+      '#description' => t('The name of the attribute which contains the group name. In the example above, it would be <em style="font-style: normal; padding: 1px 3px; border: 1px solid #8888CC; background-color: #DDDDFF">ou</em>, as the DN contains the string <em style="font-style: normal; padding: 1px 3px; border: 1px solid #8888CC; background-color: #DDDDFF">ou=Group1</em> and <em style="font-style: normal; padding: 1px 3px; border: 1px solid #8888CC; background-color: #DDDDFF">Group1</em> happens to be the desired group name. Note:  If the attribute appears more than once in the DN, the user will be listed in multiple groups.'),
     );
 
-    $form['group_attr'] = array(
+    $form['group-definitions']['group_attr'] = array(
       '#type' => 'fieldset',
       '#title' => t('Group by attribute'),
+      '#description' => t('Use this method if your user\'s LDAP entries contain attributes that define their group membership, e.g. AD\'s memberof attribute.</p>'),
       '#collapsible' => TRUE,
       '#collapsed' => !$edit['ldapgroups_in_attr'],
     );
-    $form['group_attr']['ldapgroups_in_attr'] = array(
+    $form['group-definitions']['group_attr']['ldapgroups_in_attr'] = array(
       '#type' => 'checkbox',
       '#title' => t('Groups are specified by LDAP attributes'),
+      '#description' => t('Check to enable this method.'),
       '#default_value' => $edit['ldapgroups_in_attr'],
     );
-    $form['group_attr']['ldapgroups_attr'] = array(
+    $form['group-definitions']['group_attr']['ldapgroups_attr'] = array(
       '#type' => 'textarea',
       '#title' => t('Attribute names (one per line)'),
       '#default_value' => implode("\n", ($edit['ldapgroups_attr'] ? unserialize($edit['ldapgroups_attr']) : array())),
@@ -126,53 +137,94 @@ function ldapgroups_admin_edit(&$form_state, $op, $sid) {
       '#description' => t('If the groups are stored in the user entries, along with the rest of their data, then enter here a list of attributes which may contain them.'),
     );
 
-    $form['group_entry'] = array(
+    $form['group-definitions']['group_entry'] = array(
       '#type' => 'fieldset',
       '#title' => t('Group by entry'),
+      '#description' => t('Groups exist as LDAP entries with a multivalued attribute containing either the members\' DNs or username.  E.g. Standard LDAP group objects like groupOfNames that use the \'member\' multivalue attribute or posixGroup with memberUID.'),
       '#collapsible' => TRUE,
       '#collapsed' => !$edit['ldapgroups_as_entries'],
     );
-    $form['group_entry']['ldapgroups_as_entries'] = array(
+    $form['group-definitions']['group_entry']['ldapgroups_as_entries'] = array(
       '#type' => 'checkbox',
-      '#title' => t('Groups exist as LDAP entries where a multivalued attribute contains the members\' CNs'),
+      '#title' => t('Groups exist as LDAP entries with a multivalued membership attribute'),
+      '#description' => t('Check to enable this method.'),
       '#default_value' => $edit['ldapgroups_as_entries'],
     );
-    $form['group_entry']['ldapgroups_entries'] = array(
+    $form['group-definitions']['group_entry']['ldapgroups_entries'] = array(
       '#type' => 'textarea',
-      '#title' => t('LDAP DNs containing groups (one per line)'),
+      '#title' => t('Base LDAP DNs containing groups (one per line)'),
       '#default_value' => implode("\n", ($edit['ldapgroups_entries'] ? unserialize($edit['ldapgroups_entries']) : array())),
       '#cols' => 50,
       '#rows' => 6,
-      '#description' => t('Enter here a list of LDAP nodes from where groups should be searched for. The module will look them up recursively from the given nodes.'),
+      '#description' => t('Base DNs to search for group entries. The module will look under each of these for group entries.'),
     );
-    $form['group_entry']['ldapgroups_entries_attribute'] = array(
+    $form['group-definitions']['group_entry']['ldapgroups_entries_attribute'] = array(
       '#type' => 'textfield',
       '#title' => t('Attribute holding group members'),
       '#default_value' => $edit['ldapgroups_entries_attribute'],
       '#size' => 50,
       '#maxlength' => 255,
-      '#description' => t('Name of the multivalued attribute which holds the CNs of group members, for example: !attr', array('!attr' => theme('placeholder', LDAPGROUPS_DEFAULT_ENTRIES_ATTRIBUTE))),
+      '#description' => t('Name of the multivalued attribute which holds either the DNs or LDAP usernames of group members, for example: !attr', array('!attr' => theme('placeholder', LDAPGROUPS_DEFAULT_ENTRIES_ATTRIBUTE))),
     );
+
+    // Access rules section
     $form['groups_limit'] = array(
       '#type' => 'fieldset',
-      '#title' => t('LDAP group to Drupal role limits'),
+      '#title' => t('LDAP Groups Server Access Rules'),
       '#collapsible' => TRUE,
       '#collapsed' => !$edit['ldapgroups_groups'],
     );
+    $form['groups_limit']['info'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Server Access Rules Help'),
+      '#description' => t('<p>Rules can be define below that will limit who can access this server.  These rules can take two forms.</p>' .
+        '<p>First, it can just be a list of groups.  In this case, the user must be a member of at least one of these groups to be allowed access.</p>' .
+        '<p>The second form uses rules of the format: "action-type: group-name". Each rule group-name is compared to the user\'s groups.  If the user is a member of the rule\'s group, the action is applied.  The last matching rule determines the user\'s access rights.  Note that all rule sets start with access denied.</p>' .
+        '<p>The action types are:</p>' .
+        '<ul><li>ALLOW - Access granted if user is in the group and not denied by rule below it.</li>' .
+        '<li>ALLOW-X - If the user is in the group, access is granted and rule processing ends</li>' .
+        '<li>DENY - User is denied if they are in the group unless granted by a rule below this one.</li>' .
+        '<li>DENY-X - User denied if in group and no further rules are processed.</li></ul>' .
+        '<p>In addition, there are two "PSEUDO" groups that can be used in rules:</p>' .
+        '<ul><li>ALL - Matches all authenticated LDAP users</li>' .
+        '<li>EXISTING - Matches existing users who have been authenticated by LDAP in the past.</li></ul>' .
+        '<p>Here\'s an example ruleset to deny all Group1 users but allow existing users and (new) Group2 users to access the server.</p>' .
+        '<ul><li>DENY-X: cn=Group1,ou=Groups,dc=myorg</li>' .
+        '<li>ALLOW-X: EXISTING</li>' .
+        '<li>ALLOW: cn=Group2,ou=Groups,dc=myorg</li></ul>' .
+        '<p>Note that rule types and groups are case insensitive.  However, group names must have the same spacing as returned by the server to match.  E.g. if server return cn=X,ou=Groups... then a rule group name, cn=X, ou=Groups... will not match because of the space after the comma.</p>'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+    );
     $form['groups_limit']['ldapgroups_groups'] = array(
       '#type' => 'textarea',
-      '#title' => t('LDAP groups which allow automatic account creation'),
+      '#title' => t('Group access rules'),
       '#default_value' => implode("\n", ($edit['ldapgroups_groups'] ? unserialize($edit['ldapgroups_groups']) : array())),
       '#cols' => 50,
       '#rows' => 5,
-      '#description' => t('Leave blank to automatically create accounts for all LDAP authenticated users. Otherwise, enter a one per line list of LDAP groups. If the user is not in any of those groups, the login will be denied.'),
+      '#description' => t('Leave blank to allow all LDAP authenticated users access. Otherwise, enter a one per line list of LDAP groups or access rules. If the user is not in any of those groups or the last matching rule denies access, the login will be denied.'),
     );
+
+    // Mappings section
     $form['group_filter'] = array(
       '#type' => 'fieldset',
       '#title' => t('LDAP group to Drupal role filtering'),
-      '#description' => t('The module automatically decides names for the Drupal roles based in the names of the LDAP groups. For example:<ul><li>LDAP group: Admins => Drupal role: Admins</li><li>LDAP group: ou=Underlings,dc=myorg,dc=mytld => Drupal role: Underlings.</li></ul>'),
+      '#description' => t('If there is nothing entered in this section, the module will automatically decide Drupal roles name.  These will be based on the names of the LDAP groups. For example:<ul><li>LDAP group: Admins => Drupal role: Admins</li><li>LDAP group: ou=Underlings,dc=myorg,dc=mytld => Drupal role: Underlings.</li></ul>'),
       '#collapsible' => TRUE,
-      '#collapsed' => !($edit['ldapgroups_mappings'] || $edit['ldapgroups_filter_php']),
+      '#collapsed' => !($edit['ldapgroups_mappings'] || $edit['ldapgroups_filter_php'] || $edit['ldapgroups_mappings_filter']),
+    );
+    $options_filter_mode = array(
+      LDAPGROUPS_ROLE_MODE_AUTO => t("Use automatic LDAP group name to Drupal role name mapping"),
+      LDAPGROUPS_ROLE_MODE_USE_MAP => t("Use LDAP group to Drupal role mapping defined below"),
+      LDAPGROUPS_ROLE_MODE_DISABLED => t("Do not user LDAP groups for Drupal roles (i.e. access restrictions only).")
+      );
+
+    $form['group_filter']['ldapgroups_mappings_filter'] = array(
+      '#type' => 'radios',
+      '#title' => t('Select how to map LDAP groups to Drupal roles'),
+      '#options' => $options_filter_mode,
+      '#default_value' => $edit['ldapgroups_mappings_filter'],
+//      '#description' => t('In automatic mode a Drupal role will be created for every group the user is associated with.')
     );
     $mappings = '';
     foreach (($edit['ldapgroups_mappings'] ? unserialize($edit['ldapgroups_mappings']) : array()) as $group => $role)
@@ -183,13 +235,7 @@ function ldapgroups_admin_edit(&$form_state, $op, $sid) {
       '#default_value' => $mappings,
       '#cols' => 50,
       '#rows' => 5,
-      '#description' => t('Enter a list of LDAP groups and their Drupal role mappings, one per line with a | delimiter. Should be in the form [ldap group]|[drupal role] such as:<br/>cn=ED IT NAG Staff,DC=ad,DC=uiuc,DC=edu|admin<br/>cn=Ed Webs UIUC Webmasters,DC=ad,DC=uiuc,DC=edu|committee member'),
-    );
-    $form['group_filter']['ldapgroups_mappings_filter'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Use LDAP group to Drupal roles filtering'),
-      '#default_value' => $edit['ldapgroups_mappings_filter'],
-      '#description' => t('If enabled, only above mapped groups will be mapped to Drupal roles. If not enabled, a Drupal role will be created for every group the user is associated with.')
+      '#description' => t('Enter a list of LDAP groups and their Drupal role mappings, one per line with a | delimiter. Should be in the form [ldap group]|[drupal role],[drupal role] such as:<br/>cn=ED IT NAG Staff,DC=ad,DC=uiuc,DC=edu|admin<br/>cn=Ed Webs UIUC Webmasters,DC=ad,DC=uiuc,DC=edu|author, reviewer'),
     );
     $form['group_filter']['ldapgroups_filter_php'] = array(
       '#type' => 'textarea',
@@ -258,7 +304,7 @@ function ldapgroups_admin_edit_validate($form, &$form_state) {
       if (!$ldapgroups_role_mappings)
         form_set_error('ldapgroups_mappings', t('Bad mapping syntax.'));
 
-      if ($values['ldapgroups_mappings_filter'] && !trim($values['ldapgroups_mappings']))
+      if ($values['ldapgroups_mappings_filter'] == LDAPGROUPS_ROLE_MODE_USE_MAP && !trim($values['ldapgroups_mappings']))
         form_set_error('ldapgroups_mappings', t('Mappings are missing.'));
 
       $form_state['ldapgroups_groups'] = array();
@@ -295,4 +341,260 @@ function ldapgroups_admin_edit_submit($form, &$form_state) {
       break;
   }
 }
+/**
+ * Test users against the current ldapgroups settings
+ *
+ * @param Array $form_state
+ */
+function ldapgroups_user_test(&$form_state) {
+
+  $servers = ldapauth_server_load_all();
+  $options_servers = array();
+  foreach ( $servers as $server ) {
+    $options_servers[$server->sid] = $server->name;
+  }
+
+  $form['user_selection'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('User Selection'),
+    '#description' => t('This page will let you test the ldapgroups settings against different users.  This is useful to make sure they are setup correctly and to help debug settings (e.g. user group name does not match rule name).  Enter either an existing LDAP authenticated Drupal user name or a server / dn combination and press Test to see results'),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
+  );
+  $form['user_selection']['test_user'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Drupal User name to test'),
+    '#size' => 50,
+    '#maxlength' => 255,
+    '#default_value' => $form_state['values']['test_user'],
+    '#description' => t('Enter an existing LDAP authenticated Drupal user to test group settings with.'),
+  );
+  $form['user_selection']['or'] = array(
+    '#value' => t('OR'),
+  );
+  $form['user_selection']['server'] = array(
+    '#type' => 'radios',
+    '#title' => t('Select a server'),
+    '#options' => $options_servers,
+    '#default_value' => $form_state['values']['server'],
+  );
+  $form['user_selection']['dn'] = array(
+    '#type' => 'textfield',
+    '#title' => t('LDAP DN to test'),
+    '#size' => 100,
+    '#maxlength' => 255,
+    '#description' => t('Enter an LDAP user\'s DN to test group settings with.'),
+    '#default_value' => $form_state['values']['dn'],
+  );
+  $form['user_selection']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Test'),
+  );
+
+  if ( isset($form_state['storage']['results'])) {
+    $form['results'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Test Results'),
+      '#description' => t('The following information was found for this user.'),
+      '#collapsible' => FALSE,
+      '#collapsed' => FALSE,
+    );
+    $form['results']['test_user_results'] = array(
+      '#title' => t('Test Results'),
+      '#value' => $form_state['storage']['results'],
+    );
+  }
+
+  return $form;
+}
+/**
+ * Validate the supplied test info.
+ *
+ * @param Array $form
+ * @param Array $form_state
+ */
+function ldapgroups_user_test_validate($form, &$form_state ) {
+
+  module_load_include('inc', 'ldapgroups', 'ldapgroups');
+
+  $values = $form_state['values'];
+
+  if ( $values['server'] && $values['dn'] && $values['test_user']) {
+    form_set_error('', t('Can not have all three fields filled.  Use only a Drupal name or LDAP server/dn pair.'));
+    return;
+  }
+
+  if ( $values['server'] && $values['dn'] ) {
+    if ( ! ldapgroups_is_configured( $values['server']) ) {
+      form_set_error('', t('Server, @server, has no LDAP group settings defined yet.', array("@server" => $values['server'])));
+    }
+    return;
+  }
+
+  $account = user_load(array('name' => $values['test_user']));
+  if ( ! $account ) {
+    form_set_error('test_user', t("Invalid user name") );
+    return;
+  }
+  if (  ! $account->ldap_authentified  || $account->ldap_authentified != 1 ) {
+    form_set_error('test_user', t("User was not an LDAP authenticated user."));
+    return;
+  }
+  if ( ! ldapgroups_is_configured( $account->ldap_config) ) {
+    form_set_error('', t('Server, @server, has no LDAP group settings defined yet.', array("@server" => $account->ldap_config)));
+    return;
+  }
+  $form_state['values']['account'] = $account;
+}
+/**
+ * Submit handler for testing user against the ldapgroups settings.
+ *
+ * @param Array $form
+ * @param Array $form_state
+ */
+function ldapgroups_user_test_submit($form, &$form_state ) {
+
+  if ( isset($form_state['values']['account']) ) {
+    $account = $form_state['values']['account'];
+    $dn = $account->ldap_dn;
+    $sid = $account->ldap_config;
+  }
+  else {
+    $account = NULL;
+    $dn = $form_state['values']['dn'];
+    $sid = $form_state['values']['server'];
+  }
+  $form_state['storage']['results'] = ldapgroups_user_test_output( $account, $sid, $dn );
+}
+/**
+ * Generate the test results for the user and ldap settings.
+ *
+ * @param Object $account
+ * @param int $sid
+ * @param String $dn
+ */
+function ldapgroups_user_test_output( $account, $sid, $dn ) {
+  global $_ldapgroups_ldap;
 
+  module_load_include('inc', 'ldapgroups', 'ldapgroups');
+
+  // Setup the global $_ldapgroups_ldap object.
+  if (!_ldapgroups_ldap_init($sid)) {
+    drupal_set_message(t('Could not initialize the LDAP connection object!'), 'error');
+    return FALSE;
+  }
+
+
+  // Use the lookup dn/password or announymous if not set.
+  // Note: This may fail if LDAP security limits access to needed info.
+  $bind_dn = $_ldapgroups_ldap->getOption('binddn');
+  $pass = $_ldapgroups_ldap->getOption('bindpw');
+  if (!$_ldapgroups_ldap->connect($bind_dn, $pass)) {
+    $bind_name = empty($bind_dn ) ? t("anonymous") : $bind_dn;
+    drupal_set_message(t('Could not bind to the LDAP server as @name!', array('@name' => $bind_name)), 'error');
+    return FALSE;
+  }
+
+  $ldap_info = ldapauth_user_lookup_by_dn($_ldapgroups_ldap, $dn, LDAPAUTH_SYNC_CONTEXT_AUTHENTICATE_DRUPAL_USER);
+  if ( empty($ldap_info) ) {
+    drupal_set_message(t("Could not find specified DN"));
+    return FALSE;
+  }
+
+  $name_attr = $_ldapgroups_ldap->getOption('user_attr');
+  $ldap_name = isset($ldap_info[$name_attr][0]) ? $ldap_info[$name_attr][0] : $ldap_info[drupal_strtolower($name_attr)][0];
+  if ( ! $account ) {
+    $account = ldapauth_drupal_user_lookup($_ldapgroups_ldap, $ldap_name, $dn, $error );
+  }
+
+  $output = '<p>';
+  $output .= "<b>" . t('Drupal User Info') . "</b><br/>";
+  if ( $account ) {
+    $output .= t("Drupal user name") . ":  {$account->name}<br/>";
+    $output .= t("LDAP Authentified") . ": " . ( $account->ldap_authentified ? "Yes" : "No") . "<br/>";
+  }
+  else {
+    $output .= t("No matching Drupal User found.") . "<br/>";
+  }
+  $output .= "<br/><b>" . t("LDAP User Info") . "</b><br/>";
+  $output .= t("LDAP server") . ": {$_ldapgroups_ldap->getOption('name')}<br/>";
+  $output .= t("LDAP user name") . ": {$ldap_name}<br/>";
+  $output .= t("LDAP dn") . ": {$dn}<br/>";
+
+
+  // First, we figure out the appropriate groups.
+  $groups = ldapgroups_groups_load($_ldapgroups_ldap, $dn, $ldap_name );
+  $output .= "<br/><b>" . t("User's LDAP Groups") . "</b><br/>";
+
+  if ( $groups ) {
+    foreach ( $groups as $group ) {
+      $output .= "{$group}<br/>";
+    }
+  }
+  else {
+    if ( $groups === FALSE ) {
+      $output .= t("An error occured getting group information!") . "<br/>";
+    }
+    else {
+      $output .= t("No groups found") . "<br/>";
+    }
+  }
+
+  $output .= "<br/><b>" . t("Server Access") . "</b><br/>";
+  $groups_allowed = _ldapgroups_ldap_info($sid, 'ldapgroups_groups');
+  if ( empty($groups_allowed)  ) { // Nothing to do here.
+    $output .= t("No access rules defined.") . "<br/>";
+  }
+
+  $denied = FALSE;
+  ldapgroups_ldap_user_deny_alter( $denied, $_ldapgroups_ldap, $ldap_name, $dn, $account );
+  $access = ! $denied ? t("Allowed") : t("Denied");
+  $output .= t("Server access") . ": {$access}<br/>";
+
+  $output .= "<br/><b>" . t("User's Drupal Roles") . "</b><br/>";
+  $role_mapping = _ldapgroups_ldap_info($sid, 'ldapgroups_mappings_filter');
+  switch ( $role_mapping ) {
+    case LDAPGROUPS_ROLE_MODE_AUTO:
+      $role_mapping_mode = t("Automatic mode");
+      break;
+    case LDAPGROUPS_ROLE_MODE_USE_MAP:
+      $role_mapping_mode = t("Mapping defined in server settings");
+      break;
+    case LDAPGROUPS_ROLE_MODE_DISABLED:
+      $role_mapping_mode =  t("Role mapping disabled");
+      break;
+  }
+
+  $output .= t("Role Mapping Mode") . ": {$role_mapping_mode}<br/>";
+
+  // Is Role mapping disabled?
+  if ( $role_mapping != LDAPGROUPS_ROLE_MODE_DISABLED ) {
+
+    // Apply site-specific rules.
+    $filtered_groups = _ldapgroups_filter($sid, $groups);
+
+    // At this point, the roles are in the full DN format or role names.
+    $roles = array();
+    if (!empty($filtered_groups)) {
+      foreach ($filtered_groups as $group) {
+        $role = _ldapgroups_mapping($sid, $group);
+        $roles[] = $role;
+      }
+    }
+    $roles = array_unique($roles);
+
+    drupal_alter("ldap_user_roles", $roles, $account, $dn, $groups, $filtered_groups );
+
+    if ( ! empty($roles) ) {
+      foreach ( $roles as $role ) {
+        $output .= "{$role}<br/>";
+      }
+    }
+    else {
+      $output .= t("No roles found") . "<br/>";
+    }
+  }
+
+  $output .= "</p>";
+  return $output;
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.api.php b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.api.php
new file mode 100644
index 0000000..ab7a3ca
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.api.php
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * @file
+ * LDAPGroups API function documentation
+ */
+
+/**
+ * Allows an LDAP user's set of ldap groups be altered or added to.
+ *
+ * This hook is called after the group detection methods defined in
+ * the admin UI have been processed but before any access rules or role
+ * mapping has been done..
+ *
+ * @param Array $groups An array whose values are the user's groupsr
+ * @param LDAPInterface $ldap LDAP server interface object bound to server as ldap user.
+ * @param String $dn The DN for the user being processed.
+ * @param String $name The user's LDAP user name.
+ */
+function hook_ldap_user_groups_alter( &$groups, $ldap, $dn, $name ) {
+  // Some example code to add a group that is the parent on the
+  // user's dn, e.g. cn=Bob Admin,ou=admins,ou=dept1,dc=myorg will have a
+  // group added like:  ou=admin,ou=dept1,dc=myorg.  This can then be used
+  // in access rules or role mapping.
+  $parts = explode(",", $dn, 2);
+  $groups[] = $parts[1];
+}
+/**
+ * Allows the roles an ldap user will be assigned to be altered.
+ *
+ * This hook is called after the mapping defined in the admin ui has been
+ * performed but before the user has been granted a role.
+ *
+ * @param Array $roles An array who's values are role names.
+ * @param Object $account The user object
+ * @param String $dn The user's ldap dn.
+ * @param Array $groups All of the user's ldap groups found
+ * @param Array $filtered_groups The user's groups after filtered by mapping rules.
+ */
+function hook_ldap_user_roles_alter(&$roles, $account, $dn, $groups, $filtered_groups ) {
+  // Some example code to add a role if the user is in two groups
+  if ( in_array("cn=Joplin Fans,ou=Groups,dc=myorg", $groups ) && in_array("cn=Morton Fans,ou=Groups,dc=myorg", $groups )) {
+    if ( ! in_array("Ragtime", $roles)) {
+      $roles[] = "Ragtime";
+    }
+  }
+}
\ No newline at end of file
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.inc
index 0af887b..d9ca929 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.inc
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.inc
@@ -1,5 +1,4 @@
 <?php
-// $Id: ldapgroups.inc,v 1.2 2009/08/25 13:53:20 miglius Exp $
 
 /**
  * @file
@@ -11,52 +10,56 @@
 
 /**
  * Implements hook_user() login operation.
+ *
+ * @param Object $account A user object verified to be ldap_authentified.
  */
 function ldapgroups_user_login(&$account) {
-  $authmap = user_get_authmaps($account->name);
-  if (!isset($authmap['ldapauth'])) {
-    // This user is not authenticated via lapauth.
+
+  // Don't do anything if disabled mode has been enabled.
+  if ( _ldapgroups_ldap_info($account, 'ldapgroups_mappings_filter') == LDAPGROUPS_ROLE_MODE_DISABLED ) {
     return;
   }
 
+  // Don't do anything until LDAP groups are configured in admin screens.
+  if (! ldapgroups_is_configured($account->ldap_config))
+    return;
+
   // Setup the global $_ldapgroups_ldap object.
   if (!_ldapgroups_ldap_init($account))
     return;
 
   // First, we figure out the appropriate groups.
   $groups = _ldapgroups_detect_groups($account);
-
-  // Apply groups restrictions.
-  if (count($groups_allow = _ldapgroups_ldap_info($account, 'ldapgroups_groups')) > 0 && count(array_intersect($groups, $groups_allow)) == 0) {
-    $account = user_load(0);
+  if ($groups === FALSE) {  // Hmm, could not contact LDAP so make no changes..
     return;
   }
 
-  // Then, we take every mapped role from the user, later below
+  // Then, we take every LDAP mapped role from the user, later below
   // we'll grant back those deserved.
   $account->ldap_drupal_roles = isset($account->ldap_drupal_roles) ? $account->ldap_drupal_roles : array();
   foreach ($account->ldap_drupal_roles as $role) {
     _ldapgroups_deny_role($account, $role);
   }
 
-  // Are there LDAP groups for the user?
-  if ($groups === FALSE)
-    return TRUE;
-
   // Next, we apply site-specific rules.
-  $groups = _ldapgroups_filter($account, $groups);
+  $filtered_groups = _ldapgroups_filter($account, $groups);
 
-  // At this point, the roles are in the full DN format.
+  // At this point, the roles are in the full DN format or role names.
   $roles = array();
-  if (!empty($groups)) {
-    $ldapgroups_mappings = _ldapgroups_ldap_info($account, 'ldapgroups_mappings');
-    foreach ($groups as $group) {
+  if (!empty($filtered_groups)) {
+    foreach ($filtered_groups as $group) {
       $role = _ldapgroups_mapping($account, $group);
-      _ldapgroups_create_role($role);
-      _ldapgroups_grant_role($account, $role);
       $roles[] = $role;
     }
   }
+  $roles = array_unique($roles);
+
+  drupal_alter("ldap_user_roles", $roles, $account, $dn, $groups, $filtered_groups );
+
+  foreach ($roles as $role ) {
+    _ldapgroups_create_role($role);
+    _ldapgroups_grant_role($account, $role);
+  }
 
   // Store roles in the user object so we know which ones
   // were granted here.
@@ -69,18 +72,17 @@ function ldapgroups_user_login(&$account) {
 /**
  * Detect user groups from the LDAP.
  *
- * @param $user
- *   A user object.
+ * @param $account
+ *   A user object that has already been checked if it is "ldap_authentified".
  *
- * @return
- *   An array of user groups.
+ * @return An array of user groups, an empty array if none found and
+ *         FALSE if none defined/could not search LDAP.
  */
-function _ldapgroups_detect_groups($user) {
+function _ldapgroups_detect_groups($account) {
   global $_ldapgroups_ldap;
 
-  // Nothing to do if the user is not LDAP authentified
-  // or there are no groups configured.
-  if (!(_ldapgroups_ldap_info($user, 'ldapgroups_in_dn') || _ldapgroups_ldap_info($user, 'ldapgroups_in_attr') || _ldapgroups_ldap_info($user, 'ldapgroups_as_entries')))
+  // Nothing to do if there are no groups configured.
+  if (! ldapgroups_is_configured($account->ldap_config))
     return FALSE;
 
   // First try to connect with the stored user's DN and password.
@@ -96,64 +98,102 @@ function _ldapgroups_detect_groups($user) {
     $dn = $row2->binddn;
     $pass = $row2->bindpw;
     if (!$_ldapgroups_ldap->connect($dn, $pass)) {
-      watchdog('ldapgroups', "User login: user %name data could not be read in the LDAP directory", array('%name' => $user->name), WATCHDOG_WARNING);
+      watchdog('ldapgroups', "User login: user %name data could not be read in the LDAP directory", array('%name' => $account->name), WATCHDOG_WARNING);
       return FALSE;
     }
   }
 
-  // Strategy 1: group extracted from user's DN.
-  $dn_groups = array();
-  if (_ldapgroups_ldap_info($user, 'ldapgroups_in_dn')) {
-    $pairs = explode(',', $user->ldap_dn);
-    foreach ($pairs as $p) {
-      $pair = explode('=', $p);
-      if (drupal_strtolower(trim($pair[0])) == drupal_strtolower(_ldapgroups_ldap_info($user, 'ldapgroups_dn_attribute')))
-        $dn_groups[] = trim($pair[1]);
-    }
-  }
+  $groups = ldapgroups_groups_load($_ldapgroups_ldap, $account->ldap_dn, $account->name );
 
-  // Strategy 2: groups in user attributes.
-  $attrib_groups = array();
-  if (_ldapgroups_ldap_info($user, 'ldapgroups_in_attr')) {
-    foreach (_ldapgroups_ldap_info($user, 'ldapgroups_attr') as $attribute)
-      $attrib_groups = array_merge($attrib_groups, $_ldapgroups_ldap->retrieveMultiAttribute($user->ldap_dn, $attribute));
+  $_ldapgroups_ldap->disconnect();
+  return $groups;
+}
+
+/**
+ * Create an array of LDAP groups related to a dn/user.
+ *
+ * @param LDAPInterface $ldap An initialized LDAP server interface object.
+ * @param String $name The ldap user name (from login form)
+ * @param String $dn The user's dn
+ *
+ * @return An array of user groups, an empty array if none found and
+ *         FALSE if none defined/could not search LDAP.
+ */
+function ldapgroups_groups_load( $ldap, $dn, $name, $reset=FALSE ) {
+  static $groups_cache = array();
+  if ( $reset ) {
+    $groups_cache = array();
+  }
+  if ( ! $ldap ) {  // allow cache clearing only calls.
+    return FALSE;
   }
 
-  // Strategy 3: groups as entries.
-  $entries_groups = array();
-  $ldapgroups_entries_attribute = _ldapgroups_ldap_info($user, 'ldapgroups_entries_attribute');
-  if (_ldapgroups_ldap_info($user, 'ldapgroups_as_entries')) {
-    foreach (_ldapgroups_ldap_info($user, 'ldapgroups_entries') as $branch) {
-      $entries = $_ldapgroups_ldap->search($branch, $ldapgroups_entries_attribute .'='. $user->ldap_dn, array($ldapgroups_entries_attribute));
-      if (empty($entries) || $entries['count'] == 0)
-        $entries = $_ldapgroups_ldap->search($branch, $ldapgroups_entries_attribute .'='. $user->name, array($ldapgroups_entries_attribute));
-      foreach ($entries as $entry) {
-        if (isset($entry['dn']))
-          $entries_groups[] = $entry['dn'];
+  if ( ! isset($groups_cache[$dn]) ) {
+    $sid = $ldap->getOption('sid');
+
+    // Nothing to do if there are no groups configured.
+    if (! ldapgroups_is_configured($sid))
+      return FALSE;
+
+    // Strategy 1: group extracted from user's DN.
+    $dn_groups = array();
+    if (_ldapgroups_ldap_info($sid, 'ldapgroups_in_dn')) {
+      $pairs = ldap_explode_dn($dn, 0);
+      foreach ($pairs as $p) {
+        $pair = explode('=', $p);
+        if (drupal_strtolower(trim($pair[0])) == drupal_strtolower(_ldapgroups_ldap_info($sid, 'ldapgroups_dn_attribute')))
+          $dn_groups[] = trim($pair[1]);
       }
     }
+
+    // Strategy 2: groups in user attributes.
+    $attrib_groups = array();
+    if (_ldapgroups_ldap_info($sid, 'ldapgroups_in_attr')) {
+      foreach (_ldapgroups_ldap_info($sid, 'ldapgroups_attr') as $attribute)
+        $attrib_groups = array_merge($attrib_groups, $ldap->retrieveMultiAttribute($dn, $attribute));
+    }
+
+    // Strategy 3: groups as entries.
+    $entries_groups = array();
+    $ldapgroups_entries_attribute = _ldapgroups_ldap_info($sid, 'ldapgroups_entries_attribute');
+    if (_ldapgroups_ldap_info($sid, 'ldapgroups_as_entries')) {
+      foreach (_ldapgroups_ldap_info($sid, 'ldapgroups_entries') as $branch) {
+        $entries = $ldap->search($branch, $ldapgroups_entries_attribute .'='. $dn, array($ldapgroups_entries_attribute));
+        if (empty($entries) || $entries['count'] == 0)
+          $entries = $ldap->search($branch, $ldapgroups_entries_attribute .'='. $name, array($ldapgroups_entries_attribute));
+        foreach ($entries as $entry) {
+          if (isset($entry['dn']))
+            $entries_groups[] = $entry['dn'];
+        }
+      }
+    }
+    $groups = array_unique(array_merge($dn_groups, $attrib_groups, $entries_groups));
+
+    // Allow other modules to modify user groups.
+    drupal_alter("ldap_user_groups", $groups, $ldap, $dn, $name );
+
+    $groups_cache[$dn] = $groups;
   }
 
-  $_ldapgroups_ldap->disconnect();
-  return array_unique(array_merge($dn_groups, $attrib_groups, $entries_groups));
+  return $groups_cache[$dn];
 }
 
 /**
  * Grant a user with a role.
  *
- * @param $user
+ * @param $account
  *   A user object.
  * @param $rolename
  *   A name of the role.
  *
  * @return
  */
-function _ldapgroups_grant_role($user, $rolename) {
-  $result = db_query("SELECT * FROM {role} WHERE name = '%s'", $rolename);
+function _ldapgroups_grant_role($account, $rolename) {
+  $result = db_query("SELECT * FROM {role} WHERE LOWER(name) = LOWER('%s')", $rolename);
   if ($row = db_fetch_object($result)) {
-    $result = db_query("SELECT * FROM {users_roles} WHERE uid = %d AND rid = %d", $user->uid, $row->rid);
+    $result = db_query("SELECT * FROM {users_roles} WHERE uid = %d AND rid = %d", $account->uid, $row->rid);
     if (!db_fetch_object($result)) {
-      db_query("INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)", $user->uid, $row->rid);
+      db_query("INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)", $account->uid, $row->rid);
     }
   }
 }
@@ -161,19 +201,19 @@ function _ldapgroups_grant_role($user, $rolename) {
 /**
  * Deny a user with a role.
  *
- * @param $user
+ * @param $account
  *   A user object.
  * @param $rolename
  *   A name of the role.
  *
  * @return
  */
-function _ldapgroups_deny_role($user, $rolename) {
-  $result = db_query("SELECT * FROM {role} WHERE name = '%s'", $rolename);
+function _ldapgroups_deny_role($account, $rolename) {
+  $result = db_query("SELECT * FROM {role} WHERE LOWER(name) = LOWER('%s')", $rolename);
   if ($row = db_fetch_object($result)) {
-    $result = db_query("SELECT * FROM {users_roles} WHERE uid = %d AND rid = %d", $user->uid, $row->rid);
+    $result = db_query("SELECT * FROM {users_roles} WHERE uid = %d AND rid = %d", $account->uid, $row->rid);
     if (db_fetch_object($result)) {
-      db_query("DELETE FROM {users_roles} WHERE uid = %d AND rid = %d", $user->uid, $row->rid);
+      db_query("DELETE FROM {users_roles} WHERE uid = %d AND rid = %d", $account->uid, $row->rid);
     }
   }
 }
@@ -187,13 +227,13 @@ function _ldapgroups_deny_role($user, $rolename) {
  * @return
  */
 function _ldapgroups_create_role($rolename) {
-  $result = db_query("SELECT * FROM {role} WHERE name = '%s'", $rolename);
+  $result = db_query("SELECT * FROM {role} WHERE LOWER(name) = LOWER('%s')", $rolename);
   if (!($row = db_fetch_object($result)))
     db_query("INSERT INTO {role} (name) VALUES ('%s')", $rolename);
 }
 
 /**
- * Filters groups only to a explicitely defined groups.
+ * Filters groups only to the groups defined in the role mapping.
  *
  * @param $groups
  *   An array of the LDAP groups.
@@ -202,39 +242,45 @@ function _ldapgroups_create_role($rolename) {
  *   An array of the filtered groups.
  */
 function _ldapgroups_filter($account, $groups) {
-  if (_ldapgroups_ldap_info($account, 'ldapgroups_mappings_filter') && count(_ldapgroups_ldap_info($account, 'ldapgroups_mappings') > 0)) {
+
+  // Filter by php code first
+  if ($code = _ldapgroups_ldap_info($account, 'ldapgroups_filter_php')) {
+    $groups = drupal_eval($code);
+  }
+
+  if (_ldapgroups_ldap_info($account, 'ldapgroups_mappings_filter') == LDAPGROUPS_ROLE_MODE_USE_MAP && count(_ldapgroups_ldap_info($account, 'ldapgroups_mappings') > 0)) {
     $groups_new = array();
     foreach ($groups as $group) {
       foreach (_ldapgroups_ldap_info($account, 'ldapgroups_mappings') as $group_approved => $role) {
-        if (strcasecmp($group_approved, $group) == 0)
-          $groups_new[] = $role;
+        if (strcasecmp($group_approved, $group) == 0) {
+          $roles = explode(',', $role);
+          foreach ( $roles as $r ) {
+            $groups_new[] = trim($r);
+          }
+        }
       }
     }
-    $groups = $groups_new;
+    $groups = array_unique($groups_new);
   }
-
-  if ($code = _ldapgroups_ldap_info($account, 'ldapgroups_filter_php'))
-    $groups = drupal_eval($code);
-
   return $groups;
 }
 
 /**
  * Maps LDAP group name to a Drupal role.
  *
- * @param $user
- *   A user object.
+ * @param $account
+ *   A user object or sid.
  * @param $group
  *   A LDAP group name.
  *
  * @return
  *   An Drupal role.
  */
-function _ldapgroups_mapping($user, $group) {
-  $ldapgroups_mappings = _ldapgroups_ldap_info($user, 'ldapgroups_mappings');
+function _ldapgroups_mapping($account, $group) {
+  $ldapgroups_mappings = _ldapgroups_ldap_info($account, 'ldapgroups_mappings');
   if (isset($ldapgroups_mappings[$group]))
     return $ldapgroups_mappings[$group];
-  else if (preg_match('/^[^=]+=([^,]+),.*$/', $group, $matches))
+  elseif (preg_match('/^[^=]+=([^,]+),.*$/', $group, $matches))
     return $matches[1];
   else
     return $group;
@@ -254,20 +300,21 @@ function _ldapgroups_ldap_init($sid) {
   if (!($sid = is_object($sid) ? (isset($sid->ldap_config) ? $sid->ldap_config : NULL) : $sid))
     return;
 
-  static $servers = array();
-  if (!isset($servers[$sid]))
-    $servers[$sid] = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE status = 1 AND sid = %d", $sid));
+  $server = ldapauth_server_load($sid);
 
-  if ($servers[$sid]) {
+  if (! empty($server) && $server->status == 1 ) {
     $_ldapgroups_ldap = new LDAPInterface();
     $_ldapgroups_ldap->setOption('sid', $sid);
-    $_ldapgroups_ldap->setOption('name', $servers[$sid]->name);
-    $_ldapgroups_ldap->setOption('server', $servers[$sid]->server);
-    $_ldapgroups_ldap->setOption('port', $servers[$sid]->port);
-    $_ldapgroups_ldap->setOption('tls', $servers[$sid]->tls);
-    $_ldapgroups_ldap->setOption('encrypted', $servers[$sid]->encrypted);
-    $_ldapgroups_ldap->setOption('basedn', $servers[$sid]->basedn);
-    $_ldapgroups_ldap->setOption('user_attr', $servers[$sid]->user_attr);
+    $_ldapgroups_ldap->setOption('name', $server->name);
+    $_ldapgroups_ldap->setOption('machine_name', $server->machine_name);
+    $_ldapgroups_ldap->setOption('server', $server->server);
+    $_ldapgroups_ldap->setOption('port', $server->port);
+    $_ldapgroups_ldap->setOption('tls', $server->tls);
+    $_ldapgroups_ldap->setOption('enc_type', $server->enc_type);
+    $_ldapgroups_ldap->setOption('basedn', $server->basedn);
+    $_ldapgroups_ldap->setOption('user_attr', $server->user_attr);
+    $_ldapgroups_ldap->setOption('binddn', $server->binddn);
+    $_ldapgroups_ldap->setOption('bindpw', $server->bindpw);
     return $_ldapgroups_ldap;
   }
 }
@@ -287,33 +334,81 @@ function _ldapgroups_ldap_info($sid, $req) {
   if (!($sid = is_object($sid) ? (isset($sid->ldap_config) ? $sid->ldap_config : NULL) : $sid))
     return;
 
-  static $servers = array();
-  if (!isset($servers[$sid]))
-    $servers[$sid] = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE sid = %d", $sid));
+  $server = ldapauth_server_load($sid);
 
   switch ($req) {
     case 'ldapgroups_in_dn':
-      return $servers[$sid]->ldapgroups_in_dn;
+      return $server->ldapgroups_in_dn;
     case 'ldapgroups_dn_attribute':
-      return !empty($servers[$sid]->ldapgroups_dn_attribute) ? $servers[$sid]->ldapgroups_dn_attribute : LDAPGROUPS_DEFAULT_DN_ATTRIBUTE;
+      return !empty($server->ldapgroups_dn_attribute) ? $server->ldapgroups_dn_attribute : LDAPGROUPS_DEFAULT_DN_ATTRIBUTE;
     case 'ldapgroups_in_attr':
-      return $servers[$sid]->ldapgroups_in_attr;
+      return $server->ldapgroups_in_attr;
     case 'ldapgroups_attr':
-      return !empty($servers[$sid]->ldapgroups_attr) ? unserialize($servers[$sid]->ldapgroups_attr) : array();
+      return !empty($server->ldapgroups_attr) ? unserialize($server->ldapgroups_attr) : array();
     case 'ldapgroups_as_entries':
-      return $servers[$sid]->ldapgroups_as_entries;
+      return $server->ldapgroups_as_entries;
     case 'ldapgroups_entries':
-      return !empty($servers[$sid]->ldapgroups_entries) ? unserialize($servers[$sid]->ldapgroups_entries) : array();
+      return !empty($server->ldapgroups_entries) ? unserialize($server->ldapgroups_entries) : array();
     case 'ldapgroups_entries_attribute':
-      return !empty($servers[$sid]->ldapgroups_entries_attribute) ? $servers[$sid]->ldapgroups_entries_attribute : LDAPGROUPS_DEFAULT_ENTRIES_ATTRIBUTE;
+      return !empty($server->ldapgroups_entries_attribute) ? $server->ldapgroups_entries_attribute : LDAPGROUPS_DEFAULT_ENTRIES_ATTRIBUTE;
     case 'ldapgroups_mappings':
-      return !empty($servers[$sid]->ldapgroups_mappings) ? unserialize($servers[$sid]->ldapgroups_mappings) : array();
+      return !empty($server->ldapgroups_mappings) ? unserialize($server->ldapgroups_mappings) : array();
     case 'ldapgroups_mappings_filter':
-      return $servers[$sid]->ldapgroups_mappings_filter;
+      return $server->ldapgroups_mappings_filter;
     case 'ldapgroups_filter_php':
-      return $servers[$sid]->ldapgroups_filter_php;
+      return $server->ldapgroups_filter_php;
     case 'ldapgroups_groups':
-      return !empty($servers[$sid]->ldapgroups_groups) ? unserialize($servers[$sid]->ldapgroups_groups) : array();
+      return !empty($server->ldapgroups_groups) ? unserialize($server->ldapgroups_groups) : array();
   }
 }
+/**
+ * Retrieve the ldapgroups access rules for the specified server.
+ *
+ * @param int $sid The server id to get the access rules for.
+ * @return An array of access rules with each element an array of type and group
+ */
+function ldapgroups_access_rules( $sid, $reset=FALSE ) {
+  static $acl = array();
+  if ( $reset ) {
+    $acl = array();
+  }
+  if ( $sid === FALSE ) { // Allow resets without lookup.
+    return;
+  }
+  if ( ! isset($acl[$sid])) {
+    $config_info = _ldapgroups_ldap_info($sid, 'ldapgroups_groups');
+    if ( empty($config_info) ) {
+      $acl[$sid][] = array(LDAPGROUPS_RULE_TYPE_ALLOW, LDAPGROUPS_GROUP_ALL);
+    }
+    else {
+      // All rule sets start with deny all
+      $acl[$sid][] = array(LDAPGROUPS_RULE_TYPE_DENY, LDAPGROUPS_GROUP_ALL);
+      // Is just a list of groups?
+      if ( ! preg_match("/^(" . LDAPGROUPS_RULE_TYPE_ALLOW . ")|(" . LDAPGROUPS_RULE_TYPE_DENY . ")??[:]\s.*/i", $config_info[0] ) ) {
+        foreach ( $config_info as $group ) {
+          if ( ! empty ($group) ) {
+            $acl[$sid][] = array(LDAPGROUPS_RULE_TYPE_ALLOW, $group);
+          }
+        }
+      }
+      // A valid ruleset
+      else {
+        foreach ( $config_info as $rule ) {
+          if ( ! empty($rule) ) {
+            $parts = explode(":", $rule, 2);
+            $acl[$sid][] = array(drupal_strtoupper($parts[0]), trim($parts[1]));
+          }
+        }
+      }
+    }
+  }
+  return $acl[$sid];
+}
+function ldapgroups_is_configured( $sid ) {
+  static $configured = array();
 
+  if ( ! isset($configured[$sid]) ) {
+    $configured[$sid] = (_ldapgroups_ldap_info($sid, 'ldapgroups_in_dn') || _ldapgroups_ldap_info($sid, 'ldapgroups_in_attr') || _ldapgroups_ldap_info($sid, 'ldapgroups_as_entries'));
+  }
+  return $configured[$sid];
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.info b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.info
index a01cac5..84b0713 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.info
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.info
@@ -1,4 +1,3 @@
-; $Id: ldapgroups.info,v 1.4 2009/02/19 16:56:16 miglius Exp $
 name = Groups
 description = Implements LDAP groups to Drupal roles mapping.
 package = LDAP integration
@@ -6,9 +5,9 @@ dependencies[] = ldapauth
 core = 6.x
 
 
-; Information added by drupal.org packaging script on 2009-10-27
-version = "6.x-1.0-beta2"
+; Information added by drupal.org packaging script on 2012-06-28
+version = "6.x-1.0-beta3"
 core = "6.x"
 project = "ldap_integration"
-datestamp = "1256654469"
+datestamp = "1340919401"
 
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.install b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.install
index 02df8b1..3ff7154 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.install
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.install
@@ -1,5 +1,4 @@
 <?php
-// $Id: ldapgroups.install,v 1.6 2009/07/04 21:54:28 miglius Exp $
 
 /**
  * @file
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.module b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.module
index d97ed71..e72b844 100644
--- a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.module
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapgroups.module
@@ -1,5 +1,4 @@
 <?php
-// $Id: ldapgroups.module,v 1.40 2009/08/25 13:23:37 miglius Exp $
 
 /**
  * @file
@@ -9,7 +8,19 @@
 //////////////////////////////////////////////////////////////////////////////
 
 define('LDAPGROUPS_DEFAULT_DN_ATTRIBUTE',      'ou');
-define('LDAPGROUPS_DEFAULT_ENTRIES_ATTRIBUTE', 'memberUid');
+define('LDAPGROUPS_DEFAULT_ENTRIES_ATTRIBUTE', 'member');
+
+define('LDAPGROUPS_RULE_TYPE_ALLOW',   'ALLOW');
+define('LDAPGROUPS_RULE_TYPE_DENY',    'DENY');
+define('LDAPGROUPS_RULE_TYPE_ALLOW_X', 'ALLOW-X');
+define('LDAPGROUPS_RULE_TYPE_DENY_X',  'DENY-X');
+
+define('LDAPGROUPS_GROUP_ALL',      'ALL');
+define('LDAPGROUPS_GROUP_EXISTING', 'EXISTING');
+
+define('LDAPGROUPS_ROLE_MODE_DISABLED', 2 );
+define('LDAPGROUPS_ROLE_MODE_USE_MAP',  1 );
+define('LDAPGROUPS_ROLE_MODE_AUTO',     0 );
 
 //////////////////////////////////////////////////////////////////////////////
 // Core API hooks
@@ -27,6 +38,19 @@ function ldapgroups_menu() {
       'access arguments' => array('administer ldap modules'),
       'file' => 'ldapgroups.admin.inc',
     ),
+    'admin/settings/ldap/ldapgroups/configure' => array(
+      'title' => 'Settings',
+      'type' => MENU_DEFAULT_LOCAL_TASK,
+    ),
+    'admin/settings/ldap/ldapgroups/test' => array(
+      'title' => 'Test Group Settings',
+      'page callback' => 'drupal_get_form',
+      'page arguments' => array('ldapgroups_user_test'),
+      'access arguments' => array('administer ldap modules'),
+      'file' => 'ldapgroups.admin.inc',
+      'type' => MENU_LOCAL_TASK,
+      'weight' => 1,
+    ),
     'admin/settings/ldap/ldapgroups/edit' => array(
       'title' => 'Groups',
       'page callback' => 'drupal_get_form',
@@ -51,12 +75,150 @@ function ldapgroups_menu() {
  * Implements hook_user().
  */
 function ldapgroups_user($op, &$edit, &$account, $category = NULL) {
+
+  // Only care about ldap authenticated users.
+  if (!isset($account->ldap_authentified))
+    return;
+
   switch ($op) {
     case 'login':
-      require_once(drupal_get_path('module', 'ldapgroups') .'/includes/LDAPInterface.inc');
-      require_once(drupal_get_path('module', 'ldapgroups') .'/ldapgroups.inc');
+      module_load_include('inc', 'ldapauth', 'includes/ldap.core');
+      module_load_include('inc', 'ldapauth', 'includes/LDAPInterface');
+      module_load_include('inc', 'ldapgroups', 'ldapgroups');
       ldapgroups_user_login($account);
       break;
   }
 }
+/**
+ * Implementation of hook_schema_alter().
+ *
+ * @param &$schema Nested array describing the schemas for all modules.
+ */
+function ldapgroups_schema_alter($schema) {
+  $schema['ldapauth']['fields']['ldapgroups_in_dn'] = array(
+    'type' => 'int',
+    'size' => 'tiny',
+    'not null' => TRUE,
+    'default' => '0',
+  );
+  $schema['ldapauth']['fields']['ldapgroups_dn_attribute'] = array(
+    'type' => 'varchar',
+    'length' => 255,
+  );
+  $schema['ldapauth']['fields']['ldapgroups_attr'] = array(
+    'type' => 'varchar',
+    'length' => 255,
+  );
+  $schema['ldapauth']['fields']['ldapgroups_in_attr'] = array(
+    'type' => 'int',
+    'size' => 'tiny',
+    'not null' => TRUE,
+    'default' => '0',
+  );
+  $schema['ldapauth']['fields']['ldapgroups_as_entries'] = array(
+    'type' => 'int',
+    'size' => 'tiny',
+    'not null' => TRUE,
+    'default' => '0',
+  );
+  $schema['ldapauth']['fields']['ldapgroups_entries'] = array(
+    'type' => 'text',
+  );
+  $schema['ldapauth']['fields']['ldapgroups_entries_attribute'] = array(
+    'type' => 'varchar',
+    'length' => 255,
+  );
+  $schema['ldapauth']['fields']['ldapgroups_mappings'] = array(
+    'type' => 'text',
+    'not null' => FALSE,
+  );
+  $schema['ldapauth']['fields']['ldapgroups_mappings_filter'] = array(
+    'type' => 'int',
+    'size' => 'tiny',
+    'not null' => TRUE,
+    'default' => '0',
+  );
+  $schema['ldapauth']['fields']['ldapgroups_filter_php'] = array(
+    'type' => 'text',
+    'not null' => FALSE,
+  );
+  $schema['ldapauth']['fields']['ldapgroups_groups'] = array(
+    'type' => 'text',
+    'not null' => FALSE,
+  );
+}
+/**
+ * Implementation of hook_ldap_user_deny_alter.
+ *
+ * User denied if server access limited by group(s) and user is not in one.
+ */
+function ldapgroups_ldap_user_deny_alter( &$denied, $ldap, $name, $dn, $account ) {
+
+  module_load_include('inc', 'ldapgroups', 'ldapgroups');
+
+  $sid = $ldap->getOption('sid');
+
+  $groups_allowed = _ldapgroups_ldap_info($sid, 'ldapgroups_groups');
+  if ( ! ldapgroups_is_configured($sid) || empty($groups_allowed) ) {
+    return;  // Nothing to do here.
+  }
+
+  $user_groups = ldapgroups_groups_load($ldap, $dn, $name);
+  if ( $user_groups === FALSE ) { // Problem getting groups!
+    $denied = TRUE;
+    return;
+  }
+  $access_rules = ldapgroups_access_rules($ldap->getOption('sid'));
+
+  $allowed = FALSE;
+  foreach ( $access_rules as $rule ) {
+    $type = $rule[0];
+    $rule_group = drupal_strtoupper($rule[1]);
+
+    // See if the rule group matches the user.
+    $matched = FALSE;
+    switch ( $rule_group ) {
+      case LDAPGROUPS_GROUP_ALL:
+        $matched = TRUE;
+        break;
+      case LDAPGROUPS_GROUP_EXISTING:
+        if ( $account->ldap_authentified ) {
+          $matched = TRUE;
+        }
+        break;
+      default:
+        foreach ( $user_groups as $group ) {
+          if ( drupal_strtoupper($group) == $rule_group ) {
+            $matched = TRUE;
+            break;
+          }
+        }
+    }
+    // Rule matched, apply action.
+    if ( $matched ) {
 
+      // Handle the match results according to rule type.
+      switch ( $type ) {
+        case LDAPGROUPS_RULE_TYPE_ALLOW:
+          $allowed = TRUE;
+          break;
+        case LDAPGROUPS_RULE_TYPE_ALLOW_X:
+          return;  // Found Allowed exit rule - hook says do nothing
+        case LDAPGROUPS_RULE_TYPE_DENY:
+          $allowed = FALSE;
+          break;
+        case LDAPGROUPS_RULE_TYPE_DENY_X:
+          $denied = TRUE;  // Found DENIED exit rule, deny and exit.
+          return;
+          break;
+        default:
+          drupal_set_message(t("Invalid rule type, @type, found in ldapgroups access rules for server, @server!", array('@type' => $type, '@server' => $ldap->getOption('name'))));
+      }
+    }
+  }
+
+  if ( ! $allowed ) {
+    $denied = TRUE;
+  }
+
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.css b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.css
new file mode 100644
index 0000000..467e25e
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.css
@@ -0,0 +1,9 @@
+ form#dblog-filter-form div#edit-type-wrapper,
+table#admin-dblog th img
+{ display: none;}
+code.export-summary {font-weight: normal;}
+
+table#admin-dblog th a,
+table#admin-dblog th {text-decoration: none; color: #000000;}
+th code {}
+
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.info b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.info
new file mode 100644
index 0000000..3911c1b
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.info
@@ -0,0 +1,12 @@
+name = "LDAP Help"
+description = LDAP Integration Admin Help.
+package = LDAP integration
+core = 6.x
+dependencies[] = ldapauth
+
+; Information added by drupal.org packaging script on 2012-06-28
+version = "6.x-1.0-beta3"
+core = "6.x"
+project = "ldap_integration"
+datestamp = "1340919401"
+
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.module b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.module
new file mode 100644
index 0000000..6bd377d
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp.module
@@ -0,0 +1,364 @@
+<?php
+/**
+ * @file
+ * The ldaphelp module is a module to help admins debug ldap_integration modules.
+ *
+ */
+
+
+global $_ldaphelp_ldaps;
+
+$default_fields['server-settings']['port'] = 389;
+$default_fields['server-settings']['tls'] = 1;
+$default_fields['server-settings']['encrypted'] = 0;
+$default_fields['login-procedure']['user_attr'] = 'uid';
+$default_fields['login-procedure']['mail_attr'] = 'mail';
+
+// http://msdn.microsoft.com/en-us/library/aa705886(VS.85).aspx
+$_ldaphelp_ldaps['ad']['name'] = t('Active Directory LDAP');
+$_ldaphelp_ldaps['ad']['description'] = t('Microsoft Active Directory');
+$_ldaphelp_ldaps['ad']['fields'] = $default_fields;
+$_ldaphelp_ldaps['ad']['fields']['login-procedure']['user_attr'] = 'sAMAccountName';
+$_ldaphelp_ldaps['ad']['person_object_class'] = 'person';
+$_ldaphelp_ldaps['ad']['fingerprint_attribute'] = 'mS-DS-CreatorSID';
+
+// http://www.novell.com/documentation/edir873/index.html?page=/documentation/edir873/edir873/data/h0000007.html
+$_ldaphelp_ldaps['novell_edir']['name'] = t('Novell eDirectory');
+$_ldaphelp_ldaps['novell_edir']['description'] = t('Novell eDirectory LDAP');
+$_ldaphelp_ldaps['novell_edir']['fields'] = $default_fields;
+$_ldaphelp_ldaps['novell_edir']['person_object_class'] = 'person';
+
+$_ldaphelp_ldaps['openldap']['name'] = t('openLDAP');
+$_ldaphelp_ldaps['openldap']['description'] = t('openLDAP default configuration');
+$_ldaphelp_ldaps['openldap']['fields'] = $default_fields;
+$_ldaphelp_ldaps['openldap']['fields']['login-procedure']['user_attr'] = 'cn';
+$_ldaphelp_ldaps['openldap']['person_object_class'] = 'person';
+
+
+// http://images.apple.com/server/macosx/docs/Open_Directory_Admin_v10.5_3rd_Ed.pdf
+$_ldaphelp_ldaps['macosxldap']['name'] = t('Mac OS X Server LDAP');
+$_ldaphelp_ldaps['macosxldap']['description'] = t('A variation on OpenLDAP');
+$_ldaphelp_ldaps['macosxldap']['fields'] = $default_fields;
+$_ldaphelp_ldaps['macosxldap']['fields']['login-procedure']['user_attr'] = 'uid';
+$_ldaphelp_ldaps['macosxldap']['person_object_class'] = 'person';
+$_ldaphelp_ldaps['macosxldap']['fingerprint_attribute'] = 'apple-generateduid';
+
+/**
+ * Implementation of hook_init().
+ */
+function ldaphelp_init() {
+  module_load_include('inc', 'ldapauth', 'ldapauth.admin');
+  module_load_include('inc', 'ldapauth', 'includes/ldap.core');
+  module_load_include('inc', 'ldapauth', 'includes/LDAPInterface');
+  drupal_add_css(drupal_get_path('module', 'ldaphelp') .'/ldaphelp.css', 'module');
+}
+
+/**
+ * Implementation of hook_menu().
+ */
+function ldaphelp_menu() {
+  $items = array();
+  $items['admin/settings/ldap/help'] = array(
+    'title' => t('LDAP Help'),
+    'description' => t('Debugging and Configuration Help with LDAP'),
+    'page callback' => 'ldaphelp_main',
+    'access arguments' => array('administer ldap modules'),
+  );
+
+  $items['admin/settings/ldap/help/resources'] = array(
+    'title' => t('Resources'),
+    'description' => t('Some help resources for LDAP modules'),
+    'page callback' => 'ldaphelp_main',
+    'access arguments' => array('administer ldap modules'),
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => 2,
+  );
+
+  $items['admin/settings/ldap/help/status'] = array(
+    'title' => t('Status'),
+    'description' => t('LDAP status page'),
+    'page callback' => 'ldaphelp_status',
+    'access arguments' => array('administer ldap modules'),
+    'file' => 'ldaphelp_status.inc',
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 4,
+  );
+
+  $items['admin/settings/ldap/help/watchdog'] = array(
+    'title' => t('Watchdog'),
+    'description' => t('LDAP watchdog logs'),
+    'page callback' => 'ldaphelp_watchdog',
+    'access arguments' => array('administer ldap modules'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 5,
+  );
+
+  $items['admin/settings/ldap/help/addcommon'] = array(
+    'title' => t('Common LDAPs'),
+    'description' => 'Add a new LDAP starting with common defaults such as Active Directory defaults.',
+    'page callback' => 'ldaphelp_addcommon',
+    'access arguments' => array('administer ldap modules'),
+    'type' => MENU_LOCAL_TASK,
+     'weight' => 7,
+  );
+
+  $items['admin/settings/ldap/help/wizard'] = array(
+    'title' => t('Wizard'),
+    'description' => t('A multi step form to help figure out LDAP server configuration.'),
+    'access arguments' => array('administer ldap modules'),
+    'file' => 'ldaphelp_wizard.inc',
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 13,
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('ldaphelp_wizard_form'),
+  );
+
+
+  return $items;
+}
+
+
+function _ldaphelp_bind_test($ldapserver) {
+    global $_ldapauth_ldap;
+    $test = array();
+    $_ldapauth_ldap = new LDAPInterface();
+    foreach ($ldapserver as $key => $value) {
+      $_ldapauth_ldap->setOption($key, $value);
+    }
+
+    if ($_ldapauth_ldap->getOption('binddn') && $_ldapauth_ldap->getOption('bindpw')) {
+      $test['bind_result'] = $_ldapauth_ldap->connectAndBind($_ldapauth_ldap->getOption('binddn'), $_ldapauth_ldap->getOption('bindpw'));
+      $test['bind_type'] = "non-anon";
+
+    }
+    else {
+      $test['bind_result'] = $_ldapauth_ldap->connectAndBind();
+      $test['bind_type'] = "anon";
+    }
+
+    if ($test['bind_result']) {
+      $test['bind_result_text'] =  "Success";
+      $test['bind_success'] = TRUE;
+    }
+    else {
+      $test['bind_result_error'] = ldap_error($_ldapauth_ldap->connection);
+      $test['bind_result_errno'] = ldap_errno($_ldapauth_ldap->connection);
+      $test['bind_result_text'] =  "Fail";
+      $test['bind_success'] = FALSE;
+    }
+
+    return $test;
+
+}
+
+function ldaphelp_bind_trial_message($trial) {
+  $tls = ($trial['tls']) ? "1" : "0";
+  $text = "Failed to bind to server: ". $trial['server'] .", port=". $trial['port'] .", tls=$tls <br/>";
+  $text .= "error: ". $trial['results']['bind_result_error'];
+  return $text;
+}
+
+
+function ldaphelp_addcommon() {
+
+  if (!module_exists('ldapauth')) {
+    drupal_set_message('Links below will not work until ldapauth module is not enabled.', 'warning');
+  }
+  global $_ldaphelp_ldaps;
+  $content = '<h3>'. t('LDAP Integration Default LDAPs') .'</h3>';
+  $content .= '<p>'. t('These links simply start an Add LDAP Server form with some common defaults.') .'</p>';
+  $content .= '<ul>';
+
+  foreach ($_ldaphelp_ldaps as $ldap_type => $default_data) {
+    $content .= "<li>". l($default_data['name'] . t(' Common Settings: '), 'admin/settings/ldap/ldapauth/add/'. $ldap_type) ."<br/><code>";
+    $content .= ldaphelp_display_settings_short($_ldaphelp_ldaps[$ldap_type]['fields']);
+    $content .= "</code></li>";
+  }
+  $content .= "</ul>";
+  return $content;
+}
+
+
+function ldaphelp_form_ldapauth_admin_form_alter(&$form, $form_state) {
+
+  global $_ldaphelp_ldaps;
+
+  if (in_array(arg(4), array_keys($_ldaphelp_ldaps))) {
+    $ldap_type = arg(4);
+
+    foreach ($_ldaphelp_ldaps[$ldap_type]['fields'] as $fieldset => $pairs) {
+      foreach ($pairs as $fieldname => $value ) {
+        $form[$fieldset][$fieldname]['#default_value'] = $value;
+      }
+    }
+  }
+
+  // don't hide/collapse login fieldset if data in it.
+  if ($form['login-procedure']['basedn']['#default_value']  ||
+      $form['login-procedure']['user_attr']['#default_value']  ||
+      $form['login-procedure']['mail_attr']['#default_value'] ) {
+    $form['login-procedure']['#collapsed'] = FALSE;
+  }
+}
+
+
+function _ldaphelp_get_configuration($admin_settings = TRUE, $sids = NULL) {
+
+  if ($admin_settings) {
+    $form = ldapauth_admin_settings();
+    $data['admin_settings'] = _ldaphelp_get_form_values($form);
+  }
+
+  $data['ldaps'] = array();
+
+  if ( ! (is_array($sids) && count($sids) == 0)) {
+    if ($sids == NULL) {
+      $result = db_query("SELECT sid FROM {ldapauth} ORDER BY name");
+      while ($row = db_fetch_object($result)) {
+        $sids[] = $row->sid;
+      }
+    }
+    if (count($sids) > 0) {
+      foreach ($sids as $sid) {
+        $form = ldapauth_admin_form($form_state, 'edit', $sid);
+        $data['ldaps'][$sid] = _ldaphelp_get_form_values($form);
+        unset($data['ldaps'][$sid]['bindpw_clear']);
+      }
+    }
+  }
+  return $data;
+}
+
+function _ldaphelp_get_form_values(&$form) {
+  $values = array();
+  foreach ($form as $key => $item) {
+    if ($form[$key]['#type'] == 'fieldset') {
+      foreach ($form[$key] as $subskey => $subitem) {
+        if ( drupal_substr($subskey, 0, 1) != '#') {
+          $values[$subskey] = ($subitem['#value']) ? $subitem['#value'] : $subitem['#default_value'];
+        }
+      }
+    }
+    elseif (drupal_substr($key, 0, 1) != '#' && $key != 'submit' && $key != 'reset') {
+      $values[$key] = ($item['#value']) ? $item['#value'] : $item['#default_value'];
+    }
+  }
+  return $values;
+}
+
+function ldaphelp_display_settings_short($ldap) {
+  foreach ( $ldap as $fieldset => $pairs) {
+    foreach ($ldap[$fieldset] as $fieldname => $value ) {
+      $ret .= "$fieldname = $value; ";
+    }
+  }
+  return $ret;
+}
+
+function ldaphelp_arraytohtmllist($array) {
+  foreach ($array as $key => $value) {
+    $text .= "<li>$key: $value</li>\r\n";
+  }
+  return "<ul>$text</ul>";
+}
+
+function ldaphelp_arraytohtml($array) {
+  foreach ($array as $key => $value) {
+    $text .= "<br/>$key: $value";
+  }
+  return $text;
+}
+
+function ldaphelp_arraytotxt($array) {
+  foreach ($array as $key => $value) {
+    $text .= "$key: $value\r\n";
+  }
+  return $text;
+}
+
+function ldaphelp_get_export_comments($export_conf_data) {
+  if ($export_conf_data['admin_settings']) {
+    $text = "\r\nAdmin Settings: \r\n".  ldaphelp_arraytotxt($export_conf_data['admin_settings']);
+  }
+  foreach ($export_conf_data['ldaps'] as $sid => $ldap) {
+    $text .= "\r\n" . ldaphelp_arraytotxt($ldap);
+  }
+  return $text;
+}
+
+function ldaphelp_main() {
+
+  $text = '<h3>'. t('LDAP Help Module') .'</h3><p>'.
+  t('This module is meant to assist Drupal admins in configuring, debugging, sharing, and submitting
+  support and bug request related to LDAP integration modules.') .'<strong><em>'.
+  t(' LDAP Help Module should be disabled unless you are debugging or configuring ldap problems.') .'</em></strong>'.
+  t(' It adds no functionality to the LDAP modules.') .'</p>';
+
+  $path = drupal_get_path("module", "ldapauth");
+
+  $text .= <<<EOT
+
+  <h3>LDAP Integration Module Resources</h3>
+  <ul>
+  <li>The <a href="/$path/README.txt">readme file</a> covers basics of module.</li>
+  <li><a href="http://drupal.org/node/62217">LDAP Integration Contributed Module Documentation</a>
+  overviews ldapauth, ldapgroups, and ldapdata modules and their installation and configuration.
+  Sometimes out of date.  Be sure that documentation matches the version you are using.  This
+  is a great opportunity for new users to contribute to the module:  when  you first use the
+  documentation take notes on what needs to be clarified.
+  </li>
+  <li>Search <a href="http://drupal.org/project/issues/search/ldap_integration">issue que</a>  For best results,
+  select version and category before searching.</li>
+  <li><a href="http://drupal.org/project/issues/ldap_integration">View all issues</a></li>
+  </ul>
+
+   <h3>General Drupal Support Help</h3>
+
+  <ul>
+  <li><a href="http://drupal.org/node/314185">How to report a problem in Drupal</a></li>
+  <li><a href="http://drupal.org/node/19279">How to report bugs in Drupal</a></li>
+  <li><a href="http://drupal.org/Troubleshooting-FAQ">Drupal Troubleshooting FAQ</a></li>
+  </ul>
+
+  <h3>General LDAP Resources</h3>
+  <ul>
+  <li><a href="http://us.php.net/manual/en/book.ldap.php">PHP LDAP</a></li>
+  <li><a href="http://directory.apache.org/studio/">Apache Directory Studio</a> LDAP Browser and Directory Client.</li>
+  <li><a href="http://www.novell.com/documentation/edir873/index.html?page=/documentation/edir873/edir873/data/h0000007.html">Novell Edirectory</a></li>
+  <li><a href="http://images.apple.com/server/macosx/docs/Open_Directory_Admin_v10.5_3rd_Ed.pdf">Apple Open Directory</a></li>
+  <li><a href="http://msdn.microsoft.com/en-us/library/aa705886(VS.85).aspx">Microsoft Active Directory LDAP</a></li>
+  </ul>
+
+EOT;
+
+
+  return $text;
+}
+
+function ldaphelp_watchdog() {
+
+  /* watchdog table */
+  drupal_add_css(drupal_get_path('module', 'ldaphelp') .'/ldaphelp.css', 'module', 'all', FALSE);
+  $path =    drupal_get_path("module", "ldapauth");
+  $_content = "";
+  if (module_exists('dblog')) {
+    include_once(drupal_get_path('module', 'dblog') .'/dblog.admin.inc');
+
+    $_SESSION['dblog_overview_filter']['type'] = Array('ldapauth' => 'ldapauth');
+    if (! ($_SESSION['dblog_overview_filter'] || $_SESSION['dblog_overview_filter']['severity'])) {
+      $_SESSION['dblog_overview_filter']['severity'] = array();
+    }
+
+    $_content .= "<h3>". t('LDAP Watchdog Errors and Notifications') ."</h3>";
+    $_content .= dblog_overview();
+    $_content .= l('...more watchdog', 'admin/reports/dblog');
+  }
+  else {
+    $_content .= "<h3>". t('LDAP Help Watchdog Errors and Notifications') ."</h3>";
+    $_content .= 'This feature requires <code>Database logging</code> module to be turned on. ';
+    $_content .= l('Module enable page', 'admin/build/modules');
+  }
+
+
+  return $_content;
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp_status.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp_status.inc
new file mode 100644
index 0000000..0fe1fca
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp_status.inc
@@ -0,0 +1,373 @@
+<?php
+/**
+ * @file
+ * status file for ldaphelp module
+ *
+ */
+
+define('REQUIREMENT_INFO', -1);
+define('REQUIREMENT_OK', 0);
+define('REQUIREMENT_WARNING', 1);
+define('REQUIREMENT_ERROR', 2);
+
+
+function ldaphelp_status() {
+
+  drupal_add_css(drupal_get_path('module', 'system') .'/system.css', 'module', 'all', FALSE);
+  include_once(drupal_get_path('module', 'system') .'/system.admin.inc');
+
+  // server and LDAP Module Data
+  $heading = "Server and LDAP Module";
+  $key = 'server';
+
+  $phpinfo = ldaphelp_parsePHPModules();
+
+  $status = ldaphelp_get_server($phpinfo, $info);
+
+  $reporting_text .= _ldaphelp_parse_status_to_text($status, $heading);
+
+  $content .=  "<h3>$heading</h3>" . theme_status_report($status);
+
+  // overall ldapauth settings
+  $heading = "LDAP Authentication Settings";
+  $status = ldaphelp_get_ldapauth($info);
+  $content .= "<h3>$heading</h3>". theme_status_report($status);
+  $reportingtext .= _ldaphelp_parse_status_to_text($status, $heading);
+
+  $conf_data = _ldaphelp_get_configuration(TRUE, NULL);
+  $ldaps  = $conf_data['ldaps'];
+
+  foreach ($ldaps as $sid => $ldap) {
+    $heading =  $ldap['name'] .' LDAP (sid='. $ldap['sid'] .')';
+    $edit_ldap = l(t('[edit]'), "admin/settings/ldap/ldapauth/edit/". $sid );
+    $test_results = _ldaphelp_testldap($ldap, $sid);
+    $status = ldaphelp_get_ldap_server($info, $sid, $ldap, $test_results, $edit_ldap);
+    $content .= "<h3>$heading</h3>". theme_status_report($status);
+    $reportingtext .= _ldaphelp_parse_status_to_text($status, $heading, array($edit_ldap => ""));
+  }
+
+
+  $reportingtext .= "ADMIN SETTINGS". ldaphelp_arraytotxt($conf_data['admin_settings']);
+  foreach ($conf_data['ldaps'] as $sid => $ldap) {
+    $reportingtext .= "\r\nLDAP sid=$sid\r\n". ldaphelp_arraytotxt($conf_data['ldaps'][$sid]);
+  }
+  $content .= '<h3>Bug and Support Reporting Info</h3><p>
+  Cut and paste this into a text file and attach it to any bug or support requests.
+  <strong><em>Remove or replace any data you feel should not be made public before sharing this data.</em></strong></p>
+  <form><textarea cols="80" rows="20">'. $reportingtext .'</textarea></form>';
+
+  return $content;
+}
+function ldaphelp_get_server($phpinfo, &$info) {
+
+  $info['phpversion'] = phpversion();
+  $info['ldaploaded'] = extension_loaded('ldap');
+  $info['ldap'] = $phpinfo['ldap'];
+
+  $text = "";
+  foreach ($phpinfo['ldap'] as $key => $value) {
+    $text .= "<br/>$key: ". $value[0];
+  }
+  $info['ldap']['text'] = $text;
+
+  //$info['ldap']['text'] = ldaphelp_arraytohtml($phpinfo['ldap']);
+
+  $modules = module_rebuild_cache();
+  $ldapmodules = array('ldapauth', 'ldapgroups', 'ldapdata', 'ldaphelp');
+  foreach ( $ldapmodules as $ldapmodule) {
+    $data['status'] = $modules[$ldapmodule]->status;
+    $data['schema_version'] = $modules[$ldapmodule]->schema_version;
+    $data['version'] = $modules[$ldapmodule]->info['version'];
+    $data['text'] = "status: ". $data['status']
+      .", schema_version: " . $data['schema_version']
+      .", v: " . $data['version'];
+
+    $info[$ldapmodule] = $data;
+  }
+
+  // set status array to be converted into html table.
+  if ($phpinfo['Apache Environment']) {
+    $status[] = array(
+      'title' => 'Apache',
+      'value' => $phpinfo['Apache Environment']['SERVER_SOFTWARE']
+    );
+  }
+  elseif ($_SERVER["SERVER_SOFTWARE"]) {
+        $status[] = array(
+      'title' => 'SERVER_SOFTWARE',
+      'value' => $_SERVER["SERVER_SOFTWARE"]
+    );
+
+  }
+
+  $status[] = array(
+    'title' => 'PHP version',
+    'value' => phpversion()
+  );
+
+  if (! $info['ldaploaded']) {
+    $status[] = array( 'title' => 'PHP ldap extension not loaded',
+    'value' => l(t('PHP LDAP extension'), 'http://us2.php.net/ldap') . ' ' . t('must be loaded for LDAP Integration to work.
+    It comes compiled with most versions of PHP.')  ,
+    'severity' => REQUIREMENT_ERROR);
+  }
+  else {
+    $status[] = array( 'title' => 'PHP ldap extension data',
+    'value' => $info['ldap']['text']  ,
+    'severity' => 0);
+  }
+
+  $status[] = array('title' => 'Drupal', 'value' => VERSION , 'severity' => "0");
+
+  foreach ( $ldapmodules as $ldapmodule) {
+    $status[] =  array('title' => $ldapmodule, value => $info[$ldapmodule]['text'], 'severity' => "0");
+  }
+  return $status;
+}
+
+function ldaphelp_get_ldapauth(&$info) {
+  $info['ldapauth']['login_process_text'] = (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_EXCLUSIVED) ? "LDAP directory only" : "Mixed Mode";
+  $info['ldapauth']['login_process_text'] .= " (". LDAPAUTH_LOGIN_PROCESS .')';
+  $info['ldapauth']['login_conflict_text'] = (LDAPAUTH_LOGIN_CONFLICT == LDAPAUTH_CONFLICT_RESOLVE) ? "Associate local account with the ldap entry" : "Disallow login and log the conflict";
+  $info['ldapauth']['login_conflict_text'] .= "  (". LDAPAUTH_LOGIN_CONFLICT .')';
+
+  $status[] =  array(
+    'title' => 'Authentication mode',
+    value =>   $info['ldapauth']['login_process_text'] ,
+  'severity' => "0");
+
+  $status[] =  array(
+    'title' => 'Conflict Resolve Feature',
+    value =>   $info['ldapauth']['login_conflict_text'],
+  'severity' => "0");
+
+  $info['ldapauth']['ldapauth_disable_pass_change_text'] = (LDAPAUTH_FORGET_PASSWORDS == TRUE) ? "Do not " : "Do";
+  $info['ldapauth']['ldapauth_disable_pass_change_text'] .= 'store users\' passwords during sessions.';
+
+  $status[] =  array('title' => 'Security Options', value => $info['ldapauth']['ldapauth_disable_pass_change_text'], 'severity' => "0");
+
+  $info['ldapauth']['ldapauth_disable_pass_change_text'] = (LDAPAUTH_DISABLE_PASS_CHANGE == TRUE) ? "R" : "Do not R";
+  $info['ldapauth']['ldapauth_disable_pass_change_text'] .= 'emove password change fields from user edit form';
+
+  $info['ldapauth']['ldapauth_alter_email_field_text'] = 'ldapauth_alter_email_field: '. LDAPAUTH_ALTER_EMAIL_FIELD ;
+
+  $status[] =  array('title' => 'LDAP UI Options', value => $info['ldapauth']['ldapauth_disable_pass_change_text'] ."<br/>". $info['ldapauth']['ldapauth_alter_email_field_text'], 'severity' => "0");
+
+  return $status;
+}
+function ldaphelp_get_ldap_server(&$info, $sid, &$ldap, &$test, $edit_ldap) {
+
+  $description =  "server: ". $ldap['server'] .
+    "<br/>port: " . $ldap['port'] .
+    "<br/>tls: ". $ldap['tls'] .
+    "<br/>encrypted: ". $ldap['encrypted'];
+  $status[] = array( 'title' => 'Server Settings '. $edit_ldap, 'value' => $description , 'severity' => "0");
+
+  // login procedure
+  $description =  "user_attr:<code> ". $ldap['user_attr'] .
+    "</code><br/>mail_attr: <code>". $ldap['mail_attr'] ."</code>";
+  $status[] = array( 'title' => 'Login Procedure '. $edit_ldap, 'value' => $description , 'severity' => "0");
+
+  // advanced configuration
+  $description = "binddn: <code>". $ldap['binddn'] .
+    "</code><br/>bindpw: ". $ldap['bindpw'];
+  $status[] = array( 'title' => 'Advanced Configuration '. $edit_ldap, 'value' => $description , 'severity' => "0");
+
+
+  // bind test
+  $description =   "Bind Type: ". $test['bind_type'] .
+    "<br/>Bind Result?: ". $test['bind_result_text'];
+  if (! $test['bind_success']) {
+    $description .=  ldaphelp_arraytohtml(
+      array(
+      'LDAP Error' => $test['bind_result_error'],
+      'LDAP Error Number' => $test['bind_result_errno'],
+      ));
+  }
+  // 49: invalid credentials.
+  $severity = ($test['bind_success'] === TRUE) ? "0" : "2";
+  $status[] = array( 'title' => 'Bind Test to <code>'. $ldap['server'] ."</code>", 'value' => $description , 'severity' => $severity);
+
+
+  foreach ($test['basedns'] as  $basedn) {
+
+    if (isset($basedn['result']['count'])) {
+        $usersfound =  TRUE ;
+        $usersfoundtext = "Yes";
+        $severity = 0;
+    }
+    else {
+      $usersfound =  FALSE ;
+      $usersfoundtext = "No";
+      $validbasedn = $basedn['basedn'];
+      $severity = 2;
+
+      $result = ldaphelp_baddn($basedn['basedn'], 'Base DN') ;
+
+      if (!$result['boolean']) {
+        $error['mal_formed_dn'] = $result['text'];
+      }
+
+      $error['bind_success_search_failed'] = "<br/>Successfully bound to server <code>". $ldap['server'] ."</code>, but found" .
+      " no users in generic search (". $ldap['user_attr'] ."=*)  Suggestions: <ul>";
+
+      if ($basedn['result']['no_user_attr_success'] && ! $data['result']['with_user_attr_success']) {
+        $error['bind_success_search_failed'] .= "<li> User attribute name <code>" .  $ldap['user_attr'] .
+        " </code> may be wrong. Found LDAP entries with search filter <code>CN=*</code>, ".
+        " but not with search filter <code>". $ldap['user_attr'] ."=*</code>.  </li>";
+      }
+      elseif ($tests[$sid]['bind_type'] == 'non-anon') { // no results in either search and non anonymous search
+        // you are not allowed to perform an anonymous search of your ldap
+        // or you meant to perform a non-anonymouse search but left the password empty.
+        $error['bind_success_search_failed'] .= "<li>Anonymous searches of your LDAP or the Base DN <code>".  $basedn['basedn'] .
+        " </code> may not be allowed.  Perhaps you need to create or use a service account to query the ldap.</li>";
+      }
+      $error['bind_success_search_failed'] .= "<li>Perhaps Base DN is incorrect: <code>".  $basedn['basedn'] ."</code></li>";
+      $error['bind_success_search_failed'] .= "</ul>";
+
+    }
+
+  $header = 'Base DN:<br/><code>'. $basedn['basedn'] .'</code>';
+  $value =   "<br/>Found Users in search of base DN?: <strong>". $usersfoundtext ."</strong>".
+    $error['bind_success_search_failed']
+    . $error['mal_formed_dn'];
+  $status[] = array( 'title' =>  $header .' '. $edit_ldap, 'value' => $value , 'severity' => $severity);
+  }
+  return $status;
+
+}
+function _ldaphelp_parse_status_to_text($status, $heading, $replacements = array()) {
+
+  $var_del = "\r\n------------------------------------------------\r\n";
+  $section_del = "\r\n\r\n================================================\r\n";
+  $name_val_del = ":\r\n";
+  $lr = "\r\n";
+
+  $replacements = array_merge($replacements, array(
+  '<br/>' => $lr,
+  '<ul>' => $lr,
+  '</ul>' => $lr,
+  '<li>' => $lr,
+  '</li>' => "",
+  "<code>" => "",
+  "</code>" => "",
+  "<strong>" => "",
+  "</strong>" => ""
+  ));
+
+
+  $content = drupal_strtoupper($heading) . $lr  ;
+  foreach ($status as $item) {
+  //  $item['value'] = str_replace(array('<br/>','<ul>','</ul>','<li>','</li>',"<code>","</code>"),
+   // array("\r\n","\r\n","\r\n","\r\n","\r\n"),$item['value'] );
+    $item['value'] = str_replace(array_keys($replacements), array_values($replacements), $item['value'] );
+    $item['title'] = str_replace(array_keys($replacements), array_values($replacements), $item['title'] );
+    $content .=   $item['title'] . $name_val_del . $item['value'] . $var_del;
+  }
+  return $content;
+}
+
+function _ldaphelp_testldap($ldap, $sid) {
+  global $_ldapauth_ldap;
+
+ // foreach ($ldaps as $sid => $ldap) {
+    $test = array();
+    // Initialize LDAP.
+    _ldapauth_init($sid);
+
+    if ($_ldapauth_ldap->getOption('binddn') && $_ldapauth_ldap->getOption('bindpw')) {
+      $test['bind_result'] = $_ldapauth_ldap->connectAndBind($_ldapauth_ldap->getOption('binddn'), $_ldapauth_ldap->getOption('bindpw'));
+      $test['bind_type'] = "non-anon";
+
+    }
+    else {
+      $test['bind_result'] = $_ldapauth_ldap->connectAndBind();
+      $test['bind_type'] = "anon";
+    }
+
+    if ($test['bind_result']) {
+      $test['bind_result_text'] =  "Success";
+      $test['bind_success'] = TRUE;
+    }
+    else {
+      $test['bind_result_error'] = ldap_error($_ldapauth_ldap->connection);
+      $test['bind_result_errno'] = ldap_errno($_ldapauth_ldap->connection);
+      $test['bind_result_text'] =  "Fail";
+      $test['bind_success'] = FALSE;
+    }
+
+    foreach (explode("\r\n", $_ldapauth_ldap->getOption('basedn')) as $base_dn) {
+      $user_attr = $_ldapauth_ldap->getOption('user_attr') ? $_ldapauth_ldap->getOption('user_attr') : LDAPAUTH_DEFAULT_USER_ATTR;
+      $filter = "$user_attr=*";
+      $result = $_ldapauth_ldap->search($base_dn, $filter, array($user_attr), 0, 1, 1);
+      $basedn_data = array();
+      $basedn_data['result']['error'] = ldap_error($_ldapauth_ldap->connection);
+      $basedn_data['basedn'] = $base_dn;
+      $basedn_data['result']['count'] = $result['count'];
+      $basedn_data['result']['sample0'] = $result[0];
+      $basedn_data['result']['dnufn'] = ldap_dn2ufn($base_dn);
+
+      if (! $basedn_data['result']['count']) {
+          $basedn_data['result']['with_user_attr_success'] = FALSE;
+        // try searching for any object to see if user_attr is wrong
+          $filter = "CN=*";
+          $result = $_ldapauth_ldap->search($base_dn, $filter, array($user_attr), 0, 1, 1);
+          $basedn_data['result']['no_user_attr_success'] = ($result['count']) ? TRUE : FALSE;
+        // bad attribute name
+      }
+      else {
+        $basedn_data['result']['with_user_attr_success'] = TRUE;
+      }
+      $test['basedns'][] = $basedn_data;
+    }
+  return $test;
+}
+
+function ldaphelp_baddn($dn, $dn_name) {
+  $result = array();
+  $valid_attr_name = '[a-zA-Z\d\s]';
+  $valid_attr_values = '[a-zA-Z\d\s]';
+  $regex = '/^('. $valid_attr_name .'*\='. $valid_attr_values .'*[,]{1})*('. $valid_attr_name .'*\='. $valid_attr_values .'*){1}$/';
+  // $target = "CN=Schema A1, CN2 =Configuration,DC=ad,DC=uiuc,DC=edu";
+  // $target = "ou=education,dc=ad,dc=uiuc,dc=edu";
+  $match = (preg_match($regex, $dn)) ? TRUE : FALSE;
+  $result['boolean'] = $match;
+  if (!$match) {
+    $result['text'] = "Invalid format for:<br/> <code><strong>". htmlspecialchars($dn)
+    ."</strong><code><br/> One cause may be editing $dn_name with a wysiwyg editor which leaves html.";
+
+  }
+  return $result;
+}
+
+/** parse php modules from phpinfo */
+function ldaphelp_parsePHPModules() {
+  ob_start();
+  phpinfo();
+  $s = ob_get_contents();
+  ob_end_clean();
+
+  $s = strip_tags($s, '<h2><th><td>');
+  $s = preg_replace('/<th[^>]*>([^<]+)<\/th>/', "<info>\\1</info>", $s);
+  $s = preg_replace('/<td[^>]*>([^<]+)<\/td>/', "<info>\\1</info>", $s);
+  $vtmp = preg_split('/(<h2>[^<]+<\/h2>)/', $s, -1, PREG_SPLIT_DELIM_CAPTURE);
+  $vmodules = array();
+  for ($i=1; $i<count($vtmp); $i++) {
+    if (preg_match('/<h2>([^<]+)<\/h2>/', $vtmp[$i], $vmat)) {
+      $vname = trim($vmat[1]);
+      $vtmp2 = explode("\n", $vtmp[$i+1]);
+      foreach ($vtmp2 AS $vone) {
+        $vpat = '<info>([^<]+)<\/info>';
+        $vpat3 = "/$vPat\s*$vpat\s*$vpat/";
+        $vpat2 = "/$vPat\s*$vpat/";
+        if (preg_match($vpat3, $vone, $vmat)) { // 3cols
+          $vmodules[$vname][trim($vmat[1])] = array(trim($vmat[2]), trim($vmat[3]));
+        }
+        elseif (preg_match($vpat2, $vone, $vmat)) { // 2cols
+          $vmodules[$vname][trim($vmat[1])] = trim($vmat[2]);
+        }
+      }
+    }
+  }
+  return $vmodules;
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp_wizard.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp_wizard.inc
new file mode 100644
index 0000000..db86adb
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldaphelp/ldaphelp_wizard.inc
@@ -0,0 +1,368 @@
+<?php
+/**
+ * @file
+ * wizard file for ldaphelp module
+ *
+ */
+function ldaphelp_wizard_form(&$form_state = NULL) {
+
+
+  $inputs = array(
+    'server' => array( 'fieldset' => 'server-settings', 'step' => 1 , 'copy_input' => TRUE, 'default_value' => '' ),
+    'port' => array( 'fieldset' => 'server-settings', 'step' => 1 , 'copy_input' => TRUE , 'default_value' => ''),
+    'tls' => array( 'fieldset' => 'server-settings', 'step' => 1 , 'copy_input' => TRUE , 'default_value' => 0),
+
+    'basedn' => array( 'fieldset' => 'login-procedure', 'step' => 2, 'copy_input' => FALSE),
+    'user_attr' => array( 'fieldset' => 'login-procedure' , 'step' => 2, 'copy_input' => TRUE, 'default_value' => ""),
+    'mail_attr' => array( 'fieldset' => 'login-procedure' , 'step' => 2, 'copy_input' => TRUE, 'default_value' => ""),
+    'sample_user' => array( 'fieldset' => 'login-procedure' , 'step' => 2, 'copy_input' => FALSE, 'default_value' => ""),
+    'binddn' => array( 'fieldset' => 'advanced' , 'step' => 2 , 'copy_input' => TRUE  ),
+    'bindpw' => array( 'fieldset' => 'advanced' , 'step' => 2,  'copy_input' => TRUE, 'unstored' => TRUE),
+  );
+
+  if (! $form_state['storage']['step'] ) {
+    $form_state['storage']['step'] = 1;
+  }
+  elseif ($form_state['clicked_button']['#value'] && $form_state['clicked_button']['#value'] == $form_state['values']['submit_server_settings']) {
+    $form_state['storage']['step'] = 2;
+  }
+  $step = $form_state['storage']['step'];
+
+
+  switch ($step) {
+    case 1:
+
+    $instructions = t('<em>Note: This wizard does not populate the server configuration.  Its
+      just for testing the settings</em>. The goal of this form is to help configure an LDAP server for the LDAP auth module.
+    It will help test and/or determine some of the values needed on the ') .
+    l(t("Add Server form"), 'admin/settings/ldapauth/add/ad') . ' ' .
+    t('If you are unsure about your LDAP, a simple email to your LDAP administrator will save you some time
+    and frustration.')
+    .'<br/>'. t('Step 1 is to try to bind to the root of an LDAP server.');
+
+    $ldapauth_admin_form = ldapauth_admin_form($form_state, NULL, NULL);
+    $form['step'] = array('#type' => 'hidden', '#default_value' => $step);
+    $form['server-settings'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('1. Server settings'),
+      '#collapsible' => FALSE,
+      '#collapsed' => FALSE,
+      '#description' => $instructions,
+    );
+
+    foreach ($inputs as $fieldname => $conf) {
+      if ($conf['step'] == 1 && $conf['copy_input']) {
+      $form[$conf['fieldset']][$fieldname] = $ldapauth_admin_form[$conf['fieldset']][$fieldname];
+      }
+    };
+
+    if (! $form_state['clicked_button']['#post']) { // initial state, set defaults
+      foreach ($inputs as $fieldname => $conf) {
+        if ($conf['step'] == 1 && $conf['default_value']) {
+          $form[$conf['fieldset']][$fieldname]['#default_value'] = $conf['default_value'];
+        }
+      }
+    }
+    else { // post from same form, no longer use default values
+
+      $form_state['values']['tls'] = ($form_state['values']['tls']) ? 1 : 0;
+
+      foreach ($inputs as $fieldname => $conf) {
+        if ($conf['step'] == 1 && ( ! $conf['unstored']) ) {
+          $form_state['storage'][$fieldname] = $form_state['values'][$fieldname];
+          $form[$conf['fieldset']][$fieldname]['#default_value'] = $form_state['values'][$fieldname];
+        }
+      }
+
+      if (! form_get_errors()) {
+        $bind_form_values_success = ldaphelp_bindtrials($form_state['values']);  // try binding to ldap.
+      }
+    }
+
+    $form['submit'] = array(
+      '#type' => 'submit',
+      '#value' => t('Test'),
+    );
+    if ($bind_form_values_success) {
+      $form['submit_server_settings'] = array(
+        '#type' => 'submit',
+        '#value' => t('Next Step'),
+      );
+    }
+
+    break;
+
+    case 2:
+
+      $instructions = t('Step 2 is to test of assist in finding Base DNs, Username Attributes, and Email Attributes. Enter as much of the information
+      you know below.') ."<br/>".
+        "server: " . $form_state['storage']['server'] .", port: ". $form_state['storage']['port'] .", tls: ". $form_state['storage']['tls'];
+
+      $form['step'] = array('#type' => 'hidden', '#default_value' => $step);
+      $ldapauth_admin_form = ldapauth_admin_form($form_state, NULL, NULL);
+
+      $form['login-procedure'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('2. Login procedure'),
+        '#collapsible' => FALSE,
+        '#collapsed' => FALSE,
+        '#description' => $instructions,
+        );
+
+      $form['login-procedure']['basedn'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Single Base DN to test'),
+          '#description' => t('Enter one base DN.  For the final configuration,
+            you may search within several base DNs.  But you can only test one at a time here.'),
+          '#size' => 60,
+          '#maxlength' => 255,
+          '#required' => TRUE,
+        );
+
+      foreach ($inputs as $fieldname => $conf) {
+        if ($conf['step'] == 2 && $conf['copy_input']) {
+        $form[$conf['fieldset']][$fieldname] = $ldapauth_admin_form[$conf['fieldset']][$fieldname];
+        }
+      };
+
+      $form['login-procedure']['sample_user'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Sample username'),
+        '#description' => t('sample username for testing (e.g. jdoe)'),
+        '#size' => 20,
+        '#maxlength' => 255,
+        '#required' => TRUE,
+      );
+
+      $form['advanced'] = $ldapauth_admin_form['advanced'];
+      $form['advanced']['#collapsed'] = FALSE;
+      $form['advanced']['bindpw']['#type'] = 'textfield';
+
+      $form['submit'] = array(
+        '#type' => 'submit',
+        '#value' => t('Test'),
+      );
+
+
+      if ($form_state['clicked_button']['#value'] == 'Next Step') {  // coming from step 1, do nothing.  perhaps clear defaults
+
+        foreach ($inputs as $fieldname => $conf) {
+          if ($conf['step'] == 2 && isset($conf['default_value'])) {
+            $form[$conf['fieldset']][$fieldname]['#default_value'] = $conf['default_value'];
+          }
+        }
+        $form['login-procedure']['basedn']['#default_value'] = 'dc='. str_replace('.', ',dc=', $form_state['storage']['server']);
+      }
+      else {
+        // staying in step 2.  form is submitting to itself over and over.
+
+        $values = $form_state['values'];
+        foreach ($inputs as $fieldname => $conf) {
+          if ($conf['step'] == 2) {
+            if (! $conf['unstored']) {
+              $form_state['storage'][$fieldname] = $values[$fieldname];
+            }
+            $form[$conf['fieldset']][$fieldname]['#default_value'] = $form_state['values'][$fieldname];
+          }
+        }
+
+        if (form_get_errors()) {
+          break;
+        }
+        $ldapserver = array();
+        $mappings = array('server', 'port', 'tls', 'binddn', 'basedn', 'user_attr', 'mail_attr', 'bindpw');
+        foreach ($mappings as $key) {
+          if ($inputs[$key]['unstored']) {
+            $ldapserver[$key]  = $values[$key];
+          }
+          else {
+            $ldapserver[$key] = $form_state['storage'][$key];
+          }
+        }
+        global $_ldapauth_ldap;
+        $result = _ldaphelp_bind_test($ldapserver);
+
+        if ($result['bind_success'] != 1) {
+          drupal_set_message(t('Failed to bind to LDAP server'), 'error');
+          return $form;
+        }
+
+        $sample_user = $form_state['storage']['sample_user'];
+        $mail_attrs = array();
+        $user_attrs = array();
+        global $_ldaphelp_ldaps;
+        foreach ($_ldaphelp_ldaps as $ldapid => $ldaptype) {
+          $mail_attr = $ldaptype['fields']['login-procedure']['mail_attr'];
+          $user_attr = $ldaptype['fields']['login-procedure']['user_attr'];
+          if (! in_array($mail_attr, $mail_attrs)) {
+            $mail_attrs[] = $mail_attr;
+          }
+          if (! in_array($user_attr, $user_attrs)) {
+            $user_attrs[] = $user_attr;
+            $large_filter .= "(". $user_attr ."=". $sample_user .")";
+          }
+        }
+
+
+    // 1. do a search of the ldap (with or without credentials) and see if it works.
+
+        $user_attr = $form_state['storage']['user_attr'];
+
+        $filter = ($user_attr) ? "$user_attr=$sample_user" : "(|$large_filter)";
+
+        $result = $_ldapauth_ldap->search($ldapserver['basedn'], $filter);
+        $basedn_data = array();
+        $basedn_data['result']['error'] = ldap_error($_ldapauth_ldap->connection);
+        $basedn_data['result']['errno'] = ldap_errno($_ldapauth_ldap->connection);
+        $search_description = 'search where base dn = <code>'. $ldapserver['basedn'] .'</code> and filter =<code>'.  $filter ."</code>";
+
+        $basedn_data['result']['count'] = $result['count'];
+        $basedn_data['result']['sample0'] = $result[0];
+        $basedn_data['result']['dnufn'] = ldap_dn2ufn($base_dn);
+
+
+        $suggestions[0] = "... your sample username is wrong.";
+        if (! $form_state['storage']['binddn']) {
+          $suggestions[1] = "... you must bind non anonymously.";
+        }
+        $suggestions[2] = "... " . t("your base DN does not have accounts within it.");
+        $suggestions[4] = "... " . t("your base DN is incorrect.");
+        $suggestions[3] = "... " . t("you are using the wrong user attribute or haven't picked one. <br/>Maybe one of the following: <code>") . join(", ", $user_attrs) ."</code>";
+
+        if ($basedn_data['result']['errno'] != 0 ) {
+          drupal_set_message(t('Error encountered in') . ' ' . $search_description .".<br/>error name: ". $basedn_data['result']['error'] .', error number: '.
+          $basedn_data['result']['errno'] .".  Perhaps:". ldaphelp_suggest($suggestions, array(1, 4)), 'error');
+          break;
+        }
+
+        if (! $basedn_data['result']['count']) {
+          drupal_set_message(t('Could not find any results with') . ' ' . $search_description .".  Perhaps:". ldaphelp_suggest($suggestions, array(0, 1, 2, 3)), 'error');
+          break;
+        }
+
+        if (! $basedn_data['result']['count'] > 1) {
+          drupal_set_message(t('More than one result was found with') . ' ' . $search_description ."  Perhaps:". ldaphelp_suggest($suggestions, array(3)), 'error');
+          break;
+        }
+
+        $ldap_object = $basedn_data['result']['sample0'];
+        $message = t("Found 1 user object with") . " " . $search_description .".  Search should return exactly one object.";
+        $mail_attrs = ($form_state['storage']['mail_attr']) ? array($form_state['storage']['mail_attr']) : $mail_attrs;
+
+        foreach ($mail_attrs as $mail_attr) {
+          if ($ldap_object[$mail_attr] ) {
+            $message .= "<br/>" . t("Email Attribute of") ." <code>$mail_attr</code> ". t("is present with a value of") . ' ' . $ldap_object[$mail_attr][0] ;
+          }
+          elseif (! $form_state['storage']['mail_attr'] ) {
+            $message .= "<br/>" . t("Email Attribute of") ." <code>$mail_attr</code> ". t("<strong>not present</strong>.") ;
+          }
+        }
+        drupal_set_message($message);
+      }
+    break;
+  }  // end switch step 1 or 2
+  return $form;
+}
+
+function ldaphelp_suggest($all_suggestions, $suggestions) {
+  $ul = "<ul>\r\n";
+  foreach ($suggestions as $suggestion) {
+    if ($all_suggestions[$suggestion]) {
+      $ul .= "<li>". $all_suggestions[$suggestion] ."</li>";
+    }
+  }
+  $ul .= "</ul>\r\n";
+  return $ul;
+}
+
+function ldaphelp_bindtrials($values) {
+
+
+  // first try values in form if port is entered:
+  $bind_success = FALSE;
+  $bind_form_values_success = FALSE;
+
+  if ($values['port']) {
+    $trial = array( 'server' => $values['server'], 'port' => $values['port'], 'tls' => $values['tls']);
+    $trial['results']  = _ldaphelp_bind_test($trial);
+    if ($trial['results']['bind_success'] == 1) {
+      drupal_set_message(t("Successfully bound to port @port with tls=@tls on server @server", array('@port' => $values['port'], '@tls' => $values['tls'], '@server' => $values['server'])));
+      $bind_success = TRUE;
+      $bind_form_values_success = TRUE;
+    }
+    else {
+      drupal_set_message(check_plain(ldaphelp_bind_trial_message($trial)), 'error');
+    }
+    $trials['form_values'] = $trial;
+  }
+
+  if ( (! $values['port']) || $trials['form_values']['results']['bind_success'] != 1) {
+    $trials['tls'] = array('port' => 389, 'tls' => 1, 'server' => $values['server']);
+    $trials['encrypted'] = array('port' => 636, 'tls' => 0, 'server' => $values['server']);
+    $trials['odd'] = array('port' => 636, 'tls' => 1, 'server' => $values['server']);
+    foreach ($trials as $name => $trial) {
+      $trial['results'] = _ldaphelp_bind_test($trial);
+      if ($trial['results']['bind_success'] == 1) {
+        drupal_set_message(t("Successfully bound to port @port with tls=@tls on server @server", array('@port' => $trial['port'], '@tls' => $trial['tls'], '@server' => $trial['server'])));
+        $bind_success = TRUE;
+      }
+      else {
+        drupal_set_message(check_plain(ldaphelp_bind_trial_message($trial)), 'error');
+      }
+    }
+  }
+
+  if (! $bind_success ) {
+    drupal_set_message(t('Could not bind to ldap to server @server', array('@server' =>  $values['server'])) .
+      ' ' . t('Perhaps you have the wrong hostname, its on a nonstandard port, ' .
+        'or it doesn not allow anononymous binds.  Try pinging the server.'), 'error');
+  }
+
+  if ( $bind_success && ! $bind_form_values_success ) {
+    drupal_set_message(t('Was able to bind to server @server with some ' .
+      'configurations, but not the data you entered.  If one of the ' .
+      'successful attempts looks correct, enter it in the form to go to next step.',
+      array('@server' => $values['server'])), 'warn');
+  }
+  return $bind_form_values_success;
+}
+
+function ldaphelp_wizard_form_validate($form, &$form_state) {
+  $values = $form_state['values'];
+
+  switch ($form_state['storage']['step']) {
+
+    case 1:
+      if ($values['port'] && !is_numeric($values['port'])) {
+        form_set_error('port', t('The TCP/IP port must be an integer.'));
+      }
+
+    case 2:
+
+      return;
+      if (! trim($form_state['values']['import_data_serialized'])) {
+        $haserror = TRUE;
+      }
+      else {
+        $import_data = unserialize(trim($form_state['values']['import_data_serialized']));
+        if (! is_array($import_data)) {
+          $haserror = TRUE;
+          }
+        elseif ( ! ($import_data['ldaps'] ||  $import_data['admin_settings'])) {
+          $haserror = TRUE;
+        }
+      }
+
+      if ($haserror) {
+        drupal_set_message( t("Input not valid.  Input should be a ' .
+          'serialized array from the export function. It should look ' .
+          'something like: ") .'<code>a:1:{s:5:"ldaps";a:1:{i:1;a:1</code>...',
+          'error');
+        $form_state['storage']['step'] =  $form_state['storage']['step'] - 1;
+        return FALSE;
+      }
+      break;
+  }
+
+
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.admin.inc b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.admin.inc
new file mode 100644
index 0000000..2bd2d4f
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.admin.inc
@@ -0,0 +1,140 @@
+<?php
+
+/**
+ * @file
+ * Module admin page callbacks.
+ */
+
+//////////////////////////////////////////////////////////////////////////////
+// ldapsync settings
+
+/**
+ * Implements the settings page.
+ *
+ * @return
+ *   The form structure.
+ */
+function ldapsync_admin_settings() {
+
+  $form['options'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('LDAPsync settings'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+  );
+  $options_time_interval = array(
+    0 => t('As often as possible'),
+    1*3600 => t('1 hour'),
+    6*3600 => t('6 hours'),
+    12*3600 => t('12 hours'),
+    24*3600 => t('24 hours'),
+    24*7*3600 => t('1 week'),
+    -1 => t('never (only sync manually)')
+  );
+  $form['options']['ldapsync_time_interval'] = array(
+    '#type' => 'select',
+    '#title' => t('Sync time interval'),
+    '#description' => t('The number of hours between each sync. A larger setting reduces server load for large LDAP directories.<br />You must have enabled cron, and ldapsync will not run more often than cron.'),
+    '#default_value' => variable_get('ldapsync_time_interval', -1),
+    '#options' => $options_time_interval,
+  );
+  $form['options']['ldapsync_existing_only'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Sync existing users only.'),
+    '#default_value' => variable_get('ldapsync_existing_only', 0),
+    '#description' => t("If checked, only existing users will be synced with LDAP, no new users will be created.  Note, the ldapauth 'Create new Drupal user' option will also prevent new user create."),
+  );
+  $options_login_conflict = array(
+    LDAPSYNC_CONFLICT_FOLLOW_LDAPAUTH => t('Follow LDAP Authentication setting'),
+    LDAPAUTH_CONFLICT_LOG => t('Disallow login and log the conflict'),
+    LDAPAUTH_CONFLICT_RESOLVE => t('Associate local account with the LDAP entry'),
+  );
+
+  $form['options']['ldapsync_login_conflict'] = array(
+    '#type' => 'select',
+    '#title' => t('Choose user conflict resolve procedure'),
+    '#description' => t('Pick what should be done if the local Drupal account already exists with the same login name.'),
+    '#default_value' => variable_get('ldapsync_login_conflict', LDAPSYNC_CONFLICT_FOLLOW_LDAPAUTH),
+    '#options' => $options_login_conflict,
+    '#required' => TRUE,
+  );
+
+  $form['options']['ldapsync_missing_users_action'] = array(
+    '#type' => 'select',
+    '#title' => t('Missing users action'),
+    '#description' => t("What to do when LDAP-authentified Drupal users don't exist or are disabled in LDAP. Choose block to disable the user accounts in Drupal. Choose warn to only log a warning to the Drupal log."),
+    '#default_value' => variable_get('ldapsync_missing_users_action', 'warn'),
+    '#options' => array('warn' => t('warn'), 'block' => t('block')),
+  );
+  $form['options']['ldapsync_load_user_by'] = array(
+    '#type' => 'select',
+    '#title' => t('What to use for testing for existing users.'),
+    '#description' => t("If you want to check for users by email, change this."),
+    '#default_value' => variable_get('ldapsync_load_user_by', 'name'),
+    '#options' => array('name' => t('User name'), 'email ' => t('E-mail')),
+  );
+  $form['options']['ldapsync_filter'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Optional Search filters'),
+    '#default_value' => variable_get('ldapsync_filter', ''),
+    '#cols' => 50,
+    '#rows' => 6,
+    '#description' => t('The default filter looks for all entries that contain the user name attribute, e.g. (uid=*). This can return either unwanted or too many results. For instance, AD limits searchs to 1000 results. LDAP filters (Google "ldap search filter tutorial") can be entered on separate lines to refine/limit the users found.  Each server/basedn area will be searched for users using the filters defined below.<br/ >For example: (&(objectClass=person)(|(uid=*)(sAMAccountName=*)))'),
+    '#required' => FALSE,
+  );
+  $form['options']['ldapsync_filter_append_default'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Append default filter'),
+    '#default_value' => variable_get('ldapsync_filter_append_default', 0),
+    '#description' => t("If checked, the default filter will be 'and-ed' with the optional search filters above.  E.g. (&([optional filter]<u>(uid=*)</u>"),
+  );
+
+  $form['manual'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Manually sync users now'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+  );
+  $form['manual']['syncnow'] = array(
+    '#type'  => 'submit',
+    '#value' => t('Sync now'),
+    '#submit' => array('ldapsync_admin_settings_sync_now'),
+  );
+
+  $form['submit'] = array(
+    '#type'  => 'submit',
+    '#value' => t('Save settings'),
+  );
+
+  return $form;
+}
+
+/**
+ * Validate hook for the settings form.
+ */
+function ldapsync_admin_settings_validate($form, &$form_state) {
+}
+
+/**
+ * Submit hook for the settings form.
+ */
+function ldapsync_admin_settings_submit($form, &$form_state) {
+  $values = $form_state['values'];
+  variable_set('ldapsync_time_interval', $values['ldapsync_time_interval']);
+  variable_set('ldapsync_filter', trim($values['ldapsync_filter']));
+  variable_set('ldapsync_missing_users_action', $values['ldapsync_missing_users_action']);
+  variable_set('ldapsync_load_user_by', $values['ldapsync_load_user_by']);
+  variable_set('ldapsync_filter_append_default', $values['ldapsync_filter_append_default']);
+  variable_set('ldapsync_existing_only', $values['ldapsync_existing_only']);
+  variable_set('ldapsync_login_conflict', $values['ldapsync_login_conflict']);
+
+  drupal_set_message(t('Settings saved'));
+}
+
+/**
+ * Syncs accounts.
+ */
+function ldapsync_admin_settings_sync_now() {
+  $message = _ldapsync_sync();
+  drupal_set_message(check_plain($message));
+}
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.info b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.info
new file mode 100644
index 0000000..93b89b4
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.info
@@ -0,0 +1,14 @@
+; $Id$
+name = Synchronization
+description = Implements LDAP users sync with Drupal
+package = LDAP integration
+dependencies[] = ldapauth
+core = 6.x
+
+
+; Information added by drupal.org packaging script on 2012-06-28
+version = "6.x-1.0-beta3"
+core = "6.x"
+project = "ldap_integration"
+datestamp = "1340919401"
+
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.install b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.install
new file mode 100644
index 0000000..72719bd
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.install
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * ldapsync module installation and upgrade code.
+ */
+
+//////////////////////////////////////////////////////////////////////////////
+// Core API hooks
+
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function ldapsync_uninstall() {
+  $ret = array();
+
+  variable_del('ldapsync_time_interval');
+  variable_del('ldapsync_last_sync_time');
+  variable_del('ldapsync_existing_only');
+  variable_del('ldapsync_login_conflict');
+  variable_del('ldapsync_missing_users_action');
+  variable_del('ldapsync_load_user_by');
+  variable_del('ldapsync_filter');
+  variable_del('ldapsync_filter_append_default');
+
+  return $ret;
+}
+
diff --git a/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.module b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.module
new file mode 100644
index 0000000..99a0be2
--- /dev/null
+++ b/kolab.org/www/drupal-6.26/sites/all/modules/ldap_integration/ldapsync.module
@@ -0,0 +1,423 @@
+<?php
+
+/**
+ * @file
+ * ldapsync keeps LDAP and Drupal user lists synchronized.
+ */
+
+//////////////////////////////////////////////////////////////////////////////
+
+define('LDAPSYNC_CONFLICT_FOLLOW_LDAPAUTH', 3);
+
+define('LDAPSYNC_TIME_INTERVAL',  variable_get('ldapsync_time_interval', -1));
+define('LDAPSYNC_FILTER',         variable_get('ldapsync_filter', ''));
+define('LDAPSYNC_LOGIN_CONFLICT', variable_get('ldapsync_login_conflict', LDAPSYNC_CONFLICT_FOLLOW_LDAPAUTH));
+
+//////////////////////////////////////////////////////////////////////////////
+// Core API hooks
+
+/**
+ * Implements hook_init().
+ */
+function ldapsync_init() {
+  module_load_include('inc', 'ldapauth', 'includes/ldap.core');
+  module_load_include('inc', 'ldapauth', 'includes/LDAPInterface');
+}
+
+/**
+ * Implementation of hook_help().
+ */
+function ldapsync_help($path, $arg) {
+  $output = '';
+  switch ($path) {
+    case "admin/help#ldapsync":
+      $output = '<p>'. t("Searches LDAP to update Drupal user membership and information.") .'</p>';
+      break;
+  }
+  return $output;
+}
+
+/**
+ * Implementation of hook_menu().
+ */
+function ldapsync_menu() {
+  return array(
+    'admin/settings/ldap/ldapsync' => array(
+      'title' => 'Synchronization',
+      'description' => 'Configure LDAP sync settings.',
+      'page callback' => 'drupal_get_form',
+      'page arguments' => array('ldapsync_admin_settings'),
+      'access arguments' => array('administer ldap modules'),
+      'file' => 'ldapsync.admin.inc',
+    ),
+  );
+}
+
+/**
+ * Implements hook_cron().
+ *
+ * Checks ldapsync_time_interval and ldapsync_last_sync_time variables to determine whether to run ldapsync.
+ */
+function ldapsync_cron() {
+  $time_interval = variable_get('ldapsync_time_interval', -1); // -1 means "only sync manually"
+  $last_sync_time = variable_get('ldapsync_last_sync_time', 0);
+  if (((time() - $last_sync_time) > $time_interval) && ($time_interval != -1)) {
+    _ldapsync_sync();
+  }
+}
+
+/**
+ * Main routine.
+ */
+function _ldapsync_sync() {
+  global $_ldapsync_ldap;
+
+  // If ldapgroups is enabled, include it for groups-role sync.
+  if (module_exists('ldapgroups')) {
+    module_load_include('inc', 'ldapgroups', 'ldapgroups');
+  }
+
+  // Find all users in specified OU (using base DN and bind information from ldapauth).
+  // and take appropriate action on the Drupal side.
+  $ldap_users = _ldapsync_search();
+
+  $count_orphaned_users=0;
+
+  // Do we have any LDAP-authentified Drupal users who don't exist in LDAP?
+  if ($ldap_users) {
+    $result = db_query("SELECT uid, name, data FROM {users} WHERE status = %d", 1);
+    while ($row = db_fetch_array($result)) {
+      if ( ! isset($ldap_users[drupal_strtolower($row['name'])]) ) {
+        $data = unserialize($row['data']);
+        if ($data['ldap_authentified']) {
+          // Block user if appropriate module setting is set.
+          if (variable_get('ldapsync_missing_users_action', 'warn') == 'block') {
+            // Block user.
+            db_query("UPDATE {users} SET status=0 WHERE uid=%d", $row['uid']);
+            // Log out blocked user.
+            $account = user_load(array('uid' => $row['uid']));
+            $array = array();
+            user_module_invoke('logout', $array, $account);
+            // Log this.
+            watchdog('ldapsync', 'Disabled LDAP-authentified user %name because the corresponding LDAP account does not exist or is disabled.', array('%name' => $row['name']));
+          }
+          $count_orphaned_users++;
+        }
+      }
+    }
+  }
+  // Send watchdog message with process summary.
+  $params = array(
+    '@ldap_users' => ldapsync_stats('ldap_users'),
+    '@existing_users' => ldapsync_stats('existing_users'),
+    '@new_users' => ldapsync_stats('new_users'),
+    '@orphaned_users' => $count_orphaned_users,
+  );
+  $converted = ldapsync_stats('converted');
+  $ldap_disabled = ldapsync_stats('ldap_users_disabled');
+  $notices = ldapsync_stats('notices');
+  $denied_by_module = ldapsync_stats('denied_by_module');
+
+  $summary = t('Completed LDAP sync. LDAP users found: @ldap_users. Existing users updated: @existing_users. New users created: @new_users. LDAP-authentified users that do not have an enabled LDAP account: @orphaned_users.', $params);
+  if ( $converted ) {
+    $summary .= ' ' . t('Existing users converted to LDAP: @converted.', array('@converted' => $converted));
+  }
+  if ( $ldap_disabled ) {
+    $summary .= ' ' . t('Disabled LDAP users: @disabled.', array('@disabled' => $ldap_disabled));
+  }
+  if ( $notices ) {
+    $summary .= ' ' . t('Watchdog notices/warnings written: @notices.', array('@notices' => $notices));
+  }
+  if ( $denied_by_module ) {
+    $summary .= ' ' . t('Access denied by other modules: @denied.', array('@denied' => $denied_by_module));
+  }
+  watchdog('ldapsync', $summary);
+
+  // Update last sync time variable, so that we don't sync again until the specified time period passes again.
+  variable_set('ldapsync_last_sync_time', time());
+
+  // Useful if calling manually from settings page.
+  return $summary;
+}
+
+/**
+ * Find all LDAP users from servers and OUs specified in ldapauth settings and
+ * create or update existing users as needed.
+ *
+ * @return An array keyed by lower cased Drupal account name of all users found.
+ */
+function _ldapsync_search() {
+  global $_ldapsync_ldap;
+
+  $users=array();
+
+  // Cycle through LDAP configurations.
+  $result = db_query("SELECT sid FROM {ldapauth} WHERE status = %d ORDER BY sid", 1);
+  while ($row = db_fetch_object($result)) {
+    // Initialize LDAP.
+    if (!_ldapsync_init($row->sid)) {
+      watchdog('ldapsync', 'ldapsync init failed for ldap server %sid.', array('%sid' => $row->sid));
+      continue;
+    }
+
+    // Set up for LDAP search.
+    $name_attr = $_ldapsync_ldap->getOption('user_attr') ? $_ldapsync_ldap->getOption('user_attr') : LDAPAUTH_DEFAULT_USER_ATTR;
+    $user_attr = drupal_strtolower($name_attr); // used to find in results.
+    $filters = array();
+    if ( LDAPSYNC_FILTER ) {
+      $filters = explode("\r\n", LDAPSYNC_FILTER);
+    }
+    else {
+      $filters[] = "({$name_attr}=*)";
+    }
+    $attrs = ldapauth_attributes_needed(LDAPAUTH_SYNC_CONTEXT_AUTHENTICATE_DRUPAL_USER, $_ldapsync_ldap->getOption('sid'));
+
+    // If there is no bindn and bindpw - the connect will be an anonymous connect.
+    $_ldapsync_ldap->connect($_ldapsync_ldap->getOption('binddn'), $_ldapsync_ldap->getOption('bindpw'));
+
+    // Search each basedn defined for this server
+    foreach (explode("\r\n", $_ldapsync_ldap->getOption('basedn')) as $base_dn) {
+      if (empty($base_dn)) {
+        continue;
+      }
+
+      // Re-initialize database object each time.
+      $ldapresult = array();
+      $filter_found_users = array();
+
+      // Search this server and basedn using all defined filters.
+      foreach ( $filters as $filter ) {
+        $filter = trim($filter);
+        if (empty($filter)) {
+          continue;
+        }
+        if ( variable_get('ldapsync_filter_append_default', 0) ) {
+          $filter = "(&{$filter}({$name_attr}=*))";
+        }
+
+        if (!($ldapresult = $_ldapsync_ldap->search($base_dn, $filter, $attrs))) {
+          continue;
+        }
+
+        // Cycle through results to build array of user information.
+        foreach ($ldapresult as $entry) {
+          $name = $entry[$user_attr][0];
+
+          // Don't include if no name attribute.
+          if (empty($name)) {
+            continue;
+          }
+
+          // Don't process the same entry found by different filters twice.
+          $lcname = drupal_strtolower($name);
+          if ( isset($filter_found_users[$lcname])) {
+            continue;  // Already found
+          }
+          $filter_found_users[$lcname] = $name;
+
+          ldapsync_stats('ldap_users', 1);
+
+          // Don't include if LDAP account is disabled.
+          $status = $entry['useraccountcontrol'][0];
+          if (($status & 2) != 0) {  // This only works for Active Directory -- search includes disabled accounts in other directories.
+            ldapsync_stats('ldap_users_disabled', 1);
+            continue;
+          }
+
+          // Process this entry to create/update drupal user (if any).
+          $account = _ldapsync_process_entry($_ldapsync_ldap, $name, $entry);
+          if ( ! $account ) {
+            continue;
+          }
+
+          $users[drupal_strtolower($account->name)] = array(
+            'uid' => $account->uid,
+          );
+        }
+      }
+    }
+  }
+
+  return $users;
+}
+/**
+ * Take an ldap object entry and determine if there is an existing account or
+ * a new account needs to be created.
+ *
+ * @param LDAPInterface $ldap An initialized LDAP server interface object
+ * @param String $name The user name attribute value
+ * @param Array $ldap_entry LDAP attributes for user.
+ * @return The account object or FALSE if problem
+ */
+function _ldapsync_process_entry( $ldap, $name, $ldap_entry  ) {
+
+  // check whether user is in an OU mapped in module settings (need to create admin/settings/ldapsync page)
+  $dn = $ldap_entry['dn'];
+
+  if ( $ldap->getOption('puid_attr')) {
+    $puid = ldapauth_extract_puid($server, $name, $ldap_entry);
+  }
+
+  // See if there is a matching Drupal user account
+  $error = '';
+  $account = ldapauth_drupal_user_lookup($ldap, $name, $dn, $error, $puid );
+  if ( $account === NULL ) {
+    ldapsync_stats('notices', 1 );
+    watchdog('ldapsync', 'drupal_user_lookup() returned: ' . $error, NULL, WATCHDOG_ERROR);
+    return FALSE;
+  }
+
+  // Handle map by e-mail option (Issue #1209556)
+  // If no account or PUID not used and account found does not have matching e-mail
+  $user_test_method = variable_get('ldapsync_load_user_by', 'name');
+  if ( $user_test_method == 'email' && ( ! $account || (! $ldap->getOption('puid_attr') && drupal_strtolower($account->mail) != drupal_strtolower($ldap_entry['mail'])))) {
+    $account = user_load(array('mail' => $ldap_entry['mail']));
+  }
+
+  // Allow other modules to determine if this ldap user can access server.
+  if ( ldapauth_user_denied( $ldap, $name, $dn, $account ) ) {
+    ldapsync_stats('denied_by_module', 1);
+    return;
+  }
+
+  // No account found - try to create one
+  if ( ! $account ) {
+    if ( variable_get('ldapsync_existing_only', 0)) {
+      return FALSE;
+    }
+    $error = '';
+    $account = ldapauth_drupal_user_create($ldap, $name, $ldap_entry, $error);
+    if ( $account === FALSE ) {
+      ldapsync_stats('notices', 1 );
+      return FALSE;
+    }
+    ldapsync_stats('new_users', 1 );  // Increment counter
+  }
+
+  // User exists in Drupal -- check a few things
+  else {
+
+    // Check authentication method.
+    if (! $account->ldap_authentified ) {
+      $conflict_resolution = LDAPSYNC_LOGIN_CONFLICT;
+      if ( $conflict_resolution == LDAPSYNC_CONFLICT_FOLLOW_LDAPAUTH ) {
+        $conflict_resolution = LDAPAUTH_LOGIN_CONFLICT;
+      }
+      if ($conflict_resolution == LDAPAUTH_CONFLICT_LOG) {
+        ldapsync_stats('notices', 1 );
+        watchdog('ldapsync', 'Could not create ldap-authentified account for user %name because a local user by that %test_value already exists.', array('%name' => $name, '%test_value' => $user_test_method));
+        return FALSE;
+      }
+      else {
+        $converted = TRUE;
+        ldapsync_stats('converted', 1);
+      }
+    }
+
+    // Make sure all the information is up to date.
+    $drupal_name = ldapauth_drupal_user_name($name, $ldap, $dn);
+    $data = array(
+      'ldap_dn' => $dn,
+      'ldap_config' => $ldap->getOption('sid'),
+      'ldap_authentified' => TRUE,
+      'authname_ldapauth' => $drupal_name,
+      'ldap_name' => $name,
+    );
+    // Follow ldapauth password sync rules.
+    if (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_MIXED && LDAPAUTH_SYNC_PASSWORDS) {
+      $data['pass'] = $pass;
+    }
+    $puid = $account->ldap_puid; // save setting from drupal_user_lookupsave.
+    $account = user_save($account, $data);
+
+    // Make sure the ldapauth_users info is current (User object may have been moved).
+    $user_info = ldapauth_userinfo_load_by_uid( $account->uid );
+    if ( empty($user_info) ) {   // Don't have entry, so make one.
+      $user_info = new stdClass();
+      $user_info->uid = $account->uid;
+    }
+    $user_info->sid = $account->ldap_config;
+    $user_info->machine_name = $ldap->getOption('machine_name');
+    $user_info->dn = $dn;
+    $user_info->puid = $puid ? $puid : $account->$name;
+    ldapauth_userinfo_save($user_info);
+
+    if ( ! $converted ) {
+      ldapsync_stats('existing_users', 1);
+    }
+  }
+
+  // Update user's groups if ldapgroups is enabled.
+  if ( module_exists('ldapgroups')) {
+    ldapgroups_user_login($account);
+  }
+  // Update user's data if ldapdata is enabled.
+  if ( module_exists('ldapdata') ) {
+    _ldapdata_user_load($account, TRUE, $ldap_users);
+  }
+
+  // Enable any blocked user who is enabled in LDAP.
+  if (!$account->status) {
+    ldapsync_stats('notices', 1 );
+    db_query("UPDATE {users} SET status = %d where uid = %d", 1, $account->uid);
+    watchdog('ldapsync', 'Enabled LDAP-authentified user %name because the corresponding LDAP account is enabled.', array('%name' => $name));
+  }
+
+  // Reset user specific caches to prevent memory problems
+  ldapauth_user_lookup_by_dn( NULL, NULL, NULL, TRUE);
+  ldapauth_drupal_user_name(NULL, NULL, NULL, TRUE);
+  if ( module_exists('ldapgroups')) {
+    ldapgroups_groups_load(NULL, NULL, NULL, TRUE);
+  }
+  return $account;
+}
+//////////////////////////////////////////////////////////////////////////////
+// Auxiliary functions
+
+/**
+ * Initiates the LDAPInterfase class.
+ *
+ * @param $sid
+ *   An ID of the LDAP server configuration.
+ *
+ * @return
+ */
+function _ldapsync_init($sid) {
+  global $_ldapsync_ldap;
+
+  $server = ldapauth_server_load($sid);
+
+  if (! empty($server) ) {
+    $_ldapsync_ldap = new LDAPInterface();
+    $_ldapsync_ldap->setOption('sid', $server->sid);
+    $_ldapsync_ldap->setOption('name', $server->name);
+    $_ldapsync_ldap->setOption('machine_name', $server->machine_name);
+    $_ldapsync_ldap->setOption('server', $server->server);
+    $_ldapsync_ldap->setOption('port', $server->port);
+    $_ldapsync_ldap->setOption('tls', $server->tls);
+    $_ldapsync_ldap->setOption('enc_type', $server->enc_type);
+    $_ldapsync_ldap->setOption('basedn', $server->basedn);
+    $_ldapsync_ldap->setOption('user_attr', $server->user_attr);
+    $_ldapsync_ldap->setOption('mail_attr', $server->mail_attr);
+    $_ldapsync_ldap->setOption('puid_attr', $server->puid_attr);
+    $_ldapsync_ldap->setOption('binary_puid', $server->binary_puid);
+    $_ldapsync_ldap->setOption('binddn', $server->binddn);
+    $_ldapsync_ldap->setOption('bindpw', $server->bindpw);
+    return $_ldapsync_ldap;
+  }
+}
+/**
+ * Statistics counter function to track summary info.
+ *
+ * @param string $type The statistics category, e.g. new_users, notices, etc.
+ * @param int $n number of users to add to category, defaults to 0.
+ * @return int current count of users in category;
+ */
+function ldapsync_stats( $type, $n=0 ) {
+  static $stats = array();
+  if ( ! isset($stats[$type] ) ) {
+    $stats[$type] = 0;
+  }
+  $stats[$type] += $n;
+  return $stats[$type];
+}





More information about the commits mailing list