Disabling Auto-Provisioning in Funambol

By default the Funambol server will automatically create new User, Device and Principal records for any user who attempts to use the server. This can be very helpful in some cases - but it can also be a problem. There are three ways to work around this problem.

Change the Provisioning Officer

The standard Funambol v8 release package ships with two different Officers that can be configured through the administration tool. To find the setting:

  • Log into the administrator tool
  • click on Server Settings
  • In the data-entry panel search for Officer.

User Provisioning Officer

The default Officer is called UserProvisioningOfficer.xml. It automatically creates new User, Device and Principal records for anybody who tries to use the server (a Principal record is used to relate a given user to a given device.)

As written in the Funambol docs this can be very helpful if you have a thousand new users to configure. On the other hand it creates a few problems also: Imagine, for example, the average person who makes a typing mistake when configuring a new device, ie: "it seems to work but there's something wrong?!" Then there is the problem that a service provider will have with non-paying subscribers using a server that is accessible to the public.

DB Officer

The alternate Officer that comes with Funambol is DBOfficer.xml. This code resolves the problems with the User Provisioning Officer by going to the other extreme: It does not insert new User or Principal records.

Initially one might think this is a great idea: the user can simply send an email before attempting to sync a new device. The problem with this is that the new device is assigned a random ID when the Funambol software is installed into it. As far as I can tell the only way to find out what the ID is would be to try to sync - then check the server logs for the error message that contains the User ID and Device ID. Try it - it's not fun.

Other Options

There are two other possible solutions to the problem:

  • The nice thing about Open Source projects is that you can download the source code and change it. It turns out that the code required to make the change is very, very simple. It's even relatively easy to find even though the overall project is huge. Once you've made the necessary changes, though, you find that the instructions for rebuilding the Funambol server make it sound like a big job.
  • Realistically all we want to do is stop the server from inserting new records into the User table. One simple way to do this is to set the database permissions to disallow any updates to the user table! This method turns out to be the easiest way to get the job done.

Change the Code

To change the Auto Provisioning code so that it does not auto-provision users (without changing anything else,) you only need to add a "return null;" statement to one file - then recompile the code.

It's a good idea to take a quick look at the notes on the Funambol Wiki related to this subject:

(The Develop Funambol with Eclipse page makes it sound easy... but the Building Funambol page makes it sound like a week-end marathon!)

Begin by checking out the source code from the SVN repository (as described in the Funambol Wiki,) and edit the following file:

./core/funambol/ds/ds-server/src/main/java/com/funambol/server/security/UserProvisioningOfficer.java

Look for this code in the file:

// ------------------------------------------------------- Protected Methods /** * Checks the given credential. If the user or the principal isn't found, * they are created. * * @param credential the credential to check * * @return the Sync4jUser if the credential is autenticated, null otherwise */ protected Sync4jUser authenticateBasicCredential(Cred credential) {

A little bit further down you will find the block that you need to edit. Change it to read as follows:

// // Gets the user without checking the password // Sync4jUser user = getUser(username, null); if (user == null) { // // disable auto-provisioning // if ( true ) // no auto-provisioning of user records return null; if (log.isTraceEnabled()) { log.trace("User '" + username + "' not found. A new user will be created"); }

Finally, rebuild the server as documented in the Wiki.

Use the Database Permissions

Setting up the build environment for Funambol is not a small job for those of us who do not do much Java development. As such the above steps are time-consuming to complete. Fortunately there is an easier way: Change the Permissions of the Database so that Insert statements are rejected.

By default the Funambol project ships with a database called Hyperion. As I personally don't know this database I switched to MySQL. If you wish to use Hyperion you will have to review the appropriate documentation to figure out how to change the table permissions.

Below are two scripts that were written for MySQL and Funambol v8. The steps required to switch to MySQL are well documented in the Administrators Guide for those who wish to use these scripts:

funambol-user-ro.sql: Script to restrict access to the user table by the funambol user:

drop user funambol@localhost; grant usage on funambol.* to funambol@localhost identified by "funambol"; grant all privileges on funambol.fnbl_client_mapping to funambol@localhost; grant all privileges on funambol.fnbl_connector to funambol@localhost; grant all privileges on funambol.fnbl_connector_source_type to funambol@localhost; grant all privileges on funambol.fnbl_device to funambol@localhost; grant all privileges on funambol.fnbl_device_caps to funambol@localhost; grant all privileges on funambol.fnbl_device_config to funambol@localhost; grant all privileges on funambol.fnbl_device_datastore to funambol@localhost; grant all privileges on funambol.fnbl_device_ext to funambol@localhost; grant all privileges on funambol.fnbl_ds_ctcap to funambol@localhost; grant all privileges on funambol.fnbl_ds_ctcap_prop to funambol@localhost; grant all privileges on funambol.fnbl_ds_ctcap_prop_param to funambol@localhost; grant all privileges on funambol.fnbl_ds_cttype_rx to funambol@localhost; grant all privileges on funambol.fnbl_ds_cttype_tx to funambol@localhost; grant all privileges on funambol.fnbl_ds_filter_cap to funambol@localhost; grant all privileges on funambol.fnbl_ds_filter_rx to funambol@localhost; grant all privileges on funambol.fnbl_ds_mem to funambol@localhost; grant all privileges on funambol.fnbl_email_account to funambol@localhost; grant all privileges on funambol.fnbl_email_cache to funambol@localhost; grant all privileges on funambol.fnbl_email_enable_account to funambol@localhost; grant all privileges on funambol.fnbl_email_folder to funambol@localhost; grant all privileges on funambol.fnbl_email_inbox to funambol@localhost; grant all privileges on funambol.fnbl_email_mailserver to funambol@localhost; grant all privileges on funambol.fnbl_email_push_registry to funambol@localhost; grant all privileges on funambol.fnbl_email_sentpop to funambol@localhost; grant all privileges on funambol.fnbl_id to funambol@localhost; grant all privileges on funambol.fnbl_last_sync to funambol@localhost; grant all privileges on funambol.fnbl_module to funambol@localhost; grant all privileges on funambol.fnbl_module_connector to funambol@localhost; grant all privileges on funambol.fnbl_pending_notification to funambol@localhost; grant all privileges on funambol.fnbl_pim_address to funambol@localhost; grant all privileges on funambol.fnbl_pim_calendar to funambol@localhost; grant all privileges on funambol.fnbl_pim_calendar_exception to funambol@localhost; grant all privileges on funambol.fnbl_pim_contact to funambol@localhost; grant all privileges on funambol.fnbl_pim_contact_item to funambol@localhost; grant all privileges on funambol.fnbl_pim_contact_photo to funambol@localhost; grant all privileges on funambol.fnbl_pim_listener_registry to funambol@localhost; grant all privileges on funambol.fnbl_pim_note to funambol@localhost; grant all privileges on funambol.fnbl_principal to funambol@localhost; grant all privileges on funambol.fnbl_push_listener_registry to funambol@localhost; grant all privileges on funambol.fnbl_role to funambol@localhost; grant all privileges on funambol.fnbl_sync_source to funambol@localhost; grant all privileges on funambol.fnbl_sync_source_type to funambol@localhost; grant select on funambol.fnbl_user to funambol@localhost; grant select on funambol.fnbl_user_role to funambol@localhost; flush privileges;

Executing the above script causes new users to see the message "invalid credentials," if their User ID & Password is not already in the User database. However, if the Administrator has already added the User ID and the Password - the remaining auto-provisioning code will kick-in and automatically provide the necessary Device and Principal records when the user first attempts to sync. This is the naturally expected behavior for a publicly accessible repository.

Unfortunately, once the above script is used the Administration Tool is no longer able to update the User table. As such it is necessary, before using the Administration Tool, to restore Insert operations on the User table temporarily:

funambol-user-rw.sql: Script to grant full access to the user table by the funambol user:

drop user funambol@localhost; grant all privileges on funambol.* to funambol@localhost identified by "funambol"; flush privileges;

You can switch back and forth between the two sets of permissions by shelling into the server and executing the above scripts:

To disable auto-provisioning:

$ mysql --user=<myuser> -p < funambol-user-ro.sql $ sudo /opt/Funambol/bin/funambol stop $ sudo /opt/Funambol/bin/funambol start

and to re-enable it to allow using the Admin tools:

$ mysql --user=<myuser> -p < funambol-user-rw.sql $ sudo /opt/Funambol/bin/funambol stop $ sudo /opt/Funambol/bin/funambol start

(Don't forget to disable auto-provisioning after you are finished using the admin tools!)

Note: If you forget to restart the Funambol server it will continue using the same connection and permissions that it had before you changed them. To put it another way: Permissions changes will be ignored until Funambol is shut-down and started again.