Tuesday, June 30, 2009

How to monitor Sun Directory Server 5.2?

Yes, there are still a lot of Sun Directory Server 5.2 deployment in Asia region. (even though 6.x has been released for quite a while)

I was meeting a customer today. He is interested in migrating from Sun Directory Server 5.2 to Sun OpenDS Standard Edition 2.0 (target release date is Mid July 2009). 

Why Sun OpenDS SE 2.0 and not Sun Directory Server 6.3.1? I was told the price for commercial support differ by quite a lot, at least S$12k for his case. Wow!

Anyway, that's not my objective. I'm providing Professional Service/Consultancy. I'll leave the pricing to the folks.

So, I asked during the meeting when is the peak period and what is the concurrent hit like? I was given figures ranging from 70-80k per hour to 5 millions hit per day. 

I was not convinced. Thus I asked for facts which can be easily extracted with the tools provided by Sun Directory Server 5.2.

You can use the GUI to monitor the suffix status online. (Click on "Continuous refresh") Otherwise, for people like me, command-line is best.

bash-3.00# ldapsearch -D "cn=Directory Manager" -w password -b "cn=monitor,cn=userRoot,cn=ldbm database,cn=plugins,cn=config" objectclass=*
version: 1
dn: cn=monitor,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
objectClass: top
objectClass: extensibleObject
cn: monitor
database: ldbm database
readonly: 0
nextid: 10
dbentrycount: 9
ldapentrycount: 9
entrycachehits: 26
entrycachetries: 36
entrycachehitratio: 72
currententrycachesize: 14796
maxentrycachesize: 10485760
currententrycachecount: 9
maxentrycachecount: -1
Remember to execute the above command over a period of time in order to capture the overall statistics. A cron job will help.

Monday, June 29, 2009

How to scale Directory Server?

Again, the following typical question is asked whenever I provide Directory Service consultancy:

How do we scale our Directory Service?

There are actually 2 considerations - READ and WRITE operations.

The answer to READ operation is very simple. 
  1. Add more nodes;
  2. Configure replication across all nodes;
  3. Place a load-balancer in-front of all nodes;
Done. Simple!

The answer to WRITE operation is far more complex.

  • If the solution is to cater for more WRITE than READ, then I'll ask "Are you actually looking for a database?" (LDAP is built for fast and frequent read ops, with occasionally write ops.)
  • You'll be surprised at the answers you get. There are really customers who cannot differentiate between LDAP and database.
  • If the customer is really sure they need Directory Service, then I'll suggest that they spilt their users into various organizations/groups. Then each logical group will be stored in different LDAP sources.

Quoted from OpenDS site:
Note that you cannot use replication to scale write operations because a write operation to one directory server results in a write operation to every other server in the topology. The only way to scale write operations horizontally is to split the directory data among multiple databases and place those databases on different servers.

Corrupted database exception in Sun Directory Server

I am reading OpenDS System Requirement in preparation for a presentation tomorrow to a local teleco in Singapore.

The section on File Descriptor Requirements (Linux Systems) reminds me of an escalation case I was assigned to in Feburary.

The case involved a global logistics company in Malaysia. It has an issue with Sun Directory Server 5.2 SP4 running on Redhat Enterprise Linux Server AS 4. Long story short - the problem was due to insufficient tuning.

Linux systems limit the number of file descriptors that any one process may open to 1024 per process.

After the directory server has exceeded the file descriptor limit of 1024 per process, any new process and worker threads will be blocked.

For example, if the directory server attempts to open a Oracle Berkeley JE database file when the operating system has exceeded the file descriptor limit, the directory server will no longer be able to open a connection, which results in a corrupted database exception. Likewise, if you have a directory server that exceeds the file descriptor limit set by the operating system, the directory server can become unresponsive as the LDAP connection handler consumes all of the CPU's processing in attempting to open a new connection.

To fix this condition, set the maximum file descriptor limit per process on Linux

Wednesday, June 24, 2009

Over-Quota logging in Sun Messaging Server

The company I work for has been supporting Sun Java System Messaging Server for a Singapore government-link group of companies for close to 2 years - a total of 25-30 hosted domains.

A typical question I always get from my customers is: Why is my mail delivered late?

If email is not delivered at all, then it is easier to reply:
  1. Held by anti-spam/anti-virus server
  2. Sender did not even get the email sent (stuck in their outbox)
  3. Sender sent to wrong email address (Ha! It really happened before!)
  4. etc ...

But the complain now is why email is delivered late ... It took me quite a while ... 

In the end, I found the answer by parsing the mail.log file. 

19-Jun-2009 16:43:28.75 ims-ms                    R 57 ahcheng@abc.com rfc822;max@abc.com max%abc.com@ims-ms-daemon /
opt/SUNWmsgsr/data/queue/ims-ms/003/ZZg0x5H1dfFdv.00 <00a901c9f0b9$fe729d30$fb57d790$%lim@abc.com> mailsrv  Over quota

Tuesday, June 23, 2009

Changing JAVA HOME on Solaris 10

I'm trying to install Sun Java System Calendar Server 7 Beta. It has a pre-requisite for JDK 6. 

We know that default Solaris 10 has JDK 5 pre-installed. So, I went ahead to download JDK 6 from here.

From my experience, I know that all JDK installation on Solaris can be found in /usr/jdk. So I unpacked the JDK 6 binary in the same directory.

bash-3.00# cd /usr/jdk/
bash-3.00# ./jdk-6u14-solaris-i586.sh 

Well, after unpacking, we need to make sure that we are calling the latest JDK system-wide. Otherwise, you'll see the following:

bash-3.00# java -version
java version "1.5.0_14"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03)
Java HotSpot(TM) Client VM (build 1.5.0_14-b03, mixed mode, sharing)
bash-3.00# javac -version
javac 1.5.0_14

This is not what we want!

So here we go: I'll try to find out the exact location of the various Java related commands.

bash-3.00# ls -al /usr/bin/java*
lrwxrwxrwx   1 root     other         16 Jul  3  2008 /usr/bin/java -> ../java/bin/java
lrwxrwxrwx   1 root     other         17 Jul  3  2008 /usr/bin/javac -> ../java/bin/javac
lrwxrwxrwx   1 root     other         19 Jul  3  2008 /usr/bin/javadoc -> ../java/bin/javadoc
lrwxrwxrwx   1 root     other         17 Jul  3  2008 /usr/bin/javah -> ../java/bin/javah
lrwxrwxrwx   1 root     other         17 Jul  3  2008 /usr/bin/javap -> ../java/bin/javap
lrwxrwxrwx   1 root     other         18 Jul  3  2008 /usr/bin/javaws -> ../java/bin/javaws

bash-3.00# ls -al /usr/java   
lrwxrwxrwx   1 root     other         15 Jul  3  2008 /usr/java -> jdk/jdk1.5.0_14

So, it's simple! Remove the existing symbolic link of "usr/java" from JDK 1.5 to 1.6.

bash-3.00# rm /usr/java
bash-3.00# ln -s jdk/jdk1.6.0_14 /usr/java

bash-3.00# java -version
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) Client VM (build 14.0-b16, mixed mode, sharing)
bash-3.00# javac -version
javac 1.6.0_14

I also did not feel easy with "latest" directory symbolic-linked to JDK 1.5 in "/usr/jdk". So I went ahead to replace it with JDK 1.6, even though I knew nothing will break.

bash-3.00# cd /usr/jdk
bash-3.00# ls -altr
total 16
lrwxrwxrwx   1 root     other          7 Jul  3  2008 j2sdk1.4.2_16 -> ../j2se
drwxr-xr-x   3 root     bin          512 Jul  3  2008 instances
lrwxrwxrwx   1 root     other         18 Jul  3  2008 jdk1.5.0_14 -> instances/jdk1.5.0
lrwxrwxrwx   1 root     other         11 Jul  3  2008 latest -> jdk1.5.0_14
drwxr-xr-x   8 root     bin          512 Jul  3  2008 packages
drwxrwxr-x  10 root     root         512 Jun 23 13:12 jdk1.6.0_14
drwxr-xr-x   5 root     bin          512 Jun 23 13:15 .
drwxr-xr-x  40 root     sys         1024 Jun 23 13:17 ..

bash-3.00# rm latest
bash-3.00# ln -s jdk1.6.0_14 latest

bash-3.00# ls -altr
total 16
lrwxrwxrwx   1 root     other          7 Jul  3  2008 j2sdk1.4.2_16 -> ../j2se
drwxr-xr-x   3 root     bin          512 Jul  3  2008 instances
lrwxrwxrwx   1 root     other         18 Jul  3  2008 jdk1.5.0_14 -> instances/jdk1.5.0
drwxr-xr-x   8 root     bin          512 Jul  3  2008 packages
drwxrwxr-x  10 root     root         512 Jun 23 13:12 jdk1.6.0_14
drwxr-xr-x  40 root     sys         1024 Jun 23 13:17 ..
lrwxrwxrwx   1 root     root          11 Jun 23 13:24 latest -> jdk1.6.0_14
drwxr-xr-x   5 root     bin          512 Jun 23 13:24 .

Reinstall Directory Service Control Center

I have a customer who likes Directory Service Control Center (DSCC) a lot. He doesn't seem to appreciate the convenience with using CLI (command line) - ssh into the terminal; use ldapsearch, ldapmodify commands. So easy!

Anyway, his DSCC is giving him problems these days. He was trying so many different ways to make DSCC work again that he somehow "crashed" DSCC.

As he needs DSCC to get working again pretty soon, I suggested removing and reinstalling again.

Remove Instruction here.

root# /opt/SUNWdsee/dscc6/bin/dsccsetup dismantle

Install Instruction here.

root# /opt/SUNWdsee/dscc6/bin/dsccsetup initialize


Sunday, June 21, 2009

Gmail Aliases

Released in Jan 2009, Gmail now offers address aliases.

Gmail doesn't offer traditional aliases, but you can receive messages sent to your.username+any.alias@gmail.com. For example, messages sent to jane.doe+notes@gmail.com are delivered to jane.doe@gmail.com.

You can set up filters to automatically direct these messages to Trash, apply a label or star, skip the inbox, or forward to another email account.

Slightly different from the shared folder concept in Sun Java System Messaging Server which I wrote about 2 days ago. 

Gmail offering is more suitably used as a filtering tool. 

Saturday, June 20, 2009

Issue with Outlook Connector Upgrades

Interesting question from info-iMS mailing list:


We have a community of about 500 users who use the Outlook Connector. We're having significant difficulty is managing upgrades to the connector software and maintaining the most recent version across all 500 users' systems.

We're even having difficulty identifying which users/machines are using the outlook connector to even approach them to upgrade. When an upgrade becomes available, installing it involves sending support staff around to hundreds of users' PC to perform the upgrade, as most users aren't savvy enough or have appropriate access to perform the upgrade on their own.

Have others encountered this same problem and what have others done to manage connector upgrades?


Desktop connector deployment is always a challenge, not to mention upgrade. It's always a nightmare. 

That is why I seldom introduce my customers to Sun Java System Connector for Microsoft Outlook.

From my ground experience, those who are hard-core Exchange/Outlook users will always ask for more if you introduce them to the Outlook Connector. Many times, I have to tell them the features they are looking for are proprietary/non-conforming standards. 

I'll move on most of the time. These are not the customers I'm targeting.  

Remember 80/20 rule: "Never spend 80% of my time on 20% of the requirements that I know I'll never be able to fulfill"

Friday, June 19, 2009

Shared folder in Sun Messaging Server

Shared folder is a rarely used feature in Sun Messaging Server, at least for my customers base.

Today, I happened to receive a huge email (10 MB) from my customer which I need to disseminate to my colleague. 

What would most people do? 
  • Forward the same email (yes, 10 MB!!)
  • Download to corporate network drive; ask my colleague to pick the document from there
  • Download to a thumbdrive; work over to my colleague's desk; ask him to copy the document 
Tedious. Troublesome. My principle is always to "Keep It Simple!"

Then I remembered that there's this Shared Folder feature with Sun Messaging Server. 

(Yes, we eat our own dog food. Our corporate mail server is Sun Messaging Server 7.0. Our company guideline is: "If you do not use the technology yourself, do not deploy it for your customers.")

So, I login to OpenMail (Sun Java System Communications Express) to create and configure a shared folder which I shared out to my colleague. 

Step 1: Create a folder called "Shared".  Choose "Share Folder" from Folder Actions.

Step 2: Click "Search..." to select my colleague's User ID. Allow him "Read only" permission.

PS: There is another nice feature if you take a detailed look at the previous image - "Enable directory delivery of email to folder". This feature allows anyone to send emails directly to the shared folder. e.g. "cheechong+Shared@xyz.com.sg".

This is useful for project-related emails. I can share out a folder. My team members can subscribe to this folder. I'll ask my customers to send emails to "cheechong+Shared@xyz.com.sg".


Sun Directory Server 6.3.1 - ZIP Patch

I talked about my preference for Native Package Install for Sun Directory Server 6.x. (Read here)

Well, I decided to play around with ZIP install and especially to tinkle around with ZIP patch. Surprise! It's a breeze. 

The command to patch is exactly the same as install:

bash-3.00# ./dsee_deploy install -i  /comms/dsee

However, I do note some differences with ZIP install over Native Package install:
  • You need to install your own web container to deploy DSEE Console (a .war file). It is not tightly integrated with Java Web Console (aka smcwebserver). This is troublesome to me!

  • You cannot utilize the default system-installed CACAO agent. A standalone caocao will be installed in /dsee6/cacao_2 . Might cause confusion for someone who is handling operation.

If your customers (like my American bank customer) prefer a dedicated directory/partition for directory server installation, then you're likely to use ZIP installation.

Note: Native Package installation will create directories in /opt, /etc/opt, and /var/opt. This is the default installation paths for almost all Sun software.

# cluster shutdown -g0 -y

Sun Cluster 3.2 can be installed on both Sparc and x86/64 platform. 

The command "cluster shutdown -g0 -y" shuts down the entire cluster in an orderly fashion.

cluster shutdown” performs the following actions when it shuts down the cluster: 
  • Changes all functioning resource groups on the cluster to an offline state
  • Unmount all file systems
  • Shuts down all active device services
  • Runs /usr/sbin/init 0 on all nodes
Now, the only difference between Sparc and x86/64 platform is in the last step when /usr/sbin/init 0 is executed.

On Sparc platform, all nodes will drop to "OK" prompt. On x86/64 platform, all nodes will display "Press any key to continue".

By the way, you'll be surprised how extensively is Sun Cluster being used in the healthcare/maritime/defense industry in S'pore. 

Thursday, June 18, 2009

How to track Last Successful Login Time

There is a new requirement from my Thai customer today. They ask whether or not Sun Directory Server is able to capture the last authentication time of each user. Bank is usually very sensitive regarding this matter.

Luckily, with Sun Directory Server 6 onwards, the feature is there with this new attribute pwdKeepLastAuthTime.

However, do note the following:

  • pwdKeepLastAuthTime feature is not enabled by default
  • Directory Server, by default, is in DS5-compatible-mode
  • Directory Server has to be DS6-mode compatible, in order to enable pwdKeepLastAuthTime
  • The server state can move only towards stricter compliance with the new password policy specifications. It implies "no way to rollback once you make the change".

Special Note:

Using this feature can affect performance. When you configure Directory Server to save pwdLastAuthTimetimestamps, the server must perform an internal modify operation for each successful bind.

Unless it is really a necessity, I do not recommend enabling this feature.

Wednesday, June 17, 2009

How to install Sun Directory Server 6.3.1

I have been deploying and supporting Sun Directory Server for a while, since 5 years ago with version 5.2. The current Directory Server version is 6.3.1. 

At present, there are 2 ways to install Sun Directory Server - native package (PKG) or compressed archive (ZIP).

Most of my customers runs Solaris, with exception of one global logistic company running Red Hat. As such, my preference is to always choose PKG install. 

Reason is simple: 

If we need to patch the Directory Server later, all we need to do is to download the latest patch (in PKG format, of course) and execute pkgadd command. Clean and simple! I like to keep things simple.

So, here we go:

Go to this download page.

Select "Native Package (PKG)" for Delivery Type.

Choose "Base Full Install DSEE 6.0". (since we need base installation)

Right-click on the "java_es-5-idensuite-ga-solaris-x86.zip" hyperlink. I prefer to download directly instead of via the Sun Download Manager. (as usual, keep it simple!)

Now, once the download begins, we need to navigate back to the previous screen to download the "Patch Only Install".

Why? Because the base installation comes with DSEE 6.0. We need to patch it to 6.3.1.
Troublesome? It seems so initially, but I'm thinking ahead when further patch(es) comes. My job will be easier then.

Monday, June 15, 2009

Log Rotation for Sun Messaging Server

This week, I'm based in S'pore performing a migration of Sun Java System Messaging Server from version 5.2 to 7.0u2 for an American bank. 

They asked about log rotation -  a question frequently asked. 
Sun Java System Messaging Server provides numerous logs. What we are more concern with is the MTA log (mail.log, mail.log_current, and mail.log_yesterday).

If MTA log is enabled, then we need to pay attention to mail.log. 

With logging is enabled, the mail.log file steadily grows and, if left unchecked, consumes all available disk space. Monitor the size of this file and periodically delete unnecessary contents. You can also delete the entire file as another version will be created as needed.
The message return job, which runs every night around midnight, appends any existing mail.log_yesterday to the cumulative log file, mail.log, renames the current mail.log_current file to mail.log_yesterday, and then begins a new mail.log_current file.

At this point, criticism comes in.

Why? No automatic log rotation? How can that be from an Enterprise product?

Well, I replied: 

Sun is giving you the flexibility. :)

Anyway, to rotate mail.log is not too difficult on Solaris platform. We just need to learn about logadm.
You need to know that logadm is already configured out-of-the-box.

bash-3.00# crontab -l
# The root crontab should be used to perform accounting data collection.
10 3 * * * /usr/sbin/logadm

All we need to do is to add a new entry into logadm.conf file.

bash-3.00# ls -al /etc/logadm.conf 
-rw-r--r--   1 root     sys         1485 Jun 11 03:10 /etc/logadm.conf

e.g. /appl/SJMS/log/mail.log -c -C 356 -t '$dirname/$basename.$n'

Rotate the log file by copying it and truncating the original logfile to zero length, rather than renaming the file.

-C count
Delete the oldest versions until there are not more than count files left.

-t template
Specify the template to use when renaming log files.

The directory of the file to be rotated

The log file name, without the directory name

The version number, 0 is most recent, 1 is next most recent, and so forth

Thursday, June 11, 2009

Cannot start Java Web Console (smcwebserver)

I deployed Sun Cluster for MySQL HA two weeks ago for a defense customer. Everything runs fine and they are able to manage the cluster via CLI (command line interface).

Now, they request for Sun Cluster Manager which was introduced to them during their course. Frankly speaking, I'm trained in Sun Cluster but I have never seen the GUI version before. I did not know of its existence. :)

Upon their request, I made some research and realized it's accessible  via Java Web Console. Now, I know a lot about Java Web Console! I'hv deployed numerous Sun Java System Directory Manager 6.x. Managing directory configuration/data can be made via Java Web Console.

Well, to start Java Web Console is trivial.

1. Ensure Cacao is running
    $ cacaoadm status
2. Ensure SMC Web Server is running
    $ smcwebserver status
3. If it is not running, start it
    $ smcwebserver start

Today, I'm not lucky. I kept getting this error while starting Java Web Console.

$ smcwebserver start
Starting Sun Java(TM) Web Console Version 3.1 ...
Cannot determine if console service is running.
Check log file: /var/svc/log/system-webconsole:console.log
Run "svcs system/webconsole:console" to determine its status.

Finally, the issue was resolved.

$ /usr/share/webconsole/private/bin/wcremove -i console
$ svcadm clear system/webconsole:console

Restart of the server is required. We need to be careful as we are in cluster mode.

On node 1,
$ clnode evacuate 
$ init 6

Upon node 1 reboot, few things happen:
1. Node 1 rejoins the cluster
2. cacao and smcwebserver daemon start automatically
3. Able to access https://localhost:6789

On node 2,
$ clnode evacuate 
$ init 6

The same happens to node 2 upon reboot.


Wednesday, June 10, 2009

OpenMail Control Panel

I talked about our switch to Sun Java System Messaging Server some times back (read here). We brand it as OpenMail

Feedbacks were gathered and it was very obvious that our customers did not like Sun Java System Delegated Administrator - an administrative user interface. It was not intuitive for normal administrators. (These are usually non-technical people being assigned to manage user mail accounts for his/her company) 

I must admit the words "Delegated Administrator" already create confusion among our customers. Thus, we decided that we need to build our own administrative user interface - from scratch. 

We call it OpenMail Control Panel. (Many people know what is CPanel.  They can relate to what it is supposed to do. Thus, "Control Panel" is suitable.)

We consciously apply Pareto principle (commonly known as 80/20 rule) during development. 
  1. We will only develop features required by 80% of our user base.
  2. 20% of the features requests will take up 80% of our development time, but might not be useful to our users (at least for 80% of them). Thus, we should not spend time on these.
The features should be business-driven, practical and intuitive:
  1. Non-cluttered interface
  2. Single page to create new email account (no wizard please!)
  3. Single page to create new mailing list (again - no wizard please!)
  4. Single page to list users' quota (new feature request)
  5. Receive a list of over-quota email accounts (new feature request)

Create New Email Account

Create New Mailing List

View Over-Quota Accounts ( New Feature )

Receive Over-Quota Accounts Notification ( New Feature )

This is our initial release and we'll spend a couple of weeks gathering feedback from our customers. We hope to refine the current features before new ones are added.

Tuesday, June 9, 2009

How to backup Sun Directory Server Data?

Can we backup the LDAP data by executing a filesystem backup on a daily basis?

This question has popped up twice - once from a local defense customer; the other time is from my Thai customer. 

The answer is "No". The LDAP is constantly running, and thus is "hot". A filesystem backup is definitely not appropriate.  

For Sun Directory Server 6.x, there is this helpful command "dsconf" to assist you in backing up your LDAP data.

I suggest a database backup, followed by a LDIF backup.

Backs up Directory Server data (configuration data excluded)
/opt/SUNWdsee/ds6/bin/dsconf backup -p 389 -c /ldap/backup/db/`date +%Y_%m_%d_%H%M%S`

Exports suffix data to LDIF format

/opt/SUNWdsee/ds6/bin/dsconf export -Q -p 389 -c o=isp /ldap/backup/ldif/123.ldif

By using the "dsconf" command, you can be assured that there is no downtime in your directory service.

Thursday, June 4, 2009

Sun Access Manager : Session Timeout

I'm still in Bangkok today with the same local Thai bank. Today, we were discussing about Session Timeout with Sun Java System Access Manager 7.1 SP1.  (FYI, AM 8.x is now known as Sun OpenSSO Enterprise. OpenSSO is free; OpenSSO Enterprise is commercial licensed)

The customer is asking why an authenticated user is getting Session Timeout error. 

For example, the user has logon to the Access Manager and been idle for more than a few minutes. When he comes back and tries to continue with what he previously left with, he gets the "Your session has timed out" error message.

Well, I point them to the above diagram which I find very useful. (If you need to know more about Session Service, you can read from here)

If you analyze the state diagram carefully, you'll realize that an Idle Time-Out session will go into Expired Session state. In this state, the session has not been destroyed yet, unless the purge delay time elapses. 

Therefore, in the Session table, you'll find a session with SSO token event type  "SSO_TOKEN_IDLE_TIMEOUT". This explains why the error message "Your session has timed out" appears.

The next question is how do we avoid getting this Session timeout error.

Well, the explanation is here.

Edit the AMConfig.properties file.
Change the value 

Restart your AM server.

The customer then asks why an unauthenticated user is also getting Session Timeout error. 

For example, the user has been on the Access Manager login screen and been idle for more than a few minutes. When he comes back and try to logon, he gets the "Your session has timed out" error message.

Well, this took me quite a while to answer. The detail is hidden here.  

Basically, you need to do a few things:
1. Know which authentication module is utilized
2. Search for the appropriate XML file in [webapp-path]/SUNWam/web-src/services/config/auth/default. (In our case, LDAP.xml)
3. Set value to 0 for every occurrence of the attribute timeout
4. Restart AM server

Wednesday, June 3, 2009

Sun Directory Server: Disallow anonymous access

This week, I am in Bangkok providing consultancy to a local Thai Bank. 

I have deployed Sun Directory Servers with Multi-Master Replication ("MMR") for them some time back. This trip is to fine-tune the deployment. They ask to disallow anonymous access to their Enterprise Directory Service.

By default, Sun Directory Server allow anonymous read-search access out-of-the-box. 

(target ="ldap:///o=isp")(targetattr !="userPassword")(version 3.0;acl "Anonymous read-search access";allow (read, search, compare)(userdn = "ldap:///anyone");)

Note: It does not allow reading of the userPassword attribute though.

Here we go:

bash-3.00# ldapmodify -D "cn=Directory Manager" -w password
dn: o=isp
changetype: modify
delete: aci
aci: (target ="ldap:///o=isp")(targetattr !="userPassword")
 (version 3.0;acl "Anonymous read-search access";
 allow (read, search, compare)
 (userdn = "ldap:///anyone");)

Note: There should be a space prefix to the last 3 lines.