MCD, Mission Control Desktop, AKA AutoConfig

  • Revision slug: MCD,_Mission_Control_Desktop_AKA_AutoConfig
  • Revision title: MCD, Mission Control Desktop, AKA AutoConfig
  • Revision id: 57867
  • Created:
  • Creator: Jehanproc
  • Is current revision? No
  • Comment 196 words added, 92 words removed

Revision Content

This document is a concrete example of a centralized auto-configuration of Mozilla apps, that are; Firefox, Thunderbird, Mozilla Suite 1.x.x, Seamonkey and for the record, old Netscape 4.x. Its original inspiration comes from  http://www.alain.knaff.lu/howto/MozillaCustomization/ and http://mit.edu/~firefox/www/maintain...utoconfig.html. For history, I've kept Mozilla and Netscape chapters, as certain points are complementary to the web-based AutoConfig file.

This MCD (aka autoconfig here), is not to be confused with https://wiki.mozilla.org/Thunderbird...oconfiguration . It's Mission is to enable completely automatic configuration of mozilla's apps preferences based on users properties either retrieved from system environement variables or on an organisation ldap directory.

Situation

INT-Evry manages about 3000 users (mostly students) who share computers in labs and "self service" computer rooms. Hence a single computer might connect many different users all day long. Computers are dual-boot (Windows 7 and Linux Fedora 13/15 by 2011). All users have a personal account on a Windows server (AD) and an LDAP account for Linux authentication.

Objective

The objective is to provide users with a mailer agent, a web browser, and a news reader which are automatically configured (preferences) at startup to the current user connected on the computer. Choosing Mozilla products allow us to use the same apps while running either Windows or Linux systems (I suspect MAC OSX would be fine too).

Instead of configuring end user individual preferences files (~/.mozilla/default/randomdir/prefs.js) we now use a centralized default set of preferences. This centralized preference file can lock preferences (lockPref) or initialize them (defaultPref) based on environment variables (USER, HOME...) and/or LDAP queries (fetch email address, Common Name , language, homepage etc...) from the enterprise directory.

Central Configuration File

That feature is provided through a JavaScript file.

File Location

In Thunderbird5 , FireFox5, the javascript preference file that calls the centralized preference file is located in $INSTALL_DIR_MOZ_APP/defaults/pref, for exemple in thunderbird this would be repectively for windows/linux:

C:\Program Files\Mozilla Thunderbird\defaults\pref

/usr/lib/thunderbird-5/default/pref

For the record/history purpose ... the old Netscape 4.x the file is encoded (byte-shift/rotary is 7), and the presence of the file (netscape.cfg) in the MOZILLA_HOME directory suffices for it to be read and executed. For Mozilla 1.x.x, Firefox, Thunderbird or Netscape 7 it is still a JavaScript file, the byte-shift is 13 by default, but can be removed using the pref("general.config.obscure_value", 0); preference in all.js or any appropriate .js file dedicated to autoconfig.

The name of the file can be anything you want because it is named by a general.config preference that should be added at the end of file MOZILLA_HOME/default/pref/all.js or MOZILLA_HOME/greprefs/all.js: pref("general.config.filename", "mozilla.cfg");.

File Encoding

If needed, the encoding can be done with the Perl script: moz-byteshift.pl available at http://www.alain.knaff.lu/howto/Mozi...z-byteshift.pl.

For Netscape 4.x the convert function from the Client Customization Kit (CCK) could also do that (and other things like personalize auto-installation...): http://developer.netscape.com/docs/manuals/deploymt/config.htm.

File API

That centralized preference file uses a JavaScript API that allows us to do what we need. The available functions are defined in MOZILLA_HOME/default/autoconfig/prefcalls.js. The presence of pref("general.config.filename", "mozilla.cfg"); in all.js enables the read and execution of prefcalls.js.

Available functions are (see {{ Source("extensions/pref/autoconfig/src/prefcalls.js", "prefcalls.js") }} file for details):

function getPrefBranch() 
function pref(prefName, value) 
function defaultPref(prefName, value)
function lockPref(prefName, value) 
function unlockPref(prefName) 
function getPref(prefName) 
function getLDAPAttributes(host, base, filter, attribs) 
function getLDAPValue(str, key) 
function displayError(funcname, message)
function getenv(name) 

Thunderbird

Support of AutoConfig and LDAP Calls

Unfortunately, the AutoConfig Option and LDAP Support for autoconfig (getLDAPAttributes) is not present in Fedora11 default thunderbird package (thunderbird-3.0-2.3.beta2.fc11.src.rpm) .

So we need to patch and recompile that source RPM (check  https://bugzilla.mozilla.org/show_bug.cgi?id=295329 ) ; patch:

[root@b008-02 SOURCES]# cat thunderbird-autoconfigAndLdap.patch
diff -ur thunderbird-3.0/configure thunderbird-3.0.autoldap/configure
--- thunderbird-3.0/configure    2009-06-29 11:37:21.677372297 +0200
+++ thunderbird-3.0.autoldap/configure    2009-06-29 14:41:11.547435040 +0200
@@ -12855,7 +12855,7 @@
 MOZ_FEEDS=1
 MOZ_JSDEBUGGER=1
 MOZ_JSLOADER=1
-MOZ_LDAP_XPCOM=
+MOZ_LDAP_XPCOM=1
 MOZ_MAIL_NEWS=
 MOZ_MORK=1
 MOZ_MORKREADER=
And set --enable-extensions=pref in mozconfig file, in fedora source RPM it is:
[root@b008-02 SOURCES]# grep enable-extensions /root/rpmbuild/SOURCES/thunderbird-mozconfig
ac_add_options --enable-extensions=pref
It seems worse this time , as even after applying those compilation options mentioned above, I now get the following error message while stating thunderbird with autoconfig (all.js having pref('general.config.filename','thunderbird.cfg'); )

and thunderbird.cfg calling getLDAP* functions to retrieve cm and mail address of the current user.

Netscape.cfg/AutoConfig failed. Please contact your system administrator.
 Error: getLDAPAttibutes failed: [Exception... "Component returned failure
code: 0xc1f30001 (NS_ERROR_NOT_INITIALIZED) [nsILDAPURL.spec]"  nsresult:
"0xc1f30001 (NS_ERROR_NOT_INITIALIZED)"  location: "JS frame ::
file:////usr/lib/thunderbird-3.0b2/defaults/autoconfig/prefcalls.js ::
getLDAPAttributes :: line 174"  data: no]
bug https://bugzilla.mozilla.org/show_bug.cgi?id=295329 had been re-opened .

 

AutoConfig Option and LDAP Support in Thunderbird 1.5.x

Fortunately, AutoConfig is now part of Thunderbird default packages. MOZ_LDAP_XPCOM=1 and MOZ_EXTENSIONS_DEFAULT="wallet spellcheck xmlextras pref webservices universalcharset auth" are now present in the default configure script. See {{ Bug("295329") }} for details.

Add the AutoConfig Option for Old Thunderbird 1.0.x

By default, AutoConfig did not make part of the binaries distribution of Thunderbird (1.0.x). It was apparently supposed to increase the load of the binary for a feature not used by lots of individuals. However for enterprise deployment, it is vital! So we needed to recompile Thunderbird with AutoConfig support, it's just a matter of adding --enable-extensions=pref in mozconfig file.

On my Fedora Core 3 system, I took the Thunderbird source package thunderbird-1.0.2-1.3.3.src.rpm installed it (rpm -i) then modified /usr/src/redhat/SOURCES/thunderbird-mozconfig by adding:

ac_add_options --enable-extensions=pref

Compile and install:

$ rpmbuild -ba /usr/src/redhat/SPECS/thunderbird.spec
$ rpm -Uvh /usr/src/redhat/RPMS/i386/thunderbird-1.0.2-1.3.3.i386.rpm

After instillation, AutoConfig is finally back here:

$ rpm -ql thunderbird | grep autoconfig
/usr/lib/thunderbird-1.0.2/chrome/en-US/locale/autoconfig
/usr/lib/thunderbird-1.0.2/components/autoconfig.xpt
/usr/lib/thunderbird-1.0.2/components/libautoconfig.so
/usr/lib/thunderbird-1.0.2/defaults/autoconfig
/usr/lib/thunderbird-1.0.2/defaults/autoconfig/platform.js
/usr/lib/thunderbird-1.0.2/defaults/autoconfig/prefcalls.js

Configure AutoConfig

Two directives ask Thunderbird to use AutoConfig at startup:

[root@b008-02 /usr/lib/thunderbird-1.5]
$tail -2 greprefs/all.js
pref("general.config.obscure_value", 0); // for MCD .cfg files
pref('general.config.filename', 'thunderbird.cfg'); // for MCD .cfg files

The first one just tells us that we won't encode the file (no more rotary 13 or 7... :-), the second one is the name of the file to be read: /usr/lib/thunderbird-1.5/thunderbird.cfg.

AutoConfig Directives

Here we want to set users central mail preferences: Create one account from their login name, get their email address from an LDAP request and set the enterprise IMAP and SMTP servers. Hence, when working on multiuser workstations, each person gets automatically Thunderbird configured for himself.

thunderbird.cfg

Here's the complete file, first we get the user login name from environment variables, then configure the LDAP address book, create an email account, and configure IMAP and SMTP:

[root@b008-02 /usr/lib/thunderbird-1.5]
$ cat thunderbird.cfg
//put everything in a try/catch
try {

// 1) env variables
if(getenv("USER") != "") {
  // *NIX settings
  var env_user = getenv("USER");
  var env_home = getenv("HOME");
} else {
  // Windows settings
  var env_user = getenv("USERNAME");
  var env_home = getenv("HOMEPATH");
}
var env_mozdebug= getenv("MOZILLA_DEBUG");
// var env_user = prompt("indiquez votre login", toto);

// 2) lock general preferences
//LDAP address book
lockPref("ldap_2.prefs_migrated", true);
lockPref("ldap_2.servers.LDAPINT.auth.savePassword", true);
lockPref("ldap_2.servers.LDAPINT.description", "LDAP INT");
lockPref("ldap_2.servers.LDAPINT.filename", "abook-1.mab");
lockPref("ldap_2.servers.LDAPINT.uri", "ldap://ldap1.int-evry.Fr:389/ou=people,dc=int-evry,dc=fr??sub");
lockPref("ldap_2.servers.history.filename", "history.mab");
lockPref("ldap_2.servers.history.replication.lastChangeNumber", 0);
lockPref("ldap_2.servers.pab.filename", "abook.mab");
lockPref("ldap_2.servers.pab.replication.lastChangeNumber", 0);

//Account
lockPref("mail.account.account1.server", "server1");
lockPref("mail.account.account2.identities", "id1");
lockPref("mail.account.account2.server", "server2");
lockPref("mail.accountmanager.accounts", "account1,account2");
lockPref("mail.accountmanager.defaultaccount", "account2");
lockPref("mail.accountmanager.localfoldersserver", "server1");
lockPref("mail.identity.id1.directoryServer", "ldap_2.servers.LDAPINT");
lockPref("mail.identity.id1.draft_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Drafts");
lockPref("mail.identity.id1.drafts_folder_picker_mode", "0");
lockPref("mail.identity.id1.fcc_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Sent");
lockPref("mail.identity.id1.fcc_folder_picker_mode", "0");
lockPref("mail.identity.id1.organization", "INT Evry France");
lockPref("mail.identity.id1.overrideGlobal_Pref", true);
lockPref("mail.identity.id1.reply_to", "");

//IMAP
lockPref("mail.server.server2.hostname", "imap-int.int-evry.fr");
lockPref("mail.server.server2.isSecure", true);
lockPref("mail.server.server2.login_at_startup", true);
lockPref("mail.server.server2.max_cached_connections", 5);
//lockPref("mail.server.server2.name", "jehan.procaccia@int-evry.fr");
lockPref("mail.server.server2.type", "imap");
lockPref("mail.server.server2.userName", env_user);

//SMTP
lockPref("mail.identity.id1.smtpServer", "smtp1");
lockPref("mail.identity.id1.stationery_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Templates");
lockPref("mail.identity.id1.tmpl_folder_picker_mode", "0");
lockPref("mail.identity.id1.valid", true);

//SMTP general
lockPref("mail.smtp.defaultserver", "smtp1");
lockPref("mail.smtpserver.smtp1.auth_method", 0);
lockPref("mail.smtpserver.smtp1.hostname", "smtp-int.int-evry.fr");
lockPref("mail.smtpserver.smtp1.port", 25);
lockPref("mail.smtpserver.smtp1.try_ssl", 0);
lockPref("mail.smtpserver.smtp1.username", "");
lockPref("mail.smtpservers", "smtp1");
lockPref("mail.startup.enabledMailCheckOnce", true);
lockPref("mailnews.quotingPrefs.version", 1);
lockPref("mailnews.ui.threadpane.version", 5);

/* 3) define here (because if set after "4)" below it doesn't work!) processLDAPValues which is eventually called by getLDAPAttributes() just below,
 check getLDAPAttributes() code from $MOZILLA_HOME/defaults/autoconfig/prefcalls.js to see the inside call to "user defined" processLDAPValues
*/
function processLDAPValues(values) {
  if(values) {
    // set the global var with the values returned from the LDAP query
    ldap_values = values;
    var uid = getLDAPValue(values, "uid");
    var cn = getLDAPValue(values, "cn");
    var mail = getLDAPValue(values, "mail");
    var URL = getLDAPValue(values, "labeledURI");

// Those LDAP variables are only available in this processLDAPValues context!
// so we set the preferences that need them here.
lockPref("mail.identity.id1.useremail", mail);
lockPref("mail.server.server2.name", mail);
lockPref("mail.identity.id1.fullName", cn);
//Debug with popup error messages doesn't work anymore :-( !!
var env_mozdebug= getenv("MOZILLA_DEBUG");
if (env_mozdebug) {displayError("NO ERROR, just a debug, cn =" + cn + " and mail = " + mail); }
    }
  }
// 4) Call LDAP servers to get LDAP Attributes (mail & cn), this will finally call processLDAPValues, "3)" just above.
  getLDAPAttributes("ldap2.int-evry.fr","ou=people,dc=int-evry,dc=fr","uid=" + env_user,"uid,cn,mail,labeledURI");

// Close the try, and call the catch()
} catch(e) {
  displayError("lockedPref", e);
}
Test AutoConfig
Debug

To check that our AutoConfig works fine, we just set to env variable to check the read of thunderbird.cfg file:

$ export NSPR_LOG_MODULES=MCD:5
$ export NSPR_LOG_FILE=/tmp/thunderbird-log.txt

When Thunderbird has started, you should read:

 $ cat /tmp/thunderbird-log.txt
-1209403040[808a788]: general.config.filename = thunderbird.cfg
-1209403040[808a788]: evaluating .cfg file thunderbird.cfg with obscureValue 0
Clean

Then, to be sure to start with a fresh Thunderbird account, don't do this if you already have one and want to preserve your emails  and preferences!

$ rm -rf ~/.thunderbird
Start It
$ thunderbird

If Thunderbird ask you to import your profile from Netscape/Mozilla depending on you mail client history, don't import anything, to check the AutoConfig job alone!

That should work, just restart the process by setting a different USER variable (USER=procacci, USER=test etc... anyone in your LDAP directory...) to check multiuser AutoConfig.

Bugs Reports Related

For the record, for old 1.0.x releases...

Unwanted White Space Reappeared

Unfortunately the 'blank space bug' has reappeared in Thunderbird 1.0.2. See {{ Bug("229271") }}. Although it was corrected in Mozilla mainstream: mozilla/extensions/pref/autoconfig/src/nsLDAPSyncQuery.cpp 1.7.2.1 by late 2004, it is still present in Thunderbird 1.0.2 at least :-(, so I applied the workaround I proposed in that bug report (start_pos += 1;).

Thunderbird 2.x beta 2

Recently (2007/03/21) I've tested with thunderbird 2 beta 2 (2007/01/16) to check if autoconfig + ldap is still supported . Apprently it's OK . Autonfig API is there, ldap call works fine, good !.

My tests were on Windows Vista, and I noticed at least one difference, it is that Paths changed; now the profile is in (for my procacci user sample): C:\Users\procacci\AppData\Roaming\Thunderbird\Profiles\v6we4uku.default

Vista profile location

Start in debug mode in Comand Line Interface:

Start in debug Comand Line Interface

 

Debug with displayError()

 

Here's the result, I used the displayError() method ( not the best way :-( see {{ Bug("206294") }} ) to show environment and ldap variables in order to check that it worked fine. Just setting MOZILLA_DEBUG=1 (see js code in thunderbird.cfg) allow that message to appear , it's very useful in debuging context ...

TB-vista-MCD-debug-msg.jpg

The displayError() function does not work properly in Thunderbird 3.1: See https://bugzilla.mozilla.org/show_bu...?id=502597#c34

A usable workaround is placing the following code at the top of your autoconfig script:

// Enable logging.
pref("MCD.logging.console", "All");
pref("MCD.logging.dump", "All");
Components.utils.import("resource:///modules/gloda/log4moz.js");
var log = Log4Moz.getConfiguredLogger("MCD");

// Enable alerts.
var alerts = Components.classes["@mozilla.org/alerts-service;1"]
.getService(Components.interfaces.nsIAlertsService);

// displayError() is broken. Let's override it.
function displayError(title, msg) {
log.debug(title + ": " + msg);
alerts.showAlertNotification("chrome://branding/content/icon48.png", title, msg);
}

Firefox

It's the same principle as above for Thunderbird. Binary distributions now include support for AutoConfig (pref extension!) but unfortunately not for LDAP calls :-( (cf. MOZ_LDAP_XPCOM=1). It is not vital in Firefox as it is for us in Thunderbird (need to get the cn and email address to set email account, which are not available by default in the environment variables). However I could be useful to get LDAP values for Firefox extra config, for example to set the default home page to the labeledURI LDAP attribute of the user.

AutoConfig (pref) and LDAP Support in Packages

Add LDAP Support in Firefox 1.5

A least from Firefox 1.5, AutoConfig is compiled by default (cf. browser, MOZ_EXTENSIONS_DEFAULT="pref...") but not LDAP (MOZ_LDAP_XPCOM=1). You need to recompile the package to get it, cf. {{ Bug("295329") }}.

Add AutoConfig and LDAP Support in Firefox 1.0.x

Add pref extension (--enable-extensions=pref) and remove --disable-ldap from mozconfig file. One can check how Firefox has been compiled by opening about:buildconfig (don't know the equivalent for Thunderbird! how as it been compiled?)

about:buildconfig

Build platform
target
i686-pc-linux-gnu

Build tools
Compiler Version Compiler flags
gcc gcc version 3.4.3 20050227 (Red Hat 3.4.3-22.fc3) -Wall -W -Wno-unused -Wpointer-arith -Wcast-align -Wno-long-long -pedantic -pthread -pipe
c++ gcc version 3.4.3 20050227 (Red Hat 3.4.3-22.fc3) -fno-rtti -fno-exceptions -Wall -Wconversion -Wpointer-arith -Wcast-align -Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -Wno-long-long -pedantic -fshort-wchar -pthread -pipe -I/usr/X11R6/include

Configure arguments
--disable-mailnews --enable-extensions=cookie,xml-rpc,xmlextras,pref,transformiix,universalchardet,webservices,inspector,gnomevfs,negotiateauth --enable-crypto --disable-composer --enable-single-profile --disable-profilesharing --with-system-jpeg --with-system-zlib --with-system-png --with-pthreads --disable-tests --disable-jsd --disable-installer '--enable-optimize=-Os -g -pipe -m32 -march=i386 -mtune=pentium4' --enable-xft --enable-xinerama --enable-default-toolkit=gtk2 --enable-official-branding --disable-xprint --disable-strip --enable-pango 

all.js

[root@b008-02 /usr/lib/firefox-1.5.0.2]
$tail -4 greprefs/all.js
// AutoConfig jehan
pref('general.config.obscure_value', 0);
pref('general.config.filename', 'firefox.cfg');

firefox.cfg

This file will set the browser home page to the labeledURI page defined in the user's LDAP entry, hence it checks that both AutoConfig + LDAP work fine.

[root@b008-02 /usr/lib/firefox-1.5.0.2]
$cat firefox.cfg
//put everything in a try/catch
try {

//Privacy & Security
defaultPref("signon.rememberSignons", false);

// 1) env variables
if(getenv("USER") != "") {
  // *NIX settings
  var env_user = getenv("USER");
  var env_home = getenv("HOME");
} else {
  // Windows settings
  var env_user = getenv("USERNAME");
  var env_home = getenv("HOMEPATH");
}
var env_mozdebug = getenv("MOZILLA_DEBUG");

/* 2) define here (because if set after "3)" below it doesn't work!) processLDAPValues which is eventually called by getLDAPAttributes() just below,
 check getLDAPAttributes() code from $MOZILLA_HOME/defaults/autoconfig/prefcalls.js to see the inside call to "user defined" processLDAPValues
*/
function processLDAPValues(values) {
  if(values) {
    // set the global var with the values returned from the LDAP query
    ldap_values = values;
    var uid = getLDAPValue(values, "uid");
    var cn = getLDAPValue(values, "cn");
    var mail = getLDAPValue(values, "mail");
    var URL = getLDAPValue(values, "labeledURI");
//Debug with popup error messages doesn't work anymore :-( !!
var env_mozdebug= getenv("MOZILLA_DEBUG");
if (env_mozdebug) {displayError("NO ERROR, just a debug, cn =" + cn + " and mail = " + mail + ", labeledURI= " + URL); }
lockPref("browser.startup.homepage", URL);
    }
  }

//lockPref("browser.startup.homepage", "http://www.renater.fr/");
// 3) Call LDAP servers to get LDAP Attributes (mail & cn), this will finally call processLDAPValues, "2)" just above.
  getLDAPAttributes("ldap2.int-evry.fr","ou=people,dc=int-evry,dc=fr","uid=" + env_user,"uid,cn,mail,labeledURI");

// Close the try, and call the catch()
} catch(e) {displayError("lockedPref", e);}

Debug

If you set a username and the MOZILLA_DEBUG variable ($export MOZILLA_DEBUG=1; export USER=procacci), then the displayError() will show you this popup:

Image:mozilla-autoconfig-en001.png

That's a popup titled as "error", but it's just a debug tool for me as I didn't find any other way to popup information. cf. {{ Bug("206294") }}:

 ------- Comment #14 From Daniel Wang 2003-11-06 09:06 PDT [reply] -------

Jehan Procaccia, you need to change 5.8 to reflect what I said in comment 21.

Preference files and config files are special JavaScript files with limited scopes. They
can only call the get/set pref/env methods and have no access to other objects
(need to investigate what exactly are allowed). alert() is a method of the
Window object.

cf. also related post in Newsgroups: mozilla.dev.tech.js-engine

Date: Wed, 17 May 2006 19:06:28 +0200
From: jehan procaccia <jehan.procaccia@int-evry.fr>

Newsgroups: mozilla.dev.tech.js-engine
Subject: scope of js file functions in Frefox/Thunderbird AutoConfig context

Firefox 2.x

Recently (2007/03/20), I've tested autoconfig support in Firefox 2.0.0.2 on a Linux fedora. Autoconfig works fine, but ldap calls are still unavailable in Firefox (as it was the case in Firefox 1.x, but fortunatly not the case for Thunderbird !). That "bug" report is then still up to date!: {{ Bug("295329") }}

$ cat /etc/redhat-release 
Fedora Core release 6 (Zod)

$ rpm -qi firefox
Name        : firefox                      Relocations: (not relocatable)
Version     : 2.0.0.2                           Vendor: Remi Collet
Release     : 1.fc6.remi                    Build Date: Sat 24 Feb 2007 01:45:37 PM CET
Install Date: Tue 20 Mar 2007 02:47:27 PM CET      Build Host: remi.famillecollet.com
Packager    : http://remi.collet.free.fr/

References

Other Documents About AutoConfig

http://mit.edu/~firefox/www/maintain...utoconfig.html

http://www.alain.knaff.lu/howto/Mozi...ion/index.html
http://thegoldenear.org/toolbox/wind...re-config.html
http://ilias.ca/blog/2005/03/locking...efox-settings/

Compile on Windows:
http://forums.mozillazine.org/viewtopic.php?t=276014

http://www.mozilla.org/community/dev...er-forums.html
http://forums.mozillazine.org/viewto...config#2090731
http://forums.mozillazine.org/viewto...config#1354355
http://forums.mozillazine.org/viewto...toconfig#32783

Related Bugs

{{ Bug("295329") }}
{{ Bug("222973") }}
{{ Bug("225288") }}
{{ Bug("178685") }}
{{ Bug("272970") }}
{{ Bug("206294") }}
{{ Bug("302096") }}

 

 

Thunderbird Comm-central_source_code_(Mercurial)

 

based on {{ Bug("295329") }} , since TB 3.0.X autoconfig doesn't work anymore.

according to the discussion in  mozilla.dev.apps.thunderbird , change from CVS to Mercurial and recent changes to the nsLDAPURL code might have borken autoconfig . below we start to debug this by rebuilding a thunderbird from Comm-central-source-code (mercurial) .

Build

install mercurial tools
[root@b008-02 ~]# yum install mercurial

Installed:
  mercurial.i586 0:1.2.1-1.fc11
check merge tools in
[root@b008-02 ~]# vim /etc/mercurial/hgrc.d/mergetools.rc
 get the source comm-central
[root@b008-02 Moz]# time hg clone http://hg.mozilla.org/comm-central/ commsrc
requesting all changes
adding changesets
adding manifests
adding file changes
added 2975 changesets with 16793 changes to 7117 files (+3 heads)
updating working directory
5644 files updated, 0 files merged, 0 files removed, 0 files unresolved

real    0m40.771s
user    0m9.284s
sys     0m1.304s
 
[root@b008-02 commsrc]# python client.py checkout
Executing command: ['hg', 'pull', '-R', './.', '-r', 'tip']
pulling from http://hg.mozilla.org/comm-central/
searching for changes
no changes found
Executing command: ['hg', 'update', '-r', 'default', '-R', './.']
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
Updated to revision c10119db13cad9797b05750bfe18a57261a88922.
Executing command: ['hg', 'clone', 'http://hg.mozilla.org/releases/mozilla-1.9.1/', './mozilla']
requesting all changes
adding changesets
...
Executing command: ['hg', 'update', '-r', 'default', '-R', './mozilla/extensions/inspector']
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
Updated to revision 51c6d483a4c15a657df18540219bd0201896c6f2.
CVS checkout begin: 2009-06-30 10:28:31 UTC
Executing command: ['cvs', '-d', ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot', '-q', 'checkout', '-P', '-r', 'LDAPCSDK_6_0_6B_MOZILLA_RTM', '-d', 'c-sdk', 'mozilla/directory/c-sdk']
U c-sdk/.cvsignore
U c-sdk/Makefile.in
...
updating working directory
163 files updated, 0 files merged, 0 files removed, 0 files unresolved
Executing command: ['hg', 'update', '-r', 'default', '-R', './mozilla/extensions/venkman']
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
Updated to revision 06ea5135b7f3c9a639c483183ceb9802abee621b.

 Build Thunderbird

prepare compile options
[root@b008-02 commsrc]# cp ./mozilla/browser/config/mozconfig .mozconfig
[root@b008-02 commsrc]# cat .mozconfig 
mk_add_options AUTOCONF=autoconf-2.13
ac_add_options --enable-application=mail
ac_add_options --prefix="/usr/local/thunderbirdDebug"
ac_add_options --libdir="/usr/local/thunderbirdDebugLibs"
ac_add_options --enable-extensions=pref
ac_add_options --enable-static
ac_add_options --disable-shared
ac_add_options --disable-crashreporter

the option --disable-crashreporter is necessary if you get compile error at this stage of the build

gmake[7]: Entering directory
`/usr/local/Moz2/commsrc/mozilla/toolkit/crashreporter/google-breakpad/src/common/linux'
dump_symbols.cc
Build

then start building

[root@b008-02 commsrc]# time make -f client.mk build
rm -f ../../mozilla/dist/bin/TestCookie
if test -f ../../mozilla/dist/bin/TestTArray; 
then cp ../../mozilla/dist/bin/TestTArray ../../mozilla/dist/bin/TestCookie; fi;
gmake[5]: quittant le répertoire « /usr/local/Moz/commsrc/mail/app »
gmake[4]: quittant le répertoire « /usr/local/Moz/commsrc/mail »
gmake[3]: quittant le répertoire « /usr/local/Moz/commsrc »
gmake[2]: quittant le répertoire « /usr/local/Moz/commsrc »
make[1]: quittant le répertoire « /usr/local/Moz/commsrc »

real    23m33.845s
user    20m34.356s
sys     1m49.752s

Install

Then install (--enable-static and --disable-shared necessary in .mozconfig !)

[root@b008-02 commsrc]# make install -n
/usr/bin/gmake -C mail/installer install
gmake[1]: entrant dans le répertoire « /usr/local/Moz/commsrc/mail/installer »
rm -rf ../../mozilla/dist/thunderbird ../../mozilla/dist/thunderbird-3.0b3pre.en-US.linux-i686.tar ../../mozilla/dist/thunderbird-3.0b3pre.en-US.linux-i686.dmg stage-package 
echo "Creating package directory..."
...
/usr/local/Moz/commsrc/mozilla/config/nsinstall -D /usr/local/thunderbirdDebug/bin
rm -f -f /usr/local/thunderbirdDebug/bin/thunderbird
ln -s /usr/local/thunderbirdDebugLibs/thunderbird-3.0b3pre/thunderbird /usr/local/thunderbirdDebug/bin
gmake[1]: quittant le répertoire « /usr/local/Moz/commsrc/mail/installer »

[root@b008-02 commsrc]# ls -l /usr/local/thunderbirdDebugLibs/thunderbird-3.0b3pre/ | grep ^d
drwxr-xr-x 3 root root     4096 juil.  2 10:45 chrome
drwxr-xr-x 2 root root    12288 juil.  2 10:45 components
drwxr-xr-x 6 root root     4096 juil.  1 10:24 defaults
drwxr-xr-x 2 root root     4096 juil.  2 10:45 dictionaries
drwxr-xr-x 3 root root     4096 juil.  1 10:24 extensions
drwxr-xr-x 2 root root     4096 juil.  2 10:27 greprefs
drwxr-xr-x 2 root root     4096 juil.  1 10:18 icons
drwxr-xr-x 3 root root     4096 juil.  2 10:45 isp
drwxr-xr-x 4 root root     4096 juil.  2 10:45 modules
drwxr-xr-x 2 root root     4096 juil.  2 10:45 OutTestData
drwxr-xr-x 6 root root     4096 juil.  2 10:45 res
[root@b008-02 commsrc]# ls -l /usr/local/thunderbirdDebug/bin/
total 4
lrwxrwxrwx 1 root root 64 juil.  2 10:45 thunderbird -> /usr/local/thunderbirdDebugLibs/thunderbird-3.0b3pre/thunderbird

[root@b008-02 thunderbirdDebugLibs]# find /usr/local/thunderbirdDebugLibs/ -name prefcalls.js
/usr/local/thunderbirdDebugLibs/thunderbird-3.0b3pre/defaults/autoconfig/prefcalls.js

Old Mozilla 1.x, Possibly Netscape 6/7

The following is for the record... it also contains an interesting feature that I did not use anymore -> AutoConfig from a web server!

Changes

Between 2002 and 2003, we needed to upgrade the old Netscape 4.x (4.79) version to Mozilla 1.x (1.4), and now (2004-2005) Mozilla 1.7. The AutoConfiguration subsystem is quite the same as described the section on 'old' Netscape 4.x, but also slightly different.

Mozilla New Features in Regard to Netscape

In Mozilla, we don't use the convert function from Netscape 4.5 CCK anymore, but moz-byteshift.pl Perl script, to encode mozilla.cfg file.

The use of the getLDAPAttributes() function by calling inside itself the processLDAPValues() as a user defined function (see prefcalls.js) forces us to slightly change these calls in our original web CGI JavaScript (here mci-mozilla-glob-prefs-tux.cgi). The variables generated (mail, cn, uid) are defined only inside the processLDAPValues() function, that explains why lockPref related to these variables are located inside that function. I also couldn't use the alert() function anymore, so I changed to displayerror() function!

Locating The File on a Web Server

That was the case in the Netscape 4.x description below, however, at first it was a hard thing to do in Mozilla, cf. {{ Bug("206294") }}. So now you only need to create a small encoded cfg file making a call to a web located CGI script which will actually generate the JavaScript configuration directives to the Mozilla client. Hence you can change all of your Mozilla clients preferences by simply modifying a single file on a web server, great!

Call File

This file calls a CGI on a web server, the CGI generating the JavaScript code that will set preferences. Here the vendor name (mci-mozilla-web-tux) must match the name of the cfg file (mci-mozilla-web-tux.cfg).

$ cat mci-mozilla-web-tux.js
lockPref("general.config.vendor", "mci-mozilla-web-tux");
lockPref("autoadmin.global_config_url","http://corbeau.int-evry.fr/cgi-bin/mci-mozilla-glob-prefs-tux.cgi");

Encoding mozilla.js File to mozilla.cfg

Just use the moz-byteshift.pl Perl script which for Mozilla 1.x and Netscape 6/7 uses a shift of 13, in Netscape 4.x it was 7.

$ more moz-byteshift.pl
#!/usr/bin/perl
 
# Byte-shifting program for Mozilla's netscape.cfg files
 
# Old Netscape 4.x uses a byte-shift of 7
#   To decode: moz-byteshift.pl -s -7 <netscape.cfg >netscape.cfg.txt
#   To encode: moz-byteshift.pl -s  7 <netscape.cfg.txt >netscape.cfg
 
# Mozilla uses a byte-shift of 13
#   To decode: moz-byteshift.pl -s -13 <netscape.cfg >netscape.cfg.txt
#   To encode: moz-byteshift.pl -s  13 <netscape.cfg.txt >netscape.cfg
 
# To activate the netscape.cfg file, place the encoded netscape.cfg file
# into your C:\Program Files\mozilla.org\Mozilla directory.
# Then add the following line to your
# C:\Program Files\mozilla.org\Mozilla\defaults\pref\all.js file:
# pref("general.config.filename", "mozilla.cfg");
...

$ ./moz-byteshift.pl -s 13 < mci-mozilla-web-tux.js > mci-mozilla-web-tux.cfg

Location of mci-mozilla-web-tux.cfg

The location of the netscape.cfg (here renamed to mci-mozilla-web-tux.cfg) and the way to call it is different from the old Netscape 4.x. It's location is in MOZILLA_HOME ; c:\program files\mozilla.org\mozilla in Windows, or /usr/lib/mozilla-1.7-3/ in Linux Fedora.

Call to mci-mozilla-web-tux.cfg

The way to call it is through all.js file by adding at the end:

$ tail -2 /usr/lib/mozilla-1.7-3/defaults/pref/all.js
pref("general.config.filename", "mci-mozilla-web-tux.cfg");
pref("general.config.vendor", "mci-mozilla-web-tux");

Web Base CGI JavaScript Preferences Generator File

[root@corbeau /var/www/cgi-bin]
$ cat mci-mozilla-glob-prefs-tux.cgi
#!/usr/bin/perl -w

print("Content-type: application/javascript-config\n\n");
$page = <<"EOP";
 
try {
  var env_user = getenv("USER");
  var env_home = getenv("HOME");
  var env_mozdebug= getenv("MOZILLA_DEBUG");
  function processLDAPValues(values) {
    var uid = getLDAPValue(values, "uid");
    var cn = getLDAPValue(values, "cn");
    var mail = getLDAPValue(values, "mail");
    lockPref("mail.server.server1.name", mail);
    lockPref("mail.identity.id1.fullName", cn);
    lockPref("mail.identity.id1.useremail", mail);

  if (env_mozdebug) {
    displayError("debug mozilla.cfg v2.8", "mail:" + mail + "uid:" + uid + "cn" + cn + "user:" + env_user);
  } 
}
//BROWSER
/*defaultPref("startup.homepage_override_url", "http://www.int-evry.fr/mci/user/");
lockPref("browser.startup.homepage_override", true);
lockPref("browser.startup.page", 1);
defaultPref("browser.startup.homepage", "http://www.int-evry.fr/mci/user/");
*/
lockPref("browser.startup.homepage", "http://www.int-evry.fr/mci/user/");
lockPref("browser.startup.homepage_override", true);
lockPref("general.config.vendor", "mci-mozilla-web-tux");
lockPref("startup.homepage_override_url", "http://www.int-evry.fr/mci/user/");
lockPref("browser.cache.disk.capacity", 0);
lockPref("network.cookie.cookieBehavior", 0);
lockPref("network.proxy.autoconfig_url", "http://www.int-evry.fr/local/config.proxy");
lockPref("network.proxy.type", 2);
 
//Account
lockPref("mail.account.account1.identities", "id1");
lockPref("mail.account.account1.server", "server1");
lockPref("mail.account.account2.server", "server2");
lockPref("mail.account.account3.server", "server3");
lockPref("mail.accountmanager.accounts", "account1,account2,account3");
lockPref("mail.accountmanager.defaultaccount", "account1");
 
//IMAP
lockPref("mail.server.server1.hostname", "imap-int.int-evry.fr");
lockPref("mail.server.server1.type", "imap");
lockPref("mail.server.server1.login_at_startup", true);
lockPref("mail.identity.id1.draft_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Drafts");
lockPref("mail.identity.id1.drafts_folder_picker_mode", "0");
lockPref("mail.identity.id1.fcc_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Sent");
lockPref("mail.identity.id1.fcc_folder_picker_mode", "0");
lockPref("mail.identity.id1.stationery_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Templates");
lockPref("mail.identity.id1.tmpl_folder_picker_mode", "0");
lockPref("mail.identity.id1.valid", true);
lockPref("mail.identity.id1.overrideGlobal_Pref", true);
lockPref("mail.server.server1.download_on_biff", true);
lockPref("mail.server.server1.login_at_startup", true);
lockPref("mail.server.server1.userName", env_user);
lockPref("mail.server.server1.delete_model", 0);
 
//SMTP
lockPref("mail.identity.id1.smtpServer", "smtp1");
defaultPref("mail.smtpserver.smtp1.auth_method", 0);
lockPref("mail.smtpservers", "smtp1");
lockPref("mail.smtpservers", "smtp1");
lockPref("mail.smtp.defaultserver", "smtp1");
lockPref("mail.smtpserver.smtp1.hostname", "smtp-int.int-evry.fr");
lockPref("mail.identity.id1.organization", "INT Evry France");
lockPref("mail.startup.enabledMailCheckOnce", true);
lockPref("mail.ui.folderpane.version", 3);
lockPref("mailnews.ui.threadpane.version", 2);
 
//LDAP config
lockPref("mail.identity.id1.directoryServer", "ldap_2.servers.ldapint");
lockPref("ldap_2.prefs_migrated", true);
lockPref("ldap_2.servers.history.filename", "history.mab");
lockPref("ldap_2.servers.history.replication.lastChangeNumber", 0);
lockPref("ldap_2.servers.ldapint.auth.savePassword", true);
lockPref("ldap_2.servers.ldapint.description", "ldap-int");
lockPref("ldap_2.servers.ldapint.filename", "abook-1.mab");
lockPref("ldap_2.servers.ldapint.position", 3);
lockPref("ldap_2.servers.ldapint.uri", "ldap://ldap1.int-evry.fr:389/ou=people,dc=int-evry,dc=fr??sub");
lockPref("ldap_2.servers.pab.filename", "abook.mab");
lockPref("ldap_2.servers.pab.replication.lastChangeNumber", 0);
 
//News config
lockPref("mail.server.server3.hostname", "news.int-evry.fr");
lockPref("mail.server.server3.max_cached_connections", 2);
lockPref("mail.server.server3.name", "news.int-evry.fr");
lockPref("mail.server.server3.type", "nntp");
lockPref("mail.server.server3.userName", env_user);
 
//Call to ldap to get user's attribute.
getLDAPAttributes("ldap2.int-evry.fr", "ou=people,dc=int-evry,dc=fr", "uid=" +env_user, "uid,cn,mail");
 
} catch(e) {
  displayError("lockedPref", e);
}
 
EOP
print $page;

Windows Peculiarities

Without web base CGI file, beware that in Windows, the original (before encoding) mozilla.js file must start with: //BEGIN CE prefs , if not you'll get "failed to read configuration file..." message, and Mozilla won't start :-(

In Windows environment variables like USER or HOME, are USERNAME and HOMEPATH, that's why we must create a different pair of configuration files (cfg and cgi) for both systems (Linux/Windows). Perhaps there's a way in JavaScript to detect operating system and hence use either USER or USERNAME, but I'm not that fluent in JavaScript, let me know if you know how...//

Windows Call File
$ cat mci-mozilla-web-win.js
lockPref("general.config.vendor", "mci-mozilla-web-win");
lockPref("autoadmin.global_config_url","http://corbeau.int-evry.fr/cgi-bin/mci-mozilla-glob-prefs-win.cgi");
Windows all.js File

To be encoded by moz-byteshift.pl as stated above...

c:\type c:\program files\mozilla.org\mozilla\defaults\pref\all.js
pref("general.config.filename", "mci-mozilla-web-win.cfg");
pref("general.config.vendor", "mci-mozilla-web-win");
Windows CGI file
$ cat mci-mozilla-glob-prefs-win.cgi
#!/usr/bin/perl -w

print("Content-type: application/javascript-config\n\n");
$page = <<"EOP";
 
try {
  var env_user = getenv("USERNAME");
  var env_home = getenv("HOMEPATH");
  var env_mozdebug= getenv("MOZILLA_DEBUG");
...

The rest of the file is identical to the Linux version, only the environment variables (var env_*) are different!

Versions Tested

This configuration was validated on Linux with Mozilla 1.4, 1.6 and 1.7, and on Windows with Mozilla 1.4, 1.5, 1.7.

Debugging - Bugzilla

Run Time Messages

Note: the presence of var env_mozdebug=getenv("MOZILLA_DEBUG")allows user to print debugging messages if MOZILLA_DEBUG is defined in either the shell for Unix (export MOZILLA_DEBUG=1) or in the command.com environment in Windows (set MOZILLA_DEBUG=1).

Blank Space Bug

I noticed a problem which is due to be corrected in Mozilla 1.8 I think... Here's the report and workaround: {{ Bug("229271") }}. To fix, add the following:

        start_pos += search_key.length;
//start 
        start_pos +=1;
//end

to function getLDAPValue() in autoconfig/preffcalls.js.

Documentation

I also opened a report on the lack of documentation {{ Bug("178685") }} which led to the wonderful doc: http://wangrepublic.org/daniel/mozilla/prefs/

defeultPref for Home Page

I cannot set the home page with the defaultPref function, so that it is set by default, but still allows the user to change it! A bug is opened on this, see {{ Bug("272970") }}

greprefs Right Access

Beware also on Linux that MOZILLA_HOME/greprefs directory is closed by default to users and then AutoConfig doesn't work properly, I've opened a bug on this: {{ Bug("270623") }}. The workaround is chmod 755 greprefs!

CGI Base Config File

There has been a issue about the use of autoadmin.global_config_url, see {{ Bug("206294") }}.

Mail Folders

Implementing that solution, we encounter difficulties with mail folder. Our first idea was to use local mail folders from home directory of the current user. In Unix that would have been $HOME/nsmail/..., in Windows it would have been a Samba mount of that same Unix path (ex: U:\nsmail ; with U: = Samba mount: \\samba-server\%USERNAME). Unfortunately file system writes and/or mail format differs between Windows and Unix, and folders soon become unreadable or even corrupted when read/written from one system to the other.

That's why we finally decided to use IMAP, and hence IMAP folders. By migrating from University of Washington IMAP server to Cyrus IMAP we also inherited some interesting features like quotas, share folders, ACL, mail only account (no need for /etc/passwd entry!) much better performances, etc...

Reliability

Fail-over and Uniqueness

A contribution from Roberto Aguilar gives the Mozilla AutoConfig JavaScript a way to search through different LDAP replicas in case one LDAP server is down.

It also allows users to use a single JavaScript for both systems (Linux and Windows) with a subtle if... else test on environment variables.

LDAP fail-over

Creating an array of possible running LDAP servers permits an LDAP fail-over, then a shuffle function allows us to randomly pick up a running LDAP server.

The shuffle function comes from here: http://www.mickweb.com/javascript/ar...reshuffle.html

Before publishing the code changes, please add this right before the shuffle function:

 /**
  * setup the shuffle method for an array, from Mickweb Script
  * Factory at:
  * http://www.mickweb.com/javascript/arrays/pureshuffle.html
  */

Here's how the LDAP fail-over works:

// 2) setup multiple LDAP servers for fail-over
  var ldap_values;
  var ldap_servers = new Array('ldap2.int-evry.fr',
                      'ldap1.int-evry.fr',
                      'openldap.int-evry.fr'
                      );
  // shuffle function to randomize the server array
  // setup the shuffle method for an array
  Array.prototype.shuffle = function(times) {
    var i,j,t,l=this.length;
    while(times--) {
      with(Math) {
    i = floor(random()*l);
    j = floor(random()*l);
      }
      t       = this[i];
      this[i] = this[j];
      this[j] = t;
    }
    return this;
  }
 // mix up the LDAP servers so we don't hit the same one each time
  ldap_servers.shuffle(10);
....
// 4) Call LDAP servers to get LDAP Attributes (mail & cn), this will finally call processLDAPValues, "3)" just above.
// Go through the LDAP replicas list
for(i = 0; i < ldap_servers.length; i ++) {
// Search for attribute mail & cn through LDAP servers where uid = $USER|$USERNAME
  getLDAPAttributes(ldap_servers[i],
       "ou=people,dc=int-evry,dc=fr",
       "uid=" + env_user,
       "uid,cn,mail");
    // If we catch a running LDAP server, exit the loop,
    if(ldap_values) {
      running_ldap_server = ldap_servers[i];
        // If $MOZILLA_DEBUG=1 display in a popup the running server
      if (env_mozdebug) {
        displayError("getLDAPAttributes: debug 2 running_ldap_server: " + running_ldap_server);
       }
      break;
    }
  }

Unique Script for Windows and Linux

An if... else test permits us to check whether we use a Linux or Windows environment variable for the USER / USERNAME.

// 1) env variables
if(getenv("USER") != "") {
   // *NIX settings
   var env_user = getenv("USER");
   var env_home = getenv("HOME");
 } else {
   // Windows settings
   var env_user = getenv("USERNAME");
   var env_home = getenv("HOMEPATH");
 }
  var env_mozdebug= getenv("MOZILLA_DEBUG");

Final Production Script

Here's the complete final and commented production script:

//Mozilla AutoConfiguration, Jehan Procaccia & Roberto Aguilar
 
//put everything in a try/catch
try {
/*
1) define environment variables,
2) list & randomize LDAP replicas,
3) define processLDAPValues(),
4) Call LDAP server to get LDAP Attributes (mail & cn) getLDAPAttributes()
5) set user preferences
*/
 
// 1) env variables
if(getenv("USER") != "") {
   // *NIX settings
   var env_user = getenv("USER");
   var env_home = getenv("HOME");
 } else {
   // Windows settings
   var env_user = getenv("USERNAME");
   var env_home = getenv("HOMEPATH");
 }
  var env_mozdebug= getenv("MOZILLA_DEBUG");
 
// 2) setup multiple LDAP servers for fail-over
  var ldap_values;
  var ldap_servers = new Array('ldap2.int-evry.fr',
                      'ldap1.int-evry.fr',
                      'openldap.int-evry.fr'
                      );
  // shuffle function to randomize the server array
/**
  * setup the shuffle method for an array, from "mickweb script
  * factory" at:
  * http://www.mickweb.com/javascript/arrays/pureshuffle.html
  */ 
  // setup the shuffle method for an array
  Array.prototype.shuffle = function(times) {
    var i,j,t,l=this.length;
    while(times--) {
      with(Math) {
    i = floor(random()*l);
    j = floor(random()*l);
      }
      t       = this[i];
      this[i] = this[j];
      this[j] = t;
    }
    return this;
  }
 // mix up the LDAP servers so we don't hit the same one each time
  ldap_servers.shuffle(10);
 
/* 3) define here (because if set after "4)" below it doesn't work!) processLDAPValues which is eventually called by getLDAPAttributes() just below,
 check getLDAPAttributes() code from $MOZILLA_HOME/defaults/autoconfig/prefcalls.js to see the inside call to "user defined" processLDAPValues
*/
function processLDAPValues(values) {
 if(values) {
      // set the global var with the values returned from the LDAP query
      ldap_values = values;
    var uid = getLDAPValue(values, "uid");
    var cn = getLDAPValue(values, "cn");
    var mail = getLDAPValue(values, "mail");
     // lock LDAP variable (mail & cn) dependent preferences while we have access to them
    lockPref("mail.server.server1.name", mail);
    lockPref("mail.identity.id1.fullName", cn);
    lockPref("mail.identity.id1.useremail", mail);
    defaultPref("network.ftp.anonymous_password", mail);
 
    // if $MOZILLA_DEBUG=1, popup a debug message
    if (env_mozdebug) {
        displayError("NO ERROR -> MCI (jehan.procaccia@int-evry.fr)" + "\nthis message is displayed with displayError()! \ndebug 1 mozilla.cfg v3.2, NO FAILED, S2IA again!", "\nmail:" + mail + "\nuid:" +uid + "\ncn:" +cn + "\nuser:" + env_user);
        }
    }
  }
 
// 4) Call LDAP servers to get LDAP Attributes (mail & cn), this will finally call processLDAPValues, "3)" just above.
// Go through the LDAP replicas list
for(i = 0; i < ldap_servers.length; i ++) {
// Search for attribute mail & cn through LDAP servers where uid = $USER|$USERNAME
  getLDAPAttributes(ldap_servers[i],
       "ou=people,dc=int-evry,dc=fr",
       "uid=" + env_user,
       "uid,cn,mail");
    // If we catch a running LDAP server, exit the loop,
    if(ldap_values) {
      running_ldap_server = ldap_servers[i];
        // If $MOZILLA_DEBUG=1 display in a popup the running server
      if (env_mozdebug) {
        displayError("getLDAPAttributes: debug 2 running_ldap_server: " + running_ldap_server);
       }
      break;
    }
  }
 
// 5) Set user preferences
 
//BROWSER
lockPref("browser.startup.homepage", "http://www.int-evry.fr/s2ia/portail/");
//unlockPref("browser.startup.homepage");
lockPref("browser.startup.homepage_override", true);
lockPref("startup.homepage_override_url", "http://www.int-evry.fr/s2ia/portail/");
//unlockPref("startup.homepage_override_url");
lockPref("browser.cache.disk.capacity", 100);
lockPref("network.cookie.cookieBehavior", 0);
 
//Network preferences
lockPref("network.proxy.autoconfig_url", "http://www.int-evry.fr/local/config.proxy");
lockPref("network.proxy.type", 2);
 
//Privacy & Security
defaultPref("signon.rememberSignons", false);
 
//Account
lockPref("mail.account.account1.identities", "id1");
lockPref("mail.account.account1.server", "server1");
lockPref("mail.account.account2.server", "server2");
lockPref("mail.account.account3.server", "server3");
lockPref("mail.accountmanager.accounts", "account1,account2,account3");
lockPref("mail.accountmanager.defaultaccount", "account1");
 
//IMAP
lockPref("mail.server.server1.hostname", "imap-int.int-evry.fr");
lockPref("mail.server.server1.type", "imap");
lockPref("mail.server.server1.login_at_startup", true);
lockPref("mail.identity.id1.draft_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Drafts");
lockPref("mail.identity.id1.drafts_folder_picker_mode", "0");
lockPref("mail.identity.id1.fcc_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Sent");
lockPref("mail.identity.id1.fcc_folder_picker_mode", "0");
lockPref("mail.identity.id1.stationery_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Templates");
lockPref("mail.identity.id1.tmpl_folder_picker_mode", "0");
lockPref("mail.identity.id1.valid", true);
lockPref("mail.identity.id1.overrideGlobal_Pref", true);
lockPref("mail.server.server1.download_on_biff", true);
lockPref("mail.server.server1.login_at_startup", true);
lockPref("mail.server.server1.userName", env_user);
lockPref("mail.server.server1.delete_model", 0);
 
//SMTP
defaultPref("mail.identity.id1.smtpServer", "smtp1");
defaultPref("mail.smtpserver.smtp1.auth_method", 0);
defaultPref("mail.smtpservers", "smtp1");
defaultPref("mail.smtpservers", "smtp1");
defaultPref("mail.smtp.defaultserver", "smtp1");
defaultPref("mail.smtpserver.smtp1.hostname", "smtp-int.int-evry.fr");
lockPref("mail.identity.id1.organization", "INT Evry France");
lockPref("mail.startup.enabledMailCheckOnce", true);
lockPref("mail.ui.folderpane.version", 3);
lockPref("mailnews.ui.threadpane.version", 2);
 
//LDAP config
lockPref("mail.identity.id1.directoryServer", "ldap_2.servers.ldapint");
lockPref("ldap_2.prefs_migrated", true);
lockPref("ldap_2.servers.history.filename", "history.mab");
lockPref("ldap_2.servers.history.replication.lastChangeNumber", 0);
lockPref("ldap_2.servers.ldapint.auth.savePassword", true);
lockPref("ldap_2.servers.ldapint.description", "ldap-int");
lockPref("ldap_2.servers.ldapint.filename", "abook-1.mab");
lockPref("ldap_2.servers.ldapint.position", 3);
lockPref("ldap_2.servers.ldapint.uri", "ldap://ldap1.int-evry.fr:389/ou=people,dc=int-evry,dc=fr??sub");
lockPref("ldap_2.servers.pab.filename", "abook.mab");
lockPref("ldap_2.servers.pab.replication.lastChangeNumber", 0);
 
//News config
lockPref("mail.server.server3.hostname", "news.int-evry.fr");
lockPref("mail.server.server3.max_cached_connections", 2);
lockPref("mail.server.server3.name", "news.int-evry.fr");
lockPref("mail.server.server3.type", "nntp");
lockPref("mail.server.server3.userName", env_user);
 
// Close the try, and call the catch()
} catch(e) {
  displayError("lockedPref", e);
}

For The Record, Old Reliably Scripts...

At least tested on Netscape 4.x.

In the original files below (in Netscape 4.x section), we hard-coded a single web server to retrieve the JavaScript preference file, and a single hard-coded LDAP server to get mail and cn attributes. It would be safer to get secondary servers in case of failure. For the web server name we can use an LDAP query to get the list of possible ones. Hence, we won't have to re-encode the netscape.cfg file at every change. We set the netscape.cfg file just once while imaging computers with the operating system, then any changes happen in LDAP or on the web server JavaScript preference file (central configuration).

Enhance netscape.cfg

The list of possible web servers to query is defined in netscape.cfg. This is also where the JavaScript preference filenames are defined so that netscape.cfg doesn't need to be changed after imaging the computers at every change we need to do.

LDAP Web Server List Subtree
$ ldapsearch -x * -b "ou=browser,ou=information,dc=int-evry, dc=fr" cn -LLL
dn: ou=browser,ou=information,dc=int-evry,dc=fr

dn: sn=http_server,ou=browser,ou=information,dc=int-evry, dc=fr
cn: web1.int-evry.fr
cn: web2.int-evry.fr

dn: sn=http_unix_file, ou=browser,ou=information,dc=int-evry, dc=fr
cn: /browser/config_file_unix.jsc

dn: sn=http_win_file, ou=browser,ou=information,dc=int-evry, dc=fr
cn: /browser/config_file_win.jsc
netscape.cfg

Here we select an operational LDAP server simply by testing a LDAP query, to make sure that our LDAP queries for setting preferences will be answered. {Again, I am not fluent in JavaScript. There should be a better way to make sure that an LDAP server is up and running. As for checking a web server, feel free to optimize this code, and let me know...)

if (getLDAPAttributes("ldap1.int-evry.fr", \
 "ou=browser,ou=information,dc=int-evry,dc=fr", \
 "sn=http_server", "cn") )
 var running_ldap_server = "ldap1.int-evry.fr";
 else if (getLDAPAttributes("ldap2.int-evry.fr", \
 "ou=browser,ou=information,dc=int-evry,dc=fr", \
 "sn=http_server", "cn") )
  var running_ldap_server = "ldap2.int-evry.fr";
  else if (getLDAPAttributes("ldap0.int-evry.fr", \
  "ou=browser,ou=information,dc=int-evry,dc=fr", \
  "sn=http_server", "cn") )
   var running_ldap_server = "ldap0.int-evry.fr";
  else alert("No LDAP server available!");

Here's a complete example of the Unix netscape.cfg file.

with (PrefConfig) { // Must be done inside the PrefConfig module

// create some variables we might want to use later on...
var env_user = getenv("USER");       // Windows username
var env_home = getenv("HOME");       // User HomeDir
var env_mozilla_home = getenv("MOZILLA_HOME");
var env_mozdebug = getenv("MOZILLA_DEBUG");

//check which LDAP server is running (needs a better procedure!)

if (getLDAPAttributes("ldap1.int-evry.fr", \
 "ou=browser,ou=information,dc=int-evry,dc=fr", \
 "sn=http_server", "cn") )
 var running_ldap_server = "ldap1.int-evry.fr";
 else if (getLDAPAttributes("ldap2.int-evry.fr", \
  "ou=browser,ou=information,dc=int-evry,dc=fr", \
  "sn=http_server", "cn") )
  var running_ldap_server = "ldap2.int-evry.fr";
  else if (getLDAPAttributes("ldap0.int-evry.fr", \
  "ou=browser,ou=information,dc=int-evry,dc=fr", \
  "sn=http_server", "cn") )
   var running_ldap_server = "ldap0.int-evry.fr";
  else alert("No LDAP server available!");

if (running_ldap_server){ 
var ldap_http_server_values = getLDAPAttributes(running_ldap_server, \
"ou=browser,ou=information,dc=int-evry,dc=fr", "sn=http_server", "cn");
var ldap_http_server = getLDAPValue(ldap_http_server_values, "cn");
var ldap_http_unix_uri_values = getLDAPAttributes(running_ldap_server, \
"ou=browser,ou=information,dc=int-evry,dc=fr", "sn=http_unix_file", "cn");
var ldap_http_unix_uri = getLDAPValue(ldap_http_unix_uri_values, "cn");
var values = getLDAPAttributes(running_ldap_server, \
"ou=people,dc=int-evry,dc=fr", "uid="+env_user, "cn,mail");
var ldap_email = getLDAPValue(values, "mail");
var ldap_gecos = getLDAPValue(values, "cn");
env_user=env_user.toLowerCase();
}
else
 alert("No LDAP server available, AutoConfig impossible!");

//popup debug message if export MOZILLA_DEBUG=1 
if (env_mozdebug) {
 alert("MOZILLA_DEBUG\nrunning LDAP server: " + running_ldap_server);
 alert("MOZILLA_DEBUG\nExecuting " + ldap_http_server + \
 ldap_http_unix_uri);
 alert("MOZILLA_DEBUG\nfetching http://" + ldap_http_server \
 + ldap_http_unix_uri + "");
}

//go fetch the preference file in a HTTP server 
//needs a way to check if http server is running!

config(
"autoadmin.global_config_url", "http://" + ldap_http_server + \
ldap_http_unix_uri + ""
);

// Since we use a file, if it's not accessible, something is
// terribly wrong anyway
config(
"autoadmin.failover_to_cached", false
);

// don't use ?useremail=email-addr to CGI URL request
config(
"autoadmin.append_emailaddr", false
);

} // with (PrefConfig)

For the Windows version of that netscape.cfg file, we replace "sn=http_unix_file" by "sn=http_win_file" in the LDAP query.

OLD Netscape 4.x

Call File, netscape.cfg

In the following example, that file is a "call" file, because it will actually be used to only redirect a call to an even more centralized file, a file that will be located on a web server. That allows us first to encode (byte-shift) that file (netscape.cfg) -just once- because it will call a non-encoded JavaScript file config_file_system.jsc (or whatever name) on the web server.

Second, as that latest JavaScript file is located on a web server, there's no need to recopy it on every station at every single change! That feature is available through autoadmin.global_config_url directive as in config("autoadmin.global_config_url","http://www/browser/config-file-system.jsc"), for example. Unfortunately I am unable to run that really useful directive with Netscape 6/7 or Mozilla 1.x :-(, (if anyone knows how, please let me know!)

In Windows that encoded netscape.cfg file is located in NETSCAPE_HOME\Communicator\Program (C:\Program Files\netscape\Communicator\Programs), in Red Hat 7.3 it is in /usr/lib/X11/app-defaults. Beware that in Windows, that file is already there, so it must be saved before being replaced by ours, in order to come back to a normal state in case of problem. If neither original or personalized netscape.cfg is there, Netscape won't start!

// This file is not usable in its present form. it must be encoded
// with the "convert" function of the CCK "file" menu
// Netscape's Flow of preference configuration:
//    configure defaults from internal JavaScript file in ns executable
//    global prefs from netscape.cfg (this file)
//    executes ~/.netscape/preferences.js file
//    executes ~/.netscape/user.js
// (somewhere in here liprefs.js is run, but i haven't yet figured out
// what liprefs is for....)
//=========================================================================

with (PrefConfig) { // Must be done inside the PrefConfig module

// create some variables we might want to use later on...
var platform    = getPlatform();        // E.G. SunOS4.1.3_U1
var env_user    = getenv("USER");       // Unix username
var env_home    = getenv("HOME");       // User HomeDir
var env_display = getenv("DISPLAY");    // X11 Display
var env_editor  = getenv("EDITOR");     // use in mail edit?
var env_visual  = getenv("VISUAL");     // use in mail edit?
var env_mozilla_home    = getenv("MOZILLA_HOME")
var env_mozdebug        = getenv("MOZILLA_DEBUG")
// For ease of update... We use the AutoAdmin operation to redirect
// netscape.cfg to read the plain-text "config-file-unix.jsc" file.
// Any changes
// from now on can be made here w/o re-encoding the netscape.jsc file to
// netscape.cfg.
config(
"autoadmin.global_config_url", \
"http://lugdunum.int-evry.fr/browser/config-file-unix.jsc"
);
// How often (in minutes) to update
// Every 6 hours seems a good interval to keep hosts who don't ever
// exit Netscape updated on current changes.
config(
"autoadmin.refresh_interval", 360
);
// Since we use a file, if it's not accessible, something is
// terribly wrong anyway
config(
"autoadmin.failover_to_cached", false
);
// don't use ?useremail=email-addr to cgi URL request
config(
"autoadmin.append_emailaddr", false
);

LockPref Configuration File

This file (on the web server: http://www/browser/config-file-system.jsc) is where we set and lock Preferences. Because computers are shared, we need to personalize preferences based on the user login. The login is taken from the environment variable: USER in Unix, USERNAME in Windows. Different environment names and different paths between Windows and Unix explain why we need two different configuration files. There might be a way to manage those differences within a same file, but I am not very fluent in JavaScript :-(

Here is an example of a lockPref preference configuration file for Unix (config_file_unix.jsc). We lock (lockPref) some preferences (IMAP server name, company name, cache location and size...), others can be just set as default (defaultPref); startup.homepage... We also use LDAP functions (from prefcalls.js) to get the current user (USER or USERNAME) email address and common name, respectively mail and cn in LDAP.

[root@lugdunum /var/www/html/browser]
$ more config_file_unix.jsc
// Functions you can use:
// lockPref(name, value) user is disallowed from changing
//  (aka lock_pref())
// defaultPref(name, value) unless user overrides, this is value
//  (aka default_pref())
// unlockPref(name) unlock previously "lockPref"-ed name
// config(name, value) usually for menus...
// value = getPref(name) gets current setting
// getLDAPAttributes(host, base, filter, attributes)
// getLDAPValue(values, attribute)
// .mime.type, .begin_mime_def, .end_mime_def..
// .plat
// alert(message);
// var = prompt(message);
// var = getPlatform() returns Win32,...
//  getPlatform().contains("UNIX")...
// var = getenv(envvar)
// var = putenv(envvar)
//
// Objects/Functions you *can't* use because they aren't defined
// navigator.* (argh, this *REALLY* bites)
//=========================================================================
// Preferences Configuration
//=========================================================================
with (PrefConfig) {
var values = getLDAPAttributes("ldap2.int-evry.fr", \
"ou=people,dc=int-evry,dc=fr", "uid=" + env_user, "cn,mail");
var ldap_email = getLDAPValue(values, "mail");
var ldap_gecos = getLDAPValue(values, "cn");
//var toto = prompt("email");
//alert("ldap_mail = " + ldap_email + "toto=" + toto);
if (env_mozdebug) {
 alert("env_user:" + env_user + "\nenv_home:" + env_home + \
"\nldap_email:" + ldap_email + "\nldap_gecos:" + ldap_gecos + "\n");
}
//-----------------------------------------------------------------------
// [ General Browser configuration ]
//-----------------------------------------------------------------------
config("autoadmin.refresh_interval", 1440); // auto-update every 24 hours
defaultPref("browser.startup.page",1); 
//0=blank page, 1=homepage, 2=last visited
defaultPref("browser.startup.homepage", "http://www/mci/mode-d-emploi.shtml");
lockPref("browser.cache.directory", "/tmp");
lockPref("browser.cache.memory_cache_size", 0);

lockPref("mail.server_type",1); // POP=0 IMAP=1
lockPref("network.hosts.imap_servers", "pop-int");
lockPref("mail.imap.server.pop-int.using_subscription",true);
lockPref("mail.imap.server.pop-int.userName", env_user);
lockPref("mail.identity.useremail", ldap_email);
lockPref("mail.identity.username", ldap_gecos);
lockPref("mail.check_new_mail", false);
lockPref("mail.directory", env_home+"/nsmail");
lockPref("mail.identity.defaultdomain", "int-evry.fr");
lockPref("mail.identity.organization", "INT Evry Essonne ");

// LDAP
lockPref("ldap_2.autoComplete.useDirectory", true);
lockPref("ldap_2.servers.LDAPINT.autoComplete.enabled", true);
lockPref("ldap_2.servers.LDAPINT.csid", "UTF-8");
lockPref("ldap_2.servers.LDAPINT.description", "LDAP INT");
lockPref("ldap_2.servers.LDAPINT.filename", "LDAPINT.na2");
lockPref("ldap_2.servers.LDAPINT.position", 2);
lockPref("ldap_2.servers.LDAPINT.searchBase", "ou=people,dc=int-evry,dc=fr");
lockPref("ldap_2.servers.LDAPINT.serverName", "ldap1.int-evry.fr");

//news
lockPref("news.directory", "/tmp");
//proxy
lockPref("network.proxy.autoconfig_url", \
"http://www.int-evry.fr/local/config.proxy");

} // with (PrefConfig)

This document was translated from LaTeX with HEVEA.

{{ OrigDocInfo{ author : " Jehan Procaccia MCI INT-EVRY- jehan.procaccia AT int-evry.fr", date : " 02 September 2006" } }}

{{ languages( { "ja": "ja/MCD,_Mission_Control_Desktop_AKA_AutoConfig" } ) }}

Revision Source

<p>This document is a concrete example of a centralized auto-configuration of Mozilla apps, that are; Firefox, Thunderbird, Mozilla Suite 1.x.x, Seamonkey and for the record, old Netscape 4.x. Its original inspiration comes from  <a class=" external" href="http://www.alain.knaff.lu/howto/MozillaCustomization/" rel="freelink">http://www.alain.knaff.lu/howto/MozillaCustomization/</a> and <a class=" external" href="http://mit.edu/~firefox/www/maintainers/autoconfig.html" rel="freelink">http://mit.edu/~firefox/www/maintain...utoconfig.html</a>. For history, I've kept Mozilla and Netscape chapters, as certain points are complementary to the web-based AutoConfig file.<a class="moz-txt-link-freetext external" href="http://translate.google.com/translate?js=n&amp;prev=_t&amp;hl=en&amp;ie=UTF-8&amp;layout=2&amp;eotf=1&amp;sl=auto&amp;tl=en&amp;u=http://habrahabr.ru/blogs/sysadm/101905/&amp;act=url"><br>
</a></p>
<p>This MCD (aka autoconfig here), is not to be confused with <a class=" link-https" href="https://wiki.mozilla.org/Thunderbird:Autoconfiguration" rel="freelink">https://wiki.mozilla.org/Thunderbird...oconfiguration</a> . It's Mission is to enable completely automatic configuration of mozilla's apps preferences based on users properties either retrieved from system environement variables or on an organisation ldap directory.</p>
<h3 name="Situation">Situation</h3>
<p><a class="external" href="http://www.int-evry.fr/">INT-Evry</a> manages about 3000 users (mostly students) who share computers in labs and "self service" computer rooms. Hence a single computer might connect many different users all day long. Computers are dual-boot (Windows 7 and Linux Fedora 13/15 by 2011). All users have a personal account on a Windows server (AD) and an LDAP account for Linux authentication.</p>
<h3 name="Objective">Objective</h3>
<p>The objective is to provide users with a mailer agent, a web browser, and a news reader which are automatically configured (preferences) at startup to the current user connected on the computer. Choosing Mozilla products allow us to use the same apps while running either Windows or Linux systems (I suspect MAC OSX would be fine too).</p>
<p>Instead of configuring end user individual preferences files (<code>~/.mozilla/default/randomdir/prefs.js</code>) we now use a centralized default set of preferences. This centralized preference file can lock preferences (<code>lockPref</code>) or initialize them (<code>defaultPref</code>) based on environment variables (<code>USER</code>, <code>HOME</code>...) and/or LDAP queries (fetch email address, Common Name , language, homepage etc...) from the enterprise directory.</p>
<h3 name="Central_Configuration_File">Central Configuration File</h3>
<p>That feature is provided through a JavaScript file.</p>
<h4 name="File_Location">File Location</h4>
<p>In Thunderbird5 , FireFox5, the javascript preference file that calls the centralized preference file is located in $INSTALL_DIR_MOZ_APP/defaults/pref, for exemple in thunderbird this would be repectively for windows/linux:</p>
<p><code>C:\Program Files\Mozilla Thunderbird\defaults\pref</code></p>
<p><code>/usr/lib/thunderbird-5/default/pref</code></p>
<p>For the record/history purpose ... the old Netscape 4.x the file is encoded (byte-shift/rotary is 7), and the presence of the file (<code>netscape.cfg</code>) in the <code>MOZILLA_HOME</code> directory suffices for it to be read and executed. For Mozilla 1.x.x, Firefox, Thunderbird or Netscape 7 it is still a JavaScript file, the byte-shift is 13 by default, but can be removed using the <code>pref("general.config.obscure_value", 0);</code> preference in <code>all.js</code> or any appropriate <code>.js</code> file dedicated to autoconfig.</p>
<p>The name of the file can be anything you want because it is named by a <code>general.config</code> preference that should be added at the end of file <code>MOZILLA_HOME/default/pref/all.js</code> or <code>MOZILLA_HOME/greprefs/all.js</code>: <code>pref("general.config.filename", "mozilla.cfg");</code>.</p>
<h4 name="File_Encoding">File Encoding</h4>
<p>If needed, the encoding can be done with the Perl script: <code>moz-byteshift.pl</code> available at <a class=" external" href="http://www.alain.knaff.lu/howto/MozillaCustomization/moz-byteshift.pl" rel="freelink">http://www.alain.knaff.lu/howto/Mozi...z-byteshift.pl</a>.</p>
<p>For Netscape 4.x the convert function from the Client Customization Kit (CCK) could also do that (and other things like personalize auto-installation...): <a class="external" href="http://web.archive.org/web/20040821150212/http://developer.netscape.com/docs/manuals/deploymt/config.htm">http://developer.netscape.com/docs/manuals/deploymt/config.htm</a>.</p>
<h4 name="File_API">File API</h4>
<p>That centralized preference file uses a JavaScript API that allows us to do what we need. The available functions are defined in <code>MOZILLA_HOME/default/autoconfig/prefcalls.js</code>. The presence of <code>pref("general.config.filename", "mozilla.cfg");</code> in <code>all.js</code> enables the read and execution of <code>prefcalls.js</code>.</p>
<p>Available functions are (see <code>{{ Source("extensions/pref/autoconfig/src/prefcalls.js", "prefcalls.js") }}</code> file for details):</p>
<pre>function getPrefBranch() 
function pref(prefName, value) 
function defaultPref(prefName, value)
function lockPref(prefName, value) 
function unlockPref(prefName) 
function getPref(prefName) 
function getLDAPAttributes(host, base, filter, attribs) 
function getLDAPValue(str, key) 
function displayError(funcname, message)
function getenv(name) 
</pre>
<h3 name="Thunderbird">Thunderbird</h3>
<h4 name="Support_of_AutoConfig_and_LDAP_Calls">Support of AutoConfig and LDAP Calls</h4>
<p>Unfortunately, the AutoConfig Option and LDAP Support for autoconfig (getLDAPAttributes) is not present in Fedora11 default thunderbird package (thunderbird-3.0-2.3.beta2.fc11.src.rpm) .</p>
<p>So we need to patch and recompile that source RPM (check  <a class=" link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=295329" rel="freelink">https://bugzilla.mozilla.org/show_bug.cgi?id=295329</a> ) ; patch:</p>
<pre>[root@b008-02 SOURCES]# cat thunderbird-autoconfigAndLdap.patch
diff -ur thunderbird-3.0/configure thunderbird-3.0.autoldap/configure
--- thunderbird-3.0/configure    2009-06-29 11:37:21.677372297 +0200
+++ thunderbird-3.0.autoldap/configure    2009-06-29 14:41:11.547435040 +0200
@@ -12855,7 +12855,7 @@
 MOZ_FEEDS=1
 MOZ_JSDEBUGGER=1
 MOZ_JSLOADER=1
-MOZ_LDAP_XPCOM=
+MOZ_LDAP_XPCOM=1
 MOZ_MAIL_NEWS=
 MOZ_MORK=1
 MOZ_MORKREADER=
</pre>
<h5 name="AutoConfig_Option_and_LDAP_Support_in_Thunderbird_1.5.x">And set --enable-extensions=pref in mozconfig file, in fedora source RPM it is:</h5>
<pre>[root@b008-02 SOURCES]# grep enable-extensions /root/rpmbuild/SOURCES/thunderbird-mozconfig
ac_add_options --enable-extensions=pref
</pre>
<h5 name="AutoConfig_Option_and_LDAP_Support_in_Thunderbird_1.5.x">It seems worse this time , as even after applying those compilation options mentioned above, I now get the following error message while stating thunderbird with autoconfig (all.js having pref('general.config.filename','thunderbird.cfg'); )</h5>
<p>and thunderbird.cfg calling getLDAP* functions to retrieve cm and mail address of the current user.</p>
<pre>Netscape.cfg/AutoConfig failed. Please contact your system administrator.
 Error: getLDAPAttibutes failed: [Exception... "Component returned failure
code: 0xc1f30001 (NS_ERROR_NOT_INITIALIZED) [nsILDAPURL.spec]"  nsresult:
"0xc1f30001 (NS_ERROR_NOT_INITIALIZED)"  location: "JS frame ::
file:////usr/lib/thunderbird-3.0b2/defaults/autoconfig/prefcalls.js ::
getLDAPAttributes :: line 174"  data: no]
</pre>
<h5 name="AutoConfig_Option_and_LDAP_Support_in_Thunderbird_1.5.x">bug <a class=" link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=295329" rel="freelink">https://bugzilla.mozilla.org/show_bug.cgi?id=295329</a> had been re-opened .</h5>
<p> </p>
<h5 name="AutoConfig_Option_and_LDAP_Support_in_Thunderbird_1.5.x">AutoConfig Option and LDAP Support in Thunderbird 1.5.x</h5>
<p>Fortunately, AutoConfig is now part of Thunderbird default packages. <code>MOZ_LDAP_XPCOM=1</code> and <code>MOZ_EXTENSIONS_DEFAULT="wallet spellcheck xmlextras pref webservices universalcharset auth"</code> are now present in the default <code>configure</code> script. See {{ Bug("295329") }} for details.</p>
<h5 name="Add_the_AutoConfig_Option_for_Old_Thunderbird_1.0.x">Add the AutoConfig Option for Old Thunderbird 1.0.x</h5>
<p>By default, AutoConfig did not make part of the binaries distribution of Thunderbird (1.0.x). It was apparently supposed to increase the load of the binary for a feature not used by lots of individuals. However for enterprise deployment, it is vital! So we needed to recompile Thunderbird with AutoConfig support, it's just a matter of adding <code>--enable-extensions=pref</code> in <code>mozconfig</code> file.</p>
<p>On my Fedora Core 3 system, I took the Thunderbird source package <code>thunderbird-1.0.2-1.3.3.src.rpm</code> installed it (<code>rpm -i</code>) then modified <code>/usr/src/redhat/SOURCES/thunderbird-mozconfig</code> by adding:</p>
<pre>ac_add_options --enable-extensions=pref
</pre>
<p>Compile and install:</p>
<pre>$ rpmbuild -ba /usr/src/redhat/SPECS/thunderbird.spec
$ rpm -Uvh /usr/src/redhat/RPMS/i386/thunderbird-1.0.2-1.3.3.i386.rpm
</pre>
<p>After instillation, AutoConfig is finally back here:</p>
<pre>$ rpm -ql thunderbird | grep autoconfig
/usr/lib/thunderbird-1.0.2/chrome/en-US/locale/autoconfig
/usr/lib/thunderbird-1.0.2/components/autoconfig.xpt
/usr/lib/thunderbird-1.0.2/components/libautoconfig.so
/usr/lib/thunderbird-1.0.2/defaults/autoconfig
/usr/lib/thunderbird-1.0.2/defaults/autoconfig/platform.js
/usr/lib/thunderbird-1.0.2/defaults/autoconfig/prefcalls.js
</pre>
<h4 name="Configure_AutoConfig">Configure AutoConfig</h4>
<p>Two directives ask Thunderbird to use AutoConfig at startup:</p>
<pre>[root@b008-02 /usr/lib/thunderbird-1.5]
$tail -2 greprefs/all.js
pref("general.config.obscure_value", 0); // for MCD .cfg files
pref('general.config.filename', 'thunderbird.cfg'); // for MCD .cfg files
</pre>
<p>The first one just tells us that we won't encode the file (no more rotary 13 or 7... :-), the second one is the name of the file to be read: <code>/usr/lib/thunderbird-1.5/thunderbird.cfg</code>.</p>
<h4 name="AutoConfig_Directives">AutoConfig Directives</h4>
<p>Here we want to set users central mail preferences: Create one account from their login name, get their email address from an LDAP request and set the enterprise IMAP and SMTP servers. Hence, when working on multiuser workstations, each person gets automatically Thunderbird configured for himself.</p>
<h5 name="thunderbird.cfg">thunderbird.cfg</h5>
<p>Here's the complete file, first we get the user login name from environment variables, then configure the LDAP address book, create an email account, and configure IMAP and SMTP:</p>
<pre>[root@b008-02 /usr/lib/thunderbird-1.5]
$ cat thunderbird.cfg
//put everything in a try/catch
try {

// 1) env variables
if(getenv("USER") != "") {
  // *NIX settings
  var env_user = getenv("USER");
  var env_home = getenv("HOME");
} else {
  // Windows settings
  var env_user = getenv("USERNAME");
  var env_home = getenv("HOMEPATH");
}
var env_mozdebug= getenv("MOZILLA_DEBUG");
// var env_user = prompt("indiquez votre login", toto);

// 2) lock general preferences
//LDAP address book
lockPref("ldap_2.prefs_migrated", true);
lockPref("ldap_2.servers.LDAPINT.auth.savePassword", true);
lockPref("ldap_2.servers.LDAPINT.description", "LDAP INT");
lockPref("ldap_2.servers.LDAPINT.filename", "abook-1.mab");
lockPref("ldap_2.servers.LDAPINT.uri", "ldap://ldap1.int-evry.Fr:389/ou=people,dc=int-evry,dc=fr??sub");
lockPref("ldap_2.servers.history.filename", "history.mab");
lockPref("ldap_2.servers.history.replication.lastChangeNumber", 0);
lockPref("ldap_2.servers.pab.filename", "abook.mab");
lockPref("ldap_2.servers.pab.replication.lastChangeNumber", 0);

//Account
lockPref("mail.account.account1.server", "server1");
lockPref("mail.account.account2.identities", "id1");
lockPref("mail.account.account2.server", "server2");
lockPref("mail.accountmanager.accounts", "account1,account2");
lockPref("mail.accountmanager.defaultaccount", "account2");
lockPref("mail.accountmanager.localfoldersserver", "server1");
lockPref("mail.identity.id1.directoryServer", "ldap_2.servers.LDAPINT");
lockPref("mail.identity.id1.draft_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Drafts");
lockPref("mail.identity.id1.drafts_folder_picker_mode", "0");
lockPref("mail.identity.id1.fcc_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Sent");
lockPref("mail.identity.id1.fcc_folder_picker_mode", "0");
lockPref("mail.identity.id1.organization", "INT Evry France");
lockPref("mail.identity.id1.overrideGlobal_Pref", true);
lockPref("mail.identity.id1.reply_to", "");

//IMAP
lockPref("mail.server.server2.hostname", "imap-int.int-evry.fr");
lockPref("mail.server.server2.isSecure", true);
lockPref("mail.server.server2.login_at_startup", true);
lockPref("mail.server.server2.max_cached_connections", 5);
//lockPref("mail.server.server2.name", "jehan.procaccia@int-evry.fr");
lockPref("mail.server.server2.type", "imap");
lockPref("mail.server.server2.userName", env_user);

//SMTP
lockPref("mail.identity.id1.smtpServer", "smtp1");
lockPref("mail.identity.id1.stationery_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Templates");
lockPref("mail.identity.id1.tmpl_folder_picker_mode", "0");
lockPref("mail.identity.id1.valid", true);

//SMTP general
lockPref("mail.smtp.defaultserver", "smtp1");
lockPref("mail.smtpserver.smtp1.auth_method", 0);
lockPref("mail.smtpserver.smtp1.hostname", "smtp-int.int-evry.fr");
lockPref("mail.smtpserver.smtp1.port", 25);
lockPref("mail.smtpserver.smtp1.try_ssl", 0);
lockPref("mail.smtpserver.smtp1.username", "");
lockPref("mail.smtpservers", "smtp1");
lockPref("mail.startup.enabledMailCheckOnce", true);
lockPref("mailnews.quotingPrefs.version", 1);
lockPref("mailnews.ui.threadpane.version", 5);

/* 3) define here (because if set after "4)" below it doesn't work!) processLDAPValues which is eventually called by getLDAPAttributes() just below,
 check getLDAPAttributes() code from $MOZILLA_HOME/defaults/autoconfig/prefcalls.js to see the inside call to "user defined" processLDAPValues
*/
function processLDAPValues(values) {
  if(values) {
    // set the global var with the values returned from the LDAP query
    ldap_values = values;
    var uid = getLDAPValue(values, "uid");
    var cn = getLDAPValue(values, "cn");
    var mail = getLDAPValue(values, "mail");
    var URL = getLDAPValue(values, "labeledURI");

// Those LDAP variables are only available in this processLDAPValues context!
// so we set the preferences that need them here.
lockPref("mail.identity.id1.useremail", mail);
lockPref("mail.server.server2.name", mail);
lockPref("mail.identity.id1.fullName", cn);
//Debug with popup error messages doesn't work anymore :-( !!
var env_mozdebug= getenv("MOZILLA_DEBUG");
if (env_mozdebug) {displayError("NO ERROR, just a debug, cn =" + cn + " and mail = " + mail); }
    }
  }
// 4) Call LDAP servers to get LDAP Attributes (mail &amp; cn), this will finally call processLDAPValues, "3)" just above.
  getLDAPAttributes("ldap2.int-evry.fr","ou=people,dc=int-evry,dc=fr","uid=" + env_user,"uid,cn,mail,labeledURI");

// Close the try, and call the catch()
} catch(e) {
  displayError("lockedPref", e);
}
</pre>
<h5 name="Test_AutoConfig">Test AutoConfig</h5>
<h6 name="Debug">Debug</h6>
<p>To check that our AutoConfig works fine, we just set to env variable to check the read of <code>thunderbird.cfg</code> file:</p>
<pre>$ export NSPR_LOG_MODULES=MCD:5
$ export NSPR_LOG_FILE=/tmp/thunderbird-log.txt
</pre>
<p>When Thunderbird has started, you should read:</p>
<pre> $ cat /tmp/thunderbird-log.txt
-1209403040[808a788]: general.config.filename = thunderbird.cfg
-1209403040[808a788]: evaluating .cfg file thunderbird.cfg with obscureValue 0
</pre>
<h6 name="Clean">Clean</h6>
<p>Then, to be sure to start with a fresh Thunderbird account, don't do this if you already have one and want to preserve your emails  and preferences!</p>
<pre>$ rm -rf ~/.thunderbird
</pre>
<h6 name="Start_It">Start It</h6>
<pre>$ thunderbird
</pre>
<p>If Thunderbird ask you to import your profile from Netscape/Mozilla depending on you mail client history, don't import anything, to check the AutoConfig job alone!</p>
<p>That should work, just restart the process by setting a different <code>USER</code> variable (<code>USER=procacci</code>, <code>USER=test</code> etc... anyone in your LDAP directory...) to check multiuser AutoConfig.</p>
<h4 name="Bugs_Reports_Related">Bugs Reports Related</h4>
<p>For the record, for old 1.0.x releases...</p>
<h5 name="Unwanted_White_Space_Reappeared">Unwanted White Space Reappeared</h5>
<p>Unfortunately the 'blank space bug' has reappeared in Thunderbird 1.0.2. See {{ Bug("229271") }}. Although it was corrected in Mozilla mainstream: <code>mozilla/extensions/pref/autoconfig/src/nsLDAPSyncQuery.cpp 1.7.2.1</code> by late 2004, it is still present in Thunderbird 1.0.2 at least :-(, so I applied the workaround I proposed in that bug report (<code>start_pos += 1;</code>).</p>
<h4 name="Thunderbird_2.x_beta_2">Thunderbird 2.x beta 2</h4>
<p>Recently (2007/03/21) I've tested with thunderbird 2 beta 2 (2007/01/16) to check if autoconfig + ldap is still supported . Apprently it's OK . Autonfig API is there, ldap call works fine, good !.</p>
<p>My tests were on Windows Vista, and I noticed at least one difference, it is that Paths changed; now the profile is in (for my procacci user sample): C:\Users\procacci\AppData\Roaming\Thunderbird\Profiles\v6we4uku.default</p>
<p><img alt="Vista profile location" class="internal" src="/@api/deki/files/381/=TB-vista-pref-location.jpg"></p>
<p>Start in debug mode in Comand Line Interface:</p>
<p><img alt="Start in debug Comand Line Interface" class="internal" src="/@api/deki/files/380/=TB-vista-MCD-test-cli.jpg"></p>
<p> </p>
<h4>Debug with displayError()</h4>
<p> </p>
<p>Here's the result, I used the displayError() method ( not the best way :-( see {{ Bug("206294") }} ) to show environment and ldap variables in order to check that it worked fine. Just setting MOZILLA_DEBUG=1 (see js code in thunderbird.cfg) allow that message to appear , it's very useful in debuging context ...</p>
<p><img alt="TB-vista-MCD-debug-msg.jpg" class="internal default" src="/@api/deki/files/4816/=TB-vista-MCD-debug-msg.jpg"></p>
<p>The displayError() function does not work properly in Thunderbird 3.1: See <a class=" link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=502597#c34" rel="freelink">https://bugzilla.mozilla.org/show_bu...?id=502597#c34</a></p>
<p>A usable workaround is placing the following code at the top of your autoconfig script:<code><br>
</code></p>
<pre><code>// Enable logging.<br>pref("MCD.logging.console", "All");<br>pref("MCD.logging.dump", "All");<br>Components.utils.import("resource:///modules/gloda/log4moz.js");<br>var log = Log4Moz.getConfiguredLogger("MCD");<br><br>// Enable alerts.<br>var alerts = Components.classes["@mozilla.org/alerts-service;1"]<br>             .getService(Components.interfaces.nsIAlertsService);<br><br>// displayError() is broken. Let's override it.<br>function displayError(title, msg) {<br>    log.debug(title + ": " + msg);<br>    alerts.showAlertNotification("chrome://branding/content/icon48.png", title, msg);<br>}</code>
</pre>
<h3 name="Firefox">Firefox</h3>
<p>It's the same principle as above for Thunderbird. Binary distributions now include support for AutoConfig (pref extension!) but unfortunately not for LDAP calls :-( (cf. <code>MOZ_LDAP_XPCOM=1</code>). It is not vital in Firefox as it is for us in Thunderbird (need to get the cn and email address to set email account, which are not available by default in the environment variables). However I could be useful to get LDAP values for Firefox extra config, for example to set the default home page to the <code>labeledURI</code> LDAP attribute of the user.</p>
<h4 name="AutoConfig_.28pref.29_and_LDAP_Support_in_Packages">AutoConfig (pref) and LDAP Support in Packages</h4>
<h5 name="Add_LDAP_Support_in_Firefox_1.5">Add LDAP Support in Firefox 1.5</h5>
<p>A least from Firefox 1.5, AutoConfig is compiled by default (cf. browser, <code>MOZ_EXTENSIONS_DEFAULT="pref..."</code>) but not LDAP (<code>MOZ_LDAP_XPCOM=1</code>). You need to recompile the package to get it, cf. {{ Bug("295329") }}.</p>
<h5 name="Add_AutoConfig_and_LDAP_Support_in_Firefox_1.0.x">Add AutoConfig and LDAP Support in Firefox 1.0.x</h5>
<p>Add pref extension (<code>--enable-extensions=pref</code>) and remove <code>--disable-ldap</code> from <code>mozconfig</code> file. One can check how Firefox has been compiled by opening <code>about:buildconfig</code> (don't know the equivalent for Thunderbird! how as it been compiled?)</p>
<pre>about:buildconfig

Build platform
target
i686-pc-linux-gnu

Build tools
Compiler Version Compiler flags
gcc gcc version 3.4.3 20050227 (Red Hat 3.4.3-22.fc3) -Wall -W -Wno-unused -Wpointer-arith -Wcast-align -Wno-long-long -pedantic -pthread -pipe
c++ gcc version 3.4.3 20050227 (Red Hat 3.4.3-22.fc3) -fno-rtti -fno-exceptions -Wall -Wconversion -Wpointer-arith -Wcast-align -Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -Wno-long-long -pedantic -fshort-wchar -pthread -pipe -I/usr/X11R6/include

Configure arguments
--disable-mailnews --enable-extensions=cookie,xml-rpc,xmlextras,pref,transformiix,universalchardet,webservices,inspector,gnomevfs,negotiateauth --enable-crypto --disable-composer --enable-single-profile --disable-profilesharing --with-system-jpeg --with-system-zlib --with-system-png --with-pthreads --disable-tests --disable-jsd --disable-installer '--enable-optimize=-Os -g -pipe -m32 -march=i386 -mtune=pentium4' --enable-xft --enable-xinerama --enable-default-toolkit=gtk2 --enable-official-branding --disable-xprint --disable-strip --enable-pango 
</pre>
<h4 name="all.js">all.js</h4>
<pre>[root@b008-02 /usr/lib/firefox-1.5.0.2]
$tail -4 greprefs/all.js
// AutoConfig jehan
pref('general.config.obscure_value', 0);
pref('general.config.filename', 'firefox.cfg');
</pre>
<h4 name="firefox.cfg">firefox.cfg</h4>
<p>This file will set the browser home page to the <code>labeledURI</code> page defined in the user's LDAP entry, hence it checks that both AutoConfig + LDAP work fine.</p>
<pre>[root@b008-02 /usr/lib/firefox-1.5.0.2]
$cat firefox.cfg
//put everything in a try/catch
try {

//Privacy &amp; Security
defaultPref("signon.rememberSignons", false);

// 1) env variables
if(getenv("USER") != "") {
  // *NIX settings
  var env_user = getenv("USER");
  var env_home = getenv("HOME");
} else {
  // Windows settings
  var env_user = getenv("USERNAME");
  var env_home = getenv("HOMEPATH");
}
var env_mozdebug = getenv("MOZILLA_DEBUG");

/* 2) define here (because if set after "3)" below it doesn't work!) processLDAPValues which is eventually called by getLDAPAttributes() just below,
 check getLDAPAttributes() code from $MOZILLA_HOME/defaults/autoconfig/prefcalls.js to see the inside call to "user defined" processLDAPValues
*/
function processLDAPValues(values) {
  if(values) {
    // set the global var with the values returned from the LDAP query
    ldap_values = values;
    var uid = getLDAPValue(values, "uid");
    var cn = getLDAPValue(values, "cn");
    var mail = getLDAPValue(values, "mail");
    var URL = getLDAPValue(values, "labeledURI");
//Debug with popup error messages doesn't work anymore :-( !!
var env_mozdebug= getenv("MOZILLA_DEBUG");
if (env_mozdebug) {displayError("NO ERROR, just a debug, cn =" + cn + " and mail = " + mail + ", labeledURI= " + URL); }
lockPref("browser.startup.homepage", URL);
    }
  }

//lockPref("browser.startup.homepage", "http://www.renater.fr/");
// 3) Call LDAP servers to get LDAP Attributes (mail &amp; cn), this will finally call processLDAPValues, "2)" just above.
  getLDAPAttributes("ldap2.int-evry.fr","ou=people,dc=int-evry,dc=fr","uid=" + env_user,"uid,cn,mail,labeledURI");

// Close the try, and call the catch()
} catch(e) {displayError("lockedPref", e);}
</pre>
<h4 name="Debug_2">Debug</h4>
<p>If you set a username and the <code>MOZILLA_DEBUG</code> variable (<code>$export MOZILLA_DEBUG=1; export USER=procacci</code>), then the <code>displayError()</code> will show you this popup:</p>
<p><img alt="Image:mozilla-autoconfig-en001.png" class="internal" src="/@api/deki/files/776/=Mozilla-autoconfig-en001.png"></p>
<p>That's a popup titled as "error", but it's just a debug tool for me as I didn't find any other way to popup information. cf. {{ Bug("206294") }}:</p>
<pre> ------- Comment #14 From Daniel Wang 2003-11-06 09:06 PDT [reply] -------

Jehan Procaccia, you need to change 5.8 to reflect what I said in comment 21.

Preference files and config files are special JavaScript files with limited scopes. They
can only call the get/set pref/env methods and have no access to other objects
(need to investigate what exactly are allowed). alert() is a method of the
Window object.
</pre>
<p>cf. also related post in Newsgroups: mozilla.dev.tech.js-engine</p>
<pre>Date: Wed, 17 May 2006 19:06:28 +0200
From: jehan procaccia &lt;jehan.procaccia@int-evry.fr&gt;

Newsgroups: mozilla.dev.tech.js-engine
Subject: scope of js file functions in Frefox/Thunderbird AutoConfig context
</pre>
<h4 name="Firefox_2.x">Firefox 2.x</h4>
<p>Recently (2007/03/20), I've tested autoconfig support in Firefox 2.0.0.2 on a Linux fedora. Autoconfig works fine, but ldap calls are still unavailable in Firefox (as it was the case in Firefox 1.x, but fortunatly not the case for Thunderbird !). That "bug" report is then still up to date!: {{ Bug("295329") }}</p>
<pre>$ cat /etc/redhat-release 
Fedora Core release 6 (Zod)

$ rpm -qi firefox
Name        : firefox                      Relocations: (not relocatable)
Version     : 2.0.0.2                           Vendor: Remi Collet
Release     : 1.fc6.remi                    Build Date: Sat 24 Feb 2007 01:45:37 PM CET
Install Date: Tue 20 Mar 2007 02:47:27 PM CET      Build Host: remi.famillecollet.com
Packager    : http://remi.collet.free.fr/
</pre>
<h3 name="References">References</h3>
<h4 name="Other_Documents_About_AutoConfig">Other Documents About AutoConfig</h4>
<p><a class=" external" href="http://mit.edu/~firefox/www/maintainers/autoconfig.html" rel="freelink">http://mit.edu/~firefox/www/maintain...utoconfig.html</a></p>
<p><a class=" external" href="http://www.alain.knaff.lu/howto/MozillaCustomization/index.html" rel="freelink">http://www.alain.knaff.lu/howto/Mozi...ion/index.html</a><br>
<a class=" external" href="http://thegoldenear.org/toolbox/windows/docs/mozilla-pre-config.html" rel="freelink">http://thegoldenear.org/toolbox/wind...re-config.html</a><br>
<a class=" external" href="http://ilias.ca/blog/2005/03/locking-mozilla-firefox-settings/" rel="freelink">http://ilias.ca/blog/2005/03/locking...efox-settings/</a></p>
<p>Compile on Windows:<br>
<a class=" external" href="http://forums.mozillazine.org/viewtopic.php?t=276014" rel="freelink">http://forums.mozillazine.org/viewtopic.php?t=276014</a></p>
<p><a class=" external" href="http://www.mozilla.org/community/developer-forums.html" rel="freelink">http://www.mozilla.org/community/dev...er-forums.html</a><br>
<a class=" external" href="http://forums.mozillazine.org/viewtopic.php?p=2090731&amp;highlight=autoconfig#2090731" rel="freelink">http://forums.mozillazine.org/viewto...config#2090731</a><br>
<a class=" external" href="http://forums.mozillazine.org/viewtopic.php?p=1354355&amp;highlight=autoconfig#1354355" rel="freelink">http://forums.mozillazine.org/viewto...config#1354355</a><br>
<a class=" external" href="http://forums.mozillazine.org/viewtopic.php?p=32783&amp;highlight=autoconfig#32783" rel="freelink">http://forums.mozillazine.org/viewto...toconfig#32783</a></p>
<h4 name="Related_Bugs">Related Bugs</h4>
<p>{{ Bug("295329") }}<br>
{{ Bug("222973") }}<br>
{{ Bug("225288") }}<br>
{{ Bug("178685") }}<br>
{{ Bug("272970") }}<br>
{{ Bug("206294") }}<br>
{{ Bug("302096") }}</p>
<p> </p>
<p> </p>
<h3 name="Old_Mozilla_1.x.2C_Possibly_Netscape_6.2F7">Thunderbird Comm-central_source_code_(Mercurial)</h3>
<p> </p>
<p>based on {{ Bug("295329") }} , since TB 3.0.X autoconfig doesn't work anymore.</p>
<p>according to the discussion in  <a class="external" href="http://groups.google.com/group/mozilla.dev.apps.thunderbird/browse_thread/thread/9b1962efdeb92f4e#" title="http://groups.google.com/group/mozilla.dev.apps.thunderbird/browse_thread/thread/9b1962efdeb92f4e#">mozilla.dev.apps.thunderbird </a>, change from CVS to Mercurial and recent changes to the nsLDAPURL code might have borken autoconfig . below we start to debug this by rebuilding a thunderbird from <a class="external" href="/En/Developer_Guide/Source_Code/Getting_comm-central" title="https://developer.mozilla.org/en/Comm-central_source_code_(Mercurial)">Comm-central-source-code (mercurial)</a> .</p>
<h4>Build</h4>
<h5>install mercurial tools</h5>
<pre>[root@b008-02 ~]# yum install mercurial

Installed:
  mercurial.i586 0:1.2.1-1.fc11
</pre>
<h5>check merge tools in</h5>
<pre>[root@b008-02 ~]# vim /etc/mercurial/hgrc.d/mergetools.rc</pre>
<h5> get the source comm-central</h5>
<pre>[root@b008-02 Moz]# time hg clone http://hg.mozilla.org/comm-central/ commsrc
requesting all changes
adding changesets
adding manifests
adding file changes
added 2975 changesets with 16793 changes to 7117 files (+3 heads)
updating working directory
5644 files updated, 0 files merged, 0 files removed, 0 files unresolved

real    0m40.771s
user    0m9.284s
sys     0m1.304s
 </pre>
<pre>[root@b008-02 commsrc]# python client.py checkout
Executing command: ['hg', 'pull', '-R', './.', '-r', 'tip']
pulling from http://hg.mozilla.org/comm-central/
searching for changes
no changes found
Executing command: ['hg', 'update', '-r', 'default', '-R', './.']
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
Updated to revision c10119db13cad9797b05750bfe18a57261a88922.
Executing command: ['hg', 'clone', 'http://hg.mozilla.org/releases/mozilla-1.9.1/', './mozilla']
requesting all changes
adding changesets
...
Executing command: ['hg', 'update', '-r', 'default', '-R', './mozilla/extensions/inspector']
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
Updated to revision 51c6d483a4c15a657df18540219bd0201896c6f2.
CVS checkout begin: 2009-06-30 10:28:31 UTC
Executing command: ['cvs', '-d', ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot', '-q', 'checkout', '-P', '-r', 'LDAPCSDK_6_0_6B_MOZILLA_RTM', '-d', 'c-sdk', 'mozilla/directory/c-sdk']
U c-sdk/.cvsignore
U c-sdk/Makefile.in
...
updating working directory
163 files updated, 0 files merged, 0 files removed, 0 files unresolved
Executing command: ['hg', 'update', '-r', 'default', '-R', './mozilla/extensions/venkman']
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
Updated to revision 06ea5135b7f3c9a639c483183ceb9802abee621b.
</pre>
<h4> Build Thunderbird</h4>
<h5>prepare compile options</h5>
<pre>[root@b008-02 commsrc]# cp ./mozilla/browser/config/mozconfig .mozconfig
[root@b008-02 commsrc]# cat .mozconfig 
mk_add_options AUTOCONF=autoconf-2.13
ac_add_options --enable-application=mail
ac_add_options --prefix="/usr/local/thunderbirdDebug"
ac_add_options --libdir="/usr/local/thunderbirdDebugLibs"
ac_add_options --enable-extensions=pref
ac_add_options --enable-static
ac_add_options --disable-shared
ac_add_options --disable-crashreporter

</pre>
<p>the option --disable-crashreporter is necessary if you get compile error at this stage of the build</p>
<pre class="bz_comment_text">gmake[7]: Entering directory
`/usr/local/Moz2/commsrc/mozilla/toolkit/crashreporter/google-breakpad/src/common/linux'
dump_symbols.cc
</pre>
<h5>Build</h5>
<p>then start building</p>
<pre class="eval">[root@b008-02 commsrc]# time make -f client.mk build
rm -f ../../mozilla/dist/bin/TestCookie
if test -f ../../mozilla/dist/bin/TestTArray; 
then cp ../../mozilla/dist/bin/TestTArray ../../mozilla/dist/bin/TestCookie; fi;
gmake[5]: quittant le répertoire « /usr/local/Moz/commsrc/mail/app »
gmake[4]: quittant le répertoire « /usr/local/Moz/commsrc/mail »
gmake[3]: quittant le répertoire « /usr/local/Moz/commsrc »
gmake[2]: quittant le répertoire « /usr/local/Moz/commsrc »
make[1]: quittant le répertoire « /usr/local/Moz/commsrc »

real    23m33.845s
user    20m34.356s
sys     1m49.752s

</pre>
<h5>Install</h5>
<p>Then install (--enable-static and --disable-shared necessary in .mozconfig !)</p>
<pre>[root@b008-02 commsrc]# make install -n
/usr/bin/gmake -C mail/installer install
gmake[1]: entrant dans le répertoire « /usr/local/Moz/commsrc/mail/installer »
rm -rf ../../mozilla/dist/thunderbird ../../mozilla/dist/thunderbird-3.0b3pre.en-US.linux-i686.tar ../../mozilla/dist/thunderbird-3.0b3pre.en-US.linux-i686.dmg stage-package 
echo "Creating package directory..."
...
/usr/local/Moz/commsrc/mozilla/config/nsinstall -D /usr/local/thunderbirdDebug/bin
rm -f -f /usr/local/thunderbirdDebug/bin/thunderbird
ln -s /usr/local/thunderbirdDebugLibs/thunderbird-3.0b3pre/thunderbird /usr/local/thunderbirdDebug/bin
gmake[1]: quittant le répertoire « /usr/local/Moz/commsrc/mail/installer »

[root@b008-02 commsrc]# ls -l /usr/local/thunderbirdDebugLibs/thunderbird-3.0b3pre/ | grep ^d
drwxr-xr-x 3 root root     4096 juil.  2 10:45 chrome
drwxr-xr-x 2 root root    12288 juil.  2 10:45 components
drwxr-xr-x 6 root root     4096 juil.  1 10:24 defaults
drwxr-xr-x 2 root root     4096 juil.  2 10:45 dictionaries
drwxr-xr-x 3 root root     4096 juil.  1 10:24 extensions
drwxr-xr-x 2 root root     4096 juil.  2 10:27 greprefs
drwxr-xr-x 2 root root     4096 juil.  1 10:18 icons
drwxr-xr-x 3 root root     4096 juil.  2 10:45 isp
drwxr-xr-x 4 root root     4096 juil.  2 10:45 modules
drwxr-xr-x 2 root root     4096 juil.  2 10:45 OutTestData
drwxr-xr-x 6 root root     4096 juil.  2 10:45 res
[root@b008-02 commsrc]# ls -l /usr/local/thunderbirdDebug/bin/
total 4
lrwxrwxrwx 1 root root 64 juil.  2 10:45 thunderbird -&gt; /usr/local/thunderbirdDebugLibs/thunderbird-3.0b3pre/thunderbird

[root@b008-02 thunderbirdDebugLibs]# find /usr/local/thunderbirdDebugLibs/ -name prefcalls.js
/usr/local/thunderbirdDebugLibs/thunderbird-3.0b3pre/defaults/autoconfig/prefcalls.js

</pre>
<h3 name="Old_Mozilla_1.x.2C_Possibly_Netscape_6.2F7">Old Mozilla 1.x, Possibly Netscape 6/7</h3>
<p>The following is for the record... it also contains an interesting feature that I did not use anymore -&gt; AutoConfig from a web server!</p>
<h4 name="Changes">Changes</h4>
<p>Between 2002 and 2003, we needed to upgrade the old Netscape 4.x (4.79) version to Mozilla 1.x (1.4), and now (2004-2005) Mozilla 1.7. The AutoConfiguration subsystem is quite the same as described the section on 'old' Netscape 4.x, but also slightly different.</p>
<h4 name="Mozilla_New_Features_in_Regard_to_Netscape">Mozilla New Features in Regard to Netscape</h4>
<p>In Mozilla, we don't use the convert function from Netscape 4.5 CCK anymore, but <code>moz-byteshift.pl</code> Perl script, to encode <code>mozilla.cfg</code> file.</p>
<p>The use of the <code>getLDAPAttributes()</code> function by calling inside itself the <code>processLDAPValues()</code> as a user defined function (see <code>prefcalls.js</code>) forces us to slightly change these calls in our original web CGI JavaScript (here <code>mci-mozilla-glob-prefs-tux.cgi</code>). The variables generated (<code>mail</code>, <code>cn</code>, <code>uid</code>) are defined only inside the <code>processLDAPValues()</code> function, that explains why lockPref related to these variables are located inside that function. I also couldn't use the <code>alert()</code> function anymore, so I changed to <code>displayerror()</code> function!</p>
<h4 name="Locating_The_File_on_a_Web_Server">Locating The File on a Web Server</h4>
<p>That was the case in the Netscape 4.x description below, however, at first it was a hard thing to do in Mozilla, cf. {{ Bug("206294") }}. So now you only need to create a small encoded <code>cfg</code> file making a call to a web located CGI script which will actually generate the JavaScript configuration directives to the Mozilla client. Hence you can change all of your Mozilla clients preferences by simply modifying a single file on a web server, great!</p>
<h5 name="Call_File">Call File</h5>
<p>This file calls a CGI on a web server, the CGI generating the JavaScript code that will set preferences. Here the <code>vendor</code> name (<code>mci-mozilla-web-tux</code>) must match the name of the <code>cfg</code> file (<code>mci-mozilla-web-tux.cfg</code>).</p>
<pre>$ cat mci-mozilla-web-tux.js
lockPref("general.config.vendor", "mci-mozilla-web-tux");
lockPref("autoadmin.global_config_url","http://corbeau.int-evry.fr/cgi-bin/mci-mozilla-glob-prefs-tux.cgi");
</pre>
<h4 name="Encoding_mozilla.js_File_to_mozilla.cfg">Encoding mozilla.js File to mozilla.cfg</h4>
<p>Just use the <code>moz-byteshift.pl</code> Perl script which for Mozilla 1.x and Netscape 6/7 uses a shift of 13, in Netscape 4.x it was 7.</p>
<pre>$ more moz-byteshift.pl
#!/usr/bin/perl
 
# Byte-shifting program for Mozilla's netscape.cfg files
 
# Old Netscape 4.x uses a byte-shift of 7
#   To decode: moz-byteshift.pl -s -7 &lt;netscape.cfg &gt;netscape.cfg.txt
#   To encode: moz-byteshift.pl -s  7 &lt;netscape.cfg.txt &gt;netscape.cfg
 
# Mozilla uses a byte-shift of 13
#   To decode: moz-byteshift.pl -s -13 &lt;netscape.cfg &gt;netscape.cfg.txt
#   To encode: moz-byteshift.pl -s  13 &lt;netscape.cfg.txt &gt;netscape.cfg
 
# To activate the netscape.cfg file, place the encoded netscape.cfg file
# into your C:\Program Files\mozilla.org\Mozilla directory.
# Then add the following line to your
# C:\Program Files\mozilla.org\Mozilla\defaults\pref\all.js file:
# pref("general.config.filename", "mozilla.cfg");
...

$ ./moz-byteshift.pl -s 13 &lt; mci-mozilla-web-tux.js &gt; mci-mozilla-web-tux.cfg
</pre>
<h4 name="Location_of_mci-mozilla-web-tux.cfg">Location of mci-mozilla-web-tux.cfg</h4>
<p>The location of the <code>netscape.cfg</code> (here renamed to <code>mci-mozilla-web-tux.cfg</code>) and the way to call it is different from the old Netscape 4.x. It's location is in <code>MOZILLA_HOME ; c:\program files\mozilla.org\mozilla</code> in Windows, or <code>/usr/lib/mozilla-1.7-3/</code> in Linux Fedora.</p>
<h4 name="Call_to_mci-mozilla-web-tux.cfg">Call to mci-mozilla-web-tux.cfg</h4>
<p>The way to call it is through <code>all.js</code> file by adding at the end:</p>
<pre>$ tail -2 /usr/lib/mozilla-1.7-3/defaults/pref/all.js
pref("general.config.filename", "mci-mozilla-web-tux.cfg");
pref("general.config.vendor", "mci-mozilla-web-tux");
</pre>
<h4 name="Web_Base_CGI_JavaScript_Preferences_Generator_File">Web Base CGI JavaScript Preferences Generator File</h4>
<pre>[root@corbeau /var/www/cgi-bin]
$ cat mci-mozilla-glob-prefs-tux.cgi
#!/usr/bin/perl -w

print("Content-type: application/javascript-config\n\n");
$page = &lt;&lt;"EOP";
 
try {
  var env_user = getenv("USER");
  var env_home = getenv("HOME");
  var env_mozdebug= getenv("MOZILLA_DEBUG");
  function processLDAPValues(values) {
    var uid = getLDAPValue(values, "uid");
    var cn = getLDAPValue(values, "cn");
    var mail = getLDAPValue(values, "mail");
    lockPref("mail.server.server1.name", mail);
    lockPref("mail.identity.id1.fullName", cn);
    lockPref("mail.identity.id1.useremail", mail);

  if (env_mozdebug) {
    displayError("debug mozilla.cfg v2.8", "mail:" + mail + "uid:" + uid + "cn" + cn + "user:" + env_user);
  } 
}
//BROWSER
/*defaultPref("startup.homepage_override_url", "http://www.int-evry.fr/mci/user/");
lockPref("browser.startup.homepage_override", true);
lockPref("browser.startup.page", 1);
defaultPref("browser.startup.homepage", "http://www.int-evry.fr/mci/user/");
*/
lockPref("browser.startup.homepage", "http://www.int-evry.fr/mci/user/");
lockPref("browser.startup.homepage_override", true);
lockPref("general.config.vendor", "mci-mozilla-web-tux");
lockPref("startup.homepage_override_url", "http://www.int-evry.fr/mci/user/");
lockPref("browser.cache.disk.capacity", 0);
lockPref("network.cookie.cookieBehavior", 0);
lockPref("network.proxy.autoconfig_url", "http://www.int-evry.fr/local/config.proxy");
lockPref("network.proxy.type", 2);
 
//Account
lockPref("mail.account.account1.identities", "id1");
lockPref("mail.account.account1.server", "server1");
lockPref("mail.account.account2.server", "server2");
lockPref("mail.account.account3.server", "server3");
lockPref("mail.accountmanager.accounts", "account1,account2,account3");
lockPref("mail.accountmanager.defaultaccount", "account1");
 
//IMAP
lockPref("mail.server.server1.hostname", "imap-int.int-evry.fr");
lockPref("mail.server.server1.type", "imap");
lockPref("mail.server.server1.login_at_startup", true);
lockPref("mail.identity.id1.draft_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Drafts");
lockPref("mail.identity.id1.drafts_folder_picker_mode", "0");
lockPref("mail.identity.id1.fcc_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Sent");
lockPref("mail.identity.id1.fcc_folder_picker_mode", "0");
lockPref("mail.identity.id1.stationery_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Templates");
lockPref("mail.identity.id1.tmpl_folder_picker_mode", "0");
lockPref("mail.identity.id1.valid", true);
lockPref("mail.identity.id1.overrideGlobal_Pref", true);
lockPref("mail.server.server1.download_on_biff", true);
lockPref("mail.server.server1.login_at_startup", true);
lockPref("mail.server.server1.userName", env_user);
lockPref("mail.server.server1.delete_model", 0);
 
//SMTP
lockPref("mail.identity.id1.smtpServer", "smtp1");
defaultPref("mail.smtpserver.smtp1.auth_method", 0);
lockPref("mail.smtpservers", "smtp1");
lockPref("mail.smtpservers", "smtp1");
lockPref("mail.smtp.defaultserver", "smtp1");
lockPref("mail.smtpserver.smtp1.hostname", "smtp-int.int-evry.fr");
lockPref("mail.identity.id1.organization", "INT Evry France");
lockPref("mail.startup.enabledMailCheckOnce", true);
lockPref("mail.ui.folderpane.version", 3);
lockPref("mailnews.ui.threadpane.version", 2);
 
//LDAP config
lockPref("mail.identity.id1.directoryServer", "ldap_2.servers.ldapint");
lockPref("ldap_2.prefs_migrated", true);
lockPref("ldap_2.servers.history.filename", "history.mab");
lockPref("ldap_2.servers.history.replication.lastChangeNumber", 0);
lockPref("ldap_2.servers.ldapint.auth.savePassword", true);
lockPref("ldap_2.servers.ldapint.description", "ldap-int");
lockPref("ldap_2.servers.ldapint.filename", "abook-1.mab");
lockPref("ldap_2.servers.ldapint.position", 3);
lockPref("ldap_2.servers.ldapint.uri", "ldap://ldap1.int-evry.fr:389/ou=people,dc=int-evry,dc=fr??sub");
lockPref("ldap_2.servers.pab.filename", "abook.mab");
lockPref("ldap_2.servers.pab.replication.lastChangeNumber", 0);
 
//News config
lockPref("mail.server.server3.hostname", "news.int-evry.fr");
lockPref("mail.server.server3.max_cached_connections", 2);
lockPref("mail.server.server3.name", "news.int-evry.fr");
lockPref("mail.server.server3.type", "nntp");
lockPref("mail.server.server3.userName", env_user);
 
//Call to ldap to get user's attribute.
getLDAPAttributes("ldap2.int-evry.fr", "ou=people,dc=int-evry,dc=fr", "uid=" +env_user, "uid,cn,mail");
 
} catch(e) {
  displayError("lockedPref", e);
}
 
EOP
print $page;
</pre>
<h4 name="Windows_Particularities">Windows Peculiarities</h4>
<p>Without web base CGI file, beware that in Windows, the original (before encoding) <code>mozilla.js</code> file must start with: <code>//BEGIN CE prefs </code>, if not you'll get "failed to read configuration file..." message, and Mozilla won't start :-(</p>
<p>In Windows environment variables like <code>USER</code> or <code>HOME</code>, are <code>USERNAME</code> and <code>HOMEPATH</code>, that's why we must create a different pair of configuration files (<code>cfg</code> and <code>cgi</code>) for both systems (Linux/Windows). Perhaps there's a way in JavaScript to detect operating system and hence use either <code>USER</code> or <code>USERNAME</code>, but I'm not that fluent in JavaScript, let me know if you know how...//</p>
<h5 name="Windows_Call_File">Windows Call File</h5>
<pre>$ cat mci-mozilla-web-win.js
lockPref("general.config.vendor", "mci-mozilla-web-win");
lockPref("autoadmin.global_config_url","http://corbeau.int-evry.fr/cgi-bin/mci-mozilla-glob-prefs-win.cgi");
</pre>
<h5 name="Windows_all.js_File">Windows all.js File</h5>
<p>To be encoded by <code>moz-byteshift.pl</code> as stated above...</p>
<pre>c:\type c:\program files\mozilla.org\mozilla\defaults\pref\all.js
pref("general.config.filename", "mci-mozilla-web-win.cfg");
pref("general.config.vendor", "mci-mozilla-web-win");
</pre>
<h5 name="Windows_CGI_file">Windows CGI file</h5>
<pre>$ cat mci-mozilla-glob-prefs-win.cgi
#!/usr/bin/perl -w

print("Content-type: application/javascript-config\n\n");
$page = &lt;&lt;"EOP";
 
try {
  var env_user = getenv("USERNAME");
  var env_home = getenv("HOMEPATH");
  var env_mozdebug= getenv("MOZILLA_DEBUG");
...
</pre>
<p>The rest of the file is identical to the Linux version, only the environment variables (var env_*) are different!</p>
<h4 name="Versions_Tested">Versions Tested</h4>
<p>This configuration was validated on Linux with Mozilla 1.4, 1.6 and 1.7, and on Windows with Mozilla 1.4, 1.5, 1.7.</p>
<h3 name="Debugging_-_Bugzilla">Debugging - Bugzilla</h3>
<h4 name="Run_Time_Messages">Run Time Messages</h4>
<p>Note: the presence of <code>var env_mozdebug=getenv("MOZILLA_DEBUG")</code>allows user to print debugging messages if <code>MOZILLA_DEBUG</code> is defined in either the shell for Unix (<code>export MOZILLA_DEBUG=1</code>) or in the <code>command.com</code> environment in Windows (<code>set MOZILLA_DEBUG=1</code>).</p>
<h4 name="Blank_Space_Bug">Blank Space Bug</h4>
<p>I noticed a problem which is due to be corrected in Mozilla 1.8 I think... Here's the report and workaround: {{ Bug("229271") }}. To fix, add the following:</p>
<pre>        start_pos += search_key.length;
//start 
        start_pos +=1;
//end
</pre>
<p>to function <code>getLDAPValue()</code> in <code>autoconfig/preffcalls.js</code>.</p>
<h4 name="Documentation">Documentation</h4>
<p>I also opened a report on the lack of documentation {{ Bug("178685") }} which led to the wonderful doc: <a class="external" href="http://web.archive.org/web/20050415163430/http://wangrepublic.org/daniel/mozilla/prefs/">http://wangrepublic.org/daniel/mozilla/prefs/</a></p>
<h4 name="defeultPref_for_Home_Page">defeultPref for Home Page</h4>
<p>I cannot set the home page with the <code>defaultPref</code> function, so that it is set by default, but still allows the user to change it! A bug is opened on this, see {{ Bug("272970") }}</p>
<h4 name="greprefs_Right_Access">greprefs Right Access</h4>
<p>Beware also on Linux that <code>MOZILLA_HOME/greprefs</code> directory is closed by default to users and then AutoConfig doesn't work properly, I've opened a bug on this: {{ Bug("270623") }}. The workaround is <code>chmod 755 greprefs</code>!</p>
<h4 name="CGI_Base_Config_File">CGI Base Config File</h4>
<p>There has been a issue about the use of <code>autoadmin.global_config_url</code>, see {{ Bug("206294") }}.</p>
<h3 name="Mail_Folders">Mail Folders</h3>
<p>Implementing that solution, we encounter difficulties with mail folder. Our first idea was to use local mail folders from home directory of the current user. In Unix that would have been <code>$HOME/nsmail/...</code>, in Windows it would have been a Samba mount of that same Unix path (ex: <code>U:\nsmail</code> ; with <code>U:</code> = Samba mount: <code>\\samba-server\%USERNAME</code>). Unfortunately file system writes and/or mail format differs between Windows and Unix, and folders soon become unreadable or even corrupted when read/written from one system to the other.</p>
<p>That's why we finally decided to use IMAP, and hence IMAP folders. By migrating from University of Washington IMAP server to Cyrus IMAP we also inherited some interesting features like quotas, share folders, ACL, mail only account (no need for <code>/etc/passwd</code> entry!) much better performances, etc...</p>
<h3 name="Reliability">Reliability</h3>
<h4 name="Fail-over_and_Uniqueness">Fail-over and Uniqueness</h4>
<p>A contribution from Roberto Aguilar gives the Mozilla AutoConfig JavaScript a way to search through different LDAP replicas in case one LDAP server is down.</p>
<p>It also allows users to use a single JavaScript for both systems (Linux and Windows) with a subtle <code>if... else</code> test on environment variables.</p>
<h4 name="LDAP_fail-over">LDAP fail-over</h4>
<p>Creating an array of possible running LDAP servers permits an LDAP fail-over, then a shuffle function allows us to randomly pick up a running LDAP server.</p>
<p>The shuffle function comes from here: <a class=" external" href="http://www.mickweb.com/javascript/arrays/pureshuffle.html" rel="freelink">http://www.mickweb.com/javascript/ar...reshuffle.html</a></p>
<p>Before publishing the code changes, please add this right before the shuffle function:</p>
<pre> /**
  * setup the shuffle method for an array, from Mickweb Script
  * Factory at:
  * http://www.mickweb.com/javascript/arrays/pureshuffle.html
  */
</pre>
<p>Here's how the LDAP fail-over works:</p>
<pre>// 2) setup multiple LDAP servers for fail-over
  var ldap_values;
  var ldap_servers = new Array('ldap2.int-evry.fr',
                      'ldap1.int-evry.fr',
                      'openldap.int-evry.fr'
                      );
  // shuffle function to randomize the server array
  // setup the shuffle method for an array
  Array.prototype.shuffle = function(times) {
    var i,j,t,l=this.length;
    while(times--) {
      with(Math) {
    i = floor(random()*l);
    j = floor(random()*l);
      }
      t       = this[i];
      this[i] = this[j];
      this[j] = t;
    }
    return this;
  }
 // mix up the LDAP servers so we don't hit the same one each time
  ldap_servers.shuffle(10);
....
// 4) Call LDAP servers to get LDAP Attributes (mail &amp; cn), this will finally call processLDAPValues, "3)" just above.
// Go through the LDAP replicas list
for(i = 0; i &lt; ldap_servers.length; i ++) {
// Search for attribute mail &amp; cn through LDAP servers where uid = $USER|$USERNAME
  getLDAPAttributes(ldap_servers[i],
       "ou=people,dc=int-evry,dc=fr",
       "uid=" + env_user,
       "uid,cn,mail");
    // If we catch a running LDAP server, exit the loop,
    if(ldap_values) {
      running_ldap_server = ldap_servers[i];
        // If $MOZILLA_DEBUG=1 display in a popup the running server
      if (env_mozdebug) {
        displayError("getLDAPAttributes: debug 2 running_ldap_server: " + running_ldap_server);
       }
      break;
    }
  }
</pre>
<h4 name="Unique_Script_for_Windows_and_Linux">Unique Script for Windows and Linux</h4>
<p>An <code> if... else</code> test permits us to check whether we use a Linux or Windows environment variable for the <code>USER</code> / <code>USERNAME</code>.</p>
<pre>// 1) env variables
if(getenv("USER") != "") {
   // *NIX settings
   var env_user = getenv("USER");
   var env_home = getenv("HOME");
 } else {
   // Windows settings
   var env_user = getenv("USERNAME");
   var env_home = getenv("HOMEPATH");
 }
  var env_mozdebug= getenv("MOZILLA_DEBUG");
</pre>
<h4 name="Final_Production_Script">Final Production Script</h4>
<p>Here's the complete final and commented production script:</p>
<pre>//Mozilla AutoConfiguration, Jehan Procaccia &amp; Roberto Aguilar
 
//put everything in a try/catch
try {
/*
1) define environment variables,
2) list &amp; randomize LDAP replicas,
3) define processLDAPValues(),
4) Call LDAP server to get LDAP Attributes (mail &amp; cn) getLDAPAttributes()
5) set user preferences
*/
 
// 1) env variables
if(getenv("USER") != "") {
   // *NIX settings
   var env_user = getenv("USER");
   var env_home = getenv("HOME");
 } else {
   // Windows settings
   var env_user = getenv("USERNAME");
   var env_home = getenv("HOMEPATH");
 }
  var env_mozdebug= getenv("MOZILLA_DEBUG");
 
// 2) setup multiple LDAP servers for fail-over
  var ldap_values;
  var ldap_servers = new Array('ldap2.int-evry.fr',
                      'ldap1.int-evry.fr',
                      'openldap.int-evry.fr'
                      );
  // shuffle function to randomize the server array
/**
  * setup the shuffle method for an array, from "mickweb script
  * factory" at:
  * http://www.mickweb.com/javascript/arrays/pureshuffle.html
  */ 
  // setup the shuffle method for an array
  Array.prototype.shuffle = function(times) {
    var i,j,t,l=this.length;
    while(times--) {
      with(Math) {
    i = floor(random()*l);
    j = floor(random()*l);
      }
      t       = this[i];
      this[i] = this[j];
      this[j] = t;
    }
    return this;
  }
 // mix up the LDAP servers so we don't hit the same one each time
  ldap_servers.shuffle(10);
 
/* 3) define here (because if set after "4)" below it doesn't work!) processLDAPValues which is eventually called by getLDAPAttributes() just below,
 check getLDAPAttributes() code from $MOZILLA_HOME/defaults/autoconfig/prefcalls.js to see the inside call to "user defined" processLDAPValues
*/
function processLDAPValues(values) {
 if(values) {
      // set the global var with the values returned from the LDAP query
      ldap_values = values;
    var uid = getLDAPValue(values, "uid");
    var cn = getLDAPValue(values, "cn");
    var mail = getLDAPValue(values, "mail");
     // lock LDAP variable (mail &amp; cn) dependent preferences while we have access to them
    lockPref("mail.server.server1.name", mail);
    lockPref("mail.identity.id1.fullName", cn);
    lockPref("mail.identity.id1.useremail", mail);
    defaultPref("network.ftp.anonymous_password", mail);
 
    // if $MOZILLA_DEBUG=1, popup a debug message
    if (env_mozdebug) {
        displayError("NO ERROR -&gt; MCI (jehan.procaccia@int-evry.fr)" + "\nthis message is displayed with displayError()! \ndebug 1 mozilla.cfg v3.2, NO FAILED, S2IA again!", "\nmail:" + mail + "\nuid:" +uid + "\ncn:" +cn + "\nuser:" + env_user);
        }
    }
  }
 
// 4) Call LDAP servers to get LDAP Attributes (mail &amp; cn), this will finally call processLDAPValues, "3)" just above.
// Go through the LDAP replicas list
for(i = 0; i &lt; ldap_servers.length; i ++) {
// Search for attribute mail &amp; cn through LDAP servers where uid = $USER|$USERNAME
  getLDAPAttributes(ldap_servers[i],
       "ou=people,dc=int-evry,dc=fr",
       "uid=" + env_user,
       "uid,cn,mail");
    // If we catch a running LDAP server, exit the loop,
    if(ldap_values) {
      running_ldap_server = ldap_servers[i];
        // If $MOZILLA_DEBUG=1 display in a popup the running server
      if (env_mozdebug) {
        displayError("getLDAPAttributes: debug 2 running_ldap_server: " + running_ldap_server);
       }
      break;
    }
  }
 
// 5) Set user preferences
 
//BROWSER
lockPref("browser.startup.homepage", "http://www.int-evry.fr/s2ia/portail/");
//unlockPref("browser.startup.homepage");
lockPref("browser.startup.homepage_override", true);
lockPref("startup.homepage_override_url", "http://www.int-evry.fr/s2ia/portail/");
//unlockPref("startup.homepage_override_url");
lockPref("browser.cache.disk.capacity", 100);
lockPref("network.cookie.cookieBehavior", 0);
 
//Network preferences
lockPref("network.proxy.autoconfig_url", "http://www.int-evry.fr/local/config.proxy");
lockPref("network.proxy.type", 2);
 
//Privacy &amp; Security
defaultPref("signon.rememberSignons", false);
 
//Account
lockPref("mail.account.account1.identities", "id1");
lockPref("mail.account.account1.server", "server1");
lockPref("mail.account.account2.server", "server2");
lockPref("mail.account.account3.server", "server3");
lockPref("mail.accountmanager.accounts", "account1,account2,account3");
lockPref("mail.accountmanager.defaultaccount", "account1");
 
//IMAP
lockPref("mail.server.server1.hostname", "imap-int.int-evry.fr");
lockPref("mail.server.server1.type", "imap");
lockPref("mail.server.server1.login_at_startup", true);
lockPref("mail.identity.id1.draft_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Drafts");
lockPref("mail.identity.id1.drafts_folder_picker_mode", "0");
lockPref("mail.identity.id1.fcc_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Sent");
lockPref("mail.identity.id1.fcc_folder_picker_mode", "0");
lockPref("mail.identity.id1.stationery_folder", "imap://" + env_user + "@imap-int.int-evry.fr/Templates");
lockPref("mail.identity.id1.tmpl_folder_picker_mode", "0");
lockPref("mail.identity.id1.valid", true);
lockPref("mail.identity.id1.overrideGlobal_Pref", true);
lockPref("mail.server.server1.download_on_biff", true);
lockPref("mail.server.server1.login_at_startup", true);
lockPref("mail.server.server1.userName", env_user);
lockPref("mail.server.server1.delete_model", 0);
 
//SMTP
defaultPref("mail.identity.id1.smtpServer", "smtp1");
defaultPref("mail.smtpserver.smtp1.auth_method", 0);
defaultPref("mail.smtpservers", "smtp1");
defaultPref("mail.smtpservers", "smtp1");
defaultPref("mail.smtp.defaultserver", "smtp1");
defaultPref("mail.smtpserver.smtp1.hostname", "smtp-int.int-evry.fr");
lockPref("mail.identity.id1.organization", "INT Evry France");
lockPref("mail.startup.enabledMailCheckOnce", true);
lockPref("mail.ui.folderpane.version", 3);
lockPref("mailnews.ui.threadpane.version", 2);
 
//LDAP config
lockPref("mail.identity.id1.directoryServer", "ldap_2.servers.ldapint");
lockPref("ldap_2.prefs_migrated", true);
lockPref("ldap_2.servers.history.filename", "history.mab");
lockPref("ldap_2.servers.history.replication.lastChangeNumber", 0);
lockPref("ldap_2.servers.ldapint.auth.savePassword", true);
lockPref("ldap_2.servers.ldapint.description", "ldap-int");
lockPref("ldap_2.servers.ldapint.filename", "abook-1.mab");
lockPref("ldap_2.servers.ldapint.position", 3);
lockPref("ldap_2.servers.ldapint.uri", "ldap://ldap1.int-evry.fr:389/ou=people,dc=int-evry,dc=fr??sub");
lockPref("ldap_2.servers.pab.filename", "abook.mab");
lockPref("ldap_2.servers.pab.replication.lastChangeNumber", 0);
 
//News config
lockPref("mail.server.server3.hostname", "news.int-evry.fr");
lockPref("mail.server.server3.max_cached_connections", 2);
lockPref("mail.server.server3.name", "news.int-evry.fr");
lockPref("mail.server.server3.type", "nntp");
lockPref("mail.server.server3.userName", env_user);
 
// Close the try, and call the catch()
} catch(e) {
  displayError("lockedPref", e);
}
</pre>
<h4 name="For_The_Record.2C_Old_Reliably_Scripts...">For The Record, Old Reliably Scripts...</h4>
<p>At least tested on Netscape 4.x.</p>
<p>In the original files below (in Netscape 4.x section), we hard-coded a single web server to retrieve the JavaScript preference file, and a single hard-coded LDAP server to get <code>mail</code> and <code>cn</code> attributes. It would be safer to get secondary servers in case of failure. For the web server name we can use an LDAP query to get the list of possible ones. Hence, we won't have to re-encode the <code>netscape.cfg</code> file at every change. We set the <code>netscape.cfg</code> file just once while imaging computers with the operating system, then any changes happen in LDAP or on the web server JavaScript preference file (central configuration).</p>
<h5 name="Enhance_netscape.cfg">Enhance netscape.cfg</h5>
<p>The list of possible web servers to query is defined in <code>netscape.cfg</code>. This is also where the JavaScript preference filenames are defined so that <code>netscape.cfg</code> doesn't need to be changed after imaging the computers at every change we need to do.</p>
<h5 name="LDAP_Web_Server_List_Subtree">LDAP Web Server List Subtree</h5>
<pre>$ ldapsearch -x * -b "ou=browser,ou=information,dc=int-evry, dc=fr" cn -LLL
dn: ou=browser,ou=information,dc=int-evry,dc=fr

dn: sn=http_server,ou=browser,ou=information,dc=int-evry, dc=fr
cn: web1.int-evry.fr
cn: web2.int-evry.fr

dn: sn=http_unix_file, ou=browser,ou=information,dc=int-evry, dc=fr
cn: /browser/config_file_unix.jsc

dn: sn=http_win_file, ou=browser,ou=information,dc=int-evry, dc=fr
cn: /browser/config_file_win.jsc
</pre>
<h5 name="netscape.cfg">netscape.cfg</h5>
<p>Here we select an operational LDAP server simply by testing a LDAP query, to make sure that our LDAP queries for setting preferences will be answered. {Again, I am not fluent in JavaScript. There should be a better way to make sure that an LDAP server is up and running. As for checking a web server, feel free to optimize this code, and let me know...)</p>
<pre>if (getLDAPAttributes("ldap1.int-evry.fr", \
 "ou=browser,ou=information,dc=int-evry,dc=fr", \
 "sn=http_server", "cn") )
 var running_ldap_server = "ldap1.int-evry.fr";
 else if (getLDAPAttributes("ldap2.int-evry.fr", \
 "ou=browser,ou=information,dc=int-evry,dc=fr", \
 "sn=http_server", "cn") )
  var running_ldap_server = "ldap2.int-evry.fr";
  else if (getLDAPAttributes("ldap0.int-evry.fr", \
  "ou=browser,ou=information,dc=int-evry,dc=fr", \
  "sn=http_server", "cn") )
   var running_ldap_server = "ldap0.int-evry.fr";
  else alert("No LDAP server available!");
</pre>
<p>Here's a complete example of the Unix netscape.cfg file.</p>
<pre>with (PrefConfig) { // Must be done inside the PrefConfig module

// create some variables we might want to use later on...
var env_user = getenv("USER");       // Windows username
var env_home = getenv("HOME");       // User HomeDir
var env_mozilla_home = getenv("MOZILLA_HOME");
var env_mozdebug = getenv("MOZILLA_DEBUG");

//check which LDAP server is running (needs a better procedure!)

if (getLDAPAttributes("ldap1.int-evry.fr", \
 "ou=browser,ou=information,dc=int-evry,dc=fr", \
 "sn=http_server", "cn") )
 var running_ldap_server = "ldap1.int-evry.fr";
 else if (getLDAPAttributes("ldap2.int-evry.fr", \
  "ou=browser,ou=information,dc=int-evry,dc=fr", \
  "sn=http_server", "cn") )
  var running_ldap_server = "ldap2.int-evry.fr";
  else if (getLDAPAttributes("ldap0.int-evry.fr", \
  "ou=browser,ou=information,dc=int-evry,dc=fr", \
  "sn=http_server", "cn") )
   var running_ldap_server = "ldap0.int-evry.fr";
  else alert("No LDAP server available!");

if (running_ldap_server){ 
var ldap_http_server_values = getLDAPAttributes(running_ldap_server, \
"ou=browser,ou=information,dc=int-evry,dc=fr", "sn=http_server", "cn");
var ldap_http_server = getLDAPValue(ldap_http_server_values, "cn");
var ldap_http_unix_uri_values = getLDAPAttributes(running_ldap_server, \
"ou=browser,ou=information,dc=int-evry,dc=fr", "sn=http_unix_file", "cn");
var ldap_http_unix_uri = getLDAPValue(ldap_http_unix_uri_values, "cn");
var values = getLDAPAttributes(running_ldap_server, \
"ou=people,dc=int-evry,dc=fr", "uid="+env_user, "cn,mail");
var ldap_email = getLDAPValue(values, "mail");
var ldap_gecos = getLDAPValue(values, "cn");
env_user=env_user.toLowerCase();
}
else
 alert("No LDAP server available, AutoConfig impossible!");

//popup debug message if export MOZILLA_DEBUG=1 
if (env_mozdebug) {
 alert("MOZILLA_DEBUG\nrunning LDAP server: " + running_ldap_server);
 alert("MOZILLA_DEBUG\nExecuting " + ldap_http_server + \
 ldap_http_unix_uri);
 alert("MOZILLA_DEBUG\nfetching http://" + ldap_http_server \
 + ldap_http_unix_uri + "");
}

//go fetch the preference file in a HTTP server 
//needs a way to check if http server is running!

config(
"autoadmin.global_config_url", "http://" + ldap_http_server + \
ldap_http_unix_uri + ""
);

// Since we use a file, if it's not accessible, something is
// terribly wrong anyway
config(
"autoadmin.failover_to_cached", false
);

// don't use ?useremail=email-addr to CGI URL request
config(
"autoadmin.append_emailaddr", false
);

} // with (PrefConfig)
</pre>
<p>For the Windows version of that <code>netscape.cfg</code> file, we replace <code>"sn=http_unix_file"</code> by <code>"sn=http_win_file"</code> in the LDAP query.</p>
<h3 name="OLD_Netscape_4.x">OLD Netscape 4.x</h3>
<h4 name="Call_File.2C_netscape.cfg">Call File, netscape.cfg</h4>
<p>In the following example, that file is a "call" file, because it will actually be used to only redirect a call to an even more centralized file, a file that will be located on a web server. That allows us first to encode (byte-shift) that file (<code>netscape.cfg</code>) -just once- because it will call a non-encoded JavaScript file <code>config_file_system.jsc</code> (or whatever name) on the web server.</p>
<p>Second, as that latest JavaScript file is located on a web server, there's no need to recopy it on every station at every single change! That feature is available through <code>autoadmin.global_config_url</code> directive as in <code>config("autoadmin.global_config_url","<span class="nowiki">http://www/browser/config-file-system.jsc</span>"),</code> for example. Unfortunately I am unable to run that really useful directive with Netscape 6/7 or Mozilla 1.x :-(, (if anyone knows how, please let me know!)</p>
<p>In Windows that encoded <code>netscape.cfg</code> file is located in <code>NETSCAPE_HOME\Communicator\Program</code> (<code>C:\Program Files\netscape\Communicator\Programs</code>), in Red Hat 7.3 it is in <code>/usr/lib/X11/app-defaults</code>. Beware that in Windows, that file is already there, so it must be saved before being replaced by ours, in order to come back to a normal state in case of problem. If neither original or personalized netscape.cfg is there, Netscape won't start!</p>
<pre>// This file is not usable in its present form. it must be encoded
// with the "convert" function of the CCK "file" menu
// Netscape's Flow of preference configuration:
//    configure defaults from internal JavaScript file in ns executable
//    global prefs from netscape.cfg (this file)
//    executes ~/.netscape/preferences.js file
//    executes ~/.netscape/user.js
// (somewhere in here liprefs.js is run, but i haven't yet figured out
// what liprefs is for....)
//=========================================================================

with (PrefConfig) { // Must be done inside the PrefConfig module

// create some variables we might want to use later on...
var platform    = getPlatform();        // E.G. SunOS4.1.3_U1
var env_user    = getenv("USER");       // Unix username
var env_home    = getenv("HOME");       // User HomeDir
var env_display = getenv("DISPLAY");    // X11 Display
var env_editor  = getenv("EDITOR");     // use in mail edit?
var env_visual  = getenv("VISUAL");     // use in mail edit?
var env_mozilla_home    = getenv("MOZILLA_HOME")
var env_mozdebug        = getenv("MOZILLA_DEBUG")
// For ease of update... We use the AutoAdmin operation to redirect
// netscape.cfg to read the plain-text "config-file-unix.jsc" file.
// Any changes
// from now on can be made here w/o re-encoding the netscape.jsc file to
// netscape.cfg.
config(
"autoadmin.global_config_url", \
"http://lugdunum.int-evry.fr/browser/config-file-unix.jsc"
);
// How often (in minutes) to update
// Every 6 hours seems a good interval to keep hosts who don't ever
// exit Netscape updated on current changes.
config(
"autoadmin.refresh_interval", 360
);
// Since we use a file, if it's not accessible, something is
// terribly wrong anyway
config(
"autoadmin.failover_to_cached", false
);
// don't use ?useremail=email-addr to cgi URL request
config(
"autoadmin.append_emailaddr", false
);
</pre>
<h4 name="LockPref_Configuration_File">LockPref Configuration File</h4>
<p>This file (on the web server: <code><span class="nowiki">http://www/browser/config-file-system.jsc</span></code>) is where we set and lock Preferences. Because computers are shared, we need to personalize preferences based on the user login. The login is taken from the environment variable: <code>USER</code> in Unix, <code>USERNAME</code> in Windows. Different environment names and different paths between Windows and Unix explain why we need two different configuration files. There might be a way to manage those differences within a same file, but I am not very fluent in JavaScript :-(</p>
<p>Here is an example of a <code>lockPref</code> preference configuration file for Unix (<code>config_file_unix.jsc</code>). We lock (<code>lockPref</code>) some preferences (IMAP server name, company name, cache location and size...), others can be just set as default (<code>defaultPref</code>); <code>startup.homepage</code>... We also use LDAP functions (from <code>prefcalls.js</code>) to get the current user (<code>USER</code> or <code>USERNAME</code>) email address and common name, respectively <code>mail</code> and <code>cn</code> in LDAP.</p>
<pre>[root@lugdunum /var/www/html/browser]
$ more config_file_unix.jsc
// Functions you can use:
// lockPref(name, value) user is disallowed from changing
//  (aka lock_pref())
// defaultPref(name, value) unless user overrides, this is value
//  (aka default_pref())
// unlockPref(name) unlock previously "lockPref"-ed name
// config(name, value) usually for menus...
// value = getPref(name) gets current setting
// getLDAPAttributes(host, base, filter, attributes)
// getLDAPValue(values, attribute)
// .mime.type, .begin_mime_def, .end_mime_def..
// .plat
// alert(message);
// var = prompt(message);
// var = getPlatform() returns Win32,...
//  getPlatform().contains("UNIX")...
// var = getenv(envvar)
// var = putenv(envvar)
//
// Objects/Functions you *can't* use because they aren't defined
// navigator.* (argh, this *REALLY* bites)
//=========================================================================
// Preferences Configuration
//=========================================================================
with (PrefConfig) {
var values = getLDAPAttributes("ldap2.int-evry.fr", \
"ou=people,dc=int-evry,dc=fr", "uid=" + env_user, "cn,mail");
var ldap_email = getLDAPValue(values, "mail");
var ldap_gecos = getLDAPValue(values, "cn");
//var toto = prompt("email");
//alert("ldap_mail = " + ldap_email + "toto=" + toto);
if (env_mozdebug) {
 alert("env_user:" + env_user + "\nenv_home:" + env_home + \
"\nldap_email:" + ldap_email + "\nldap_gecos:" + ldap_gecos + "\n");
}
//-----------------------------------------------------------------------
// [ General Browser configuration ]
//-----------------------------------------------------------------------
config("autoadmin.refresh_interval", 1440); // auto-update every 24 hours
defaultPref("browser.startup.page",1); 
//0=blank page, 1=homepage, 2=last visited
defaultPref("browser.startup.homepage", "http://www/mci/mode-d-emploi.shtml");
lockPref("browser.cache.directory", "/tmp");
lockPref("browser.cache.memory_cache_size", 0);

lockPref("mail.server_type",1); // POP=0 IMAP=1
lockPref("network.hosts.imap_servers", "pop-int");
lockPref("mail.imap.server.pop-int.using_subscription",true);
lockPref("mail.imap.server.pop-int.userName", env_user);
lockPref("mail.identity.useremail", ldap_email);
lockPref("mail.identity.username", ldap_gecos);
lockPref("mail.check_new_mail", false);
lockPref("mail.directory", env_home+"/nsmail");
lockPref("mail.identity.defaultdomain", "int-evry.fr");
lockPref("mail.identity.organization", "INT Evry Essonne ");

// LDAP
lockPref("ldap_2.autoComplete.useDirectory", true);
lockPref("ldap_2.servers.LDAPINT.autoComplete.enabled", true);
lockPref("ldap_2.servers.LDAPINT.csid", "UTF-8");
lockPref("ldap_2.servers.LDAPINT.description", "LDAP INT");
lockPref("ldap_2.servers.LDAPINT.filename", "LDAPINT.na2");
lockPref("ldap_2.servers.LDAPINT.position", 2);
lockPref("ldap_2.servers.LDAPINT.searchBase", "ou=people,dc=int-evry,dc=fr");
lockPref("ldap_2.servers.LDAPINT.serverName", "ldap1.int-evry.fr");

//news
lockPref("news.directory", "/tmp");
//proxy
lockPref("network.proxy.autoconfig_url", \
"http://www.int-evry.fr/local/config.proxy");

} // with (PrefConfig)
</pre>
<p>This document was translated from LaTeX with <a class="external" href="http://pauillac.inria.fr/~maranget/hevea/">HEVEA</a>.</p>
<p>{{ OrigDocInfo{ author : " Jehan Procaccia MCI INT-EVRY- jehan.procaccia AT int-evry.fr", date : " 02 September 2006" } }}</p>
<p>{{ languages( { "ja": "ja/MCD,_Mission_Control_Desktop_AKA_AutoConfig" } ) }}</p>
Revert to this revision