Only in ldap_integration_beta2/: ChangeLog
Only in ldap_integration_beta3/: changelog.txt
Only in ldap_integration_beta2/: .cvsignore
Common subdirectories: ldap_integration_beta2/includes and ldap_integration_beta3/includes
diff ldap_integration_beta2/ldapauth.admin.inc ldap_integration_beta3/ldapauth.admin.inc
2d1
< // $Id: ldapauth.admin.inc,v 1.6 2009/10/27 14:29:16 miglius Exp $
26a26,30
>   $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'),
>   );
38c42
<     '#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.'),
68c72,78
<     '#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.'),
77a88,95
>   $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,
>   );
82c100
<     '#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.'),
122a141,142
>       variable_set('ldapauth_create_users', $values['ldapauth_create_users']);
>       variable_set('ldapauth_alter_username_field', $values['ldapauth_alter_username_field']);
133c153,154
< 
---
>       variable_del('ldapauth_create_users');
>       variable_del('ldapauth_alter_username_field');
206c227
<     $edit = db_fetch_array(db_query("SELECT * FROM {ldapauth} WHERE sid = %d", $sid));
---
>     $edit = (array) ldapauth_server_load( $sid );
210a232,236
>     $form['original_server'] = array(
>       '#type' => 'value',
>       '#value' => ldapauth_server_load( $sid ),
>     );
>     $name_classes = "ldapauth-name-update";
214a241
>       'machine_name' => '',
218c245
<       'encrypted' => 0,
---
>       'enc_type' => 0,
221a249,250
>       'puid_attr' => '',
>       'binary_puid' => 0,
226a256
>     $name_classes = "ldapauth-name";
242a273
>     '#attributes' => array('class' => $name_classes),
243a275,284
>   $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'),
>   );
> 
250c291
<     '#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.'),
259c300
<     '#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).'),
267,271c308,313
<   $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.'),
303a346,359
>   $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."),
>   );
310c366
<     '#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>')),
318c374
<     '#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>')),
379a436,438
>     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'])));
>     }
394,404c453,477
<       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']);
406,407c479,483
<         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');
409,410d484
<         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']));
411a486,489
>       if ( ! empty($values['bindpw_clear'])) {
>         $server['bindpw'] = '';
>       }
>       ldapauth_server_save($server, FALSE, TRUE);
545,547c623
<     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']);
562a639,678
>  * 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;
> }
> 
> 
> /**
592c708,848
< 
---
> /**
>  * 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 ldap_integration_beta2/ldapauth.admin.js ldap_integration_beta3/ldapauth.admin.js
1d0
< // $Id: ldapauth.admin.js,v 1.1 2009/07/28 14:03:05 miglius Exp $
21c20,47
< }
---
>   // Server edit/create form machine_name JS
>   $('.ldapauth-name:not(.processed)').each(function() {
>     $('.ldapauth-name')
>       .addClass('processed')
>       .after(' <small class="ldapauth-machine-name-suffix">&nbsp;</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();
>     }
>   });
>   
> };
Only in ldap_integration_beta3/: ldapauth.api.php
Only in ldap_integration_beta3/: ldapauth.features.inc
diff ldap_integration_beta2/ldapauth.info ldap_integration_beta3/ldapauth.info
1d0
< ; $Id: ldapauth.info,v 1.3 2009/02/19 16:56:16 miglius Exp $
9,10c8,12
< ; 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"
13c15
< datestamp = "1256654469"
---
> datestamp = "1340919401"
diff ldap_integration_beta2/ldapauth.install ldap_integration_beta3/ldapauth.install
2d1
< // $Id: ldapauth.install,v 1.20 2009/10/27 14:29:16 miglius Exp $
16a16,32
>   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;
> 
23a40
>   drupal_uninstall_schema('ldapauth_users');
32a50,51
>   variable_del('ldapauth_create_users');
>   variable_del('ldapauth_alter_username_field');
47a67
>         'no export' => TRUE,  // Do not export db key
53a74,78
>       'machine_name' => array(
>         'type' => 'varchar',
>         'length' => 255,
>         'not null' => TRUE,
>       ),
76c101
<       'encrypted' => array(
---
>       'enc_type' => array(
92a118,126
>       'puid_attr' => array(
>         'type' => 'varchar',
>         'length' => 255,
>       ),
>       'binary_puid' => array(
>         'type' => 'int',
>         'size' => 'tiny',
>         'default' => '0',
>       ),
116c150,222
<     '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
>     ),
144c250
<   db_add_field($ret, 'ldapauth', 'login_php', array(
---
>   db_add_field($ret, 'ldapauth', 'login_php',  array(
148c254
<   db_add_field($ret, 'ldapauth', 'filter_php', array(
---
>   db_add_field($ret, 'ldapauth', 'filter_php',  array(
152c258
<   db_add_field($ret, 'ldapauth', 'weight', array(
---
>   db_add_field($ret, 'ldapauth', 'weight',  array(
173a280,403
>   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);
diff ldap_integration_beta2/ldapauth.module ldap_integration_beta3/ldapauth.module
2d1
< // $Id: ldapauth.module,v 1.46 2009/10/27 14:29:16 miglius Exp $
8a8
> 
20,28c20,40
< 
< 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));
37c49,50
<   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');
54c67
<   return array(
---
>   $items = array(
68c81
<      'file' => 'ldapauth.admin.inc',
---
>       'file' => 'ldapauth.admin.inc',
131a145,153
>     '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',
>     ),
> 
132a155,175
>   // 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;
152c195,200
<     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
161,163d208
< 
<       if (LDAPAUTH_ALTER_EMAIL_FIELD == LDAPAUTH_EMAIL_FIELD_REMOVE)
<         unset($edit['mail']);
167c212
<         $row = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE sid = %d", $account->ldap_config));
---
>         $server = ldapauth_server_load( $account->ldap_config );
169,174c214,235
<          '#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,
>           ),
175a237,246
>         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,
>           );
>         }
177a249,253
>     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;
208c284,285
<       if (LDAPAUTH_DISABLE_PASS_CHANGE)
---
>     case 'user_login':
>       if (LDAPAUTH_DISABLE_PASS_CHANGE && $user->uid != 1) {
209a287,289
>         $key = array_search('user_login_final_validate', $form['#validate']);
>         $form['#validate'][$key] = 'ldapauth_user_login_final_validate';
>       }
214,215c294,307
<         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']);
>         }
236a329,355
> 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']);
>     }
>   }
> 
> }
> 
> 
> 
259c378
<  * Main user validation function.
---
>  * Main user validation function.  Replaces Drupal default login form validation.
268c387
<  * Main user authentication function.
---
>  * Main user authentication function.  Called by form validator.
276c395
<   $pass = trim($form_values['pass']);
---
>   $pass = $form_values['pass'];
286c405
<   $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);
294c413
<     $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);
308,310c427,436
<   $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);
313,314c439,440
<   // 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 ) ) {
315a442,455
>   }
> 
>   // 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
>     }
>   }
317,318c457,458
<   // Authenticate LDAP user.
<   if (!($dn = _ldapauth_auth($name, $pass)))
---
>   // If there is any validations errors, we do not query LDAP.
>   if (form_get_errors())
320a461
>   // No matching Drupal user, try to create one for this LDAP account.
322,338c463,467
<     // 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;
339a469
>     $user = $account;
340a471,472
> 
>   // Login existing user.
342d473
<     // Login existing user.
345a477
>       'ldap_name' => $name,
347a480
>     // LDAP and local user conflict.
349d481
<       // LDAP and local user conflict.
357c489,490
<         $data['authname_ldapauth'] = $name;
---
>         $drupal_name = ldapauth_drupal_user_name($name, $_ldapauth_ldap, $dn);
>         $data['authname_ldapauth'] = $drupal_name;
363c496
<     if (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_MIXED && LDAPAUTH_SYNC_PASSWORDS)
---
>     if (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_MIXED && LDAPAUTH_SYNC_PASSWORDS) {
364a498
>     }
365a500,511
> 
>     // 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);
377c523,525
<  * Authenticate the user against LDAP server.
---
>  * Authenticate the user against LDAP servers.
>  *
>  * Note: Related server information is passed via the global _ldapauth_ldap variable.
387c535,536
< function _ldapauth_auth($name, $pass) {
---
> function _ldapauth_auth($name, $pass, $create_account = FALSE) {
> 
414a564,573
>     // 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;
>       }
>     }
> 
422a582,583
>  * Note: Assumes that global $_ldapauth_ldap variable has been initialized.
>  *
439c600,604
<   $_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;
>   }
446c611,612
<     $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 );
500,502c666
<   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);
504c668
<   if ($servers[$sid]) {
---
>   if ( ! empty($server) && $server->status == 1 ) {
507,516c671,683
<     $_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);
523c690
<  * Retrieve the saved ldapgroups saved setting.
---
>  * Retrieve the saved ldapauth PhP code filters.
528c695
<  *   An attribute name.
---
>  *   The filter code needed, e.g. login_php or filter_php.
537,539c704
<   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);
543c708
<       return $servers[$sid]->login_php;
---
>       return $server->login_php;
545c710,723
<       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);
548a727,781
> /**
>  * 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 ldap_integration_beta2/ldapauth.theme.inc ldap_integration_beta3/ldapauth.theme.inc
2d1
< // $Id: ldapauth.theme.inc,v 1.2 2009/10/27 14:29:17 miglius Exp $
21c20
<     array('data' => t('Operations'), 'colspan' => 3),
---
>     array('data' => t('Operations'), 'colspan' => 4),
32a32,37
>       if ( module_exists('ctools')) {
>         $row[] = l(t('export'), 'admin/settings/ldap/ldapauth/export/'. $sid);
>       }
>       else {
>         $row[] = '&nbsp;';
>       }
49d53
< 
diff ldap_integration_beta2/ldapdata.admin.inc ldap_integration_beta3/ldapdata.admin.inc
2d1
< // $Id: ldapdata.admin.inc,v 1.9 2009/07/28 14:03:05 miglius Exp $
155a155
>     $content_profile_fields = _ldapdata_retrieve_content_profile_fields();
158c158,159
<       '#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>',
171a173,190
>     // 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>',
>       );
>     }
> 
421d439
< 
diff ldap_integration_beta2/ldapdata.info ldap_integration_beta3/ldapdata.info
1d0
< ; $Id: ldapdata.info,v 1.3 2009/02/19 16:56:16 miglius Exp $
9,10c8,9
< ; 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"
13c12
< datestamp = "1256654469"
---
> datestamp = "1340919401"
diff ldap_integration_beta2/ldapdata.install ldap_integration_beta3/ldapdata.install
2d1
< // $Id: ldapdata.install,v 1.9 2009/07/20 19:35:40 miglius Exp $
67a67
>   variable_del('ldapauth_disable_picture_change');
diff ldap_integration_beta2/ldapdata.module ldap_integration_beta3/ldapdata.module
2d1
< // $Id: ldapdata.module,v 1.31 2009/10/27 14:29:17 miglius Exp $
10a10
> // LDAPDATA_SYNC: 0 = user login; 1 = Page load; 2 = Each user load.
15a16
> define('LDAPDATA_DISABLE_PICTURE_CHANGE', variable_get('ldapdata_disable_picture_change', FALSE));
29c30,31
<   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');
91a94,98
> 
>   // Only care about ldap authenticated users.
>   if (!isset($account->ldap_authentified))
>     return;
> 
165c172
<   $entry = $_ldapdata_ldap->retrieveAttributes($user->ldap_dn);
---
>   $entry = ldapauth_user_lookup_by_dn( $_ldapdata_ldap, $user->ldap_dn, LDAPAUTH_SYNC_CONTEXT_UPDATE_DRUPAL_USER );
186a194,197
>  *
>  * @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.
188c199,200
< function _ldapdata_user_load(&$account, $sync = FALSE) {
---
> function _ldapdata_user_load(&$account, $sync = FALSE, $newentry = NULL) {
> 
191a204
>   // NOTE: Other functions assume this function will always initialize this
195c208,209
<   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)) {
196a211
>   }
205,206c220
<   $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)) {
211,214c225,242
<   $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++;
>     }
> 
217c245,246
<   if ($entry = $_ldapdata_ldap->retrieveAttributes($account->ldap_dn)) {
---
>   if (isset($entry)) {
> 
220a250
>     $content_profile_fields = _ldapdata_retrieve_content_profile_fields();
222a253,281
>     // 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();
> 
228c287,295
<       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)
>           ));
>         }
> 
239a307,359
>       // 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;
>             }
>           }
>         }
>       }
> 
241c361
<       else if (isset($account->$drupal_field) && !in_array($drupal_field, array('pass'))) {
---
>       elseif (isset($account->$drupal_field) && !in_array($drupal_field, array('pass'))) {
245c365,379
<     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']);
>         }
>       }
246a381,389
>     }
>     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
>       }
>     }
250a394,436
>  /**
>  * 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'];
> }
> 
> 
268,269c454,455
<   // Setup the global $_ldapdata_ldap object.
<   if (!_ldapdata_init($user))
---
>   // Only care about ldap authenticated users.
>   if (!isset($user->ldap_authentified))
272,273c458,459
<   $authmap = user_get_authmaps($user->name);
<   if (!isset($authmap['ldapauth']))
---
>   // Setup the global $_ldapdata_ldap object.
>   if (!_ldapdata_init($user))
289c475
<   else if ($category == 'account') {
---
>   elseif ($category == 'account') {
315,316c501,506
<   // 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.
317a508
>   }
319,320c510,511
<   $authmap = user_get_authmaps($user->name);
<   if (!isset($authmap['ldapauth']))
---
>   // Setup the global $_ldapdata_ldap object.
>   if (!_ldapdata_init($user))
329c520
<   $entry = $_ldapdata_ldap->retrieveAttributes($user->ldap_dn);
---
>   $entry = ldapauth_user_lookup_by_dn( $_ldapdata_ldap, $user->ldap_dn, LDAPAUTH_SYNC_CONTEXT_UPDATE_DRUPAL_USER );
333c524
<   foreach (_ldapdata_ldap_info($user, 'ldapdata_attrs') as $attr_name => $attr_info) {
---
>   foreach ($ldapdata_attrs as $attr_name => $attr_info) {
404,405c595,613
<             $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] = '';
435a644,653
>   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);
>   }
440c658,662
<     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])) {
463c685
<         '#title' => array_shift($info),
---
>         '#title' => check_plain(array_shift($info)),
467c689
<         '#description' => array_shift($info),
---
>         '#description' => check_plain(array_shift($info)),
475c697
<         '#title' => array_shift($info),
---
>         '#title' => check_plain(array_shift($info)),
479c701
<         '#description' => array_shift($info),
---
>         '#description' => check_plain(array_shift($info)),
527a750,752
>   if ( variable_get('user_pictures', '0') ) {
>     $fields['picture'] =  'picture';
>   }
559c784
<   $row = db_fetch_object(db_query("SELECT ldapdata_binddn, ldapdata_bindpw FROM {ldapauth} WHERE sid = %d", $sid));
---
>   $server = ldapauth_server_load($sid);
562,563c787,788
<     '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'] : ''),
599,605c824,833
<   static $servers = array();
<   if (!isset($servers[$sid]))
<     $servers[$sid] = db_fetch_object(db_query("SELECT * FROM {ldapauth} WHERE status = 1 AND sid = %d", $sid));
< 
<   if ($servers[$sid]) {
<     // Other modules can invoke user load from hook_init() before ldapdata.
<     require_once(drupal_get_path('module', 'ldapdata') .'/includes/LDAPInterface.inc');
---
>   // 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');
>   }
> 
>   $server = ldapauth_server_load($sid);
> 
>   if (! empty($server) ) {
609,615c837,847
<     $_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);
637,640c869
<   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);
643c872
<       $ldapdata_mappings = !empty($servers[$sid]->ldapdata_mappings) ? unserialize($servers[$sid]->ldapdata_mappings) : array();
---
>       $ldapdata_mappings = !empty($server->ldapdata_mappings) ? unserialize($server->ldapdata_mappings) : array();
646c875
<       return !empty($servers[$sid]->ldapdata_mappings) ? unserialize($servers[$sid]->ldapdata_mappings) : array();
---
>       return !empty($server->ldapdata_mappings) ? unserialize($server->ldapdata_mappings) : array();
648c877
<       return !empty($servers[$sid]->ldapdata_roattrs) ? unserialize($servers[$sid]->ldapdata_roattrs) : array();
---
>       return !empty($server->ldapdata_roattrs) ? unserialize($server->ldapdata_roattrs) : array();
650c879
<       return !empty($servers[$sid]->ldapdata_rwattrs) ? unserialize($servers[$sid]->ldapdata_rwattrs) : array();
---
>       return !empty($server->ldapdata_rwattrs) ? unserialize($server->ldapdata_rwattrs) : array();
652c881
<       return $servers[$sid]->ldapdata_binddn;
---
>       return $server->ldapdata_binddn;
654c883
<       return $servers[$sid]->ldapdata_bindpw;
---
>       return $server->ldapdata_bindpw;
656c885
<       return !empty($servers[$sid]->ldapdata_attrs) ? unserialize($servers[$sid]->ldapdata_attrs) : array();
---
>       return !empty($server->ldapdata_attrs) ? unserialize($server->ldapdata_attrs) : array();
658c887
<       return $servers[$sid]->ldapdata_filter_php;
---
>       return $server->ldapdata_filter_php;
661a891,1200
> /**
>  * 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 ldap_integration_beta2/ldapdata.theme.inc ldap_integration_beta3/ldapdata.theme.inc
2d1
< // $Id: ldapdata.theme.inc,v 1.3 2009/03/18 12:12:02 miglius Exp $
diff ldap_integration_beta2/ldapgroups.admin.inc ldap_integration_beta3/ldapgroups.admin.inc
2d1
< // $Id: ldapgroups.admin.inc,v 1.11 2009/05/04 00:26:17 miglius Exp $
88c87,96
<     $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(
90a99
>       '#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>'),
94c103
<     $form['group_dn']['ldapgroups_in_dn'] = array(
---
>     $form['group-definitions']['group_dn']['ldapgroups_in_dn'] = array(
98c107
<       '#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.'),
100c109
<     $form['group_dn']['ldapgroups_dn_attribute'] = array(
---
>     $form['group-definitions']['group_dn']['ldapgroups_dn_attribute'] = array(
106c115
<       '#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.'),
109c118
<     $form['group_attr'] = array(
---
>     $form['group-definitions']['group_attr'] = array(
111a121
>       '#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>'),
115c125
<     $form['group_attr']['ldapgroups_in_attr'] = array(
---
>     $form['group-definitions']['group_attr']['ldapgroups_in_attr'] = array(
117a128
>       '#description' => t('Check to enable this method.'),
120c131
<     $form['group_attr']['ldapgroups_attr'] = array(
---
>     $form['group-definitions']['group_attr']['ldapgroups_attr'] = array(
129c140
<     $form['group_entry'] = array(
---
>     $form['group-definitions']['group_entry'] = array(
131a143
>       '#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.'),
135c147
<     $form['group_entry']['ldapgroups_as_entries'] = array(
---
>     $form['group-definitions']['group_entry']['ldapgroups_as_entries'] = array(
137c149,150
<       '#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.'),
140c153
<     $form['group_entry']['ldapgroups_entries'] = array(
---
>     $form['group-definitions']['group_entry']['ldapgroups_entries'] = array(
142c155
<       '#title' => t('LDAP DNs containing groups (one per line)'),
---
>       '#title' => t('Base LDAP DNs containing groups (one per line)'),
146c159
<       '#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.'),
148c161
<     $form['group_entry']['ldapgroups_entries_attribute'] = array(
---
>     $form['group-definitions']['group_entry']['ldapgroups_entries_attribute'] = array(
154c167
<       '#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))),
155a169,170
> 
>     // Access rules section
158c173
<       '#title' => t('LDAP group to Drupal role limits'),
---
>       '#title' => t('LDAP Groups Server Access Rules'),
161a177,198
>     $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: &quot;action-type: group-name&quot;. 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,
>     );
164c201
<       '#title' => t('LDAP groups which allow automatic account creation'),
---
>       '#title' => t('Group access rules'),
168c205
<       '#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.'),
169a207,208
> 
>     // Mappings section
173c212
<       '#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>'),
175c214,227
<       '#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.')
186,192c238
<       '#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'),
261c307
<       if ($values['ldapgroups_mappings_filter'] && !trim($values['ldapgroups_mappings']))
---
>       if ($values['ldapgroups_mappings_filter'] == LDAPGROUPS_ROLE_MODE_USE_MAP && !trim($values['ldapgroups_mappings']))
297a344,432
> /**
>  * 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;
>   }
298a434,600
>   $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;
> }
Only in ldap_integration_beta3/: ldapgroups.api.php
diff ldap_integration_beta2/ldapgroups.inc ldap_integration_beta3/ldapgroups.inc
2d1
< // $Id: ldapgroups.inc,v 1.2 2009/08/25 13:53:20 miglius Exp $
13a13,14
>  *
>  * @param Object $account A user object verified to be ldap_authentified.
16,18c17,19
<   $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 ) {
21a23,26
>   // Don't do anything until LDAP groups are configured in admin screens.
>   if (! ldapgroups_is_configured($account->ldap_config))
>     return;
> 
28,31c33
< 
<   // 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..
35c37
<   // Then, we take every mapped role from the user, later below
---
>   // Then, we take every LDAP mapped role from the user, later below
42,45d43
<   // Are there LDAP groups for the user?
<   if ($groups === FALSE)
<     return TRUE;
< 
47c45
<   $groups = _ldapgroups_filter($account, $groups);
---
>   $filtered_groups = _ldapgroups_filter($account, $groups);
49c47
<   // 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.
51,53c49,50
<   if (!empty($groups)) {
<     $ldapgroups_mappings = _ldapgroups_ldap_info($account, 'ldapgroups_mappings');
<     foreach ($groups as $group) {
---
>   if (!empty($filtered_groups)) {
>     foreach ($filtered_groups as $group) {
55,56d51
<       _ldapgroups_create_role($role);
<       _ldapgroups_grant_role($account, $role);
59a55,62
>   $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);
>   }
72,73c75,76
<  * @param $user
<  *   A user object.
---
>  * @param $account
>  *   A user object that has already been checked if it is "ldap_authentified".
75,76c78,79
<  * @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.
78c81
< function _ldapgroups_detect_groups($user) {
---
> function _ldapgroups_detect_groups($account) {
81,83c84,85
<   // 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))
99c101
<       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);
104,112c106,128
<   // 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 );
> 
>   $_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;
115,132c131,145
<   // 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));
<   }
< 
<   // 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]);
134a148,175
> 
>     // 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;
137,138c178
<   $_ldapgroups_ldap->disconnect();
<   return array_unique(array_merge($dn_groups, $attrib_groups, $entries_groups));
---
>   return $groups_cache[$dn];
144c184
<  * @param $user
---
>  * @param $account
151,152c191,192
< 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);
154c194
<     $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);
156c196
<       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);
164c204
<  * @param $user
---
>  * @param $account
171,172c211,212
< 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);
174c214
<     $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);
176c216
<       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);
190c230
<   $result = db_query("SELECT * FROM {role} WHERE name = '%s'", $rolename);
---
>   $result = db_query("SELECT * FROM {role} WHERE LOWER(name) = LOWER('%s')", $rolename);
196c236
<  * Filters groups only to a explicitely defined groups.
---
>  * Filters groups only to the groups defined in the role mapping.
205c245,251
<   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)) {
209,210c255,260
<         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);
>           }
>         }
213c263
<     $groups = $groups_new;
---
>     $groups = array_unique($groups_new);
215,218d264
< 
<   if ($code = _ldapgroups_ldap_info($account, 'ldapgroups_filter_php'))
<     $groups = drupal_eval($code);
< 
225,226c271,272
<  * @param $user
<  *   A user object.
---
>  * @param $account
>  *   A user object or sid.
233,234c279,280
< 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');
237c283
<   else if (preg_match('/^[^=]+=([^,]+),.*$/', $group, $matches))
---
>   elseif (preg_match('/^[^=]+=([^,]+),.*$/', $group, $matches))
257,259c303
<   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);
261c305
<   if ($servers[$sid]) {
---
>   if (! empty($server) && $server->status == 1 ) {
264,270c308,317
<     $_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);
290,292c337
<   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);
296c341
<       return $servers[$sid]->ldapgroups_in_dn;
---
>       return $server->ldapgroups_in_dn;
298c343
<       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;
300c345
<       return $servers[$sid]->ldapgroups_in_attr;
---
>       return $server->ldapgroups_in_attr;
302c347
<       return !empty($servers[$sid]->ldapgroups_attr) ? unserialize($servers[$sid]->ldapgroups_attr) : array();
---
>       return !empty($server->ldapgroups_attr) ? unserialize($server->ldapgroups_attr) : array();
304c349
<       return $servers[$sid]->ldapgroups_as_entries;
---
>       return $server->ldapgroups_as_entries;
306c351
<       return !empty($servers[$sid]->ldapgroups_entries) ? unserialize($servers[$sid]->ldapgroups_entries) : array();
---
>       return !empty($server->ldapgroups_entries) ? unserialize($server->ldapgroups_entries) : array();
308c353
<       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;
310c355
<       return !empty($servers[$sid]->ldapgroups_mappings) ? unserialize($servers[$sid]->ldapgroups_mappings) : array();
---
>       return !empty($server->ldapgroups_mappings) ? unserialize($server->ldapgroups_mappings) : array();
312c357
<       return $servers[$sid]->ldapgroups_mappings_filter;
---
>       return $server->ldapgroups_mappings_filter;
314c359
<       return $servers[$sid]->ldapgroups_filter_php;
---
>       return $server->ldapgroups_filter_php;
316c361
<       return !empty($servers[$sid]->ldapgroups_groups) ? unserialize($servers[$sid]->ldapgroups_groups) : array();
---
>       return !empty($server->ldapgroups_groups) ? unserialize($server->ldapgroups_groups) : array();
318a364,408
> /**
>  * 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();
319a410,414
>   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 ldap_integration_beta2/ldapgroups.info ldap_integration_beta3/ldapgroups.info
1d0
< ; $Id: ldapgroups.info,v 1.4 2009/02/19 16:56:16 miglius Exp $
9,10c8,9
< ; 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"
13c12
< datestamp = "1256654469"
---
> datestamp = "1340919401"
diff ldap_integration_beta2/ldapgroups.install ldap_integration_beta3/ldapgroups.install
2d1
< // $Id: ldapgroups.install,v 1.6 2009/07/04 21:54:28 miglius Exp $
diff ldap_integration_beta2/ldapgroups.module ldap_integration_beta3/ldapgroups.module
2d1
< // $Id: ldapgroups.module,v 1.40 2009/08/25 13:23:37 miglius Exp $
12c11,23
< 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 );
29a41,53
>     '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,
>     ),
53a78,82
> 
>   // Only care about ldap authenticated users.
>   if (!isset($account->ldap_authentified))
>     return;
> 
56,57c85,87
<       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');
61a92,159
> /**
>  * 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');
62a161,224
>   $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;
>   }
> 
> }
Only in ldap_integration_beta3/: ldaphelp
Only in ldap_integration_beta3/: ldapsync.admin.inc
Only in ldap_integration_beta3/: ldapsync.info
Only in ldap_integration_beta3/: ldapsync.install
Only in ldap_integration_beta3/: ldapsync.module
diff ldap_integration_beta2/LICENSE.txt ldap_integration_beta3/LICENSE.txt
1c1,2
< GNU GENERAL PUBLIC LICENSE
---
>                     GNU GENERAL PUBLIC LICENSE
>                        Version 2, June 1991
3,123c4,127
<               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.
---
>  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.
126,148c130,153
< 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.)
151,197c156,207
< 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
200,274c210,339
< 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.
Only in ldap_integration_beta3/: README-PUID.txt
Common subdirectories: ldap_integration_beta2/translations and ldap_integration_beta3/translations
