When you move a user account from domain1.com to domain2.com, the users calendar items don't get updated so all appointments become read-only.

The error when trying to change a calendar item is:

Code:
msg - invalid request: Changing organizer of an appointment/task is not allowed: old=user@domain1.com, new=user@domain2.com
code - service.INVALID_REQUEST
method - ZmCsfeCommand.prototype.invoke
detail - soap:Sender
This happens when you change the user's name within the same domain as well.

I wrote a little perl script to "fix" the calendars of changed users.

This script was necessary for us after our 200-user Zimbra rollout and the senior leadership decided to change the domain and username format. I thought I'd share it with the community for those who have similar problems.

It exports the calendar, does a simple find/replace, emptys the old calendar, and imports the new hacked calendar.

You'll need to give create a home directory for the zimbra user at /home/zimbra and give ownership to that directory to the zimbra user. It creates a number of files for that user (old calendar, new calendar, logs) inside of that folder for each user you run the script for. This was necessary for me to keep track if something went wrong.

Run the script as the zimbra user and feed it two arguments: the new account name and the old account name.

Usage is as follows:
fixcal.pl newaccountname@newdomain.com oldaccountname@olddomain.com

Code:
#!/usr/bin/perl
$newaccountname = $ARGV[0];
$oldaccountname = $ARGV[1];
print "Working on $newaccountname\n";
print "Old Account name is $oldaccountname\n";
    # Create a dir for this user
        $argtext = "mkdir /home/zimbra/$newaccountname";
        @args = ($argtext);
        system(@args) == 0 or print "Unable to create folder $newaccountname: $?";
    # Now we get all the calendars associated with this account
        $argtext = "zmmailbox -z-m $newaccountname gaf | grep appo >> /home/zimbra/$newaccountname/cal_list";
        @args = ($argtext);
        system(@args) == 0 or print "Unable to get the list of calendars for $newaccountname: $?";
        $calfile = "/home/zimbra/$newaccountname/cal_list";
        open(CALS, $calfile);
        @lines = <CALS>;
        close(CALS);
        foreach $line(@lines){
            # Only shared calendars contain a colon.
            if ($line !~ m/:/i) {
                $pos = index($line, "\/") + 1;
                $calendar = substr($line, $pos);
                chomp $calendar;
                # URL encode the calendar string.
                use CGI;
                $calendarurlstyle = CGI::escape($calendar); 
                # Get the calendar and export it to a file
                $argtext = "zmmailbox -z-m $newaccountname gru $calendarurlstyle > /home/zimbra/$newaccountname/calendar";
                @args = ($argtext);
                system(@args) == 0 or print "Unable to get calendar $calendar for $newaccountname: $?";
                print "$newaccountname had $calendar exported\n";

                # Open the calendar and replace the old account name with the new one.
                $calfile = "/home/zimbra/$newaccountname/calendar";
                open(CAL, $calfile);
                @mycal = <CAL>;
                close(CALS);
                # Search and replace
                @newcal = ();
                for (@mycal) { 
                    s/$oldaccountname/$newaccountname/; 
                    push(@newcal,$_);
                }
                # Push newcal info into the new file newcalendar.ics
                $newcalfile = "/home/zimbra/$newaccountname/newcalendar.ics";
                open (NEWCAL, ">$newcalfile");
                seek(NEWCAL,0,0);
                print NEWCAL (@newcal);
                close(NEWCAL);
               
                # Empty the old calendar - we don't delete it so any shares or settings should stay in place
                # command is :zmmailbox -z-m useraccount@fh.org ef "Calendar Name"
                $argtext = "zmmailbox -z-m $newaccountname ef \"$calendar\"";
                @args = ($argtext);
                system(@args) == 0 or print "Unable to empty the $calendar folder for $newaccountname: $?";
                print "$newaccountname had $calendar emptied\n";

                # Import the new calendar
                # command is: zmmailbox -z-m useraccount@fh.org pru "Calendar Name" /home/zimbra/useraccount@fh.org/newcalendar.ics
                $argtext = "zmmailbox -z-m $newaccountname pru \"$calendarurlstyle\" $newcalfile";
                @args = ($argtext);
                system(@args) == 0 or print "Unable to import the new calendar $calendar for $newaccountname: $?";
                print "$newaccountname had $calendar imported\n";
            } 
        }
print "Finished $newaccountname\n";
Hope that helps others.