步骤还挺复杂我先粗略的写下
基于 rc 0.3.1
用到的plugins 是globaladdressbook
1.表结构调整
-- 表的结构 `contacts`
CREATE TABLE IF NOT EXISTS `contacts` (
  `contact_id` int(10) unsigned NOT NULL auto_increment,
  `changed` datetime NOT NULL default '1000-01-01 00:00:00',
  `del` tinyint(1) NOT NULL default '0',
  `name` varchar(128) NOT NULL,
  `email` varchar(128) NOT NULL,
  `firstname` varchar(128) NOT NULL,
  `surname` varchar(128) NOT NULL,
  `vcard` text,
  `user_id` int(10) unsigned NOT NULL default '0',
  `global_contact` int(1) NOT NULL default '0',
  `firm` varchar(128) default NULL,
  `position` varchar(50) default NULL,
  `p_tel` varchar(30) default NULL,
  `p_fax` varchar(30) default NULL,
  `p_mob` varchar(20) default NULL,
  `p_address` text,
  `w_tel` varchar(20) default NULL,
  `w_fax` varchar(20) default NULL,
  `w_mob` varchar(20) default NULL,
  `w_address` text,
  `notice` text,
  `email2` varchar(128) default NULL,
  `email3` varchar(128) default NULL,
  `email4` varchar(128) default NULL,
  `birth` varchar(10) default NULL,
  PRIMARY KEY  (`contact_id`),
  KEY `user_contacts_index` (`user_id`,`email`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ;
2.globaladdressbook 插件
-- 语言包增加 
zh_CN.inc (UTF8编码)
<?php
/* Author: Philip Weir */
$labels = array();
$labels['globaladdressbook'] = '全局联系人';
$messages = array();
?>
-- 修改 globaladdressbook.php
        public function get_address_book($args)
        {
                if ($args['id'] === $this->abook_id) {
                        $args['instance'] = new rcube_contacts(rcmail::get_instance()->db, $this->user_id);
                        $args['instance']->readonly = $this->readonly;
                        $args['instance']->global = true; #增加标示为全局
                }
3.修改 /var/www/roundcubemail/program/include/rcube_contacts.php
class rcube_contacts extends rcube_addressbook
{
  var $db = null;
  var $db_name = '';
  var $user_id = 0;
  var $filter = null;
  var $result = null;
  var $search_fields;
  var $search_string;
  var $table_cols = array('name', 'email', 'firstname', 'surname', 'global_contact', 'vcard', 'firm', 'position', 'p_tel', 'p_fax', 'p_mob', 'p_address', 'w_tel', 'w_fax', 'w_mob', 'w_address', 'notice', 'email2', 'email3', 'email4', 'birth');
  /** public properties */
  var $primary_key = 'contact_id';
  var $readonly = false;
  var $list_page = 1;
  var $page_size = 10;
  var $ready = false;
  var $global = false;
---------------
 function list_records($cols=null, $subset=0)
...
      $sql_result = $this->db->limitquery(
        "SELECT * FROM ".$this->db_name."
         WHERE  del<>1".
        ($this->global ? " AND global_contact = 1": " AND user_id=?").
        ($this->filter ? " AND (".$this->filter.")" : "") .
        " ORDER BY name",
----------------
  function count()
  {
    // count contacts for this user
    $sql_result = $this->db->query(
      "SELECT COUNT(contact_id) AS rows
       FROM ".$this->db_name."
       WHERE  del<>1".
       ($this->global ? " AND global_contact = 1": " AND user_id=?").
       ($this->filter ? " AND (".$this->filter.")" : ""),
      $this->user_id);
-----------------
  function get_record($id, $assoc=false)
...
    $this->db->query(
      "SELECT * FROM ".$this->db_name."
       WHERE  contact_id=?".
      ($this->global ? " AND global_contact = 1": " AND user_id=?").
      " AND    del<>1",
-----------------
  function update($id, $save_cols)
  {
    $updated = false;
    $write_sql = array();
    foreach ($this->table_cols as $col)
      if (isset($save_cols[$col]))
        $write_sql[] = sprintf("%s=%s", $this->db->quoteIdentifier($col), $this->db->quote($save_cols[$col]));
    if (!empty($write_sql))
    {
      $this->db->query(
        "UPDATE ".$this->db_name."
         SET    changed=".$this->db->now().", ".join(', ', $write_sql)."
         WHERE  contact_id=?".
        ($this->global ? " AND global_contact = 1": " AND user_id=?").
        " AND    del<>1",
        $id,
        $this->user_id);
      $updated = $this->db->affected_rows();
    }
    return $updated;
  }
-----------------
  function delete($ids)
  {
    if (is_array($ids))
      $ids = join(',', $ids);
    $this->db->query(
      "UPDATE ".$this->db_name."
       SET    del=1".
        ($this->global ? " WHERE global_contact = 1": " WHERE user_id=?").
       " AND    contact_id IN (".$ids.")",
      $this->user_id);
    return $this->db->affected_rows();
  }
4.修改 /var/www/roundcubemail/program/steps/addressbook/show.inc
function rcmail_contact_details($attrib)
...
  $a_show_cols = array('name', 'firstname', 'surname', 'global_contact', 'email', 'firm', 'position', 'p_tel', 'p_fax', 'p_mob', 'p_address', 'w_tel', 'w_fax', 'w_mob', 'w_address', 'notice', 'email2', 'email3', 'email4', 'birth');
  $microformats = array('name' => 'fn', 'email' => 'email');
  foreach ($a_show_cols as $col) {
if (($col=='email' || $col=='email2' || $col=='email3' || $col=='email4') && !empty($record[$col])) {
      $value = html::a(array(
        'href' => 'mailto:' . $record[$col],
        'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ($record[$col])),
        'title' => rcube_label('composeto'),
        'class' => $microformats[$col],
      ), Q($record[$col]));
    }
    else if ($col=='global_contact'){
      $value = html::span($microformats[$col], Q($record[$col]==1?'Yes':'No'));
    }
    else if (!empty($record[$col])) {
      $value = html::span($microformats[$col], Q($record[$col]));
    }
    else
      $value = '';
...
5.修改 /var/www/roundcubemail/program/steps/addressbook/edit.inc
function rcmail_contact_editform($attrib)
...
  $out = "$form_start<table>\n\n";
  $a_show_cols = array('name', 'firstname', 'surname', 'global_contact', 'email', 'firm', 'position', 'p_tel', 'p_fax', 'p_mob', 'p_address', 'w_tel', 'w_fax', 'w_mob', 'w_address', 'notice', 'email2', 'email3', 'email4', 'birth');
  foreach ($a_show_cols as $col)
  {
    $attrib['id'] = 'rcmfd_'.$col;
    $value = rcmail_get_edit_field($col, $record[$col], $attrib);
        if($col == "global_contact"){
        $out .= sprintf("<tr><td class=\"title\"><label for=\"%s\">%s</label></td><td>%s</td></tr>\n",
                    $attrib['id'],
                    Q(rcube_label($col)),
                    rcmail_get_edit_field($col, $record[$col], $attrib, 'checkbox'));
        } else if(!$value == "")
        $out .= sprintf("<tr><td class=\"title\"><label for=\"%s\">%s</label></td><td>%s</td></tr>\n",
                    $attrib['id'],
                    Q(rcube_label($col)),
                    $value);
  }
  $out .= "\n</table>$form_end";
...
6.修改 /var/www/roundcubemail/program/steps/addressbook/save.inc
// setup some vars we need
$a_save_cols = array('name', 'firstname', 'surname', 'global_contact', 'email', 'p_tel', 'firm', 'position', 'p_tel', 'p_fax', 'p_mob', 'p_address', 'w_tel', 'w_fax', 'w_mob', 'w_address', 'notice', 'email2', 'email3', 'email4', 'birth');
$a_record = array();
// read POST values into hash array
foreach ($a_save_cols as $col)
{
  $fname = '_'.$col;
if($col == 'global_contact'){
if(isset($_POST[$fname])){
$a_record[$col] = 1;
}else{
$a_record[$col] = 0;
}
}else
  if (isset($_POST[$fname]))
    $a_record[$col] = get_input_value($fname, RCUBE_INPUT_POST);
}
7. 添加 /var/www/roundcubemail/program/localization/zh_CN/labels.inc (UTF8) 
$labels['global_contact'] = '全局联系人';
$labels['firm']      = '公司名称';
$labels['position'] = '职务';
$labels['p_tel']   = '电话';
$labels['p_fax']     = '传真';
$labels['p_mob']      = '手机';
$labels['p_address'] = '地址';
$labels['w_tel']   = '工作电话';
$labels['w_fax']     = '工作传真';
$labels['w_mob']      = '工作手机';
$labels['w_address'] = '工作地址';
$labels['notice']   = '备注';
$labels['email2']     = 'E-Mail2';
$labels['email3']     = 'E-Mail3';
$labels['email4']     = 'E-Mail4';
$labels['birth']     = '生日';
8. 修改 /var/www/roundcubemail/plugins/globaladdressbook/config.inc.php
这样全局通讯录的管理权限就可以使用了
$rcmail_config['globaladdressbook_readonly'] = true;
// global address book admin user
// either a single username or an array of usernames
$rcmail_config['globaladdressbook_admin'] = array('user1@youdomain','user2@youdomain');